@ -35,16 +35,16 @@ struct Item {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						bool  out ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  appenditem ( Item  * item ,  Item  * * list ,  Item  * * last ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  appenditem ( Item  * ,  Item  * * ,  Item  * * ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  calcoffsets ( void ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  char  * cistrstr ( const  char  * s ,  const  char  * sub ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  char  * cistrstr ( const  char  * ,  const  char  * ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  cleanup ( void ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  drawmenu ( void ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  grabkeyboard ( void ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  insert ( const  char  * str ,  ssize_t  n  ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  keypress ( XKeyEvent  * ev ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  insert ( const  char  * ,  ssize_t ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  keypress ( XKeyEvent  * ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  match ( void ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  size_t  nextrune ( int  inc  ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  size_t  nextrune ( int ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  paste ( void ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  readstdin ( void ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  run ( void ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -53,100 +53,31 @@ static void usage(void);  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  char  text [ BUFSIZ ]  =  " " ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  int  bh ,  mw ,  mh ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  int  sw ,  sh ;  /* X display screen geometry width, height */  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  int  inputw ,  promptw ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  size_t  cursor  =  0 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  Atom  clip ,  utf8 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  size_t  cursor ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  Item  * items  =  NULL ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  Item  * matches ,  * matchend ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  Item  * prev ,  * curr ,  * next ,  * sel ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  Window  win ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  int  mon  =  - 1 ,  screen ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  Atom  clip ,  utf8 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  Display  * dpy ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  Window  root ,  win ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  XIC  xic ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  int  mon  =  - 1 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  ClrScheme  scheme [ SchemeLast ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  Display  * dpy ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  int  screen ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  Window  root ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  Drw  * drw ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  int  sw ,  sh ;  /* X display screen geometry width, height */  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# include  "config.h"  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  int  ( * fstrncmp ) ( const  char  * ,  const  char  * ,  size_t )  =  strncmp ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  char  * ( * fstrstr ) ( const  char  * ,  const  char  * )  =  strstr ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					int  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					main ( int  argc ,  char  * argv [ ] )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						bool  fast  =  false ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						int  i ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for ( i  =  1 ;  i  <  argc ;  i + + )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							/* these options take no arguments */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ! strcmp ( argv [ i ] ,  " -v " ) )  {       /* prints version information */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								puts ( " dmenu- " VERSION " , © 2006-2015 dmenu engineers, see LICENSE for details " ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								exit ( 0 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! strcmp ( argv [ i ] ,  " -b " ) )    /* appears at the bottom of the screen */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								topbar  =  false ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! strcmp ( argv [ i ] ,  " -f " ) )    /* grabs keyboard before reading stdin */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								fast  =  true ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! strcmp ( argv [ i ] ,  " -i " ) )  {  /* case-insensitive item matching */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								fstrncmp  =  strncasecmp ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								fstrstr  =  cistrstr ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( i + 1  = =  argc )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								usage ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							/* these options take one argument */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! strcmp ( argv [ i ] ,  " -l " ) )    /* number of lines in vertical list */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								lines  =  atoi ( argv [ + + i ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! strcmp ( argv [ i ] ,  " -m " ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								mon  =  atoi ( argv [ + + i ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! strcmp ( argv [ i ] ,  " -p " ) )    /* adds prompt to left of input field */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								prompt  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! strcmp ( argv [ i ] ,  " -fn " ) )   /* font or font set */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								fonts [ 0 ]  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! strcmp ( argv [ i ] ,  " -nb " ) )   /* normal background color */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								normbgcolor  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! strcmp ( argv [ i ] ,  " -nf " ) )   /* normal foreground color */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								normfgcolor  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! strcmp ( argv [ i ] ,  " -sb " ) )   /* selected background color */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								selbgcolor  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! strcmp ( argv [ i ] ,  " -sf " ) )   /* selected foreground color */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								selfgcolor  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								usage ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( ! setlocale ( LC_CTYPE ,  " " )  | |  ! XSupportsLocale ( ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							fputs ( " warning: no locale support \n " ,  stderr ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( ! ( dpy  =  XOpenDisplay ( NULL ) ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							die ( " dmenu: cannot open display \n " ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						screen  =  DefaultScreen ( dpy ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						root  =  RootWindow ( dpy ,  screen ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						sw  =  DisplayWidth ( dpy ,  screen ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						sh  =  DisplayHeight ( dpy ,  screen ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw  =  drw_create ( dpy ,  screen ,  root ,  sw ,  sh ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw_load_fonts ( drw ,  fonts ,  LENGTH ( fonts ) ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( ! drw - > fontcount )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							die ( " No fonts could be loaded. \n " ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw_setscheme ( drw ,  & scheme [ SchemeNorm ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( fast )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							grabkeyboard ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							readstdin ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						else  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							readstdin ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							grabkeyboard ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						setup ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						run ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						return  1 ;  /* unreachable */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					appenditem ( Item  * item ,  Item  * * list ,  Item  * * last )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( * last )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					appenditem ( Item  * item ,  Item  * * list ,  Item  * * last )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if  ( * last )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							( * last ) - > right  =  item ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							* list  =  item ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -156,25 +87,27 @@ appenditem(Item *item, Item **list, Item **last) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						* last  =  item ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					calcoffsets ( void )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					calcoffsets ( void )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						int  i ,  n ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( lines  >  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if   ( lines  >  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							n  =  lines  *  bh ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							n  =  mw  -  ( promptw  +  inputw  +  TEXTW ( " < " )  +  TEXTW ( " > " ) ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						/* calculate which items will begin the next page and previous page */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for ( i  =  0 ,  next  =  curr ;  next ;  next  =  next - > right )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ( i  + =  ( lines  >  0 )  ?  bh  :  MIN ( TEXTW ( next - > text ) ,  n ) )  >  n )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for   ( i  =  0 ,  next  =  curr ;  next ;  next  =  next - > right )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ( i  + =  ( lines  >  0 )  ?  bh  :  MIN ( TEXTW ( next - > text ) ,  n ) )  >  n )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for ( i  =  0 ,  prev  =  curr ;  prev  & &  prev - > left ;  prev  =  prev - > left )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ( i  + =  ( lines  >  0 )  ?  bh  :  MIN ( TEXTW ( prev - > left - > text ) ,  n ) )  >  n )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for   ( i  =  0 ,  prev  =  curr ;  prev  & &  prev - > left ;  prev  =  prev - > left )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ( i  + =  ( lines  >  0 )  ?  bh  :  MIN ( TEXTW ( prev - > left - > text ) ,  n ) )  >  n )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					cleanup ( void )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					cleanup ( void )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						XUngrabKey ( dpy ,  AnyKey ,  AnyModifier ,  root ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw_clr_free ( scheme [ SchemeNorm ] . bg ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw_clr_free ( scheme [ SchemeNorm ] . fg ) ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -187,18 +120,20 @@ cleanup(void) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						XCloseDisplay ( dpy ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					char  *  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					cistrstr ( const  char  * s ,  const  char  * sub )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  char  *  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					cistrstr ( const  char  * s ,  const  char  * sub )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						size_t  len ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for ( len  =  strlen ( sub ) ;  * s ;  s + + )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ! strncasecmp ( s ,  sub ,  len ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for   ( len  =  strlen ( sub ) ;  * s ;  s + + )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ! strncasecmp ( s ,  sub ,  len ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								return  ( char  * ) s ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						return  NULL ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					drawmenu ( void )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					drawmenu ( void )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						int  curpos ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						Item  * item ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						int  x  =  0 ,  y  =  0 ,  h  =  bh ,  w ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -206,7 +141,7 @@ drawmenu(void) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw_setscheme ( drw ,  & scheme [ SchemeNorm ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw_rect ( drw ,  0 ,  0 ,  mw ,  mh ,  1 ,  1 ,  1 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( prompt  & &  * prompt )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if   ( prompt  & &  * prompt )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							drw_setscheme ( drw ,  & scheme [ SchemeSel ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							drw_text ( drw ,  x ,  0 ,  promptw ,  bh ,  prompt ,  0 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							x  + =  promptw ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -216,41 +151,40 @@ drawmenu(void) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw_setscheme ( drw ,  & scheme [ SchemeNorm ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw_text ( drw ,  x ,  0 ,  w ,  bh ,  text ,  0 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( ( curpos  =  TEXTNW ( text ,  cursor )  +  bh / 2  -  2 )  <  w )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if   ( ( curpos  =  TEXTNW ( text ,  cursor )  +  bh   /   2  -  2 )  <  w )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							drw_setscheme ( drw ,  & scheme [ SchemeNorm ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							drw_rect ( drw ,  x  +  curpos  +  2 ,  2 ,  1 ,  bh  -  4 ,  1 ,  1 ,  0 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( lines  >  0 )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if   ( lines  >  0 )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							/* draw vertical list */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							w  =  mw  -  x ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							for ( item  =  curr ;  item  ! =  next ;  item  =  item - > right )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							for   ( item  =  curr ;  item  ! =  next ;  item  =  item - > right )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								y  + =  h ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if ( item  = =  sel )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if   ( item  = =  sel )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									drw_setscheme ( drw ,  & scheme [ SchemeSel ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								else  if ( item - > out )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								else  if   ( item - > out )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									drw_setscheme ( drw ,  & scheme [ SchemeOut ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									drw_setscheme ( drw ,  & scheme [ SchemeNorm ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								drw_text ( drw ,  x ,  y ,  w ,  bh ,  item - > text ,  0 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						else  if ( matches )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}  else  if  ( matches )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							/* draw horizontal list */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							x  + =  inputw ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							w  =  TEXTW ( " < " ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( curr - > left )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( curr - > left )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								drw_setscheme ( drw ,  & scheme [ SchemeNorm ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								drw_text ( drw ,  x ,  0 ,  w ,  bh ,  " < " ,  0 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							for ( item  =  curr ;  item  ! =  next ;  item  =  item - > right )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							for   ( item  =  curr ;  item  ! =  next ;  item  =  item - > right )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								x  + =  w ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								w  =  MIN ( TEXTW ( item - > text ) ,  mw  -  x  -  TEXTW ( " > " ) ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if ( item  = =  sel )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if   ( item  = =  sel )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									drw_setscheme ( drw ,  & scheme [ SchemeSel ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								else  if ( item - > out )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								else  if   ( item - > out )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									drw_setscheme ( drw ,  & scheme [ SchemeOut ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									drw_setscheme ( drw ,  & scheme [ SchemeNorm ] ) ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -258,7 +192,7 @@ drawmenu(void) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							w  =  TEXTW ( " > " ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							x  =  mw  -  w ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( next )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( next )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								drw_setscheme ( drw ,  & scheme [ SchemeNorm ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								drw_text ( drw ,  x ,  0 ,  w ,  bh ,  " > " ,  0 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -266,13 +200,14 @@ drawmenu(void) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw_map ( drw ,  win ,  0 ,  0 ,  mw ,  mh ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					grabkeyboard ( void )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					grabkeyboard ( void )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						int  i ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						/* try to grab keyboard, we may have to wait for another process to ungrab */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for ( i  =  0 ;  i  <  1000 ;  i + + )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( XGrabKeyboard ( dpy ,  DefaultRootWindow ( dpy ) ,  True ,   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for   ( i  =  0 ;  i  <  1000 ;  i + + )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( XGrabKeyboard ( dpy ,  DefaultRootWindow ( dpy ) ,  True ,   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							                 GrabModeAsync ,  GrabModeAsync ,  CurrentTime )  = =  GrabSuccess )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								return ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							usleep ( 1000 ) ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -280,29 +215,31 @@ grabkeyboard(void) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						die ( " cannot grab keyboard \n " ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					insert ( const  char  * str ,  ssize_t  n )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( strlen ( text )  +  n  >  sizeof  text  -  1 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					insert ( const  char  * str ,  ssize_t  n )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if  ( strlen ( text )  +  n  >  sizeof  text  -  1 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							return ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						/* move existing text out of the way, insert new text, and update cursor */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						memmove ( & text [ cursor  +  n ] ,  & text [ cursor ] ,  sizeof  text  -  cursor  -  MAX ( n ,  0 ) ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( n  >  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if   ( n  >  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							memcpy ( & text [ cursor ] ,  str ,  n ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						cursor  + =  n ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						match ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					keypress ( XKeyEvent  * ev )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					keypress ( XKeyEvent  * ev )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						char  buf [ 32 ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						int  len ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						KeySym  ksym  =  NoSymbol ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						Status  status ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						len  =  XmbLookupString ( xic ,  ev ,  buf ,  sizeof  buf ,  & ksym ,  & status ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( status  = =  XBufferOverflow )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if   ( status  = =  XBufferOverflow )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							return ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( ev - > state  &  ControlMask )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if   ( ev - > state  &  ControlMask )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							switch ( ksym )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							case  XK_a :  ksym  =  XK_Home ;       break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							case  XK_b :  ksym  =  XK_Left ;       break ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -328,9 +265,9 @@ keypress(XKeyEvent *ev) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								insert ( NULL ,  0  -  cursor ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							case  XK_w :  /* delete word */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								while ( cursor  >  0  & &  text [ nextrune ( - 1 ) ]  = =  '   ' )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								while   ( cursor  >  0  & &  text [ nextrune ( - 1 ) ]  = =  '   ' )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									insert ( NULL ,  nextrune ( - 1 )  -  cursor ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								while ( cursor  >  0  & &  text [ nextrune ( - 1 ) ]  ! =  '   ' )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								while   ( cursor  >  0  & &  text [ nextrune ( - 1 ) ]  ! =  '   ' )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									insert ( NULL ,  nextrune ( - 1 )  -  cursor ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							case  XK_y :  /* paste selection */   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -346,7 +283,7 @@ keypress(XKeyEvent *ev) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							default :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								return ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						else  if ( ev - > state  &  Mod1Mask )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						else  if   ( ev - > state  &  Mod1Mask )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							switch ( ksym )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							case  XK_g :  ksym  =  XK_Home ;   break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							case  XK_G :  ksym  =  XK_End ;    break ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -359,31 +296,31 @@ keypress(XKeyEvent *ev) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						switch ( ksym )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						default :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ! iscntrl ( * buf ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ! iscntrl ( * buf ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								insert ( buf ,  len ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_Delete :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( text [ cursor ]  = =  ' \0 ' )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( text [ cursor ]  = =  ' \0 ' )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								return ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							cursor  =  nextrune ( + 1 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							/* fallthrough */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_BackSpace :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( cursor  = =  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( cursor  = =  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								return ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							insert ( NULL ,  nextrune ( - 1 )  -  cursor ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_End :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( text [ cursor ]  ! =  ' \0 ' )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( text [ cursor ]  ! =  ' \0 ' )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								cursor  =  strlen ( text ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( next )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( next )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								/* jump to end of list and position items in reverse */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								curr  =  matchend ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								calcoffsets ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								curr  =  prev ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								calcoffsets ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								while ( next  & &  ( curr  =  curr - > right ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								while   ( next  & &  ( curr  =  curr - > right ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									calcoffsets ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							sel  =  matchend ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -392,7 +329,7 @@ keypress(XKeyEvent *ev) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							cleanup ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							exit ( 1 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_Home :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( sel  = =  matches )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( sel  = =  matches )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								cursor  =  0 ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -400,27 +337,27 @@ keypress(XKeyEvent *ev) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							calcoffsets ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_Left :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( cursor  >  0  & &  ( ! sel  | |  ! sel - > left  | |  lines  >  0 ) )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( cursor  >  0  & &  ( ! sel  | |  ! sel - > left  | |  lines  >  0 ) )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								cursor  =  nextrune ( - 1 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( lines  >  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( lines  >  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								return ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							/* fallthrough */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_Up :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( sel  & &  sel - > left  & &  ( sel  =  sel - > left ) - > right  = =  curr )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( sel  & &  sel - > left  & &  ( sel  =  sel - > left ) - > right  = =  curr )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								curr  =  prev ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								calcoffsets ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_Next :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ! next )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ! next )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								return ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							sel  =  curr  =  next ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							calcoffsets ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_Prior :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ! prev )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ! prev )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								return ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							sel  =  curr  =  prev ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							calcoffsets ( ) ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -428,29 +365,29 @@ keypress(XKeyEvent *ev) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_Return :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_KP_Enter :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							puts ( ( sel  & &  ! ( ev - > state  &  ShiftMask ) )  ?  sel - > text  :  text ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ! ( ev - > state  &  ControlMask ) )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ! ( ev - > state  &  ControlMask ) )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								cleanup ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								exit ( 0 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( sel )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( sel )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								sel - > out  =  true ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_Right :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( text [ cursor ]  ! =  ' \0 ' )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( text [ cursor ]  ! =  ' \0 ' )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								cursor  =  nextrune ( + 1 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( lines  >  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( lines  >  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								return ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							/* fallthrough */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_Down :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( sel  & &  sel - > right  & &  ( sel  =  sel - > right )  = =  next )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( sel  & &  sel - > right  & &  ( sel  =  sel - > right )  = =  next )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								curr  =  next ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								calcoffsets ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						case  XK_Tab :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ! sel )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ! sel )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								return ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							strncpy ( text ,  sel - > text ,  sizeof  text  -  1 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							text [ sizeof  text  -  1 ]  =  ' \0 ' ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -461,8 +398,9 @@ keypress(XKeyEvent *ev) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drawmenu ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					match ( void )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					match ( void )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						static  char  * * tokv  =  NULL ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						static  int  tokn  =  0 ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -473,41 +411,39 @@ match(void) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						strcpy ( buf ,  text ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						/* separate input text into tokens to be matched individually */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for ( s  =  strtok ( buf ,  "   " ) ;  s ;  tokv [ tokc - 1 ]  =  s ,  s  =  strtok ( NULL ,  "   " ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( + + tokc  >  tokn  & &  ! ( tokv  =  realloc ( tokv ,  + + tokn  *  sizeof  * tokv ) ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for   ( s  =  strtok ( buf ,  "   " ) ;  s ;  tokv [ tokc   -   1 ]  =  s ,  s  =  strtok ( NULL ,  "   " ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( + + tokc  >  tokn  & &  ! ( tokv  =  realloc ( tokv ,  + + tokn  *  sizeof  * tokv ) ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								die ( " cannot realloc %u bytes \n " ,  tokn  *  sizeof  * tokv ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						len  =  tokc  ?  strlen ( tokv [ 0 ] )  :  0 ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						matches  =  lprefix  =  lsubstr  =  matchend  =  prefixend  =  substrend  =  NULL ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for ( item  =  items ;  item  & &  item - > text ;  item + + )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							for ( i  =  0 ;  i  <  tokc ;  i + + )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if ( ! fstrstr ( item - > text ,  tokv [ i ] ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for   ( item  =  items ;  item  & &  item - > text ;  item + + )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							for   ( i  =  0 ;  i  <  tokc ;  i + + )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if   ( ! fstrstr ( item - > text ,  tokv [ i ] ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( i  ! =  tokc )  /* not all tokens match */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( i  ! =  tokc )  /* not all tokens match */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								continue ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							/* exact matches go first, then prefixes, then substrings */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ! tokc  | |  ! fstrncmp ( tokv [ 0 ] ,  item - > text ,  len + 1 ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ! tokc  | |  ! fstrncmp ( tokv [ 0 ] ,  item - > text ,  len   +   1 ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								appenditem ( item ,  & matches ,  & matchend ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if ( ! fstrncmp ( tokv [ 0 ] ,  item - > text ,  len ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if   ( ! fstrncmp ( tokv [ 0 ] ,  item - > text ,  len ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								appenditem ( item ,  & lprefix ,  & prefixend ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								appenditem ( item ,  & lsubstr ,  & substrend ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( lprefix )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( matches )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if   ( lprefix )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( matches )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								matchend - > right  =  lprefix ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								lprefix - > left  =  matchend ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}  else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								matches  =  lprefix ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							matchend  =  prefixend ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( lsubstr )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( matches )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if   ( lsubstr )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( matches )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								matchend - > right  =  lsubstr ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								lsubstr - > left  =  matchend ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}  else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								matches  =  lsubstr ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							matchend  =  substrend ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -515,17 +451,20 @@ match(void) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						calcoffsets ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					size_t  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					nextrune ( int  inc )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  size_t  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					nextrune ( int  inc )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						ssize_t  n ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						/* return location of next utf8 rune in the given direction (+1 or -1) */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for ( n  =  cursor  +  inc ;  n  +  inc  > =  0  & &  ( text [ n ]  &  0xc0 )  = =  0x80 ;  n  + =  inc ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for  ( n  =  cursor  +  inc ;  n  +  inc  > =  0  & &  ( text [ n ]  &  0xc0 )  = =  0x80 ;  n  + =  inc )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						return  n ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					paste ( void )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					paste ( void )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						char  * p ,  * q ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						int  di ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						unsigned  long  dl ;   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -534,64 +473,67 @@ paste(void) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						/* we have been given the current selection, now insert it into input */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						XGetWindowProperty ( dpy ,  win ,  utf8 ,  0 ,  ( sizeof  text  /  4 )  +  1 ,  False ,   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						                   utf8 ,  & da ,  & di ,  & dl ,  & dl ,  ( unsigned  char  * * ) & p ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						insert ( p ,  ( q  =  strchr ( p ,  ' \n ' ) )  ?  q - p  :  ( ssize_t ) strlen ( p ) ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						insert ( p ,  ( q  =  strchr ( p ,  ' \n ' ) )  ?  q   -   p  :  ( ssize_t ) strlen ( p ) ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						XFree ( p ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drawmenu ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					readstdin ( void )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					readstdin ( void )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						char  buf [ sizeof  text ] ,  * p ,  * maxstr  =  NULL ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						size_t  i ,  max  =  0 ,  size  =  0 ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						/* read each line from stdin and add it to the item list */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for ( i  =  0 ;  fgets ( buf ,  sizeof  buf ,  stdin ) ;  i + + )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( i + 1  > =  size  /  sizeof  * items )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if ( ! ( items  =  realloc ( items ,  ( size  + =  BUFSIZ ) ) ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for   ( i  =  0 ;  fgets ( buf ,  sizeof  buf ,  stdin ) ;  i + + )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( i   +   1  > =  size  /  sizeof  * items )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if   ( ! ( items  =  realloc ( items ,  ( size  + =  BUFSIZ ) ) ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									die ( " cannot realloc %u bytes: " ,  size ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ( p  =  strchr ( buf ,  ' \n ' ) ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ( p  =  strchr ( buf ,  ' \n ' ) ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								* p  =  ' \0 ' ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ! ( items [ i ] . text  =  strdup ( buf ) ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								die ( " cannot strdup %u bytes: " ,  strlen ( buf ) + 1 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ! ( items [ i ] . text  =  strdup ( buf ) ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								die ( " cannot strdup %u bytes: " ,  strlen ( buf )   +   1 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							items [ i ] . out  =  false ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( strlen ( items [ i ] . text )  >  max )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( strlen ( items [ i ] . text )  >  max )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								max  =  strlen ( maxstr  =  items [ i ] . text ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( items )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if   ( items )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							items [ i ] . text  =  NULL ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						inputw  =  maxstr  ?  TEXTW ( maxstr )  :  0 ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						lines  =  MIN ( lines ,  i ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					run ( void )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					run ( void )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						XEvent  ev ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						while ( ! XNextEvent ( dpy ,  & ev ) )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( XFilterEvent ( & ev ,  win ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						while   ( ! XNextEvent ( dpy ,  & ev ) )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( XFilterEvent ( & ev ,  win ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								continue ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							switch ( ev . type )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							case  Expose :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if ( ev . xexpose . count  = =  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if   ( ev . xexpose . count  = =  0 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									drw_map ( drw ,  win ,  0 ,  0 ,  mw ,  mh ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							case  KeyPress :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								keypress ( & ev . xkey ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							case  SelectionNotify :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if ( ev . xselection . property  = =  utf8 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if   ( ev . xselection . property  = =  utf8 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									paste ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							case  VisibilityNotify :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if ( ev . xvisibility . state  ! =  VisibilityUnobscured )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if   ( ev . xvisibility . state  ! =  VisibilityUnobscured )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									XRaiseWindow ( dpy ,  win ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								break ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					setup ( void )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					setup ( void )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						int  x ,  y ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						XSetWindowAttributes  swa ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						XIM  xim ;   
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -619,36 +561,35 @@ setup(void) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						lines  =  MAX ( lines ,  0 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						mh  =  ( lines  +  1 )  *  bh ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# ifdef XINERAMA  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if ( ( info  =  XineramaQueryScreens ( dpy ,  & n ) ) )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if   ( ( info  =  XineramaQueryScreens ( dpy ,  & n ) ) )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							XGetInputFocus ( dpy ,  & w ,  & di ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( mon  ! =  - 1  & &  mon  <  n )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( mon  ! =  - 1  & &  mon  <  n )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								i  =  mon ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if ( ! i  & &  w  ! =  root  & &  w  ! =  PointerRoot  & &  w  ! =  None )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( ! i  & &  w  ! =  root  & &  w  ! =  PointerRoot  & &  w  ! =  None )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								/* find top-level window containing current input focus */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								do  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									if ( XQueryTree ( dpy ,  ( pw  =  w ) ,  & dw ,  & w ,  & dws ,  & du )  & &  dws )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									if   ( XQueryTree ( dpy ,  ( pw  =  w ) ,  & dw ,  & w ,  & dws ,  & du )  & &  dws )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										XFree ( dws ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								}  while ( w  ! =  root  & &  w  ! =  pw ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								}  while   ( w  ! =  root  & &  w  ! =  pw ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								/* find xinerama screen with which the window intersects most */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if ( XGetWindowAttributes ( dpy ,  pw ,  & wa ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									for ( j  =  0 ;  j  <  n ;  j + + )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
										if ( ( a  =  INTERSECT ( wa . x ,  wa . y ,  wa . width ,  wa . height ,  info [ j ] ) )  >  area )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								if   ( XGetWindowAttributes ( 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 ( mon  = =  - 1  & &  ! area  & &  XQueryPointer ( dpy ,  root ,  & dw ,  & dw ,  & x ,  & y ,  & di ,  & di ,  & du ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								for ( i  =  0 ;  i  <  n ;  i + + )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
									if ( INTERSECT ( x ,  y ,  1 ,  1 ,  info [ i ] ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if   ( mon  = =  - 1  & &  ! area  & &  XQueryPointer ( 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   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}  else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						{   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							x  =  0 ;   
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -678,9 +619,77 @@ setup(void) {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drawmenu ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					usage ( void )  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					static  void  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					usage ( void )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						fputs ( " usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor] \n "   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						      "              [-nb color] [-nf color] [-sb color] [-sf color] [-v] \n " ,  stderr ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						exit ( 1 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					int  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					main ( int  argc ,  char  * argv [ ] )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						bool  fast  =  false ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						int  i ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						for  ( i  =  1 ;  i  <  argc ;  i + + )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							/* these options take no arguments */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							if  ( ! strcmp ( argv [ i ] ,  " -v " ) )  {       /* prints version information */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								puts ( " dmenu- " VERSION ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								exit ( 0 ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}  else  if  ( ! strcmp ( argv [ i ] ,  " -b " ) )    /* appears at the bottom of the screen */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								topbar  =  false ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if  ( ! strcmp ( argv [ i ] ,  " -f " ) )    /* grabs keyboard before reading stdin */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								fast  =  true ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if  ( ! strcmp ( argv [ i ] ,  " -i " ) )  {  /* case-insensitive item matching */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								fstrncmp  =  strncasecmp ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								fstrstr  =  cistrstr ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							}  else  if  ( i  +  1  = =  argc )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								usage ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							/* these options take one argument */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if  ( ! strcmp ( argv [ i ] ,  " -l " ) )    /* number of lines in vertical list */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								lines  =  atoi ( argv [ + + i ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if  ( ! strcmp ( argv [ i ] ,  " -m " ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								mon  =  atoi ( argv [ + + i ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if  ( ! strcmp ( argv [ i ] ,  " -p " ) )    /* adds prompt to left of input field */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								prompt  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if  ( ! strcmp ( argv [ i ] ,  " -fn " ) )   /* font or font set */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								fonts [ 0 ]  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if  ( ! strcmp ( argv [ i ] ,  " -nb " ) )   /* normal background color */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								normbgcolor  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if  ( ! strcmp ( argv [ i ] ,  " -nf " ) )   /* normal foreground color */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								normfgcolor  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if  ( ! strcmp ( argv [ i ] ,  " -sb " ) )   /* selected background color */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								selbgcolor  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else  if  ( ! strcmp ( argv [ i ] ,  " -sf " ) )   /* selected foreground color */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								selfgcolor  =  argv [ + + i ] ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
								usage ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if  ( ! setlocale ( LC_CTYPE ,  " " )  | |  ! XSupportsLocale ( ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							fputs ( " warning: no locale support \n " ,  stderr ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if  ( ! ( dpy  =  XOpenDisplay ( NULL ) ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							die ( " cannot open display \n " ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						screen  =  DefaultScreen ( dpy ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						root  =  RootWindow ( dpy ,  screen ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						sw  =  DisplayWidth ( dpy ,  screen ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						sh  =  DisplayHeight ( dpy ,  screen ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw  =  drw_create ( dpy ,  screen ,  root ,  sw ,  sh ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw_load_fonts ( drw ,  fonts ,  LENGTH ( fonts ) ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if  ( ! drw - > fontcount )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							die ( " no fonts could be loaded. \n " ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						drw_setscheme ( drw ,  & scheme [ SchemeNorm ] ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						if  ( fast )  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							grabkeyboard ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							readstdin ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}  else  {   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							readstdin ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
							grabkeyboard ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						}   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						setup ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						run ( ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
						return  1 ;  /* unreachable */   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}