]> Dogcows Code - chaz/openbox/commitdiff
add chrooting. use chroot="true" on the chroot location
authorDana Jansens <danakj@orodu.net>
Thu, 26 Apr 2007 01:25:52 +0000 (01:25 +0000)
committerDana Jansens <danakj@orodu.net>
Thu, 26 Apr 2007 01:25:52 +0000 (01:25 +0000)
openbox/config.c
openbox/keyboard.c
openbox/keyboard.h
openbox/keytree.c
openbox/keytree.h

index fda9d9f08e9b21b9384326153237059d5b5a195c..aadc4389f5b7faec7439d5c8676e37d01e04c401 100644 (file)
@@ -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);
 }
 
 /*
index 86d4f4324e1c58c9ecc56ac4298068077c3df15c..d041a35a35229454da5647e4f50b8e99d06e0a6d 100644 (file)
@@ -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,
index 80709fa51d464bc9ee23c30d341618b6c5b706ab..4c6f3bb59ec1c830a7e7b84cf7760d61f5016831 100644 (file)
@@ -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);
index b41b1cf7d7a81af2f4f6326b60f4718af23f2829..b26a4da7dac41cbe6e295cd9b915374f1137cb69 100644 (file)
@@ -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;
+}
index c3be065959a78c9286b848d4f2042236f569cd63..d3544f80b6988f392d102d9cd5795c0a829e8182 100644 (file)
@@ -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
This page took 0.037459 seconds and 4 git commands to generate.