Mercurial > audlegacy-plugins
view src/hotkey/grab.c @ 3157:d73418aa0db3
adapt to audlegacy
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Fri, 22 May 2009 19:11:38 +0900 |
parents | f1b6f1b2cdb3 |
children |
line wrap: on
line source
/* * This file is part of audacious-hotkey plugin for audacious * * Copyright (c) 2007 - 2008 Sascha Hlusiak <contact@saschahlusiak.de> * Name: grab.c * Description: grab.c * * Part of this code is from itouch-ctrl plugin. * Authors of itouch-ctrl are listed below: * * Copyright (c) 2006 - 2007 Vladimir Paskov <vlado.paskov@gmail.com> * * Part of this code are from xmms-itouch plugin. * Authors of xmms-itouch are listed below: * * Copyright (C) 2000-2002 Ville Syrjälä <syrjala@sci.fi> * Bryn Davies <curious@ihug.com.au> * Jonathan A. Davis <davis@jdhouse.org> * Jeremy Tan <nsx@nsx.homeip.net> * * audacious-hotkey is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * audacious-hotkey is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with audacious-hotkey; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include <config.h> #include <gtk/gtk.h> #include <gdk/gdkx.h> #include "grab.h" #include "plugin.h" static gint grabbed = 0; static unsigned int numlock_mask = 0; static unsigned int scrolllock_mask = 0; static unsigned int capslock_mask = 0; /* Taken from xbindkeys */ static void get_offending_modifiers (Display * dpy) { int i; XModifierKeymap *modmap; KeyCode nlock, slock; static int mask_table[8] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; nlock = XKeysymToKeycode (dpy, XK_Num_Lock); slock = XKeysymToKeycode (dpy, XK_Scroll_Lock); /* * Find out the masks for the NumLock and ScrollLock modifiers, * so that we can bind the grabs for when they are enabled too. */ modmap = XGetModifierMapping (dpy); if (modmap != NULL && modmap->max_keypermod > 0) { for (i = 0; i < 8 * modmap->max_keypermod; i++) { if (modmap->modifiermap[i] == nlock && nlock != 0) numlock_mask = mask_table[i / modmap->max_keypermod]; else if (modmap->modifiermap[i] == slock && slock != 0) scrolllock_mask = mask_table[i / modmap->max_keypermod]; } } capslock_mask = LockMask; if (modmap) XFreeModifiermap (modmap); } static int x11_error_handler (Display *dpy, XErrorEvent *error) { return 0; } /* grab required keys */ static void grab_key(const HotkeyConfiguration *hotkey, Display *xdisplay, Window x_root_window) { unsigned int modifier = hotkey->mask & ~(numlock_mask | capslock_mask | scrolllock_mask); if (hotkey->key == 0) return; if (hotkey->type == TYPE_KEY) { XGrabKey (xdisplay, hotkey->key, modifier, x_root_window, False, GrabModeAsync, GrabModeAsync); if (modifier == AnyModifier) return; if (numlock_mask) XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (capslock_mask) XGrabKey (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (scrolllock_mask) XGrabKey (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (numlock_mask && capslock_mask) XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (numlock_mask && scrolllock_mask) XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (capslock_mask && scrolllock_mask) XGrabKey (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); if (numlock_mask && capslock_mask && scrolllock_mask) XGrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window, False, GrabModeAsync, GrabModeAsync); } if (hotkey->type == TYPE_MOUSE) { XGrabButton (xdisplay, hotkey->key, modifier, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (modifier == AnyModifier) return; if (numlock_mask) XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (capslock_mask) XGrabButton (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (scrolllock_mask) XGrabButton (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (numlock_mask && capslock_mask) XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (numlock_mask && scrolllock_mask) XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (capslock_mask && scrolllock_mask) XGrabButton (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); if (numlock_mask && capslock_mask && scrolllock_mask) XGrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); } } void grab_keys ( ) { Display* xdisplay; int screen; PluginConfig* plugin_cfg = get_config(); HotkeyConfiguration *hotkey; XErrorHandler old_handler = 0; xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); if (grabbed) return; XSync(xdisplay, False); old_handler = XSetErrorHandler (x11_error_handler); get_offending_modifiers(xdisplay); hotkey = &(plugin_cfg->first); while (hotkey) { for (screen=0;screen<ScreenCount(xdisplay);screen++) { grab_key(hotkey, xdisplay, RootWindow(xdisplay, screen)); } hotkey = hotkey->next; } XSync(xdisplay, False); XSetErrorHandler (old_handler); grabbed = 1; } /* grab required keys */ static void ungrab_key(HotkeyConfiguration *hotkey, Display* xdisplay, Window x_root_window) { unsigned int modifier = hotkey->mask & ~(numlock_mask | capslock_mask | scrolllock_mask); if (hotkey->key == 0) return; if (hotkey->type == TYPE_KEY) { XUngrabKey (xdisplay, hotkey->key, modifier, x_root_window); if (modifier == AnyModifier) return; if (numlock_mask) XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window); if (capslock_mask) XUngrabKey (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window); if (scrolllock_mask) XUngrabKey (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window); if (numlock_mask && capslock_mask) XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window); if (numlock_mask && scrolllock_mask) XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window); if (capslock_mask && scrolllock_mask) XUngrabKey (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window); if (numlock_mask && capslock_mask && scrolllock_mask) XUngrabKey (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window); } if (hotkey->type == TYPE_MOUSE) { XUngrabButton (xdisplay, hotkey->key, modifier, x_root_window); if (modifier == AnyModifier) return; if (numlock_mask) XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask, x_root_window); if (capslock_mask) XUngrabButton (xdisplay, hotkey->key, modifier | capslock_mask, x_root_window); if (scrolllock_mask) XUngrabButton (xdisplay, hotkey->key, modifier | scrolllock_mask, x_root_window); if (numlock_mask && capslock_mask) XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask, x_root_window); if (numlock_mask && scrolllock_mask) XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | scrolllock_mask, x_root_window); if (capslock_mask && scrolllock_mask) XUngrabButton (xdisplay, hotkey->key, modifier | capslock_mask | scrolllock_mask, x_root_window); if (numlock_mask && capslock_mask && scrolllock_mask) XUngrabButton (xdisplay, hotkey->key, modifier | numlock_mask | capslock_mask | scrolllock_mask, x_root_window); } } void ungrab_keys ( ) { Display* xdisplay; int screen; PluginConfig* plugin_cfg = get_config(); HotkeyConfiguration *hotkey; XErrorHandler old_handler = 0; xdisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); if (!grabbed) return; if (!xdisplay) return; XSync(xdisplay, False); old_handler = XSetErrorHandler (x11_error_handler); get_offending_modifiers(xdisplay); hotkey = &(plugin_cfg->first); while (hotkey) { for (screen=0;screen<ScreenCount(xdisplay);screen++) { ungrab_key(hotkey, xdisplay, RootWindow(xdisplay, screen)); } hotkey = hotkey->next; } XSync(xdisplay, False); XSetErrorHandler (old_handler); grabbed = 0; } static GdkFilterReturn gdk_filter(GdkXEvent *xevent, GdkEvent *event, gpointer data) { HotkeyConfiguration *hotkey; hotkey = &(get_config()->first); switch (((XEvent*)xevent)->type) { case KeyPress: { XKeyEvent *keyevent = (XKeyEvent*)xevent; while (hotkey) { if ((hotkey->key == keyevent->keycode) && (hotkey->mask == (keyevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) && (hotkey->type == TYPE_KEY)) { if (handle_keyevent(hotkey->event)) return GDK_FILTER_REMOVE; break; } hotkey = hotkey->next; } break; } case ButtonPress: { XButtonEvent *buttonevent = (XButtonEvent*)xevent; while (hotkey) { if ((hotkey->key == buttonevent->button) && (hotkey->mask == (buttonevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) && (hotkey->type == TYPE_MOUSE)) { if (handle_keyevent(hotkey->event)) return GDK_FILTER_REMOVE; break; } hotkey = hotkey->next; } break; } default: return -1; } return GDK_FILTER_CONTINUE; } gboolean setup_filter() { GdkDisplay *display; int screen; display = gdk_display_get_default(); for (screen = 0; screen<gdk_display_get_n_screens(display); screen++) { gdk_window_add_filter(gdk_screen_get_root_window(gdk_display_get_screen(display, screen)), gdk_filter, NULL); } return TRUE; } void release_filter() { GdkDisplay *display; int screen; display = gdk_display_get_default(); for (screen = 0; screen<gdk_display_get_n_screens(display); screen++) { gdk_window_remove_filter(gdk_screen_get_root_window(gdk_display_get_screen(display, screen)), gdk_filter, NULL); } }