source: trunk/third/gnome-core/panel/global-keys.c @ 17152

Revision 17152, 8.5 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17151, which included commits to RCS files with non-trunk default branches.
Line 
1#include <config.h>
2
3#include <X11/keysym.h>
4#include <gdk/gdkx.h>
5#include <gdk/gdk.h>
6#include "global-keys.h"
7#include "applet.h"
8#include "panel-include.h"
9#include "gnome-run.h"
10#include "panel_config_global.h"
11
12extern GlobalConfig global_config;
13extern GSList *panel_list;
14extern GSList *panels;
15
16#define N_BITS 32 /*all modifier masks fit into it */
17
18typedef struct {
19        guint mods;
20        guint key;
21} ModAndKey;
22typedef void (*BitsCallback) (guint value, ModAndKey *mod_and_key);
23
24
25static void
26all_combinations (guint mask_to_traverse,
27                  BitsCallback callback,
28                  ModAndKey *mod_and_key)
29{
30        int indexes[N_BITS];/*indexes of bits we need to flip*/
31        int i, bit, bits_set_cnt;
32        int uppervalue;
33
34        bit = 0;
35        for (i = 0; i < N_BITS; i++) {
36                if (mask_to_traverse & (1<<i))
37                        indexes[bit++]=i;
38        }
39
40        bits_set_cnt = bit;
41
42        uppervalue = 1<<bits_set_cnt;
43        for (i = 0; i < uppervalue; i++) {
44                int j, result = 0;
45
46                for (j = 0; j < bits_set_cnt; j++) {
47                        if (i & (1<<j))
48                                result |= (1<<indexes[j]);
49                }
50                callback (result, mod_and_key);
51        }
52}
53
54static void
55do_grab_key (guint mod, ModAndKey* data)
56{
57        XGrabKey (GDK_DISPLAY(), data->key, (mod | data->mods),
58                  GDK_ROOT_WINDOW(), True, GrabModeAsync, GrabModeAsync);
59}
60
61static void
62grab_key (guint mod, guint key)
63{
64        ModAndKey data;
65        int other_mods = IGNORED_MODS & ~mod;
66   
67        data.mods = mod;
68        data.key = key;
69   
70        all_combinations (other_mods, do_grab_key, &data);
71}
72
73static void
74do_ungrab_key (guint mod, ModAndKey* data)
75{
76        XUngrabKey(GDK_DISPLAY(), data->key, (mod | data->mods),
77                   GDK_ROOT_WINDOW());
78}
79
80static void
81ungrab_key (guint mod,guint key)
82{
83        ModAndKey data;
84        int other_mods = IGNORED_MODS & ~mod;   
85   
86        data.mods = mod;
87        data.key = key;
88   
89        all_combinations(other_mods, do_ungrab_key, &data);
90}
91
92void
93panel_global_keys_setup (void)
94{
95        static guint lastkey_menu = 0;
96        static guint laststate_menu = 0;
97        static guint lastkey_run = 0;
98        static guint laststate_run = 0;
99        static guint lastkey_screenshot = 0;
100        static guint laststate_screenshot = 0;
101        static guint lastkey_window_screenshot = 0;
102        static guint laststate_window_screenshot = 0;
103
104        /* FIXME: the if trees are horrible, this shoul dbe cleaned up with
105         * lists or something */
106
107        gdk_error_trap_push();
108        if (lastkey_menu != 0) {
109                ungrab_key (laststate_menu, lastkey_menu);
110        }
111        if (lastkey_run != 0 &&
112            (lastkey_menu != lastkey_run ||
113             laststate_menu != laststate_run)) {
114                ungrab_key (laststate_run, lastkey_run);
115        }
116        if (lastkey_run != 0 &&
117            (lastkey_menu != lastkey_screenshot ||
118             laststate_menu != laststate_screenshot) &&
119            (lastkey_run != lastkey_screenshot ||
120             laststate_run != laststate_screenshot)) {
121                ungrab_key (laststate_screenshot, lastkey_screenshot);
122        }
123        if (lastkey_run != 0 &&
124            (lastkey_menu != lastkey_window_screenshot ||
125             laststate_menu != laststate_window_screenshot) &&
126            (lastkey_run != lastkey_window_screenshot ||
127             laststate_run != laststate_window_screenshot) &&
128            (lastkey_screenshot != lastkey_window_screenshot ||
129             laststate_screenshot != laststate_window_screenshot)) {
130                ungrab_key (laststate_window_screenshot,
131                            lastkey_window_screenshot);
132        }
133       
134        if (global_config.keys_enabled &&
135            global_config.menu_keysym) {
136                lastkey_menu = XKeysymToKeycode(GDK_DISPLAY(),
137                                                global_config.menu_keysym);
138                laststate_menu = global_config.menu_state;
139                if (lastkey_menu != 0)
140                        grab_key (laststate_menu, lastkey_menu);
141        } else {
142                lastkey_menu = 0;
143        }
144
145        if (global_config.keys_enabled &&
146            global_config.run_keysym) {
147                lastkey_run = XKeysymToKeycode (GDK_DISPLAY (),
148                                                global_config.run_keysym);
149                laststate_run = global_config.run_state;
150                if (lastkey_run != 0 &&
151                    (lastkey_menu != lastkey_run ||
152                     laststate_menu != laststate_run))
153                        grab_key (laststate_run, lastkey_run);
154        } else {
155                lastkey_run = 0;
156        }
157
158        if (global_config.keys_enabled &&
159            global_config.screenshot_keysym) {
160                lastkey_screenshot = XKeysymToKeycode
161                        (GDK_DISPLAY (), global_config.screenshot_keysym);
162                laststate_screenshot = global_config.screenshot_state;
163                if (lastkey_screenshot != 0 &&
164                    (lastkey_menu != lastkey_screenshot ||
165                     laststate_menu != laststate_screenshot) &&
166                    (lastkey_run != lastkey_screenshot ||
167                     laststate_run != laststate_screenshot))
168                        grab_key (laststate_screenshot, lastkey_screenshot);
169        } else {
170                lastkey_screenshot = 0;
171        }
172
173        if (global_config.keys_enabled &&
174            global_config.window_screenshot_keysym) {
175                lastkey_window_screenshot = XKeysymToKeycode
176                        (GDK_DISPLAY (), global_config.window_screenshot_keysym);
177                laststate_window_screenshot = global_config.window_screenshot_state;
178                if (lastkey_window_screenshot != 0 &&
179                    (lastkey_menu != lastkey_window_screenshot ||
180                     laststate_menu != laststate_window_screenshot) &&
181                    (lastkey_run != lastkey_window_screenshot ||
182                     laststate_run != laststate_window_screenshot) &&
183                    (lastkey_screenshot != lastkey_window_screenshot ||
184                     laststate_screenshot != laststate_window_screenshot))
185                        grab_key (laststate_window_screenshot,
186                                  lastkey_window_screenshot);
187        } else {
188                lastkey_window_screenshot = 0;
189        }
190
191        gdk_flush ();
192        gdk_error_trap_pop();
193}
194
195static gboolean
196check_for_grabs (void)
197{
198        if (gdk_pointer_grab (GDK_ROOT_PARENT(), FALSE,
199                              0, NULL, NULL, GDK_CURRENT_TIME)
200            != GrabSuccess) {
201                return TRUE;
202        } else {
203                gdk_pointer_ungrab (GDK_CURRENT_TIME);
204                return FALSE;
205        }
206}
207
208GdkFilterReturn
209panel_global_keys_filter (GdkXEvent *gdk_xevent,
210                          GdkEvent *event,
211                          gpointer data)
212{
213        XEvent *xevent = (XEvent *)gdk_xevent;
214        guint keycode, state;
215        guint menu_keycode, menu_state;
216        guint run_keycode, run_state;
217        guint screenshot_keycode, screenshot_state;
218        guint window_screenshot_keycode, window_screenshot_state;
219
220        if(xevent->type != KeyPress)
221                return GDK_FILTER_CONTINUE;
222
223        keycode = xevent->xkey.keycode;
224        state = xevent->xkey.state;
225
226        menu_keycode = XKeysymToKeycode (GDK_DISPLAY (),
227                                         global_config.menu_keysym);
228        menu_state = global_config.menu_state;
229
230        run_keycode = XKeysymToKeycode (GDK_DISPLAY (),
231                                        global_config.run_keysym);
232        run_state = global_config.run_state;
233
234        screenshot_keycode = XKeysymToKeycode (GDK_DISPLAY (),
235                                               global_config.screenshot_keysym);
236        screenshot_state = global_config.screenshot_state;
237
238        window_screenshot_keycode =
239                XKeysymToKeycode (GDK_DISPLAY (),
240                                  global_config.window_screenshot_keysym);
241        window_screenshot_state = global_config.window_screenshot_state;
242
243        if (keycode == menu_keycode &&
244            (state & USED_MODS) == menu_state) {
245                PanelWidget *panel;
246                GtkWidget *menu, *basep;
247                /* check if anybody else has a grab */
248                if (check_for_grabs ()) {
249                        return GDK_FILTER_CONTINUE;
250                }
251
252                panel = panels->data;
253                menu = make_popup_panel_menu (panel);
254                basep = panel->panel_parent;
255                if (IS_BASEP_WIDGET(basep)) {
256                        BASEP_WIDGET(basep)->autohide_inhibit = TRUE;
257                        basep_widget_autohide (BASEP_WIDGET (basep));
258                }
259                gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
260                                NULL, NULL, 0, GDK_CURRENT_TIME);
261                return GDK_FILTER_REMOVE;
262        } else if (keycode == run_keycode &&
263                   (state & USED_MODS) == run_state) {
264                /* check if anybody else has a grab */
265                if (check_for_grabs ()) {
266                        return GDK_FILTER_CONTINUE;
267                }
268
269                show_run_dialog ();
270                return GDK_FILTER_REMOVE;
271        } else if (keycode == screenshot_keycode &&
272                   (state & USED_MODS) == screenshot_state) {
273                char *argv[2];
274                char *proggie;
275
276                /* check if anybody else has a grab */
277                if (check_for_grabs ()) {
278                        return GDK_FILTER_CONTINUE;
279                }
280
281                proggie = gnome_is_program_in_path ("gnome-panel-screenshot");
282                if (proggie == NULL) {
283                        panel_error_dialog (_("Can't find the screenshot "
284                                              "program"));
285                        return GDK_FILTER_REMOVE;
286                }
287                argv[0] = proggie;
288                argv[1] = NULL;
289
290                if (gnome_execute_async (g_get_home_dir (), 1, argv)<0)
291                        panel_error_dialog (_("Can't execute the screenshot "
292                                              "program"));
293
294                g_free (proggie);
295
296                return GDK_FILTER_REMOVE;
297        } else if (keycode == window_screenshot_keycode &&
298                   (state & USED_MODS) == window_screenshot_state) {
299                char *argv[3];
300                char *proggie;
301
302                /* check if anybody else has a grab */
303                if (check_for_grabs ()) {
304                        return GDK_FILTER_CONTINUE;
305                }
306
307                proggie = gnome_is_program_in_path ("gnome-panel-screenshot");
308                if (proggie == NULL) {
309                        panel_error_dialog (_("Can't find the screenshot "
310                                              "program"));
311                        return GDK_FILTER_REMOVE;
312                }
313                argv[0] = proggie;
314                argv[1] = "--window";
315                argv[2] = NULL;
316
317                if (gnome_execute_async (g_get_home_dir (), 2, argv)<0)
318                        panel_error_dialog (_("Can't execute the screenshot "
319                                              "program"));
320
321                g_free (proggie);
322
323                return GDK_FILTER_REMOVE;
324        }
325
326        return GDK_FILTER_CONTINUE;
327}
Note: See TracBrowser for help on using the repository browser.