aboutsummaryrefslogtreecommitdiffstats
path: root/search.c
diff options
context:
space:
mode:
authoroga2008-05-20 14:50:51 +0000
committeroga2008-05-20 14:50:51 +0000
commitc4a8f44931713f32f250264ca00520aae30fc0e3 (patch)
tree28a04445e99404bad46b8fbdc9070d8635e0fe72 /search.c
parent073225cc6903924869d463a1014860a78f73b008 (diff)
downloadcwm-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.c267
1 files changed, 1 insertions, 266 deletions
diff --git a/search.c b/search.c
index e989f4e..697c4d9 100644
--- a/search.c
+++ b/search.c
@@ -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.
*/