]> Dogcows Code - chaz/openbox/blob - plugins/keyboard/keyboard.c
use the grab.h funcs to grab keys and buttons
[chaz/openbox] / plugins / keyboard / keyboard.c
1 #include "../../kernel/focus.h"
2 #include "../../kernel/dispatch.h"
3 #include "../../kernel/openbox.h"
4 #include "../../kernel/grab.h"
5 #include "../../kernel/action.h"
6 #include "tree.h"
7 #include "keyboard.h"
8 #include <glib.h>
9
10 KeyBindingTree *firstnode;
11
12 static KeyBindingTree *curpos;
13 static guint reset_key, reset_state;
14 static gboolean grabbed;
15
16 static void grab_keys(gboolean grab)
17 {
18 if (!grab) {
19 ungrab_all_keys();
20 } else {
21 KeyBindingTree *p = firstnode;
22 while (p) {
23 grab_key(p->key, p->state, GrabModeSync);
24 p = p->next_sibling;
25 }
26 }
27 }
28
29 static void reset_chains()
30 {
31 /* XXX kill timer */
32 curpos = NULL;
33 if (grabbed) {
34 grabbed = FALSE;
35 grab_keyboard(FALSE);
36 }
37 }
38
39 static gboolean kbind(GList *keylist, Action *action)
40 {
41 KeyBindingTree *tree, *t;
42 gboolean conflict;
43
44 g_assert(keylist != NULL);
45 g_assert(action != NULL);
46
47 if (!(tree = tree_build(keylist))) {
48 g_warning("invalid binding");
49 return FALSE;
50 }
51 if ((t = tree_find(tree, &conflict)) != NULL) {
52 /* already bound to something */
53 g_warning("keychain is already bound");
54 tree_destroy(tree);
55 return FALSE;
56 }
57 if (conflict) {
58 g_warning("conflict with binding");
59 tree_destroy(tree);
60 return FALSE;
61 }
62
63 /* grab the server here to make sure no key presses go missed */
64 grab_server(TRUE);
65 grab_keys(FALSE);
66
67 /* set the action */
68 t = tree;
69 while (t->first_child) t = t->first_child;
70 t->action = action;
71 /* assimilate this built tree into the main tree. assimilation
72 destroys/uses the tree */
73 tree_assimilate(tree);
74
75 grab_keys(TRUE);
76 grab_server(FALSE);
77
78 return TRUE;
79 }
80
81 static void press(ObEvent *e, void *foo)
82 {
83 if (e->data.x.e->xkey.keycode == reset_key &&
84 e->data.x.e->xkey.state == reset_state) {
85 reset_chains();
86 XAllowEvents(ob_display, AsyncKeyboard, CurrentTime);
87 } else {
88 KeyBindingTree *p;
89 if (curpos == NULL)
90 p = firstnode;
91 else
92 p = curpos->first_child;
93 while (p) {
94 if (p->key == e->data.x.e->xkey.keycode &&
95 p->state == e->data.x.e->xkey.state) {
96 if (p->first_child != NULL) { /* part of a chain */
97 /* XXX TIMER */
98 if (!grabbed) {
99 grab_keyboard(TRUE);
100 grabbed = TRUE;
101 XAllowEvents(ob_display, AsyncKeyboard, CurrentTime);
102 }
103 curpos = p;
104 } else {
105 if (p->action->func != NULL) {
106 p->action->data.any.c = focus_client;
107
108 g_assert(!(p->action->func == action_move ||
109 p->action->func == action_resize));
110
111 p->action->func(&p->action->data);
112 }
113
114 XAllowEvents(ob_display, AsyncKeyboard, CurrentTime);
115 reset_chains();
116 }
117 break;
118 }
119 p = p->next_sibling;
120 }
121 }
122 }
123
124 static void binddef()
125 {
126 GList *list = g_list_append(NULL, NULL);
127 Action *a;
128
129 /* When creating an Action struct, all of the data elements in the
130 appropriate struct need to be set, except the Client*, which will be set
131 at call-time when then action function is used.
132 */
133
134 list->data = "C-Right";
135 a = action_new(action_next_desktop);
136 a->data.nextprevdesktop.wrap = TRUE;
137 kbind(list, a);
138
139 list->data = "C-Left";
140 a = action_new(action_previous_desktop);
141 a->data.nextprevdesktop.wrap = TRUE;
142 kbind(list, a);
143
144 list->data = "C-1";
145 a = action_new(action_desktop);
146 a->data.desktop.desk = 0;
147 kbind(list, a);
148
149 list->data = "C-2";
150 a = action_new(action_desktop);
151 a->data.desktop.desk = 1;
152 kbind(list, a);
153
154 list->data = "C-3";
155 a = action_new(action_desktop);
156 a->data.desktop.desk = 2;
157 kbind(list, a);
158
159 list->data = "C-4";
160 a = action_new(action_desktop);
161 a->data.desktop.desk = 3;
162 kbind(list, a);
163
164 list->data = "C-space";
165 a = action_new(action_execute);
166 a->data.execute.path = g_strdup("xterm");
167 kbind(list, a);
168 }
169
170 void plugin_startup()
171 {
172 dispatch_register(Event_X_KeyPress, (EventHandler)press, NULL);
173
174 /* XXX parse config file! */
175 binddef();
176 }
177
178 void plugin_shutdown()
179 {
180 dispatch_register(0, (EventHandler)press, NULL);
181
182 grab_keys(FALSE);
183 tree_destroy(firstnode);
184 firstnode = NULL;
185 grab_keys(TRUE);
186 }
187
This page took 0.041415 seconds and 5 git commands to generate.