145 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* function implementations */
 | 
						|
void
 | 
						|
clearcmd(const Arg *arg)
 | 
						|
{
 | 
						|
	unsigned int i;
 | 
						|
 | 
						|
	for (i = 0; i < LENGTH(cmdkeysym); i++) {
 | 
						|
		cmdkeysym[i] = 0;
 | 
						|
		cmdmod[i] = 0;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
grabkeys(void)
 | 
						|
{
 | 
						|
	if (keymode == INSERTMODE) {
 | 
						|
		grabdefkeys();
 | 
						|
	} else if (keymode == COMMANDMODE) {
 | 
						|
		XUngrabKey(dpy, AnyKey, AnyModifier, root);
 | 
						|
		XGrabKey(dpy, AnyKey, AnyModifier, root,
 | 
						|
			 True, GrabModeAsync, GrabModeAsync);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
isprotodel(Client *c)
 | 
						|
{
 | 
						|
	int n;
 | 
						|
	Atom *protocols;
 | 
						|
	int ret = 0;
 | 
						|
 | 
						|
	if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
 | 
						|
		while (!ret && n--)
 | 
						|
			ret = protocols[n] == wmatom[WMDelete];
 | 
						|
		XFree(protocols);
 | 
						|
	}
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
keypress(XEvent *e)
 | 
						|
{
 | 
						|
	unsigned int i, j;
 | 
						|
	Arg a = {0};
 | 
						|
	Bool ismatch = False, maybematch = False;
 | 
						|
	KeySym keysym;
 | 
						|
	XKeyEvent *ev;
 | 
						|
 | 
						|
	if (keymode == INSERTMODE)
 | 
						|
		keydefpress(e);
 | 
						|
	else if (keymode == COMMANDMODE) {
 | 
						|
		ev = &e->xkey;
 | 
						|
		keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
 | 
						|
		if (keysym < XK_Shift_L || keysym > XK_Hyper_R) {
 | 
						|
			for (i = 0; i < LENGTH(cmdkeys); i++)
 | 
						|
				if (keysym == cmdkeys[i].keysym
 | 
						|
				&& CLEANMASK(cmdkeys[i].mod) == CLEANMASK(ev->state)
 | 
						|
				&& cmdkeys[i].func) {
 | 
						|
					cmdkeys[i].func(&(cmdkeys[i].arg));
 | 
						|
					ismatch = True;
 | 
						|
					break;
 | 
						|
				}
 | 
						|
			if (!ismatch) {
 | 
						|
				for (j = 0; j < LENGTH(cmdkeysym); j++)
 | 
						|
					if (cmdkeysym[j] == 0) {
 | 
						|
						cmdkeysym[j] = keysym;
 | 
						|
						cmdmod[j] = ev->state;
 | 
						|
						break;
 | 
						|
					}
 | 
						|
				for (i = 0; i < LENGTH(commands); i++) {
 | 
						|
					for (j = 0; j < LENGTH(cmdkeysym); j++) {
 | 
						|
						if (cmdkeysym[j] == commands[i].keysym[j]
 | 
						|
						&& CLEANMASK(cmdmod[j]) == CLEANMASK(commands[i].mod[j]))
 | 
						|
							ismatch = True;
 | 
						|
						else if (cmdkeysym[j] == 0
 | 
						|
						&& cmdmod[j] == 0) {
 | 
						|
							ismatch = False;
 | 
						|
							maybematch = True;
 | 
						|
							break;
 | 
						|
						} else {
 | 
						|
							ismatch = False;
 | 
						|
							break;
 | 
						|
						}
 | 
						|
					}
 | 
						|
					if (ismatch) {
 | 
						|
						if (commands[i].func)
 | 
						|
							commands[i].func(&(commands[i].arg));
 | 
						|
						clearcmd(&a);
 | 
						|
						break;
 | 
						|
					}
 | 
						|
 | 
						|
				}
 | 
						|
				if (!maybematch)
 | 
						|
					clearcmd(&a);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
onlyclient(const Arg *arg)
 | 
						|
{
 | 
						|
	Client *c;
 | 
						|
	XEvent ev;
 | 
						|
 | 
						|
	if (!selmon->sel)
 | 
						|
		return;
 | 
						|
	for (c = selmon->clients; c; c = c->next) {
 | 
						|
		if (c != selmon->sel && ISVISIBLE(c)) {
 | 
						|
			if (isprotodel(c)) {
 | 
						|
				ev.type = ClientMessage;
 | 
						|
				ev.xclient.window = c->win;
 | 
						|
				ev.xclient.message_type = wmatom[WMProtocols];
 | 
						|
				ev.xclient.format = 32;
 | 
						|
				ev.xclient.data.l[0] = wmatom[WMDelete];
 | 
						|
				ev.xclient.data.l[1] = CurrentTime;
 | 
						|
				XSendEvent(dpy, c->win, False, NoEventMask, &ev);
 | 
						|
			}
 | 
						|
			else {
 | 
						|
				XGrabServer(dpy);
 | 
						|
				XSetErrorHandler(xerrordummy);
 | 
						|
				XSetCloseDownMode(dpy, DestroyAll);
 | 
						|
				XKillClient(dpy, c->win);
 | 
						|
				XSync(dpy, False);
 | 
						|
				XSetErrorHandler(xerror);
 | 
						|
				XUngrabServer(dpy);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
setkeymode(const Arg *arg)
 | 
						|
{
 | 
						|
	Arg a = {0};
 | 
						|
 | 
						|
	if (!arg)
 | 
						|
		return;
 | 
						|
	keymode = arg->ui;
 | 
						|
	clearcmd(&a);
 | 
						|
	grabkeys();
 | 
						|
}
 | 
						|
 |