Xinqi Bao's Git

added dmenu.h, common.c
[dmenu.git] / common.c
diff --git a/common.c b/common.c
new file mode 100644 (file)
index 0000000..2d19aee
--- /dev/null
+++ b/common.c
@@ -0,0 +1,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);
+}