From: Dana Jansens Date: Thu, 26 Apr 2007 01:25:52 +0000 (+0000) Subject: add chrooting. use chroot="true" on the chroot location X-Git-Url: https://git.dogcows.com/gitweb?a=commitdiff_plain;h=b6d2529acb6e31efbf8c7791e44905a1712da891;p=chaz%2Fopenbox add chrooting. use chroot="true" on the chroot location --- diff --git a/openbox/config.c b/openbox/config.c index fda9d9f0..aadc4389 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -273,47 +273,59 @@ static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, GList *keylist) { gchar *key; - ObAction *action; - xmlNodePtr n, nact; - GList *it; - - if ((n = parse_find_node("chainQuitKey", node))) { - key = parse_string(doc, n); - translate_key(key, &config_keyboard_reset_state, - &config_keyboard_reset_keycode); - g_free(key); - } + xmlNodePtr n; + gboolean is_chroot = FALSE; - n = parse_find_node("keybind", node); - while (n) { - if (parse_attr_string("key", n, &key)) { - keylist = g_list_append(keylist, key); + if (!parse_attr_string("key", node, &key)) + return; + parse_attr_bool("chroot", node, &is_chroot); - parse_key(i, doc, n->children, keylist); + keylist = g_list_append(keylist, key); - it = g_list_last(keylist); - g_free(it->data); - keylist = g_list_delete_link(keylist, it); + /* a node either contains actions or key bindings */ + if ((n = parse_find_node("keybind", node->children))) { + while (n) { + parse_key(i, doc, n, keylist); + n = parse_find_node("keybind", n->next); } - n = parse_find_node("keybind", n->next); - } - if (keylist) { - nact = parse_find_node("action", node); - while (nact) { - if ((action = action_parse(i, doc, nact, - OB_USER_ACTION_KEYBOARD_KEY))) + } else if ((n = parse_find_node("action", node->children))) { + while (n) { + ObAction *action; + + action = action_parse(i, doc, n, OB_USER_ACTION_KEYBOARD_KEY); + if (action) keyboard_bind(keylist, action); - nact = parse_find_node("action", nact->next); + n = parse_find_node("action", n->next); } } + + if (is_chroot) + keyboard_chroot(keylist); + + g_free(key); + keylist = g_list_delete_link(keylist, g_list_last(keylist)); + + /* go to next sibling */ + if (node->next) parse_key(i, doc, node->next, keylist); } static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, gpointer d) { + xmlNodePtr n; + gchar *key; + keyboard_unbind_all(); - parse_key(i, doc, node->children, NULL); + if ((n = parse_find_node("chainQuitKey", node->children))) { + key = parse_string(doc, n); + translate_key(key, &config_keyboard_reset_state, + &config_keyboard_reset_keycode); + g_free(key); + } + + if ((n = parse_find_node("keybind", node->children))) + parse_key(i, doc, n, NULL); } /* diff --git a/openbox/keyboard.c b/openbox/keyboard.c index 86d4f432..d041a35a 100644 --- a/openbox/keyboard.c +++ b/openbox/keyboard.c @@ -106,10 +106,18 @@ static void set_curpos(KeyBindingTree *newpos) } } -void keyboard_reset_chains() +void keyboard_reset_chains(gint break_chroots) { - if (curpos) - set_curpos(NULL); + KeyBindingTree *p; + + for (p = curpos; p; p = p->parent) { + if (p->chroot) { + if (break_chroots == 0) break; /* stop here */ + if (break_chroots > 0) + --break_chroots; + } + } + set_curpos(p); } void keyboard_unbind_all() @@ -118,6 +126,19 @@ void keyboard_unbind_all() keyboard_firstnode = NULL; } +void keyboard_chroot(GList *keylist) +{ + /* try do it in the existing tree. if we can't that means it is an empty + chroot binding. so add it to the tree then. */ + if (!tree_chroot(keyboard_firstnode, keylist)) { + KeyBindingTree *tree; + if (!(tree = tree_build(keylist))) + return; + tree_chroot(tree, keylist); + tree_assimilate(tree); + } +} + gboolean keyboard_bind(GList *keylist, ObAction *action) { KeyBindingTree *tree, *t; @@ -206,7 +227,6 @@ void keyboard_interactive_end(ObInteractiveState *s, if (!interactive_states) { grab_keyboard(FALSE); grab_pointer(FALSE, FALSE, OB_CURSOR_NONE); - keyboard_reset_chains(); } } @@ -267,7 +287,7 @@ void keyboard_event(ObClient *client, const XEvent *e) if (e->xkey.keycode == config_keyboard_reset_keycode && e->xkey.state == config_keyboard_reset_state) { - keyboard_reset_chains(); + keyboard_reset_chains(-1); return; } @@ -279,11 +299,12 @@ void keyboard_event(ObClient *client, const XEvent *e) if (p->key == e->xkey.keycode && p->state == e->xkey.state) { - if (p->first_child != NULL) { /* part of a chain */ + if (p->first_child != NULL) /* part of a chain */ set_curpos(p); - } else { - - keyboard_reset_chains(); + else if (p->chroot) /* an empty chroot */ + set_curpos(p); + else { + keyboard_reset_chains(0); action_run_key(p->actions, client, e->xkey.state, e->xkey.x_root, e->xkey.y_root, diff --git a/openbox/keyboard.h b/openbox/keyboard.h index 80709fa5..4c6f3bb5 100644 --- a/openbox/keyboard.h +++ b/openbox/keyboard.h @@ -34,11 +34,14 @@ extern KeyBindingTree *keyboard_firstnode; void keyboard_startup(gboolean reconfig); void keyboard_shutdown(gboolean reconfig); +void keyboard_chroot(GList *keylist); gboolean keyboard_bind(GList *keylist, ObAction *action); void keyboard_unbind_all(); void keyboard_event(struct _ObClient *client, const XEvent *e); -void keyboard_reset_chains(); +/*! @param break_chroots how many chroots to break. -1 means to break them ALL! + */ +void keyboard_reset_chains(gint break_chroots); gboolean keyboard_interactive_grab(guint state, struct _ObClient *client, struct _ObAction *action); diff --git a/openbox/keytree.c b/openbox/keytree.c index b41b1cf7..b26a4da7 100644 --- a/openbox/keytree.c +++ b/openbox/keytree.c @@ -61,6 +61,7 @@ KeyBindingTree *tree_build(GList *keylist) ret->keylist = g_list_prepend(ret->keylist, g_strdup(kit->data)); /* deep copy */ ret->first_child = p; + if (p != NULL) p->parent = ret; if (!translate_key(it->data, &ret->state, &ret->key)) { tree_destroy(ret); return NULL; @@ -91,10 +92,12 @@ void tree_assimilate(KeyBindingTree *node) a = a->first_child; } } - if (!(last->state == b->state && last->key == b->key)) + if (!(last->state == b->state && last->key == b->key)) { last->next_sibling = b; - else { + b->parent = last->parent; + } else { last->first_child = b->first_child; + last->first_child->parent = last; g_free(b); } } @@ -127,3 +130,20 @@ KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict) } return NULL; /* it just isn't in here */ } + +gboolean tree_chroot(KeyBindingTree *tree, GList *keylist) +{ + if (keylist == NULL) { + tree->chroot = TRUE; + return TRUE; + } else { + guint key, state; + if (translate_key(keylist->data, &state, &key)) { + while (tree != NULL && !(tree->state == state && tree->key == key)) + tree = tree->next_sibling; + if (tree != NULL) + return tree_chroot(tree, keylist->next); + } + } + return FALSE; +} diff --git a/openbox/keytree.h b/openbox/keytree.h index c3be0659..d3544f80 100644 --- a/openbox/keytree.h +++ b/openbox/keytree.h @@ -28,7 +28,10 @@ typedef struct KeyBindingTree { guint key; GList *keylist; GSList *actions; /* list of Action pointers */ + gboolean chroot; + /* the level up in the tree */ + struct KeyBindingTree *parent; /* 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).*/ @@ -39,5 +42,7 @@ void tree_destroy(KeyBindingTree *tree); KeyBindingTree *tree_build(GList *keylist); void tree_assimilate(KeyBindingTree *node); KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict); +gboolean tree_chroot(KeyBindingTree *tree, GList *keylist); + #endif