value caml_mapdc(value unit) { CAMLparam1(unit); mapdc(dc, win, mw, mh); CAMLreturn(Val_unit); }
void run(void) { XEvent ev; while(running && !XNextEvent(dc->dpy, &ev)) { if(XFilterEvent(&ev, win)) continue; switch(ev.type) { case Expose: if(ev.xexpose.count == 0) mapdc(dc, win, mw, mh); break; case KeyPress: keypress(&ev.xkey); break; case SelectionNotify: if(ev.xselection.property == utf8) paste(); break; case VisibilityNotify: if(ev.xvisibility.state != VisibilityUnobscured) XRaiseWindow(dc->dpy, win); break; } } }
void drawmenu(void) { int curpos; Item *item; dc->x = 0; dc->y = 0; dc->h = bh; drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); if(prompt && *prompt) { dc->w = promptw; drawtext(dc, prompt, selcol); dc->x = dc->w; } /* draw input field */ dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; drawtext(dc, text, normcol); if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol)); /* // Draw hits */ dc->w = textw(dc, hitstxt); dc->x = mw - dc->w; drawtext(dc, hitstxt, selcol); dc->x = 0; if(lines > 0) { /* draw vertical list */ dc->w = mw - dc->x; for(item = curr; item != next; item = item->right) { dc->y += dc->h; drawtext(dc, item->text, (item == sel) ? selcol : (item->out) ? outcol : normcol); } } else if(matches) { /* draw horizontal list */ dc->x += inputw; dc->w = textw(dc, "<"); if(curr->left) drawtext(dc, "<", normcol); for(item = curr; item != next; item = item->right) { dc->x += dc->w; dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">")); drawtext(dc, item->text, (item == sel) ? selcol : (item->out) ? outcol : normcol); } dc->w = textw(dc, ">"); dc->x = mw - dc->w; if(next) drawtext(dc, ">", normcol); } mapdc(dc, win, mw, mh); }
void drawmenu(void) { int curpos; Item *item; dc->x = 0; dc->y = 0; dc->h = bh; drawrect(dc, 0, 0, mw, mh, True, normcol->BG); if(prompt && *prompt) { dc->w = promptw; drawtext(dc, prompt, selcol); dc->x = dc->w; } /* draw input field */ dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; drawtext(dc, text, normcol); if((curpos = textnw(dc, text, cursor) + dc->font.height/2) < dc->w) drawrect(dc, curpos, (dc->h - dc->font.height)/2 + 1, 1, dc->font.height -1, True, normcol->FG); if(!quiet || strlen(text) > 0) { if(lines > 0) { /* draw vertical list */ dc->w = mw - dc->x; for(item = curr; item != next; item = item->right) { dc->y += dc->h; drawtext(dc, item->text, (item == sel) ? selcol : normcol); } } else if(matches) { /* draw horizontal list */ dc->x += inputw; dc->w = textw(dc, "<"); if(curr->left) drawtext(dc, "<", normcol); for(item = curr; item != next; item = item->right) { dc->x += dc->w; dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">")); drawtext(dc, item->text, (item == sel) ? selcol : normcol); } dc->w = textw(dc, ">"); dc->x = mw - dc->w; if(next) drawtext(dc, ">", normcol); } } mapdc(dc, win, mw, mh); }
value caml_next_event(value unit) { CAMLparam1(unit); CAMLlocal1(mlev); XEvent ev; char buf[32]; KeySym ksym = NoSymbol; Status status; size_t len; while(!XNextEvent(dc->dpy, &ev)) { if(XFilterEvent(&ev, win)) continue; switch(ev.type) { case Expose: if(ev.xexpose.count == 0) mapdc(dc, win, mw, mh); break; case KeyPress: len = XmbLookupString(xic, &ev.xkey, buf, sizeof buf, &ksym, &status); buf[len] = '\0'; mlev = caml_alloc_tuple(2); Field(mlev, 0) = Val_int(ksym); Field(mlev, 1) = caml_copy_string (buf); CAMLreturn (mlev); break; case SelectionNotify: /* if(ev.xselection.property == utf8) paste(); */ break; case VisibilityNotify: if(ev.xvisibility.state != VisibilityUnobscured) XRaiseWindow(dc->dpy, win); break; } } caml_failwith("unexpected return from XNextEvent") ; }
void setup(int topbar, const char *bg, unsigned int lines) { int x = 0, y = 0; /* position of the window */ /* if (!dc) { */ dc = initdc(); /* } */ initfont(dc, font); XInitThreads(); screen = DefaultScreen(dc->dpy); Window root = RootWindow(dc->dpy, screen); XSetWindowAttributes swa; XIM xim; #ifdef XINERAMA int n; XineramaScreenInfo *info; #endif clip = XInternAtom(dc->dpy, "CLIPBOARD", False); utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); /* calculate menu geometry */ bh = dc->font.height + 2; lines = MAX(lines, 0); mh = (lines + 1) * bh; #ifdef XINERAMA if((info = XineramaQueryScreens(dc->dpy, &n))) { int a, j, di, i = 0, area = 0; unsigned int du; Window w, pw, dw, *dws; XWindowAttributes wa; XGetInputFocus(dc->dpy, &w, &di); if(w != root && w != PointerRoot && w != None) { /* find top-level window containing current input focus */ do { if(XQueryTree(dc->dpy, (pw = w), &dw, &w, &dws, &du) && dws) XFree(dws); } while(w != root && w != pw); /* find xinerama screen with which the window intersects most */ if(XGetWindowAttributes(dc->dpy, pw, &wa)) for(j = 0; j < n; j++) if((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { area = a; i = j; } } /* no focused window is on screen, so use pointer location instead */ if(!area && XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) for(i = 0; i < n; i++) if(INTERSECT(x, y, 1, 1, info[i])) break; x = info[i].x_org; y = info[i].y_org + (topbar ? 0 : info[i].height - mh); mw = info[i].width; XFree(info); } else #endif { x = 0; y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; mw = DisplayWidth(dc->dpy, screen); } /* create menu window */ swa.override_redirect = True; swa.background_pixel = getcolor(dc, bg); swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, DefaultDepth(dc->dpy, screen), CopyFromParent, DefaultVisual(dc->dpy, screen), CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); XResizeWindow(dc->dpy, win, mw, mh); /* open input methods */ xim = XOpenIM(dc->dpy, NULL, NULL, NULL); xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, XNFocusWindow, win, NULL); XMapRaised(dc->dpy, win); resizedc(dc, mw, mh); mapdc(dc, win, mw, mh); }
void drawmenu(void) { int curpos; Item *item; dc->x = 0; dc->y = 0; dc->w = 0; dc->h = height; dc->text_offset_y = 0; if(mh < height) { dc->text_offset_y = (height - mh) / 2; } drawrect(dc, 0, 0, mw, height, True, BG(dc, normcol)); if(message) { if(messageposition == RIGHT || messageposition == CENTRE) { // Find starting position aligned text dc->x = mw; for(item = curr; item != next; item = item->right) { dc->x -= textw(dc, item->text); } } if(messageposition == CENTRE) { dc->x /= 2; } for(item = curr; item != next; item = item->right) { dc->w = textw(dc, item->text); drawtext(dc, item->text, normcol); dc->x += dc->w; } } else { if(prompt) { dc->w = promptw; drawtext(dc, prompt, selcol); dc->x = dc->w; } dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; drawtext(dc, text, normcol); if((curpos = textnw(dc, text, cursor) + mh/2 - 2) < dc->w) drawrect(dc, curpos, 2 + dc->text_offset_y, 1, mh - 4, True, FG(dc, normcol)); if(lines > 0) { dc->w = mw - dc->x; for(item = curr; item != next; item = item->right) { dc->y += dc->h; drawtext(dc, item->text, (item == sel) ? selcol : normcol); } } else if(matches) { dc->x += dc->w; if(curr->left) { dc->w = textw(dc, "<"); drawtext(dc, "<", normcol); dc->x += dc->w; } for(item = curr; item != next; item = item->right) { dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">")); drawtext(dc, item->text, (item == sel) ? selcol : normcol); dc->x += dc->w; } dc->w = textw(dc, ">"); dc->x = mw - dc->w; if(next) { drawtext(dc, ">", normcol); } } } mapdc(dc, win, mw, height); }