sxhkd-rc

[fork] simple X hotkey daemon (but for the rc shell)
git clone https://hhvn.uk/sxhkd-rc
git clone git://hhvn.uk/sxhkd-rc
Log | Files | Refs | README | LICENSE

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 }