| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -6,6 +6,7 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <string.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <unistd.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <X11/keysym.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <X11/Xatom.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <X11/Xlib.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <X11/Xutil.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#ifdef XINERAMA | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -14,78 +15,72 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <draw.h> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "config.h" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define INRECT(x,y,rx,ry,rw,rh) ((rx) < (x) && (x) < (rx)+(rw) && (ry) < (y) && (y) < (ry)+(rh)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define MIN(a,b)                ((a) < (b) ? (a) : (b)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define MAX(a,b)                ((a) > (b) ? (a) : (b)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define IS_UTF8_1ST_CHAR(c)     (((c) & 0xc0) == 0xc0 || ((c) & 0x80) == 0x00) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define UTF8_CODEPOINT(c)       (((c) & 0xc0) != 0x80) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					typedef struct Item Item; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					struct Item { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						char *text; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *next;         /* traverses all items */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *left, *right; /* traverses items matching current search pattern */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *next;          /* traverses all items */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *left, *right;  /* traverses matching items */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void appenditem(Item *i, Item **list, Item **last); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void appenditem(Item *item, Item **list, Item **last); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void calcoffsetsh(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void calcoffsetsv(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static char *cistrstr(const char *s, const char *sub); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void cleanup(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void drawitem(const char *s, unsigned long col[ColLast]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void drawmenu(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void drawmenuh(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void drawmenuv(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void grabkeyboard(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void insert(const char *s, ssize_t n); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void keypress(XKeyEvent *e); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void match(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void paste(Atom atom); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void readstdin(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void run(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void setup(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void usage(void); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static char **argp = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static char *maxname = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static char *prompt; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static char text[4096]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int promptw; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int screen; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static size_t cur = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int cmdw = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static size_t cursor = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int inputw = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int lines = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int numlockmask; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int mw, mh; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned int promptw = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned long normcol[ColLast]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static unsigned long selcol[ColLast]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Atom utf8; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Bool topbar = True; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static DC dc; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Display *dpy; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Item *allitems = NULL;  /* first of all items */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Item *item = NULL;      /* first of pattern matching items */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Item *sel = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Item *next = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Item *prev = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Item *curr = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Window win, root; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Item *allitems, *matches; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Item *curr, *prev, *next, *sel; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static Window root, win; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static char *(*fstrstr)(const char *, const char *) = strstr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static void (*calcoffsets)(void) = calcoffsetsh; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					appenditem(Item *i, Item **list, Item **last) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					appenditem(Item *item, Item **list, Item **last) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(!(*last)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							*list = i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							*list = item; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						else | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							(*last)->right = i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						i->left = *last; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						i->right = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						*last = i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							(*last)->right = item; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						item->left = *last; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						item->right = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						*last = item; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					calcoffsetsh(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						unsigned int w, x; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						w = promptw + cmdw + textw(&dc, "<") + textw(&dc, ">"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						w = promptw + inputw + textw(&dc, "<") + textw(&dc, ">"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(x = w, next = curr; next; next = next->right) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if((x += MIN(textw(&dc, next->text), mw / 3)) > mw) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -128,33 +123,6 @@ cistrstr(const char *s, const char *sub) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						return (char *)s; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					cleanup(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *itm; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						while(allitems) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							itm = allitems->next; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							free(allitems->text); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							free(allitems); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							allitems = itm; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						cleanupdraw(&dc); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XDestroyWindow(dpy, win); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XUngrabKeyboard(dpy, CurrentTime); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XCloseDisplay(dpy); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					drawitem(const char *s, unsigned long col[ColLast]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						const char *p; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						unsigned int w = textnw(&dc, text, strlen(text)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						drawbox(&dc, col); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						drawtext(&dc, s, col); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(p = fstrstr(s, text); *text && (p = fstrstr(p, text)); p++) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							drawline(&dc, textnw(&dc, s, p-s) + dc.h/2 - 1, dc.h-2, w, 1, col); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					drawmenu(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						dc.x = 0; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -172,82 +140,89 @@ drawmenu(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							dc.x += dc.w; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						dc.w = mw - dc.x; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/* print command */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(cmdw && item && lines == 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							dc.w = cmdw; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/* print input area */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(matches && lines == 0 && textw(&dc, text) <= inputw) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							dc.w = inputw; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						drawtext(&dc, text, normcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						drawline(&dc, textnw(&dc, text, cur) + dc.h/2 - 2, 2, 1, dc.h-4, normcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						drawline(&dc, textnw(&dc, text, cursor) + dc.h/2 - 2, 2, 1, dc.h-4, normcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(lines > 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							drawmenuv(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						else if(curr) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						else if(curr && (dc.w == inputw || curr->next)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							drawmenuh(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						commitdraw(&dc, win); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					drawmenuh(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *item; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						dc.x += cmdw; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						dc.x += inputw; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						dc.w = textw(&dc, "<"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						drawtext(&dc, curr->left ? "<" : NULL, normcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(curr->left) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							drawtext(&dc, "<", normcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						dc.x += dc.w; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(i = curr; i != next; i = i->right) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							dc.w = MIN(textw(&dc, i->text), mw / 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							drawitem(i->text, (sel == i) ? selcol : normcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(item = curr; item != next; item = item->right) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							dc.w = MIN(textw(&dc, item->text), mw / 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(item == sel) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								drawbox(&dc, selcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							drawtext(&dc, item->text, (item == sel) ? selcol : normcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							dc.x += dc.w; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						dc.w = textw(&dc, ">"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						dc.x = mw - dc.w; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						drawtext(&dc, next ? ">" : NULL, normcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(next) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							drawtext(&dc, ">", normcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					drawmenuv(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *item; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XWindowAttributes wa; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						dc.y = topbar ? dc.h : 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						dc.w = mw - dc.x; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(i = curr; i != next; i = i->right) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							drawitem(i->text, (sel == i) ? selcol : normcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(item = curr; item != next; item = item->right) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(item == sel) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								drawbox(&dc, selcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							drawtext(&dc, item->text, (item == sel) ? selcol : normcol); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							dc.y += dc.h; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(!XGetWindowAttributes(dpy, win, &wa)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							eprint("cannot get window attributes"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XMoveResizeWindow(dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(!XGetWindowAttributes(dc.dpy, win, &wa)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							eprintf("cannot get window attributes\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(wa.height != mh) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							XMoveResizeWindow(dc.dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					grabkeyboard(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						unsigned int n; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(n = 0; n < 1000; n++) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(i = 0; i < 1000; i++) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!XGrabKeyboard(dc.dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							usleep(1000); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						exit(EXIT_FAILURE); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						eprintf("cannot grab keyboard\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					insert(const char *s, ssize_t n) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						memmove(text + cursor + n, text + cursor, sizeof text - cursor - n); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(n > 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							memcpy(text + cursor, s, n); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						cursor += n; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						match(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					keypress(XKeyEvent *e) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						char buf[sizeof text]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int num; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						unsigned int i, len; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int n; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						size_t len; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						KeySym ksym; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						len = strlen(text); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						num = XLookupString(e, buf, sizeof buf, &ksym, NULL); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(ksym == XK_KP_Enter) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							ksym = XK_Return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							ksym = (ksym - XK_KP_0) + XK_0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						else if(IsFunctionKey(ksym) || IsKeypadKey(ksym) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						|| IsMiscFunctionKey(ksym) || IsPFKey(ksym) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						|| IsPrivateKeypadKey(ksym)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/* first check if a control mask is omitted */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XLookupString(e, buf, sizeof buf, &ksym, NULL); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(e->state & ControlMask) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							switch(tolower(ksym)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							default: | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -277,8 +252,8 @@ keypress(XKeyEvent *e) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case XK_m: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								ksym = XK_Return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case XK_k: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								text[cur] = '\0'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case XK_k:  /* delete right */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								text[cursor] = '\0'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case XK_n: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								ksym = XK_Down; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -286,66 +261,44 @@ keypress(XKeyEvent *e) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case XK_p: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								ksym = XK_Up; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case XK_u: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								memmove(text, text + cur, sizeof text - cur + 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								cur = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								match(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case XK_u:  /* delete left */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								insert(NULL, -cursor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case XK_w: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(cur == 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case XK_w:  /* delete word */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(cursor == 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								i = cur; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								while(i-- > 0 && text[i] == ' '); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								while(i-- > 0 && text[i] != ' '); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								memmove(text + i + 1, text + cur, sizeof text - cur + 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								cur = i + 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								match(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case XK_y: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									FILE *fp; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									char *s; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									if(!(fp = fopen("sselp", "r"))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										eprint("cannot popen sselp\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									s = fgets(buf, sizeof buf, fp); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									fclose(fp); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									if(!s) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
										return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								num = strlen(buf); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(num && buf[num-1] == '\n') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									buf[--num] = '\0'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								n = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								while(cursor - n++ > 0 && text[cursor - n] == ' '); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								while(cursor - n++ > 0 && text[cursor - n] != ' '); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								insert(NULL, -(--n)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case XK_y:  /* paste selection */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								XConvertSelection(dc.dpy, XA_PRIMARY, utf8, None, win, CurrentTime); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/* causes SelectionNotify event */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						switch(ksym) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						default: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							num = MIN(num, sizeof text); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(num && !iscntrl((int) buf[0])) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								memmove(text + cur + num, text + cur, sizeof text - cur - num); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								memcpy(text + cur, buf, num); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								cur += num; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								match(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!iscntrl((int)*buf)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								insert(buf, MIN(strlen(buf), sizeof text - cursor)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						case XK_BackSpace: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(cur == 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(cursor == 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							for(i = 1; len - i > 0 && !IS_UTF8_1ST_CHAR(text[cur - i]); i++); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							memmove(text + cur - i, text + cur, sizeof text - cur + i); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							cur -= i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							match(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							for(n = 1; cursor - n > 0 && !UTF8_CODEPOINT(text[cursor - n]); n++); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							insert(NULL, -n); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						case XK_Delete: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(cur == len) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(cursor == len) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							for(i = 1; cur + i < len && !IS_UTF8_1ST_CHAR(text[cur + i]); i++); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							memmove(text + cur, text + cur + i, sizeof text - cur); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							match(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							for(n = 1; cursor + n < len && !UTF8_CODEPOINT(text[cursor + n]); n++); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							cursor += n; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							insert(NULL, -n); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						case XK_End: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(cur < len) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								cur = len; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(cursor < len) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								cursor = len; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							while(next) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -358,19 +311,19 @@ keypress(XKeyEvent *e) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						case XK_Escape: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							exit(EXIT_FAILURE); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						case XK_Home: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(sel == item) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								cur = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(sel == matches) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								cursor = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							sel = curr = item; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							sel = curr = matches; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							calcoffsets(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						case XK_Left: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(cur > 0 && (!sel || !sel->left || lines > 0)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								while(cur-- > 0 && !IS_UTF8_1ST_CHAR(text[cur])); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(cursor > 0 && (!sel || !sel->left || lines > 0)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								while(cursor-- > 0 && !UTF8_CODEPOINT(text[cursor])); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(lines > 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(lines > 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						case XK_Up: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!sel || !sel->left) | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -394,15 +347,16 @@ keypress(XKeyEvent *e) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							calcoffsets(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						case XK_Return: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							fprintf(stdout, "%s", ((e->state & ShiftMask) || sel) ? sel->text : text); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						case XK_KP_Enter: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							fputs(((e->state & ShiftMask) || sel) ? sel->text : text, stdout); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							fflush(stdout); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							exit(EXIT_SUCCESS); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						case XK_Right: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(cur < len) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								while(cur++ < len && !IS_UTF8_1ST_CHAR(text[cur])); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(cursor < len) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								while(cursor++ < len && !UTF8_CODEPOINT(text[cursor])); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(lines > 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(lines > 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						case XK_Down: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!sel || !sel->right) | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -417,7 +371,7 @@ keypress(XKeyEvent *e) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!sel) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							strncpy(text, sel->text, sizeof text); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							cur = strlen(text); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							cursor = strlen(text); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							match(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -427,19 +381,19 @@ keypress(XKeyEvent *e) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					match(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						unsigned int len; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *item, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						len = strlen(text); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(i = allitems; i; i = i->next) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!fstrncmp(text, i->text, len + 1)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								appenditem(i, &lexact, &exactend); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!fstrncmp(text, i->text, len)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								appenditem(i, &lprefix, &prefixend); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(fstrstr(i->text, text)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								appenditem(i, &lsubstr, &substrend); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						matches = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(item = allitems; item; item = item->next) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!fstrncmp(text, item->text, len + 1)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								appenditem(item, &lexact, &exactend); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!fstrncmp(text, item->text, len)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								appenditem(item, &lprefix, &prefixend); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(fstrstr(item->text, text)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								appenditem(item, &lsubstr, &substrend); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(lexact) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							item = lexact; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							matches = lexact; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							itemend = exactend; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(lprefix) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -448,7 +402,7 @@ match(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								lprefix->left = itemend; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								item = lprefix; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								matches = lprefix; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							itemend = prefixend; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(lsubstr) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -457,36 +411,48 @@ match(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								lsubstr->left = itemend; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								item = lsubstr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								matches = lsubstr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						curr = prev = next = sel = item; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						curr = prev = next = sel = matches; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						calcoffsets(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					paste(Atom atom) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						char *p, *q; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int di; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						unsigned long dl; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Atom da; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XGetWindowProperty(dc.dpy, win, atom, 0, sizeof text - cursor, True, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								utf8, &da, &di, &dl, &dl, (unsigned char **)&p); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						insert(p, (q = strchr(p, '\n')) ? q-p : strlen(p)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XFree(p); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						drawmenu(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					readstdin(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						char *p, buf[sizeof text]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						unsigned int len = 0, max = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *i, *new; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						char buf[sizeof text]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						size_t len; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Item *item, *new; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						i = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						while(fgets(buf, sizeof buf, stdin)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						allitems = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(item = NULL; fgets(buf, sizeof buf, stdin); item = new) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							len = strlen(buf); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(buf[len-1] == '\n') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								buf[--len] = '\0'; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!(p = strdup(buf))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								eprint("cannot strdup %u bytes\n", len); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if((max = MAX(max, len)) == len) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								maxname = p; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!(new = malloc(sizeof *new))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								eprint("cannot malloc %u bytes\n", sizeof *new); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								eprintf("cannot malloc %u bytes\n", sizeof *new); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!(new->text = strdup(buf))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								eprintf("cannot strdup %u bytes\n", len); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							inputw = MAX(inputw, textw(&dc, new->text)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							new->next = new->left = new->right = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							new->text = p; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!i) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								allitems = new; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(item) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								item->next = new; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								i->next = new; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							i = new; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								allitems = new; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -494,8 +460,7 @@ void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					run(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XEvent ev; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XSync(dpy, False); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						while(!XNextEvent(dpy, &ev)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						while(!XNextEvent(dc.dpy, &ev)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							switch(ev.type) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case Expose: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(ev.xexpose.count == 0) | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -504,62 +469,45 @@ run(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case KeyPress: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								keypress(&ev.xkey); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case SelectionNotify: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(ev.xselection.property != None) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									paste(ev.xselection.property); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case VisibilityNotify: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(ev.xvisibility.state != VisibilityUnobscured) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									XRaiseWindow(dpy, win); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									XRaiseWindow(dc.dpy, win); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						exit(EXIT_FAILURE); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					setup(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int i, j, x, y; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#if XINERAMA | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int n; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XineramaScreenInfo *info = NULL; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int x, y; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#ifdef XINERAMA | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int i, n; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XineramaScreenInfo *info; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#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; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#ifdef XINERAMA | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if((info = XineramaQueryScreens(dc.dpy, &n))) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							int di; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							unsigned int du; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							Window dw; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							XQueryPointer(dc.dpy, root, &dw, &dw, &x, &y, &di, &di, &du); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							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; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							y = info[i].y_org + (topbar ? 0 : info[i].height - mh); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							mw = info[i].width; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							XFree(info); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -567,84 +515,86 @@ setup(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#endif | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							x = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							mw = DisplayWidth(dpy, screen); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							y = topbar ? 0 : DisplayHeight(dc.dpy, screen) - mh; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							mw = DisplayWidth(dc.dpy, screen); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						win = XCreateWindow(dpy, root, x, y, mw, mh, 0, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								DefaultDepth(dpy, screen), CopyFromParent, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								DefaultVisual(dpy, screen), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/* input window */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						wa.override_redirect = True; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						wa.background_pixmap = ParentRelative; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						wa.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 | CWBackPixmap | CWEventMask, &wa); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						match(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						grabkeyboard(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						setupdraw(&dc, win); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(prompt) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							promptw = MIN(textw(&dc, prompt), mw / 5); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XMapRaised(dpy, win); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						inputw = MIN(inputw, mw / 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						utf8 = XInternAtom(dc.dpy, "UTF8_STRING", False); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						XMapRaised(dc.dpy, win); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					usage(void) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						fputs("usage: dmenu [-b] [-i] [-l <lines>] [-p <prompt>] [-fn <font>] [-nb <color>]\n" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							      "             [-nf <color>] [-sb <color>] [-sf <color>] [-v]\n", stderr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						exit(EXIT_FAILURE); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					int | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					main(int argc, char *argv[]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						unsigned int i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int i; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/* command line args */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						progname = "dmenu"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						for(i = 1; i < argc; i++) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!strcmp(argv[i], "-i")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								fstrncmp = strncasecmp; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								fstrstr = cistrstr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							/* 1-arg flags */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!strcmp(argv[i], "-v")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								fputs("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n", stdout); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								exit(EXIT_SUCCESS); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-b")) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								topbar = False; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-i")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								fstrncmp = strncasecmp; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								fstrstr = cistrstr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(i == argc-1) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								usage(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							/* 2-arg flags */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-l")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(++i < argc) lines = atoi(argv[i]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(lines > 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if((lines = atoi(argv[++i])) > 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									calcoffsets = calcoffsetsv; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-fn")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(++i < argc) font = argv[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-nb")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(++i < argc) normbgcolor = argv[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-nf")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(++i < argc) normfgcolor = argv[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-p")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(++i < argc) prompt = argv[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-sb")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(++i < argc) selbgcolor = argv[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-sf")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								if(++i < argc) selfgcolor = argv[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-v")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								printf("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								exit(EXIT_SUCCESS); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								fputs("usage: dmenu [-i] [-b] [-l <lines>] [-fn <font>] [-nb <color>]\n" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								      "             [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n", stderr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								exit(EXIT_FAILURE); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								prompt = argv[++i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								promptw = MIN(textw(&dc, prompt), mw/5); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-fn")) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								font = argv[++i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-nb")) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								normbgcolor = argv[++i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-nf")) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								normfgcolor = argv[++i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-sb")) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								selbgcolor = argv[++i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else if(!strcmp(argv[i], "-sf")) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								selfgcolor = argv[++i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							else | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								usage(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							fprintf(stderr, "dmenu: warning: no locale support\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(!(dpy = XOpenDisplay(NULL))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							eprint("cannot open display\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(atexit(&cleanup) != 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							eprint("cannot register cleanup\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						screen = DefaultScreen(dpy); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						root = RootWindow(dpy, screen); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(!(argp = malloc(sizeof *argp * (argc+2)))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							eprint("cannot malloc %u bytes\n", sizeof *argp * (argc+2)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						memcpy(argp + 2, argv + 1, sizeof *argp * argc); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							fputs("dmenu: warning: no locale support\n", stderr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(!(dc.dpy = XOpenDisplay(NULL))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							eprintf("cannot open display\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						screen = DefaultScreen(dc.dpy); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						root = RootWindow(dc.dpy, screen); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						initfont(&dc, font); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						readstdin(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						grabkeyboard(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						setup(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(maxname) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							cmdw = MIN(textw(&dc, maxname), mw / 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						match(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						run(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						return EXIT_FAILURE;  /* should not reach */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} |