aboutsummaryrefslogtreecommitdiff
path: root/common.c
blob: 2d19aeea650d4d2ad69a7bccdd0107852386d8fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* See LICENSE file for copyright and license details. */
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/keysym.h>
#ifdef XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
#include "dmenu.h"

/* variables */
char *prompt = NULL;
char text[4096] = "";
int promptw = 0;
int screen;
unsigned int numlockmask = 0;
unsigned int mw, mh;
unsigned long normcol[ColLast];
unsigned long selcol[ColLast];
Bool topbar = True;
DC dc;
Display *dpy;
Window win, root;

void
grabkeyboard(void) {
	unsigned int len;

	for(len = 1000; len; len--) {
		if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)
		== GrabSuccess)
			return;
		usleep(1000);
	}
	exit(EXIT_FAILURE);
}

void
run(void) {
	XEvent ev;

	/* main event loop */
	XSync(dpy, False);
	while(!XNextEvent(dpy, &ev))
		switch(ev.type) {
		case KeyPress:
			kpress(&ev.xkey);
			break;
		case Expose:
			if(ev.xexpose.count == 0)
				drawbar();
			break;
		case VisibilityNotify:
			if(ev.xvisibility.state != VisibilityUnobscured)
				XRaiseWindow(dpy, win);
			break;
		}
	exit(EXIT_FAILURE);
}

void
setup(unsigned int lines) {
	int i, j, x, y;
#if XINERAMA
	int n;
	XineramaScreenInfo *info = NULL;
#endif
	XModifierKeymap *modmap;
	XSetWindowAttributes wa;

	/* init modifier map */
	modmap = XGetModifierMapping(dpy);
	for(i = 0; i < 8; i++)
		for(j = 0; j < modmap->max_keypermod; j++) {
			if(modmap->modifiermap[i * modmap->max_keypermod + j]
			== XKeysymToKeycode(dpy, XK_Num_Lock))
				numlockmask = (1 << i);
		}
	XFreeModifiermap(modmap);

	dc.dpy = dpy;
	normcol[ColBG] = getcolor(&dc, normbgcolor);
	normcol[ColFG] = getcolor(&dc, normfgcolor);
	selcol[ColBG] = getcolor(&dc, selbgcolor);
	selcol[ColFG] = getcolor(&dc, selfgcolor);
	initfont(&dc, font);

	/* input window */
	wa.override_redirect = True;
	wa.background_pixmap = ParentRelative;
	wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;

	/* input window geometry */
	mh = (dc.font.height + 2) * (lines + 1);
#if XINERAMA
	if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) {
		i = 0;
		if(n > 1) {
			int di;
			unsigned int dui;
			Window dummy;
			if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui))
				for(i = 0; i < n; i++)
					if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))
						break;
		}
		x = info[i].x_org;
		y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh;
		mw = info[i].width;
		XFree(info);
	}
	else
#endif
	{
		x = 0;
		y = topbar ? 0 : DisplayHeight(dpy, screen) - mh;
		mw = DisplayWidth(dpy, screen);
	}

	win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
			DefaultDepth(dpy, screen), CopyFromParent,
			DefaultVisual(dpy, screen),
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);

	setupdraw(&dc, win);
	if(prompt)
		promptw = MIN(textw(&dc, prompt), mw / 5);
	XMapRaised(dpy, win);
}