diff options
author | uint23 <[email protected]> | 2025-04-28 07:40:40 +0100 |
---|---|---|
committer | uint23 <[email protected]> | 2025-04-28 07:40:40 +0100 |
commit | 0a1816addb7dcc1462767d6cafb2bf51dcc1c122 (patch) | |
tree | 6a655e649052f978d6a2d98d74f41ccc415c111d /src | |
parent | bc2401064614e9a87a01189e177a2a7978ff5522 (diff) |
parser not stable, testing
Diffstat (limited to 'src')
-rw-r--r-- | src/defs.h | 4 | ||||
-rw-r--r-- | src/parser.c | 211 | ||||
-rw-r--r-- | src/parser.h | 24 | ||||
-rw-r--r-- | src/sxwm.c | 13 |
4 files changed, 235 insertions, 17 deletions
@@ -95,6 +95,7 @@ typedef struct Client{ } Client; typedef struct { + int modkey; int gaps; int border_width; long border_foc_col; @@ -103,6 +104,7 @@ typedef struct { int master_width; int resize_master_amt; int snap_distance; + int bindsn; Binding binds[256]; } Config; @@ -118,7 +120,9 @@ extern void focus_prev(void); extern void inc_gaps(void); extern void move_master_next(void); extern void move_master_prev(void); +extern long parse_col(const char *hex); extern void quit(void); +extern void reload_config(void); extern void resize_master_add(void); extern void resize_master_sub(void); extern void toggle_floating(void); diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..4eca3c2 --- /dev/null +++ b/src/parser.c @@ -0,0 +1,211 @@ +#include <ctype.h> +#include <linux/limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <X11/keysym.h> +#include <X11/keysymdef.h> + +#include "parser.h" + +static struct { const char *n; void (*fn)(void); } call_table[] = { + {"close_window", close_focused}, + {"decrease_gaps", dec_gaps}, + {"focus_next", focus_next}, + {"focus_previous", focus_prev}, + {"increase_gaps", inc_gaps}, + {"master_next", move_master_next}, + {"master_previous", move_master_prev}, + {"quit", quit}, + {"reload_config", reload_config}, + {"master_increase", resize_master_add}, + {"master_decrease", resize_master_sub}, + {"floating", toggle_floating}, + {"global_floating", toggle_floating_global}, + {"fullscreen", toggle_fullscreen}, + { NULL, NULL } +}; + +void +handler(char *command, char *arg, + unsigned int mods, KeySym keysym, + Action action, Bool is_func, + Config *user_config) +{ + if (strcmp(command, "bind") == 0) { + if (is_func) { + /* look up function by name */ + for (unsigned long i = 0; i < LENGTH(call_table); ++i) { + if (strcmp(arg, call_table[i].n) == 0) { + user_config->binds[user_config->bindsn].action.fn = call_table[i].fn; + user_config->binds[user_config->bindsn].is_func = True; + user_config->binds[user_config->bindsn].mods = mods; + user_config->binds[user_config->bindsn].keysym = keysym; + ++user_config->bindsn; + return; + } + } + fprintf(stderr, "sxwmrc: unknown function call: %s\n", arg); + } else { + user_config->binds[user_config->bindsn].action.cmd = action.cmd; + user_config->binds[user_config->bindsn].is_func = False; + user_config->binds[user_config->bindsn].mods = mods; + user_config->binds[user_config->bindsn].keysym = keysym; + ++user_config->bindsn; + } + return; + } + + /* TODO USE A TABLE */ + if (strcmp(command, "gaps") == 0) user_config->gaps = atoi(arg); + else if (strcmp(command, "border_width") == 0) user_config->border_width = atoi(arg); + else if (strcmp(command, "focus_border_colour") == 0) user_config->border_foc_col = parse_col(arg); + else if (strcmp(command, "unfocus_border_colour")== 0) user_config->border_ufoc_col = parse_col(arg); + else if (strcmp(command, "swap_border_colour") == 0) user_config->border_swap_col = parse_col(arg); + else if (strcmp(command, "master_coverage") == 0) user_config->master_width = atoi(arg); + else if (strcmp(command, "resize_master_amount") == 0) user_config->resize_master_amt = atoi(arg); + else if (strcmp(command, "snap_distance") == 0) user_config->snap_distance = atoi(arg); + else + fprintf(stderr, "sxwmrc: unknown command: %s\n", command); +} + +void +parser(Config *user_config) +{ + char *home = getenv("HOME"); + if (!home) { + fputs("sxwmrc: HOME environment variable not set\n", stderr); + return; + } + char sxwmrc[PATH_MAX]; + snprintf(sxwmrc, sizeof(sxwmrc), "%s/.config/sxwmrc", home); + + FILE *f = fopen(sxwmrc, "r"); + if (!f) { + fprintf(stderr, "sxwmrc: file not found: %s\n", sxwmrc); + return; + } + + char line[512]; + while (fgets(line, sizeof(line), f)) { + char *s = strip(line); + if (!*s || *s == '#' || *s == '\n') + continue; + + char *c = strchr(s, ':'); + if (!c) { + fprintf(stderr, "sxwmrc: invalid line (no colon): %s\n", s); + continue; + } + *c = '\0'; + char *key = strip(s); + char *val = strip(c+1); + + if (strcmp(key, "bind") == 0) { + char *d = strchr(val, ':'); + if (!d) { + fprintf(stderr, "sxwmrc: invalid bind (no action): %s\n", val); + continue; + } + *d = '\0'; + char *combo = strip(val); + char *act = strip(d+1); + + if (*combo == '[') combo++; + size_t L = strlen(combo); + if (L && combo[L-1] == ']') combo[L-1] = '\0'; + + unsigned int mods = 0; + KeySym ks = 0; + char part[64]; + char *tok = strtok(combo, "+"); + while (tok) { + char *p = strip(tok); + for (size_t i=0; p[i]; i++) p[i] = tolower((unsigned char)p[i]); + if (strcmp(p,"mod") == 0) mods |= user_config->modkey; + else if (strcmp(p,"shift")==0) mods |= ShiftMask; + else if (strcmp(p,"ctrl")==0) mods |= ControlMask; + else if (strcmp(p,"alt")==0) mods |= Mod1Mask; + else { + strncpy(part, tok, sizeof(part)-1); + part[sizeof(part)-1] = '\0'; + ks = parse_keysym(strip(part)); + } + tok = strtok(NULL, "+"); + } + + Action a = { .cmd = NULL }; + Bool is_fn = False; + if (*act == '"') { + char *cmdstr = strip_quotes(act); + a.cmd = build_argv(cmdstr); + } else { + is_fn = True; + } + handler(key, act, mods, ks, a, is_fn, user_config); + + } else { + handler(key, val, 0, 0, (Action){0}, False, user_config); + } + } + + fclose(f); +} + +char * +strip(char *str) +{ + while (*str == ' ' || *str == '\t') str++; + char *end = str + strlen(str) - 1; + while (end > str && (*end==' '||*end=='\t'||*end=='\r'||*end=='\n')) + *end-- = '\0'; + return str; +} + + char * +strip_quotes(char *s) +{ + if (*s == '"') s++; + size_t n = strlen(s); + if (n && s[n-1] == '"') s[n-1] = '\0'; + return s; +} + +unsigned int +parse_mods(const char *mods, Config *user_config) +{ + unsigned int m = 0; + if (strstr(mods, "mod")) m |= user_config->modkey; + if (strstr(mods, "shift")) m |= ShiftMask; + if (strstr(mods, "ctrl")) m |= ControlMask; + if (strstr(mods, "alt")) m |= Mod1Mask; + return m; +} + +KeySym +parse_keysym(const char *key) +{ + KeySym ks = XStringToKeysym(key); + if (ks == NoSymbol) { + fprintf(stderr, "sxwmrc: unknown keysym: %s\n", key); + return 0; + } + return ks; +} + +static const char ** +build_argv(char *cmdline) +{ + char **argv = calloc(MAX_ARGS+1, sizeof(char *)); + if (!argv) return NULL; + + int argc = 0; + char *tok = strtok(cmdline, " \t"); + while (tok && argc < MAX_ARGS) { + argv[argc++] = tok; + tok = strtok(NULL, " \t"); + } + argv[argc] = NULL; + return (const char **)argv; +} diff --git a/src/parser.h b/src/parser.h index 997e245..29e2435 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,19 +1,11 @@ #pragma once #include "defs.h" +#define MAX_ARGS 64 -static struct { const char *n; void (*fn)(void); } call_table[] = { - {"close_window", close_focused}, - {"decrease_gaps", dec_gaps}, - {"focus_next", focus_next}, - {"focus_previous", focus_prev}, - {"increase_gaps", inc_gaps}, - {"master_next", move_master_next}, - {"master_previous", move_master_prev}, - {"quit", quit}, - {"master_increase", resize_master_add}, - {"master_decrease", resize_master_sub}, - {"floating", toggle_floating}, - {"global_floating", toggle_floating_global}, - {"fullscreen", toggle_fullscreen}, - {NULL,NULL} -}; +void handler(char *command, char *arg, unsigned int mods, KeySym keysym, Action action, Bool is_func, Config *user_config); +void parser(Config *user_config); +unsigned int parse_mods(const char *mods, Config *user_config); +KeySym parse_keysym(const char *key); +char* strip_quotes(char *s); +char* strip(char *str); +static const char** build_argv(char *cmdline); @@ -30,6 +30,7 @@ #include <X11/extensions/Xinerama.h> #include "defs.h" +#include "parser.h" void add_client(Window w); void change_workspace(int ws); @@ -59,8 +60,9 @@ void init_defaults(void); void move_to_workspace(int ws); void other_wm(void); int other_wm_err(Display *dpy, XErrorEvent *ee); -long parse_col(const char *hex); +/* long parse_col(const char *hex); */ /* void quit(void); */ +/* void reload_config(void); */ /* void resize_master_add(void); */ /* void resize_master_sub(void); */ void run(void); @@ -834,12 +836,14 @@ init_defaults(void) default_config.master_width = 50; default_config.resize_master_amt = 5; default_config.snap_distance = 5; + default_config.bindsn = 0; for (unsigned long i = 0; i < LENGTH(binds); ++i) { default_config.binds[i].mods = binds[i].mods; default_config.binds[i].keysym = binds[i].keysym; default_config.binds[i].action.cmd = binds[i].action.cmd; default_config.binds[i].is_func = binds[i].is_func; + ++default_config.bindsn; } user_config = default_config; @@ -973,7 +977,13 @@ quit(void) XFreeCursor(dpy, c_normal); XFreeCursor(dpy, c_resize); errx(0, "quitting..."); +} +void +reload_config(void) +{ + puts("sxwm: reloading config..."); + /* parser(&user_config); */ } void @@ -1043,6 +1053,7 @@ setup(void) setup_atoms(); other_wm(); init_defaults(); + /* parser(&user_config); */ grab_keys(); c_normal = XCreateFontCursor(dpy, XC_left_ptr); |