|  |  | @ -2,17 +2,12 @@ | 
			
		
	
		
			
				
					|  |  |  | * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | 
			
		
	
		
			
				
					|  |  |  | * See LICENSE file for license details. | 
			
		
	
		
			
				
					|  |  |  | */ | 
			
		
	
		
			
				
					|  |  |  | #include "dwm.h" | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | #include <fcntl.h> | 
			
		
	
		
			
				
					|  |  |  | #include <stdio.h> | 
			
		
	
		
			
				
					|  |  |  | #include <stdlib.h> | 
			
		
	
		
			
				
					|  |  |  | #include <string.h> | 
			
		
	
		
			
				
					|  |  |  | #include <unistd.h> | 
			
		
	
		
			
				
					|  |  |  | #include <X11/keysym.h> | 
			
		
	
		
			
				
					|  |  |  | #include <X11/Xatom.h> | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | #include "dwm.h" | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | #define ButtonMask      (ButtonPressMask | ButtonReleaseMask) | 
			
		
	
		
			
				
					|  |  |  | #define MouseMask       (ButtonMask | PointerMotionMask) | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
	
		
			
				
					|  |  | @ -54,130 +49,10 @@ Key key[] = { | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | /********** CUSTOMIZE **********/ | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | /* local functions */ | 
			
		
	
		
			
				
					|  |  |  | static void buttonpress(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void configurerequest(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void destroynotify(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void enternotify(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void leavenotify(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void expose(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void keypress(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void maprequest(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void propertynotify(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  | static void unmapnotify(XEvent *e); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | void (*handler[LASTEvent]) (XEvent *) = { | 
			
		
	
		
			
				
					|  |  |  | [ButtonPress] = buttonpress, | 
			
		
	
		
			
				
					|  |  |  | [ConfigureRequest] = configurerequest, | 
			
		
	
		
			
				
					|  |  |  | [DestroyNotify] = destroynotify, | 
			
		
	
		
			
				
					|  |  |  | [EnterNotify] = enternotify, | 
			
		
	
		
			
				
					|  |  |  | [LeaveNotify] = leavenotify, | 
			
		
	
		
			
				
					|  |  |  | [Expose] = expose, | 
			
		
	
		
			
				
					|  |  |  | [KeyPress] = keypress, | 
			
		
	
		
			
				
					|  |  |  | [MapRequest] = maprequest, | 
			
		
	
		
			
				
					|  |  |  | [PropertyNotify] = propertynotify, | 
			
		
	
		
			
				
					|  |  |  | [UnmapNotify] = unmapnotify | 
			
		
	
		
			
				
					|  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | void | 
			
		
	
		
			
				
					|  |  |  | grabkeys() | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | 
			
		
	
		
			
				
					|  |  |  | unsigned int i; | 
			
		
	
		
			
				
					|  |  |  | KeyCode code; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | for(i = 0; i < len; i++) { | 
			
		
	
		
			
				
					|  |  |  | code = XKeysymToKeycode(dpy, key[i].keysym); | 
			
		
	
		
			
				
					|  |  |  | XUngrabKey(dpy, code, key[i].mod, root); | 
			
		
	
		
			
				
					|  |  |  | XGrabKey(dpy, code, key[i].mod, root, True, | 
			
		
	
		
			
				
					|  |  |  | GrabModeAsync, GrabModeAsync); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | keypress(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | XKeyEvent *ev = &e->xkey; | 
			
		
	
		
			
				
					|  |  |  | static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | 
			
		
	
		
			
				
					|  |  |  | unsigned int i; | 
			
		
	
		
			
				
					|  |  |  | KeySym keysym; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); | 
			
		
	
		
			
				
					|  |  |  | for(i = 0; i < len; i++) | 
			
		
	
		
			
				
					|  |  |  | if((keysym == key[i].keysym) && (key[i].mod == ev->state)) { | 
			
		
	
		
			
				
					|  |  |  | if(key[i].func) | 
			
		
	
		
			
				
					|  |  |  | key[i].func(&key[i].arg); | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | resizemouse(Client *c) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | XEvent ev; | 
			
		
	
		
			
				
					|  |  |  | int ocx, ocy; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | ocx = c->x; | 
			
		
	
		
			
				
					|  |  |  | ocy = c->y; | 
			
		
	
		
			
				
					|  |  |  | if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, | 
			
		
	
		
			
				
					|  |  |  | None, cursor[CurResize], CurrentTime) != GrabSuccess) | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h); | 
			
		
	
		
			
				
					|  |  |  | for(;;) { | 
			
		
	
		
			
				
					|  |  |  | XMaskEvent(dpy, MouseMask | ExposureMask, &ev); | 
			
		
	
		
			
				
					|  |  |  | switch(ev.type) { | 
			
		
	
		
			
				
					|  |  |  | default: break; | 
			
		
	
		
			
				
					|  |  |  | case Expose: | 
			
		
	
		
			
				
					|  |  |  | handler[Expose](&ev); | 
			
		
	
		
			
				
					|  |  |  | break; | 
			
		
	
		
			
				
					|  |  |  | case MotionNotify: | 
			
		
	
		
			
				
					|  |  |  | XFlush(dpy); | 
			
		
	
		
			
				
					|  |  |  | c->w = abs(ocx - ev.xmotion.x); | 
			
		
	
		
			
				
					|  |  |  | c->h = abs(ocy - ev.xmotion.y); | 
			
		
	
		
			
				
					|  |  |  | c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w; | 
			
		
	
		
			
				
					|  |  |  | c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h; | 
			
		
	
		
			
				
					|  |  |  | resize(c, True); | 
			
		
	
		
			
				
					|  |  |  | break; | 
			
		
	
		
			
				
					|  |  |  | case ButtonRelease: | 
			
		
	
		
			
				
					|  |  |  | XUngrabPointer(dpy, CurrentTime); | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | movemouse(Client *c) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | XEvent ev; | 
			
		
	
		
			
				
					|  |  |  | int x1, y1, ocx, ocy, di; | 
			
		
	
		
			
				
					|  |  |  | unsigned int dui; | 
			
		
	
		
			
				
					|  |  |  | Window dummy; | 
			
		
	
		
			
				
					|  |  |  | /* static functions */ | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | ocx = c->x; | 
			
		
	
		
			
				
					|  |  |  | ocy = c->y; | 
			
		
	
		
			
				
					|  |  |  | if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, | 
			
		
	
		
			
				
					|  |  |  | None, cursor[CurMove], CurrentTime) != GrabSuccess) | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); | 
			
		
	
		
			
				
					|  |  |  | for(;;) { | 
			
		
	
		
			
				
					|  |  |  | XMaskEvent(dpy, MouseMask | ExposureMask, &ev); | 
			
		
	
		
			
				
					|  |  |  | switch (ev.type) { | 
			
		
	
		
			
				
					|  |  |  | default: break; | 
			
		
	
		
			
				
					|  |  |  | case Expose: | 
			
		
	
		
			
				
					|  |  |  | handler[Expose](&ev); | 
			
		
	
		
			
				
					|  |  |  | break; | 
			
		
	
		
			
				
					|  |  |  | case MotionNotify: | 
			
		
	
		
			
				
					|  |  |  | XFlush(dpy); | 
			
		
	
		
			
				
					|  |  |  | c->x = ocx + (ev.xmotion.x - x1); | 
			
		
	
		
			
				
					|  |  |  | c->y = ocy + (ev.xmotion.y - y1); | 
			
		
	
		
			
				
					|  |  |  | resize(c, False); | 
			
		
	
		
			
				
					|  |  |  | break; | 
			
		
	
		
			
				
					|  |  |  | case ButtonRelease: | 
			
		
	
		
			
				
					|  |  |  | XUngrabPointer(dpy, CurrentTime); | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | static void movemouse(Client *c); | 
			
		
	
		
			
				
					|  |  |  | static void resizemouse(Client *c); | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | buttonpress(XEvent *e) | 
			
		
	
	
		
			
				
					|  |  | @ -279,15 +154,6 @@ enternotify(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | issel = True; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | leavenotify(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | XCrossingEvent *ev = &e->xcrossing; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | if((ev->window == root) && !ev->same_screen) | 
			
		
	
		
			
				
					|  |  |  | issel = True; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | expose(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
	
		
			
				
					|  |  | @ -302,6 +168,32 @@ expose(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | keypress(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | XKeyEvent *ev = &e->xkey; | 
			
		
	
		
			
				
					|  |  |  | static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | 
			
		
	
		
			
				
					|  |  |  | unsigned int i; | 
			
		
	
		
			
				
					|  |  |  | KeySym keysym; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); | 
			
		
	
		
			
				
					|  |  |  | for(i = 0; i < len; i++) | 
			
		
	
		
			
				
					|  |  |  | if((keysym == key[i].keysym) && (key[i].mod == ev->state)) { | 
			
		
	
		
			
				
					|  |  |  | if(key[i].func) | 
			
		
	
		
			
				
					|  |  |  | key[i].func(&key[i].arg); | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | leavenotify(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | XCrossingEvent *ev = &e->xcrossing; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | if((ev->window == root) && !ev->same_screen) | 
			
		
	
		
			
				
					|  |  |  | issel = True; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | maprequest(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
	
		
			
				
					|  |  | @ -321,6 +213,40 @@ maprequest(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | manage(ev->window, &wa); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | movemouse(Client *c) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | XEvent ev; | 
			
		
	
		
			
				
					|  |  |  | int x1, y1, ocx, ocy, di; | 
			
		
	
		
			
				
					|  |  |  | unsigned int dui; | 
			
		
	
		
			
				
					|  |  |  | Window dummy; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | ocx = c->x; | 
			
		
	
		
			
				
					|  |  |  | ocy = c->y; | 
			
		
	
		
			
				
					|  |  |  | if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, | 
			
		
	
		
			
				
					|  |  |  | None, cursor[CurMove], CurrentTime) != GrabSuccess) | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); | 
			
		
	
		
			
				
					|  |  |  | for(;;) { | 
			
		
	
		
			
				
					|  |  |  | XMaskEvent(dpy, MouseMask | ExposureMask, &ev); | 
			
		
	
		
			
				
					|  |  |  | switch (ev.type) { | 
			
		
	
		
			
				
					|  |  |  | default: break; | 
			
		
	
		
			
				
					|  |  |  | case Expose: | 
			
		
	
		
			
				
					|  |  |  | handler[Expose](&ev); | 
			
		
	
		
			
				
					|  |  |  | break; | 
			
		
	
		
			
				
					|  |  |  | case MotionNotify: | 
			
		
	
		
			
				
					|  |  |  | XFlush(dpy); | 
			
		
	
		
			
				
					|  |  |  | c->x = ocx + (ev.xmotion.x - x1); | 
			
		
	
		
			
				
					|  |  |  | c->y = ocy + (ev.xmotion.y - y1); | 
			
		
	
		
			
				
					|  |  |  | resize(c, False); | 
			
		
	
		
			
				
					|  |  |  | break; | 
			
		
	
		
			
				
					|  |  |  | case ButtonRelease: | 
			
		
	
		
			
				
					|  |  |  | XUngrabPointer(dpy, CurrentTime); | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | propertynotify(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
	
		
			
				
					|  |  | @ -354,6 +280,40 @@ propertynotify(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | resizemouse(Client *c) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | XEvent ev; | 
			
		
	
		
			
				
					|  |  |  | int ocx, ocy; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | ocx = c->x; | 
			
		
	
		
			
				
					|  |  |  | ocy = c->y; | 
			
		
	
		
			
				
					|  |  |  | if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, | 
			
		
	
		
			
				
					|  |  |  | None, cursor[CurResize], CurrentTime) != GrabSuccess) | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h); | 
			
		
	
		
			
				
					|  |  |  | for(;;) { | 
			
		
	
		
			
				
					|  |  |  | XMaskEvent(dpy, MouseMask | ExposureMask, &ev); | 
			
		
	
		
			
				
					|  |  |  | switch(ev.type) { | 
			
		
	
		
			
				
					|  |  |  | default: break; | 
			
		
	
		
			
				
					|  |  |  | case Expose: | 
			
		
	
		
			
				
					|  |  |  | handler[Expose](&ev); | 
			
		
	
		
			
				
					|  |  |  | break; | 
			
		
	
		
			
				
					|  |  |  | case MotionNotify: | 
			
		
	
		
			
				
					|  |  |  | XFlush(dpy); | 
			
		
	
		
			
				
					|  |  |  | c->w = abs(ocx - ev.xmotion.x); | 
			
		
	
		
			
				
					|  |  |  | c->h = abs(ocy - ev.xmotion.y); | 
			
		
	
		
			
				
					|  |  |  | c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w; | 
			
		
	
		
			
				
					|  |  |  | c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h; | 
			
		
	
		
			
				
					|  |  |  | resize(c, True); | 
			
		
	
		
			
				
					|  |  |  | break; | 
			
		
	
		
			
				
					|  |  |  | case ButtonRelease: | 
			
		
	
		
			
				
					|  |  |  | XUngrabPointer(dpy, CurrentTime); | 
			
		
	
		
			
				
					|  |  |  | return; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  | unmapnotify(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
	
		
			
				
					|  |  | @ -363,3 +323,33 @@ unmapnotify(XEvent *e) | 
			
		
	
		
			
				
					|  |  |  | if((c = getclient(ev->window))) | 
			
		
	
		
			
				
					|  |  |  | unmanage(c); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | /* extern functions */ | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | void (*handler[LASTEvent]) (XEvent *) = { | 
			
		
	
		
			
				
					|  |  |  | [ButtonPress] = buttonpress, | 
			
		
	
		
			
				
					|  |  |  | [ConfigureRequest] = configurerequest, | 
			
		
	
		
			
				
					|  |  |  | [DestroyNotify] = destroynotify, | 
			
		
	
		
			
				
					|  |  |  | [EnterNotify] = enternotify, | 
			
		
	
		
			
				
					|  |  |  | [LeaveNotify] = leavenotify, | 
			
		
	
		
			
				
					|  |  |  | [Expose] = expose, | 
			
		
	
		
			
				
					|  |  |  | [KeyPress] = keypress, | 
			
		
	
		
			
				
					|  |  |  | [MapRequest] = maprequest, | 
			
		
	
		
			
				
					|  |  |  | [PropertyNotify] = propertynotify, | 
			
		
	
		
			
				
					|  |  |  | [UnmapNotify] = unmapnotify | 
			
		
	
		
			
				
					|  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | void | 
			
		
	
		
			
				
					|  |  |  | grabkeys() | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; | 
			
		
	
		
			
				
					|  |  |  | unsigned int i; | 
			
		
	
		
			
				
					|  |  |  | KeyCode code; | 
			
		
	
		
			
				
					|  |  |  |  | 
			
		
	
		
			
				
					|  |  |  | for(i = 0; i < len; i++) { | 
			
		
	
		
			
				
					|  |  |  | code = XKeysymToKeycode(dpy, key[i].keysym); | 
			
		
	
		
			
				
					|  |  |  | XUngrabKey(dpy, code, key[i].mod, root); | 
			
		
	
		
			
				
					|  |  |  | XGrabKey(dpy, code, key[i].mod, root, True, | 
			
		
	
		
			
				
					|  |  |  | GrabModeAsync, GrabModeAsync); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } |