Xinqi Bao's Git

added dmenu.h, common.c
[dmenu.git] / common.c
1 /* See LICENSE file for copyright and license details. */
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <X11/keysym.h>
6 #ifdef XINERAMA
7 #include <X11/extensions/Xinerama.h>
8 #endif
9 #include "dmenu.h"
10
11 /* variables */
12 char *prompt = NULL;
13 char text[4096] = "";
14 int promptw = 0;
15 int screen;
16 unsigned int numlockmask = 0;
17 unsigned int mw, mh;
18 unsigned long normcol[ColLast];
19 unsigned long selcol[ColLast];
20 Bool topbar = True;
21 DC dc;
22 Display *dpy;
23 Window win, root;
24
25 void
26 grabkeyboard(void) {
27 unsigned int len;
28
29 for(len = 1000; len; len--) {
30 if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)
31 == GrabSuccess)
32 return;
33 usleep(1000);
34 }
35 exit(EXIT_FAILURE);
36 }
37
38 void
39 run(void) {
40 XEvent ev;
41
42 /* main event loop */
43 XSync(dpy, False);
44 while(!XNextEvent(dpy, &ev))
45 switch(ev.type) {
46 case KeyPress:
47 kpress(&ev.xkey);
48 break;
49 case Expose:
50 if(ev.xexpose.count == 0)
51 drawbar();
52 break;
53 case VisibilityNotify:
54 if(ev.xvisibility.state != VisibilityUnobscured)
55 XRaiseWindow(dpy, win);
56 break;
57 }
58 exit(EXIT_FAILURE);
59 }
60
61 void
62 setup(unsigned int lines) {
63 int i, j, x, y;
64 #if XINERAMA
65 int n;
66 XineramaScreenInfo *info = NULL;
67 #endif
68 XModifierKeymap *modmap;
69 XSetWindowAttributes wa;
70
71 /* init modifier map */
72 modmap = XGetModifierMapping(dpy);
73 for(i = 0; i < 8; i++)
74 for(j = 0; j < modmap->max_keypermod; j++) {
75 if(modmap->modifiermap[i * modmap->max_keypermod + j]
76 == XKeysymToKeycode(dpy, XK_Num_Lock))
77 numlockmask = (1 << i);
78 }
79 XFreeModifiermap(modmap);
80
81 dc.dpy = dpy;
82 normcol[ColBG] = getcolor(&dc, normbgcolor);
83 normcol[ColFG] = getcolor(&dc, normfgcolor);
84 selcol[ColBG] = getcolor(&dc, selbgcolor);
85 selcol[ColFG] = getcolor(&dc, selfgcolor);
86 initfont(&dc, font);
87
88 /* input window */
89 wa.override_redirect = True;
90 wa.background_pixmap = ParentRelative;
91 wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
92
93 /* input window geometry */
94 mh = (dc.font.height + 2) * (lines + 1);
95 #if XINERAMA
96 if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) {
97 i = 0;
98 if(n > 1) {
99 int di;
100 unsigned int dui;
101 Window dummy;
102 if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui))
103 for(i = 0; i < n; i++)
104 if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))
105 break;
106 }
107 x = info[i].x_org;
108 y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh;
109 mw = info[i].width;
110 XFree(info);
111 }
112 else
113 #endif
114 {
115 x = 0;
116 y = topbar ? 0 : DisplayHeight(dpy, screen) - mh;
117 mw = DisplayWidth(dpy, screen);
118 }
119
120 win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
121 DefaultDepth(dpy, screen), CopyFromParent,
122 DefaultVisual(dpy, screen),
123 CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
124
125 setupdraw(&dc, win);
126 if(prompt)
127 promptw = MIN(textw(&dc, prompt), mw / 5);
128 XMapRaised(dpy, win);
129 }