X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=c%2Fkbind.c;fp=c%2Fkbind.c;h=0000000000000000000000000000000000000000;hb=a648c05a7a2608e7e909317f5afe8427a0ea0d68;hp=399ec83003a4c1f423ea203cd4819e4ebe01c133;hpb=474f689132d906a553bdc695d3c179652cbe8c53;p=chaz%2Fopenbox diff --git a/c/kbind.c b/c/kbind.c deleted file mode 100644 index 399ec830..00000000 --- a/c/kbind.c +++ /dev/null @@ -1,354 +0,0 @@ -#include "focus.h" -#include "openbox.h" -#include "hooks.h" -#include "kbind.h" - -#include -#ifdef HAVE_STRING_H -# include -#endif - -typedef struct KeyBindingTree { - guint state; - guint key; - GList *keylist; - - /* the next binding in the tree at the same level */ - struct KeyBindingTree *next_sibling; - /* the first child of this binding (next binding in a chained sequence).*/ - struct KeyBindingTree *first_child; -} KeyBindingTree; - - -static KeyBindingTree *firstnode, *curpos; -static guint reset_key, reset_state; -static gboolean grabbed, user_grabbed; - -guint kbind_translate_modifier(char *str) -{ - if (!strcmp("Mod1", str)) return Mod1Mask; - else if (!strcmp("Mod2", str)) return Mod2Mask; - else if (!strcmp("Mod3", str)) return Mod3Mask; - else if (!strcmp("Mod4", str)) return Mod4Mask; - else if (!strcmp("Mod5", str)) return Mod5Mask; - else if (!strcmp("C", str)) return ControlMask; - else if (!strcmp("S", str)) return ShiftMask; - g_warning("Invalid modifier '%s' in binding.", str); - return 0; -} - -static gboolean translate(char *str, guint *state, guint *keycode) -{ - char **parsed; - char *l; - int i; - gboolean ret = FALSE; - KeySym sym; - - parsed = g_strsplit(str, "-", -1); - - /* first, find the key (last token) */ - l = NULL; - for (i = 0; parsed[i] != NULL; ++i) - l = parsed[i]; - if (l == NULL) - goto translation_fail; - - /* figure out the mod mask */ - *state = 0; - for (i = 0; parsed[i] != l; ++i) { - guint m = kbind_translate_modifier(parsed[i]); - if (!m) goto translation_fail; - *state |= m; - } - - /* figure out the keycode */ - sym = XStringToKeysym(l); - if (sym == NoSymbol) { - g_warning("Invalid key name '%s' in key binding.", l); - goto translation_fail; - } - *keycode = XKeysymToKeycode(ob_display, sym); - if (!keycode) { - g_warning("Key '%s' does not exist on the display.", l); - goto translation_fail; - } - - ret = TRUE; - -translation_fail: - g_strfreev(parsed); - return ret; -} - -static void destroytree(KeyBindingTree *tree) -{ - KeyBindingTree *c; - - while (tree) { - destroytree(tree->next_sibling); - c = tree->first_child; - if (c == NULL) { - GList *it; - for (it = tree->keylist; it != NULL; it = it->next) - g_free(it->data); - g_list_free(tree->keylist); - } - g_free(tree); - tree = c; - } -} - -static KeyBindingTree *buildtree(GList *keylist) -{ - GList *it; - KeyBindingTree *ret = NULL, *p; - - if (g_list_length(keylist) <= 0) - return NULL; /* nothing in the list.. */ - - for (it = g_list_last(keylist); it != NULL; it = it->prev) { - p = ret; - ret = g_new(KeyBindingTree, 1); - ret->next_sibling = NULL; - if (p == NULL) { - GList *it; - - /* this is the first built node, the bottom node of the tree */ - ret->keylist = g_list_copy(keylist); /* shallow copy */ - for (it = ret->keylist; it != NULL; it = it->next) /* deep copy */ - it->data = g_strdup(it->data); - } - ret->first_child = p; - if (!translate(it->data, &ret->state, &ret->key)) { - destroytree(ret); - return NULL; - } - } - return ret; -} - -static void assimilate(KeyBindingTree *node) -{ - KeyBindingTree *a, *b, *tmp, *last; - - if (firstnode == NULL) { - /* there are no nodes at this level yet */ - firstnode = node; - } else { - a = firstnode; - last = a; - b = node; - while (a) { - last = a; - if (!(a->state == b->state && a->key == b->key)) { - a = a->next_sibling; - } else { - tmp = b; - b = b->first_child; - g_free(tmp); - a = a->first_child; - } - } - if (!(last->state == b->state && last->key == a->key)) - last->next_sibling = b; - else { - last->first_child = b->first_child; - g_free(b); - } - } -} - -KeyBindingTree *find(KeyBindingTree *search, gboolean *conflict) -{ - KeyBindingTree *a, *b; - - *conflict = FALSE; - - a = firstnode; - b = search; - while (a && b) { - if (!(a->state == b->state && a->key == b->key)) { - a = a->next_sibling; - } else { - if ((a->first_child == NULL) == (b->first_child == NULL)) { - if (a->first_child == NULL) { - /* found it! (return the actual node, not the search's) */ - return a; - } - } else { - *conflict = TRUE; - return NULL; /* the chain status' don't match (conflict!) */ - } - b = b->first_child; - a = a->first_child; - } - } - return NULL; // it just isn't in here -} - -static void grab_keys(gboolean grab) -{ - if (!grab) { - XUngrabKey(ob_display, AnyKey, AnyModifier, ob_root); - } else { - KeyBindingTree *p = firstnode; - while (p) { - XGrabKey(ob_display, p->key, p->state, ob_root, FALSE, - GrabModeAsync, GrabModeSync); - p = p->next_sibling; - } - } -} - -void reset_chains() -{ - /* XXX kill timer */ - curpos = NULL; - if (grabbed) { - grabbed = FALSE; - g_message("reset chains. user: %d", user_grabbed); - if (!user_grabbed) - XUngrabKeyboard(ob_display, CurrentTime); - } -} - -void kbind_fire(guint state, guint key, gboolean press) -{ - EventData *data; - struct Client *c = focus_client; - GQuark context = c != NULL ? g_quark_try_string("client") - : g_quark_try_string("root"); - - if (user_grabbed) { - data = eventdata_new_key(press ? Key_Press : Key_Release, - context, c, state, key, NULL); - g_assert(data != NULL); - hooks_fire_keyboard(data); - eventdata_free(data); - } - - if (key == reset_key && state == reset_state) { - reset_chains(); - XAllowEvents(ob_display, AsyncKeyboard, CurrentTime); - } else { - KeyBindingTree *p; - if (curpos == NULL) - p = firstnode; - else - p = curpos->first_child; - while (p) { - if (p->key == key && p->state == state) { - if (p->first_child != NULL) { /* part of a chain */ - /* XXX TIMER */ - if (!grabbed && !user_grabbed) { - /*grab should never fail because we should have a sync - grab at this point */ - XGrabKeyboard(ob_display, ob_root, 0, GrabModeAsync, - GrabModeSync, CurrentTime); - } - grabbed = TRUE; - curpos = p; - XAllowEvents(ob_display, AsyncKeyboard, CurrentTime); - } else { - data = eventdata_new_key(press ? Key_Press : Key_Release, - context, c, state, key, - p->keylist); - g_assert(data != NULL); - hooks_fire(data); - eventdata_free(data); - - XAllowEvents(ob_display, AsyncKeyboard, CurrentTime); - reset_chains(); - } - break; - } - p = p->next_sibling; - } - } -} - -gboolean kbind_add(GList *keylist) -{ - KeyBindingTree *tree, *t; - gboolean conflict; - - if (!(tree = buildtree(keylist))) - return FALSE; /* invalid binding requested */ - - t = find(tree, &conflict); - if (conflict) { - /* conflicts with another binding */ - destroytree(tree); - return FALSE; - } - - if (t != NULL) { - /* already bound to something */ - destroytree(tree); - } else { - /* grab the server here to make sure no key pressed go missed */ - XGrabServer(ob_display); - XSync(ob_display, FALSE); - - grab_keys(FALSE); - - /* assimilate this built tree into the main tree */ - assimilate(tree); // assimilation destroys/uses the tree - - grab_keys(TRUE); - - XUngrabServer(ob_display); - XFlush(ob_display); - } - - return TRUE; -} - -void kbind_clearall() -{ - grab_keys(FALSE); - destroytree(firstnode); - firstnode = NULL; - grab_keys(TRUE); -} - -void kbind_startup() -{ - gboolean b; - - curpos = firstnode = NULL; - grabbed = user_grabbed = FALSE; - - b = translate("C-G", &reset_state, &reset_key); - g_assert(b); -} - -void kbind_shutdown() -{ - if (grabbed || user_grabbed) { - grabbed = FALSE; - kbind_grab_keyboard(FALSE); - } - grab_keys(FALSE); - destroytree(firstnode); - firstnode = NULL; -} - -gboolean kbind_grab_keyboard(gboolean grab) -{ - gboolean ret = TRUE; - - if (!grab) - g_message("grab_keyboard(false). grabbed: %d", grabbed); - - user_grabbed = grab; - if (!grabbed) { - if (grab) - ret = XGrabKeyboard(ob_display, ob_root, 0, GrabModeAsync, - GrabModeAsync, CurrentTime) == GrabSuccess; - else - XUngrabKeyboard(ob_display, CurrentTime); - } - return ret; -}