diff options
author | oga | 2008-05-20 14:50:51 +0000 |
---|---|---|
committer | oga | 2008-05-20 14:50:51 +0000 |
commit | c4a8f44931713f32f250264ca00520aae30fc0e3 (patch) | |
tree | 28a04445e99404bad46b8fbdc9070d8635e0fe72 /search.c | |
parent | 073225cc6903924869d463a1014860a78f73b008 (diff) | |
download | cwm-c4a8f44931713f32f250264ca00520aae30fc0e3.tar.gz |
Pull out the behaviour in grab_label and search_start into one utility
function menu_filter(). The plan is to eventually merge in grab_menu too.
Shrinks the code a fair bit.
Also, change XMaskEvent for XWindowEvent to prevent getting exposes for other
windows. This is particuarly noticable on slow machines with a LOT of xterms
(todd, you're an odd man).
ok okan@, todd@.
Diffstat (limited to 'search.c')
-rw-r--r-- | search.c | 267 |
1 files changed, 1 insertions, 266 deletions
@@ -14,7 +14,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: search.c,v 1.10 2008/05/19 18:07:53 okan Exp $ + * $Id: search.c,v 1.11 2008/05/20 14:50:51 oga Exp $ */ #include "headers.h" @@ -24,271 +24,6 @@ static int _strsubmatch(char *, char *, int); -void -search_init(struct screen_ctx *sc) -{ - sc->searchwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, - 1, 1, 1, sc->blackpixl, sc->whitepixl); -} - -/* - * Input: list of items, - * Output: choose one - * so, exactly like menus - */ - -struct menu * -search_start(struct menu_q *menuq, - void (*match)(struct menu_q *, struct menu_q *, char *), - void (*print)(struct menu *mi, int print), - char *prompt, int dummy) -{ - struct screen_ctx *sc = screen_current(); - int x, y, dx, dy, fontheight, - focusrevert, mutated, xmax, ymax, warp, added, beobnoxious = 0; - XEvent e; - char searchstr[MENU_MAXENTRY + 1]; - char dispstr[MENU_MAXENTRY*2 + 1]; - char promptstr[MENU_MAXENTRY + 1]; - Window focuswin; - struct menu *mi = NULL, *dummy_mi = NULL; - struct menu_q resultq; - char chr; - enum ctltype ctl; - size_t len; - u_int n; - static int list = 0; - int listing = 0; - char endchar = '«'; - struct fontdesc *font = DefaultFont; - - if (prompt == NULL) - prompt = "search"; - - TAILQ_INIT(&resultq); - - xmax = DisplayWidth(X_Dpy, sc->which); - ymax = DisplayHeight(X_Dpy, sc->which); - - xu_ptr_getpos(sc->rootwin, &x, &y); - - searchstr[0] = '\0'; - - snprintf(promptstr, sizeof(promptstr), "%s »", prompt); - dy = fontheight = font_ascent(font) + font_descent(font) + 1; - snprintf(dispstr, sizeof(dispstr), "%s%c", promptstr, endchar); - dx = font_width(font, dispstr, strlen(dispstr)); - - XMoveResizeWindow(X_Dpy, sc->searchwin, x, y, dx, dy); - XSelectInput(X_Dpy, sc->searchwin, SearchMask); - XMapRaised(X_Dpy, sc->searchwin); - - /* - * TODO: eventually, the mouse should be able to select - * results as well. Right now we grab it only to set a fancy - * cursor. - */ - if (xu_ptr_grab(sc->searchwin, 0, Cursor_question) < 0) { - XUnmapWindow(X_Dpy, sc->searchwin); - return (NULL); - } - - XGetInputFocus(X_Dpy, &focuswin, &focusrevert); - XSetInputFocus(X_Dpy, sc->searchwin, RevertToPointerRoot, CurrentTime); - - for (;;) { - added = mutated = 0; - - XMaskEvent(X_Dpy, SearchMask, &e); - - switch (e.type) { - case KeyPress: - if (input_keycodetrans(e.xkey.keycode, e.xkey.state, - &ctl, &chr) < 0) - continue; - - switch (ctl) { - case CTL_ERASEONE: - if ((len = strlen(searchstr)) > 0) { - searchstr[len - 1] = '\0'; - mutated = 1; - } - break; - case CTL_UP: - mi = TAILQ_LAST(&resultq, menu_q); - if (mi == NULL) - break; - - TAILQ_REMOVE(&resultq, mi, resultentry); - TAILQ_INSERT_HEAD(&resultq, mi, resultentry); - break; - case CTL_DOWN: - mi = TAILQ_FIRST(&resultq); - if (mi == NULL) - break; - - TAILQ_REMOVE(&resultq, mi, resultentry); - TAILQ_INSERT_TAIL(&resultq, mi, resultentry); - break; - case CTL_RETURN: - /* This is just picking the match the - * cursor is over. */ - if ((mi = TAILQ_FIRST(&resultq)) != NULL) { - goto found; - } else if (dummy) { - dummy_mi = xmalloc(sizeof *dummy_mi); - (void) strlcpy(dummy_mi->text, - searchstr, sizeof(dummy_mi->text)); - dummy_mi->dummy = 1; - goto found; - } - goto out; - case CTL_WIPE: - searchstr[0] = '\0'; - mutated = 1; - break; - case CTL_ALL: - list = !list; - break; - case CTL_ABORT: - goto out; - default: - break; - } - - if (chr != '\0') { - char str[2]; - - str[0] = chr; - str[1] = '\0'; - mutated = 1; - added = - strlcat(searchstr, str, sizeof(searchstr)); - } - - beobnoxious = 0; - if (mutated && strlen(searchstr) > 0) { - (*match)(menuq, &resultq, searchstr); - beobnoxious = TAILQ_EMPTY(&resultq); - } else if (mutated) - TAILQ_INIT(&resultq); - - - if (!list && listing && !mutated) { - TAILQ_INIT(&resultq); - listing = 0; - } - - case Expose: - if (list) { - if (TAILQ_EMPTY(&resultq) && list) { - /* Copy them all over. */ - TAILQ_FOREACH(mi, menuq, entry) - TAILQ_INSERT_TAIL(&resultq, mi, - resultentry); - - listing = 1; - } else if (mutated) - listing = 0; - } - - snprintf(dispstr, sizeof(dispstr), "%s%s%c", - promptstr, searchstr, endchar); - dx = font_width(font, dispstr, strlen(dispstr)); - dy = fontheight; - - TAILQ_FOREACH(mi, &resultq, resultentry) { - char *text; - - if (print != NULL) { - (*print)(mi, listing); - text = mi->print; - } else { - mi->print[0] = '\0'; - text = mi->text; - } - - dx = MAX(dx, font_width(font, text, - MIN(strlen(text), MENU_MAXENTRY))); - dy += fontheight; - } - - /* - * Calculate new geometry. - * - * XXX - put this into a util function -- it's - * used elsewhere, too. - */ - warp = 0; - if (x < 0) { - x = 0; - warp = 1; - } - if (x + dx >= xmax) { - x = xmax - dx; - warp = 1; - } - - if (y < 0) { - y = 0; - warp = 1; - } - if (y + dy >= ymax) { - y = ymax - dy; - /* If the menu is too high, never hide the - * top of the menu. - */ - if (y < 0) - y = 0; - warp = 1; - } - - if (warp) - xu_ptr_setpos(sc->rootwin, x, y); - - XClearWindow(X_Dpy, sc->searchwin); - XMoveResizeWindow(X_Dpy, sc->searchwin, x, y, dx, dy); - - font_draw(font, dispstr, strlen(dispstr), sc->searchwin, - 0, font_ascent(font) + 1); - - n = 1; - TAILQ_FOREACH(mi, &resultq, resultentry) { - char *text = mi->print[0] != '\0' ? - mi->print : mi->text; - - font_draw(font, text, - MIN(strlen(text), MENU_MAXENTRY), - sc->searchwin, - 0, n*fontheight + font_ascent(font) + 1); - n++; - } - - if (n > 1) - XFillRectangle(X_Dpy, sc->searchwin, sc->gc, - 0, fontheight, dx, fontheight); - - if (beobnoxious) - XFillRectangle(X_Dpy, sc->searchwin, sc->gc, - 0, 0, dx, fontheight); - - break; - } - } - -out: - /* (if no match) */ - xu_ptr_ungrab(); - XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime); - -found: - XUnmapWindow(X_Dpy, sc->searchwin); - - if (dummy && dummy_mi != NULL) - return (dummy_mi); - return (mi); -} - /* * Match: label, title, class. */ |