Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User-defined shaders #119

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/sway/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ sway_cmd cmd_scratchpad;
sway_cmd cmd_seamless_mouse;
sway_cmd cmd_set;
sway_cmd cmd_shortcuts_inhibitor;
sway_cmd cmd_shader;
sway_cmd cmd_shadow_blur_radius;
sway_cmd cmd_shadow_color;
sway_cmd cmd_shadows;
Expand Down
10 changes: 10 additions & 0 deletions include/sway/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,12 @@ enum xwayland_mode {
XWAYLAND_MODE_IMMEDIATE,
};

struct foreign_shader_compile_target {
char *frag; // frag shader file path
char *vert; // vert shader file path
char *label; // shader label
};

/**
* The configuration struct. The result of loading a config file.
*/
Expand All @@ -487,6 +493,8 @@ struct sway_config {
bool shadows_on_csd_enabled;
int shadow_blur_sigma;
float shadow_color[4];
// foreign_shader_compile_target *, used by fx_rederer during initialization
list_t *foreign_shader_compile_queue;

char *swaynag_command;
struct swaynag_instance swaynag_config_errors;
Expand Down Expand Up @@ -716,6 +724,8 @@ void free_switch_binding(struct sway_switch_binding *binding);

void free_gesture_binding(struct sway_gesture_binding *binding);

void free_foreign_shader_compile_target(struct foreign_shader_compile_target *target);

void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding);

void load_swaybar(struct bar_config *bar);
Expand Down
21 changes: 21 additions & 0 deletions include/sway/desktop/fx_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <stdbool.h>
#include "list.h"

enum corner_location { ALL, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, NONE };

Expand All @@ -16,6 +17,15 @@ struct decoration_data {
bool has_titlebar;
};

// TODO: extra params in a list
struct foreign_shader {
char *label;
GLuint program;
GLint tex;
GLint pos_attrib;
GLint tex_attrib;
};

struct gles2_tex_shader {
GLuint program;
GLint proj;
Expand Down Expand Up @@ -97,6 +107,17 @@ struct fx_renderer {
GLint corner_radius;
} box_shadow;

struct {
GLuint program;
GLint proj;
GLint tex;
GLint pos_attrib;
GLint tex_attrib;
GLint position;
} invert;

list_t *foreign; // struct foreign_shader*

struct gles2_tex_shader tex_rgba;
struct gles2_tex_shader tex_rgbx;
struct gles2_tex_shader tex_ext;
Expand Down
1 change: 1 addition & 0 deletions sway/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ static const struct cmd_handler handlers[] = {
{ "popup_during_fullscreen", cmd_popup_during_fullscreen },
{ "seat", cmd_seat },
{ "set", cmd_set },
{ "shader", cmd_shader },
{ "shadow_blur_radius", cmd_shadow_blur_radius },
{ "shadow_color", cmd_shadow_color },
{ "shadows", cmd_shadows },
Expand Down
92 changes: 92 additions & 0 deletions sway/commands/shader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#define _POSIX_C_SOURCE 200809L
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include "sway/commands.h"
#include "log.h"
#include "stringop.h"

struct cmd_results *stat_file(const char *path) {
// FIXME: ~ paths don't work
FILE *f = fopen(path, "r");
if (!f) {
return cmd_results_new(CMD_FAILURE, "Failed to open custom shader file: %s", path);
}
struct stat statbuf;
if (fstat(fileno(f), &statbuf) < 0) {
fclose(f);
return cmd_results_new(CMD_FAILURE, "Failed to access custom shader file: %s", path);
}

fclose(f);
return NULL;
}

struct cmd_results *set(const char *shader) {
return cmd_results_new(CMD_SUCCESS, NULL);
}

struct cmd_results *load(char *label, char *vert_path, char *frag_path) {
struct cmd_results *result = cmd_results_new(CMD_SUCCESS, NULL);

// FIXME: erorr handling
if (vert_path != NULL) {
expand_path(&frag_path);
stat_file(vert_path);
}
stat_file(frag_path);

struct foreign_shader_compile_target *tgt =
calloc(1, sizeof(struct foreign_shader_compile_target));
if (!tgt) {
free(label);
if (vert_path != NULL)
free(vert_path);
free(frag_path);
return cmd_results_new(CMD_FAILURE, "Allocation error");
}
tgt->label = strdup(label);
if (vert_path != NULL)
tgt->vert = strdup(vert_path);
tgt->frag = strdup(frag_path);
// FIXME: free pointers!

list_add(config->foreign_shader_compile_queue, tgt);
return cmd_results_new(CMD_SUCCESS, NULL);
}

struct cmd_results *param(char *shader, char *param) {
// FIXME: finish
return cmd_results_new(CMD_SUCCESS, NULL);
}

// FIXME: passing two shader commands ruins everything
struct cmd_results *cmd_shader(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "shader", EXPECTED_AT_LEAST, 1))) {
return error;
}

/* struct sway_container *con = config->handler_context.container; */
/* if (con == NULL) { */
/* return cmd_results_new(CMD_FAILURE, "No current container"); */
/* } */

if (argc == 2) {
// Set shader as default
return cmd_results_new(CMD_SUCCESS, NULL);
}

// FIXME: quotes and stuff
if (!strcmp(argv[0], "load") && (argc == 3 || argc == 4)) {
char *vert = argc == 4 ? argv[2] : NULL;
char *frag = argc == 4 ? argv[3] : argv[2];
if (expand_path(&frag) && (!vert || expand_path(&vert)))
return load(argv[1], vert, frag);
} else if (!strcmp(argv[0], "param")) {
return param(argv[1], NULL);
}

return cmd_results_new(CMD_INVALID,
"Expected: load [vert] <frag>|param", argv[0]);
}
10 changes: 10 additions & 0 deletions sway/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ void free_config(struct sway_config *config) {
}
list_free(config->criteria);
}
if (config->foreign_shader_compile_queue) {
for (int i = 0; i < config->criteria->length; ++i) {
free_foreign_shader_compile_target(
config->foreign_shader_compile_queue->items[0]);
}
list_free(config->criteria);
}
list_free(config->no_focus);
list_free(config->active_bar_modifiers);
list_free_items_and_destroy(config->config_chain);
Expand Down Expand Up @@ -343,6 +350,7 @@ static void config_defaults(struct sway_config *config) {
config->shadows_on_csd_enabled = false;
config->shadow_blur_sigma = 20.0f;
color_to_rgba(config->shadow_color, 0x0000007F);
if (!(config->foreign_shader_compile_queue = create_list())) goto cleanup;

// The keysym to keycode translation
struct xkb_rule_names rules = {0};
Expand Down Expand Up @@ -927,6 +935,8 @@ bool read_config(FILE *file, struct sway_config *config,
config->current_config_line_number = 0;
config->current_config_line = NULL;

/* struct foreign_shader_compile_target *target = config->foreign_shader_compile_queue->items[0]; */
/* sway_log(SWAY_ERROR, "found %s %s at %p", target->label, target->frag, config->foreign_shader_compile_queue->items[0]); */
return success;
}

Expand Down
8 changes: 8 additions & 0 deletions sway/desktop/foreign_shader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "sway/config.h"

void free_foreign_shader_compile_target(struct foreign_shader_compile_target *target) {
free(target->frag);
if (target->vert)
free(target->vert);
free(target);
}
Loading