summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoruint23 <[email protected]>2025-04-28 07:40:40 +0100
committeruint23 <[email protected]>2025-04-28 07:40:40 +0100
commit0a1816addb7dcc1462767d6cafb2bf51dcc1c122 (patch)
tree6a655e649052f978d6a2d98d74f41ccc415c111d
parentbc2401064614e9a87a01189e177a2a7978ff5522 (diff)
parser not stable, testing
-rw-r--r--src/defs.h4
-rw-r--r--src/parser.c211
-rw-r--r--src/parser.h24
-rw-r--r--src/sxwm.c13
4 files changed, 235 insertions, 17 deletions
diff --git a/src/defs.h b/src/defs.h
index 000e842..e7f1144 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -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);
diff --git a/src/sxwm.c b/src/sxwm.c
index c3567db..1ffa119 100644
--- a/src/sxwm.c
+++ b/src/sxwm.c
@@ -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);