sxhkd-rc

[fork] simple X hotkey daemon (but for the rc shell)
Log | Files | Refs | README | LICENSE

commit dde1b8195300c5fe9c258f0c41d712ecf0f8d300
parent cd2c0a4e31e3a5a58998684c39316f1f36589b37
Author: Bastien Dejean <nihilhill@gmail.com>
Date:   Sat,  5 Jan 2013 18:54:13 +0100

General sequences for keysym and commands

Diffstat:
MREADME.md | 2+-
Mkeys.c | 57+++++++++++++++++++++++++++++++++++----------------------
Mkeys.h | 2+-
Msxhkd.c | 12++++++------
4 files changed, 43 insertions(+), 30 deletions(-)

diff --git a/README.md b/README.md @@ -34,7 +34,7 @@ The keysym names are those your will get from `xev` (minus the prefix if any). Mouse hotkeys can be defined by using one of the following special keysym names: `button1`, `button2`, `button3`, ..., `button24`. -`KEYSYM` can also be a sequence of the form `{KEYSYM_1,KEYSYM_2,...,KEYSYM_N}`, in which case, `COMMAND` must also contain a sequence with *N* elements: the pairing of the two sequences generates *N* hotkeys. +`KEYSYM` can contain a sequence of the form `{STRING_1,STRING_2,...,STRING_N}`, in which case, `COMMAND` must also contain a sequence with *N* elements: the pairing of the two sequences generates *N* hotkeys. What is actually executed is `/bin/sh -c COMMAND`, which means you can use environment variables in `COMMAND`. diff --git a/keys.c b/keys.c @@ -2518,11 +2518,11 @@ bool parse_modifier(char *name, uint16_t *modfield) return false; } -bool parse_sequence(char *name, char *seq) +bool parse_fold(char *name, char *folded_keysym) { - if (name[0] == SEQ_BEGIN && name[strlen(name) - 1] == SEQ_END) { - strncpy(seq, name + 1, strlen(name) - 2); - seq[strlen(name) - 2] = '\0'; + if (strchr(name, SEQ_BEGIN) != NULL && strrchr(name, SEQ_END) != NULL) { + strncpy(folded_keysym, name, strlen(name)); + folded_keysym[strlen(name)] = '\0'; return true; } return false; @@ -2545,30 +2545,43 @@ void get_lock_fields(void) PRINTF("lock fields %u %u %u\n", num_lock, caps_lock, scroll_lock); } -void unfold_hotkeys(char *keysym_seq, uint16_t modfield, xcb_event_mask_t event_mask, char *command) +bool extract_sequence(char *string, char *prefix, char *sequence, char *suffix) { - char *begin = strchr(command, SEQ_BEGIN); - char *end = strrchr(command, SEQ_END); - if (begin == NULL || end == NULL || ((end - begin - 1) < SEQ_MIN_LEN)) { - warn("Invalid sequence for command '%s'.\n", command); - return; - } - char *ks_ptr, *cmd_ptr; - char unfolded_command[MAXLEN]; - char command_seq[MAXLEN]; + char *begin = strchr(string, SEQ_BEGIN); + char *end = strrchr(string, SEQ_END); + if (begin == NULL || end == NULL || ((end - begin - 1) < SEQ_MIN_LEN)) + return false; + strncpy(sequence, begin + 1, end - begin - 1); + strncpy(prefix, string, begin - string); + strncpy(suffix, end + 1, strlen(string) - (1 + end - string)); + sequence[end - begin - 1] = '\0'; + prefix[begin - string] = '\0'; + suffix[strlen(string) - (1 + end - string)] = '\0'; + return true; +} + +void unfold_hotkeys(char *folded_keysym, uint16_t modfield, xcb_event_mask_t event_mask, char *folded_command) +{ + char keysym_sequence[MAXLEN]; + char keysym_prefix[MAXLEN]; + char keysym_suffix[MAXLEN]; + char command_sequence[MAXLEN]; char command_prefix[MAXLEN]; char command_suffix[MAXLEN]; - strncpy(command_seq, begin + 1, end - begin - 1); - strncpy(command_prefix, command, begin - command); - strncpy(command_suffix, end + 1, strlen(command) - (1 + end - command)); - command_seq[end - begin - 1] = '\0'; - command_prefix[begin - command] = '\0'; - command_suffix[strlen(command) - (1 + end - command)] = '\0'; + if (!extract_sequence(folded_keysym, keysym_prefix, keysym_sequence, keysym_suffix) || !extract_sequence(folded_command, command_prefix, command_sequence, command_suffix)) { + warn("Couldn't extract sequence from '%s' or '%s'.\n", folded_keysym, folded_command); + return; + } + char unfolded_keysym[MAXLEN], unfolded_command[MAXLEN]; xcb_keysym_t keysym = XCB_NO_SYMBOL; xcb_button_t button = XCB_NONE; - for (char *ks_item = strtok_r(keysym_seq, SEQ_SEP, &ks_ptr), *cmd_item = strtok_r(command_seq, SEQ_SEP, &cmd_ptr); ks_item != NULL && cmd_item != NULL; ks_item = strtok_r(NULL, SEQ_SEP, &ks_ptr), cmd_item = strtok_r(NULL, SEQ_SEP, &cmd_ptr)) { + char *ks_ptr, *cmd_ptr; + /* char ks_range_a = 0, ks_range_b = 0, cmd_range_a = 0, cmd_range_b = 0; */ + + for (char *ks_item = strtok_r(keysym_sequence, SEQ_SEP, &ks_ptr), *cmd_item = strtok_r(command_sequence, SEQ_SEP, &cmd_ptr); ks_item != NULL && cmd_item != NULL; ks_item = strtok_r(NULL, SEQ_SEP, &ks_ptr), cmd_item = strtok_r(NULL, SEQ_SEP, &cmd_ptr)) { snprintf(unfolded_command, sizeof(unfolded_command), "%s%s%s", command_prefix, cmd_item, command_suffix); - if (parse_key(ks_item, &keysym) || parse_button(ks_item, &button)) + snprintf(unfolded_keysym, sizeof(unfolded_keysym), "%s%s%s", keysym_prefix, ks_item, keysym_suffix); + if (parse_key(unfolded_keysym, &keysym) || parse_button(unfolded_keysym, &button)) generate_hotkeys(keysym, button, modfield, event_mask, unfolded_command); else warn("Unknown sequence keysym: '%s'.\n", ks_item); diff --git a/keys.h b/keys.h @@ -23,7 +23,7 @@ xcb_keycode_t *keycodes_from_keysym(xcb_keysym_t); bool parse_key(char *, xcb_keysym_t *); bool parse_button(char *, xcb_button_t *); bool parse_modifier(char *, uint16_t *); -bool parse_sequence(char *, char *); +bool parse_fold(char *, char *); xcb_event_mask_t key_to_mouse(xcb_event_mask_t); void get_lock_fields(void); void unfold_hotkeys(char *, uint16_t, xcb_event_mask_t, char *); diff --git a/sxhkd.c b/sxhkd.c @@ -73,13 +73,13 @@ void load_config(void) xcb_button_t button = XCB_NONE; uint16_t modfield = 0; xcb_event_mask_t event_mask = XCB_KEY_PRESS; - char keysym_seq[MAXLEN] = {'\0'}; + char folded_keysym[MAXLEN] = {'\0'}; while (fgets(line, sizeof(line), cfg) != NULL) { if (strlen(line) < 2 || line[0] == START_COMMENT) { continue; } else if (isspace(line[0])) { - if (keysym == XCB_NO_SYMBOL && button == XCB_NONE && strlen(keysym_seq) == 0) + if (keysym == XCB_NO_SYMBOL && button == XCB_NONE && strlen(folded_keysym) == 0) continue; unsigned int i = strlen(line) - 1; while (i > 0 && isspace(line[i])) @@ -89,16 +89,16 @@ void load_config(void) i++; if (i < strlen(line)) { char *command = line + i; - if (strlen(keysym_seq) == 0) + if (strlen(folded_keysym) == 0) generate_hotkeys(keysym, button, modfield, event_mask, command); else - unfold_hotkeys(keysym_seq, modfield, event_mask, command); + unfold_hotkeys(folded_keysym, modfield, event_mask, command); } keysym = XCB_NO_SYMBOL; button = XCB_NONE; modfield = 0; event_mask = XCB_KEY_PRESS; - keysym_seq[0] = '\0'; + folded_keysym[0] = '\0'; } else { char *name = strtok(line, TOK_SEP); if (name == NULL) @@ -108,7 +108,7 @@ void load_config(void) event_mask = XCB_KEY_RELEASE; name++; } - if (!parse_modifier(name, &modfield) && !parse_key(name, &keysym) && !parse_button(name, &button) && !parse_sequence(name, keysym_seq)) { + if (!parse_modifier(name, &modfield) && !parse_key(name, &keysym) && !parse_button(name, &button) && !parse_fold(name, folded_keysym)) { warn("Unrecognized key name: '%s'.\n", name); } } while ((name = strtok(NULL, TOK_SEP)) != NULL);