grab.c (4193B)
1 /* Copyright (c) 2013, Bastien Dejean 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25 #include <stdlib.h> 26 #include <stdbool.h> 27 #include "parse.h" 28 #include "grab.h" 29 30 void grab(void) 31 { 32 PUTS("grab"); 33 for (hotkey_t *hk = hotkeys_head; hk != NULL; hk = hk->next) 34 grab_chord(hk->chain->head); 35 xcb_flush(dpy); 36 grabbed = true; 37 } 38 39 void grab_chord(chord_t *chord) 40 { 41 for (chord_t *c = chord; c != NULL; c = c->more) { 42 if (c->button == XCB_NONE) { 43 xcb_keycode_t *keycodes = keycodes_from_keysym(c->keysym); 44 if (keycodes != NULL) 45 for (xcb_keycode_t *kc = keycodes; *kc != XCB_NO_SYMBOL; kc++) 46 if (c->keysym == xcb_key_symbols_get_keysym(symbols, *kc, 0)) 47 grab_key_button(*kc, c->button, c->modfield); 48 free(keycodes); 49 } else { 50 grab_key_button(XCB_NONE, c->button, c->modfield); 51 } 52 } 53 } 54 55 void grab_key_button(xcb_keycode_t keycode, xcb_button_t button, uint16_t modfield) 56 { 57 grab_key_button_checked(keycode, button, modfield); 58 if (modfield == XCB_MOD_MASK_ANY) 59 return; 60 if (num_lock != 0) 61 grab_key_button_checked(keycode, button, modfield | num_lock); 62 if (caps_lock != 0) 63 grab_key_button_checked(keycode, button, modfield | caps_lock); 64 if (scroll_lock != 0) 65 grab_key_button_checked(keycode, button, modfield | scroll_lock); 66 if (num_lock != 0 && caps_lock != 0) 67 grab_key_button_checked(keycode, button, modfield | num_lock | caps_lock); 68 if (caps_lock != 0 && scroll_lock != 0) 69 grab_key_button_checked(keycode, button, modfield | caps_lock | scroll_lock); 70 if (num_lock != 0 && scroll_lock != 0) 71 grab_key_button_checked(keycode, button, modfield | num_lock | scroll_lock); 72 if (num_lock != 0 && caps_lock != 0 && scroll_lock != 0) 73 grab_key_button_checked(keycode, button, modfield | num_lock | caps_lock | scroll_lock); 74 } 75 76 void grab_key_button_checked(xcb_keycode_t keycode, xcb_button_t button, uint16_t modfield) 77 { 78 xcb_generic_error_t *err; 79 if (button == XCB_NONE) 80 err = xcb_request_check(dpy, xcb_grab_key_checked(dpy, true, root, modfield, keycode, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_SYNC)); 81 else 82 err = xcb_request_check(dpy, xcb_grab_button_checked(dpy, true, root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, button, modfield)); 83 unsigned int value = (button == XCB_NONE ? keycode : button); 84 char *type = (button == XCB_NONE ? "key" : "button"); 85 if (err != NULL) { 86 warn("Could not grab %s %u with modfield %u: ", type, value, modfield); 87 if (err->error_code == XCB_ACCESS) 88 warn("the combination is already grabbed.\n"); 89 else 90 warn("error %u encountered.\n", err->error_code); 91 free(err); 92 } else { 93 PRINTF("grab %s %u %u\n", type, value, modfield); 94 } 95 } 96 97 void ungrab(void) 98 { 99 PUTS("ungrab"); 100 xcb_ungrab_key(dpy, XCB_GRAB_ANY, root, XCB_BUTTON_MASK_ANY); 101 xcb_ungrab_button(dpy, XCB_BUTTON_INDEX_ANY, root, XCB_MOD_MASK_ANY); 102 xcb_flush(dpy); 103 grabbed = false; 104 }