common.c
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); }