@ -51,16 +51,20 @@ using namespace DFHack;
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					# include  "dfhack/SDL_fakes/events.h" # include  "dfhack/SDL_fakes/events.h"  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					# include  "dfhack/df/ui.h"  
			
		
	
		
		
			
				
					
					# include  "dfhack/df/world.h" # include  "dfhack/df/world.h"  
			
		
	
		
		
			
				
					
					# include  "dfhack/df/world_data.h" # include  "dfhack/df/world_data.h"  
			
		
	
		
		
			
				
					
					# include  "dfhack/df/interface.h"  
			
		
	
		
		
			
				
					
					# include  "dfhack/df/viewscreen_dwarfmodest.h"  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					# include  <stdio.h> # include  <stdio.h>  
			
		
	
		
		
			
				
					
					# include  <iomanip> # include  <iomanip>  
			
		
	
		
		
			
				
					
					# include  <stdlib.h> # include  <stdlib.h>  
			
		
	
		
		
			
				
					
					# include  <fstream> # include  <fstream>  
			
		
	
		
		
			
				
					
					# include  "tinythread.h" # include  "tinythread.h"  
			
		
	
		
		
			
				
					
					using  namespace  tthread ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					using  namespace  tthread ;  
			
		
	
		
		
			
				
					
					using  namespace  df : : enums ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					struct  Core : : Cond struct  Core : : Cond  
			
		
	
		
		
			
				
					
					{ {  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -204,6 +208,7 @@ static void runInteractiveCommand(Core *core, PluginManager *plug_mgr, int &clue
 
			
		
	
		
		
			
				
					
					                          "   cls                   - Clear the console. \n " 
                          "   cls                   - Clear the console. \n " 
 
			
		
	
		
		
			
				
					
					                          "   fpause                - Force DF to pause. \n " 
                          "   fpause                - Force DF to pause. \n " 
 
			
		
	
		
		
			
				
					
					                          "   die                   - Force DF to close immediately \n " 
                          "   die                   - Force DF to close immediately \n " 
 
			
		
	
		
		
			
				
					
					                          "   keybinding            - Modify bindings of commands to keys \n " 
 
			
		
	
		
		
			
				
					
					                          " Plugin management (useful for developers): \n " 
                          " Plugin management (useful for developers): \n " 
 
			
		
	
		
		
			
				
					
					                          //"  belongs COMMAND       - Tell which plugin a command belongs to.\n"
 
                          //"  belongs COMMAND       - Tell which plugin a command belongs to.\n"
 
 
			
		
	
		
		
			
				
					
					                          "   plug [PLUGIN|v]       - List plugin state and description. \n " 
                          "   plug [PLUGIN|v]       - List plugin state and description. \n " 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -212,6 +217,27 @@ static void runInteractiveCommand(Core *core, PluginManager *plug_mgr, int &clue
 
			
		
	
		
		
			
				
					
					                          "   reload PLUGIN|all     - Reload a plugin or all loaded plugins. \n " 
                          "   reload PLUGIN|all     - Reload a plugin or all loaded plugins. \n " 
 
			
		
	
		
		
			
				
					
					                         ) ; 
                         ) ; 
 
			
		
	
		
		
			
				
					
					            } 
            } 
 
			
		
	
		
		
			
				
					
					            else  if  ( parts . size ( )  = =  1 ) 
 
			
		
	
		
		
			
				
					
					            { 
 
			
		
	
		
		
			
				
					
					                Plugin  * plug  =  plug_mgr - > getPluginByCommand ( parts [ 0 ] ) ; 
 
			
		
	
		
		
			
				
					
					                if  ( plug )  { 
 
			
		
	
		
		
			
				
					
					                    for  ( int  j  =  0 ;  j  <  plug - > size ( ) ; j + + ) 
 
			
		
	
		
		
			
				
					
					                    { 
 
			
		
	
		
		
			
				
					
					                        const  PluginCommand  &  pcmd  =  ( plug - > operator [ ] ( j ) ) ; 
 
			
		
	
		
		
			
				
					
					                        if  ( pcmd . name  ! =  parts [ 0 ] ) 
 
			
		
	
		
		
			
				
					
					                            continue ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                        if  ( pcmd . isHotkeyCommand ( ) ) 
 
			
		
	
		
		
			
				
					
					                            con . color ( Console : : COLOR_CYAN ) ; 
 
			
		
	
		
		
			
				
					
					                        con . print ( " %s: %s \n " , pcmd . name . c_str ( ) ,  pcmd . description . c_str ( ) ) ; 
 
			
		
	
		
		
			
				
					
					                        con . reset_color ( ) ; 
 
			
		
	
		
		
			
				
					
					                        if  ( ! pcmd . usage . empty ( ) ) 
 
			
		
	
		
		
			
				
					
					                            con  < <  " Usage: \n "  < <  pcmd . usage  < <  flush ; 
 
			
		
	
		
		
			
				
					
					                        return ; 
 
			
		
	
		
		
			
				
					
					                    } 
 
			
		
	
		
		
			
				
					
					                } 
 
			
		
	
		
		
			
				
					
					                con . printerr ( " Unknown command: %s \n " ,  parts [ 0 ] . c_str ( ) ) ; 
 
			
		
	
		
		
			
				
					
					            } 
 
			
		
	
		
		
			
				
					
					            else 
            else 
 
			
		
	
		
		
			
				
					
					            { 
            { 
 
			
		
	
		
		
			
				
					
					                con . printerr ( " not implemented yet \n " ) ; 
                con . printerr ( " not implemented yet \n " ) ; 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -311,7 +337,10 @@ static void runInteractiveCommand(Core *core, PluginManager *plug_mgr, int &clue
 
			
		
	
		
		
			
				
					
					                else  for  ( int  j  =  0 ;  j  <  plug - > size ( ) ; j + + ) 
                else  for  ( int  j  =  0 ;  j  <  plug - > size ( ) ; j + + ) 
 
			
		
	
		
		
			
				
					
					                { 
                { 
 
			
		
	
		
		
			
				
					
					                    const  PluginCommand  &  pcmd  =  ( plug - > operator [ ] ( j ) ) ; 
                    const  PluginCommand  &  pcmd  =  ( plug - > operator [ ] ( j ) ) ; 
 
			
		
	
		
		
			
				
					
					                    if  ( pcmd . isHotkeyCommand ( ) ) 
 
			
		
	
		
		
			
				
					
					                        con . color ( Console : : COLOR_CYAN ) ; 
 
			
		
	
		
		
			
				
					
					                    con . print ( "   %-22s - %s \n " , pcmd . name . c_str ( ) ,  pcmd . description . c_str ( ) ) ; 
                    con . print ( "   %-22s - %s \n " , pcmd . name . c_str ( ) ,  pcmd . description . c_str ( ) ) ; 
 
			
		
	
		
		
			
				
					
					                    con . reset_color ( ) ; 
 
			
		
	
		
		
			
				
					
					                } 
                } 
 
			
		
	
		
		
			
				
					
					            } 
            } 
 
			
		
	
		
		
			
				
					
					            else 
            else 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -339,7 +368,10 @@ static void runInteractiveCommand(Core *core, PluginManager *plug_mgr, int &clue
 
			
		
	
		
		
			
				
					
					                    for  ( int  j  =  0 ;  j  <  plug - > size ( ) ; j + + ) 
                    for  ( int  j  =  0 ;  j  <  plug - > size ( ) ; j + + ) 
 
			
		
	
		
		
			
				
					
					                    { 
                    { 
 
			
		
	
		
		
			
				
					
					                        const  PluginCommand  &  pcmd  =  ( plug - > operator [ ] ( j ) ) ; 
                        const  PluginCommand  &  pcmd  =  ( plug - > operator [ ] ( j ) ) ; 
 
			
		
	
		
		
			
				
					
					                        if  ( pcmd . isHotkeyCommand ( ) ) 
 
			
		
	
		
		
			
				
					
					                            con . color ( Console : : COLOR_CYAN ) ; 
 
			
		
	
		
		
			
				
					
					                        con . print ( "   %-22s- %s \n " , pcmd . name . c_str ( ) ,  pcmd . description . c_str ( ) ) ; 
                        con . print ( "   %-22s- %s \n " , pcmd . name . c_str ( ) ,  pcmd . description . c_str ( ) ) ; 
 
			
		
	
		
		
			
				
					
					                        con . reset_color ( ) ; 
 
			
		
	
		
		
			
				
					
					                    } 
                    } 
 
			
		
	
		
		
			
				
					
					                } 
                } 
 
			
		
	
		
		
			
				
					
					            } 
            } 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -354,6 +386,49 @@ static void runInteractiveCommand(Core *core, PluginManager *plug_mgr, int &clue
 
			
		
	
		
		
			
				
					
					                con . print ( " %s \n " ,  plug - > getName ( ) . c_str ( ) ) ; 
                con . print ( " %s \n " ,  plug - > getName ( ) . c_str ( ) ) ; 
 
			
		
	
		
		
			
				
					
					            } 
            } 
 
			
		
	
		
		
			
				
					
					        } 
        } 
 
			
		
	
		
		
			
				
					
					        else  if ( first  = =  " keybinding " ) 
 
			
		
	
		
		
			
				
					
					        { 
 
			
		
	
		
		
			
				
					
					            if  ( parts . size ( )  > =  3  & &  ( parts [ 0 ]  = =  " set "  | |  parts [ 0 ]  = =  " add " ) ) 
 
			
		
	
		
		
			
				
					
					            { 
 
			
		
	
		
		
			
				
					
					                std : : string  keystr  =  parts [ 1 ] ; 
 
			
		
	
		
		
			
				
					
					                if  ( parts [ 0 ]  = =  " set " ) 
 
			
		
	
		
		
			
				
					
					                    core - > ClearKeyBindings ( keystr ) ; 
 
			
		
	
		
		
			
				
					
					                for  ( int  i  =  parts . size ( ) - 1 ;  i  > =  2 ;  i - - )  
 
			
		
	
		
		
			
				
					
					                { 
 
			
		
	
		
		
			
				
					
					                    if  ( ! core - > AddKeyBinding ( keystr ,  parts [ i ] ) )  { 
 
			
		
	
		
		
			
				
					
					                        con . printerr ( " Invalid key spec: %s \n " ,  keystr . c_str ( ) ) ; 
 
			
		
	
		
		
			
				
					
					                        break ; 
 
			
		
	
		
		
			
				
					
					                    } 
 
			
		
	
		
		
			
				
					
					                } 
 
			
		
	
		
		
			
				
					
					            } 
 
			
		
	
		
		
			
				
					
					            else  if  ( parts . size ( )  > =  2  & &  parts [ 0 ]  = =  " clear " ) 
 
			
		
	
		
		
			
				
					
					            { 
 
			
		
	
		
		
			
				
					
					                for  ( unsigned  i  =  1 ;  i  <  parts . size ( ) ;  i + + ) 
 
			
		
	
		
		
			
				
					
					                { 
 
			
		
	
		
		
			
				
					
					                    if  ( ! core - > ClearKeyBindings ( parts [ i ] ) )  { 
 
			
		
	
		
		
			
				
					
					                        con . printerr ( " Invalid key spec: %s \n " ,  parts [ i ] . c_str ( ) ) ; 
 
			
		
	
		
		
			
				
					
					                        break ; 
 
			
		
	
		
		
			
				
					
					                    } 
 
			
		
	
		
		
			
				
					
					                } 
 
			
		
	
		
		
			
				
					
					            } 
 
			
		
	
		
		
			
				
					
					            else  if  ( parts . size ( )  = =  2  & &  parts [ 0 ]  = =  " list " ) 
 
			
		
	
		
		
			
				
					
					            { 
 
			
		
	
		
		
			
				
					
					                std : : vector < std : : string >  list  =  core - > ListKeyBindings ( parts [ 1 ] ) ; 
 
			
		
	
		
		
			
				
					
					                if  ( list . empty ( ) ) 
 
			
		
	
		
		
			
				
					
					                    con  < <  " No bindings. "  < <  endl ; 
 
			
		
	
		
		
			
				
					
					                for  ( unsigned  i  =  0 ;  i  <  list . size ( ) ;  i + + ) 
 
			
		
	
		
		
			
				
					
					                    con  < <  "    "  < <  list [ i ]  < <  endl ; 
 
			
		
	
		
		
			
				
					
					            } 
 
			
		
	
		
		
			
				
					
					            else 
 
			
		
	
		
		
			
				
					
					            { 
 
			
		
	
		
		
			
				
					
					                con  < <  " Usage: "  < <  endl 
 
			
		
	
		
		
			
				
					
					                    < <  "   keybinding list <key> "  < <  endl 
 
			
		
	
		
		
			
				
					
					                    < <  "   keybinding clear <key> <key>... "  < <  endl 
 
			
		
	
		
		
			
				
					
					                    < <  "   keybinding set <key>  \" cmdline \"   \" cmdline \" ... "  < <  endl 
 
			
		
	
		
		
			
				
					
					                    < <  "   keybinding add <key>  \" cmdline \"   \" cmdline \" ... "  < <  endl 
 
			
		
	
		
		
			
				
					
					                    < <  " Later adds, and earlier items within one command have priority. "  < <  endl ; 
 
			
		
	
		
		
			
				
					
					            } 
 
			
		
	
		
		
			
				
					
					        } 
 
			
		
	
		
		
			
				
					
					        else  if ( first  = =  " fpause " ) 
        else  if ( first  = =  " fpause " ) 
 
			
		
	
		
		
			
				
					
					        { 
        { 
 
			
		
	
		
		
			
				
					
					            World  *  w  =  core - > getWorld ( ) ; 
            World  *  w  =  core - > getWorld ( ) ; 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -482,12 +557,12 @@ Core::Core()
 
			
		
	
		
		
			
				
					
					    StackMutex  =  0 ; 
    StackMutex  =  0 ; 
 
			
		
	
		
		
			
				
					
					    core_cond  =  0 ; 
    core_cond  =  0 ; 
 
			
		
	
		
		
			
				
					
					    // set up hotkey capture
 
    // set up hotkey capture
 
 
			
		
	
		
		
			
				
					
					    memset ( hotkey_states , 0 , sizeof ( hotkey_states ) ) ; 
 
			
		
	
		
		
			
				
					
					    hotkey_set  =  false ; 
    hotkey_set  =  false ; 
 
			
		
	
		
		
			
				
					
					    HotkeyMutex  =  0 ; 
    HotkeyMutex  =  0 ; 
 
			
		
	
		
		
			
				
					
					    HotkeyCond  =  0 ; 
    HotkeyCond  =  0 ; 
 
			
		
	
		
		
			
				
					
					    misc_data_mutex = 0 ; 
    misc_data_mutex = 0 ; 
 
			
		
	
		
		
			
				
					
					    last_world_data_ptr  =  NULL ; 
    last_world_data_ptr  =  NULL ; 
 
			
		
	
		
		
			
				
					
					    top_viewscreen  =  NULL ; 
 
			
		
	
		
		
			
				
					
					} ; } ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  Core : : fatal  ( std : : string  output ,  bool  deactivate ) void  Core : : fatal  ( std : : string  output ,  bool  deactivate )  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -694,6 +769,19 @@ int Core::Update()
 
			
		
	
		
		
			
				
					
					        plug_mgr - > OnStateChange ( new_wdata  ?  SC_GAME_LOADED  :  SC_GAME_UNLOADED ) ; 
        plug_mgr - > OnStateChange ( new_wdata  ?  SC_GAME_LOADED  :  SC_GAME_UNLOADED ) ; 
 
			
		
	
		
		
			
				
					
					    } 
    } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    // detect if the viewscreen changed
 
 
			
		
	
		
		
			
				
					
					    if  ( df : : global : : gview )  
 
			
		
	
		
		
			
				
					
					    { 
 
			
		
	
		
		
			
				
					
					        df : : viewscreen  * screen  =  & df : : global : : gview - > view ; 
 
			
		
	
		
		
			
				
					
					        while  ( screen - > child ) 
 
			
		
	
		
		
			
				
					
					            screen  =  screen - > child ; 
 
			
		
	
		
		
			
				
					
					        if  ( screen  ! =  top_viewscreen )  
 
			
		
	
		
		
			
				
					
					        { 
 
			
		
	
		
		
			
				
					
					            top_viewscreen  =  screen ; 
 
			
		
	
		
		
			
				
					
					            plug_mgr - > OnStateChange ( SC_VIEWSCREEN_CHANGED ) ; 
 
			
		
	
		
		
			
				
					
					        } 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    // notify all the plugins that a game tick is finished
 
    // notify all the plugins that a game tick is finished
 
 
			
		
	
		
		
			
				
					
					    plug_mgr - > OnUpdate ( ) ; 
    plug_mgr - > OnUpdate ( ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -785,37 +873,166 @@ int Core::SDL_Event(SDL::Event* ev, int orig_return)
 
			
		
	
		
		
			
				
					
					    if ( ev  & &  ev - > type  = =  SDL : : ET_KEYDOWN  | |  ev - > type  = =  SDL : : ET_KEYUP ) 
    if ( ev  & &  ev - > type  = =  SDL : : ET_KEYDOWN  | |  ev - > type  = =  SDL : : ET_KEYUP ) 
 
			
		
	
		
		
			
				
					
					    { 
    { 
 
			
		
	
		
		
			
				
					
					        SDL : : KeyboardEvent  *  ke  =  ( SDL : : KeyboardEvent  * ) ev ; 
        SDL : : KeyboardEvent  *  ke  =  ( SDL : : KeyboardEvent  * ) ev ; 
 
			
		
	
		
		
			
				
					
					        bool  shift  =  ke - > ksym . mod  &  SDL : : KMOD_SHIFT ; 
        
 
			
				
				
			
		
	
		
		
			
				
					
					        // consuming F1 .. F8
 
        if ( ke - > state  = =  SDL : : BTN_PRESSED  & &  ! hotkey_states [ ke - > ksym . sym ] ) 
 
			
				
				
			
		
	
		
		
			
				
					
					        int  idx  =  ke - > ksym . sym  -  SDL : : K_F1 ; 
 
			
		
	
		
		
			
				
					
					        if ( idx  <  0  | |  idx  >  7 ) 
 
			
		
	
		
		
			
				
					
					            return  orig_return ; 
 
			
		
	
		
		
			
				
					
					        idx  + =  8 * shift ; 
 
			
		
	
		
		
			
				
					
					        // now we have the real index...
 
 
			
		
	
		
		
			
				
					
					        if ( ke - > state  = =  SDL : : BTN_PRESSED  & &  ! hotkey_states [ idx ] ) 
 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					        { 
        { 
 
			
		
	
		
		
			
				
					
					            hotkey_states [ idx ]  =  1 ; 
            hotkey_states [ ke - > ksym . sym ]  =  true ; 
 
			
				
				
			
		
	
		
		
			
				
					
					            Gui  *  g  =  getGui ( ) ; 
 
			
				
				
			
		
	
		
		
			
				
					
					            if ( g - > hotkeys  & &  g - > df_interface  & &  g - > df_menu_state ) 
            int  mod  =  0 ; 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					            if  ( ke - > ksym . mod  &  SDL : : KMOD_SHIFT )  mod  | =  1 ; 
 
			
		
	
		
		
			
				
					
					            if  ( ke - > ksym . mod  &  SDL : : KMOD_CTRL )  mod  | =  2 ; 
 
			
		
	
		
		
			
				
					
					            if  ( ke - > ksym . mod  &  SDL : : KMOD_ALT )  mod  | =  4 ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					            SelectHotkey ( ke - > ksym . sym ,  mod ) ; 
 
			
		
	
		
		
			
				
					
					        } 
 
			
		
	
		
		
			
				
					
					        else  if ( ke - > state  = =  SDL : : BTN_RELEASED ) 
 
			
		
	
		
		
			
				
					
					        { 
        { 
 
			
		
	
		
		
			
				
					
					                t_viewscreen  *  ws  =  g - > GetCurrentScreen ( ) ; 
            hotkey_states [ ke - > ksym . sym ]  =  false ; 
 
			
				
				
			
		
	
		
		
			
				
					
					                // FIXME: put hardcoded values into memory.xml
 
        } 
 
			
				
				
			
		
	
		
		
			
				
					
					                if ( ws - > getClassName ( )  = =  " viewscreen_dwarfmodest "  & &  * g - > df_menu_state  = =  0x23 ) 
    } 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					    return  orig_return ; 
    return  orig_return ; 
 
			
		
	
		
		
			
				
					
					                else 
    // do stuff with the events...
 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  Core : : SelectHotkey ( int  sym ,  int  modifiers )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    // Find the topmost viewscreen
 
 
			
		
	
		
		
			
				
					
					    if  ( ! df : : global : : gview  | |  ! df : : global : : ui ) 
 
			
		
	
		
		
			
				
					
					        return  false ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    df : : viewscreen  * screen  =  & df : : global : : gview - > view ; 
 
			
		
	
		
		
			
				
					
					    while  ( screen - > child ) 
 
			
		
	
		
		
			
				
					
					        screen  =  screen - > child ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    std : : string  cmd ; 
 
			
		
	
		
		
			
				
					
					    
 
			
		
	
		
		
			
				
					
					    { 
    { 
 
			
		
	
		
		
			
				
					
					                    t_hotkey  &  hotkey  =  ( * g - > hotkeys ) [ idx ] ; 
        tthread : : lock_guard < tthread : : mutex >  lock ( * HotkeyMutex ) ; 
 
			
				
				
			
		
	
		
		
			
				
					
					                    setHotkeyCmd ( hotkey . name ) ; 
    
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					        // Check the internal keybindings
 
 
			
		
	
		
		
			
				
					
					        std : : vector < KeyBinding >  & bindings  =  key_bindings [ sym ] ; 
 
			
		
	
		
		
			
				
					
					        for  ( int  i  =  bindings . size ( ) - 1 ;  i  > =  0 ;  - - i )  { 
 
			
		
	
		
		
			
				
					
					            if  ( bindings [ i ] . modifiers  ! =  modifiers ) 
 
			
		
	
		
		
			
				
					
					                continue ; 
 
			
		
	
		
		
			
				
					
					            if  ( ! plug_mgr - > CanInvokeHotkey ( bindings [ i ] . command [ 0 ] ,  screen ) ) 
 
			
		
	
		
		
			
				
					
					                continue ; 
 
			
		
	
		
		
			
				
					
					            cmd  =  bindings [ i ] . cmdline ; 
 
			
		
	
		
		
			
				
					
					            break ; 
 
			
		
	
		
		
			
				
					
					        } 
        } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        if  ( cmd . empty ( ) )  { 
 
			
		
	
		
		
			
				
					
					            // Check the hotkey keybindings
 
 
			
		
	
		
		
			
				
					
					            int  idx  =  sym  -  SDL : : K_F1 ; 
 
			
		
	
		
		
			
				
					
					            if ( idx  > =  0  & &  idx  <  8 ) 
 
			
		
	
		
		
			
				
					
					            { 
 
			
		
	
		
		
			
				
					
					                if  ( modifiers  &  1 ) 
 
			
		
	
		
		
			
				
					
					                    idx  + =  8 ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					                if  ( ! strict_virtual_cast < df : : viewscreen_dwarfmodest > ( screen )  | | 
 
			
		
	
		
		
			
				
					
					                    df : : global : : ui - > main . mode  ! =  ui_sidebar_mode : : Hotkeys ) 
 
			
		
	
		
		
			
				
					
					                { 
 
			
		
	
		
		
			
				
					
					                    cmd  =  df : : global : : ui - > main . hotkeys [ idx ] . name ; 
 
			
		
	
		
		
			
				
					
					                } 
                } 
 
			
		
	
		
		
			
				
					
					            } 
            } 
 
			
		
	
		
		
			
				
					
					        else  if ( ke - > state  = =  SDL : : BTN_RELEASED ) 
 
			
		
	
		
		
			
				
					
					        { 
 
			
		
	
		
		
			
				
					
					            hotkey_states [ idx ]  =  0 ; 
 
			
		
	
		
		
			
				
					
					        } 
        } 
 
			
		
	
		
		
			
				
					
					    } 
    } 
 
			
		
	
		
		
			
				
					
					    return  orig_return ; 
 
			
				
				
			
		
	
		
		
			
				
					
					    // do stuff with the events...
 
    if  ( ! cmd . empty ( ) )  { 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					        setHotkeyCmd ( cmd ) ; 
 
			
		
	
		
		
			
				
					
					        return  true ; 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					    else 
 
			
		
	
		
		
			
				
					
					        return  false ; 
 
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  bool  parseKeySpec ( std : : string  keyspec ,  int  * psym ,  int  * pmod )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    * pmod  =  0 ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    // ugh, ugly
 
 
			
		
	
		
		
			
				
					
					    for  ( ; ; )  { 
 
			
		
	
		
		
			
				
					
					        if  ( keyspec . size ( )  >  6  & &  keyspec . substr ( 0 ,  6 )  = =  " Shift- " )  { 
 
			
		
	
		
		
			
				
					
					            * pmod  | =  1 ; 
 
			
		
	
		
		
			
				
					
					            keyspec  =  keyspec . substr ( 6 ) ; 
 
			
		
	
		
		
			
				
					
					        }  else  if  ( keyspec . size ( )  >  5  & &  keyspec . substr ( 0 ,  5 )  = =  " Ctrl- " )  { 
 
			
		
	
		
		
			
				
					
					            * pmod  | =  2 ; 
 
			
		
	
		
		
			
				
					
					            keyspec  =  keyspec . substr ( 5 ) ; 
 
			
		
	
		
		
			
				
					
					        }  else  if  ( keyspec . size ( )  >  4  & &  keyspec . substr ( 0 ,  4 )  = =  " Alt- " )  { 
 
			
		
	
		
		
			
				
					
					            * pmod  | =  4 ; 
 
			
		
	
		
		
			
				
					
					            keyspec  =  keyspec . substr ( 4 ) ; 
 
			
		
	
		
		
			
				
					
					        }  else  
 
			
		
	
		
		
			
				
					
					            break ; 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    if  ( keyspec . size ( )  = =  1  & &  keyspec [ 0 ]  > =  ' A '  & &  keyspec [ 0 ]  < =  ' Z ' )  { 
 
			
		
	
		
		
			
				
					
					        * psym  =  SDL : : K_a  +  ( keyspec [ 0 ] - ' A ' ) ; 
 
			
		
	
		
		
			
				
					
					        return  true ; 
 
			
		
	
		
		
			
				
					
					    }  else  if  ( keyspec . size ( )  = =  2  & &  keyspec [ 0 ]  = =  ' F '  & &  keyspec [ 1 ]  > =  ' 1 '  & &  keyspec [ 1 ]  < =  ' 9 ' )  { 
 
			
		
	
		
		
			
				
					
					        * psym  =  SDL : : K_F1  +  ( keyspec [ 1 ] - ' 1 ' ) ; 
 
			
		
	
		
		
			
				
					
					        return  true ; 
 
			
		
	
		
		
			
				
					
					    }  else 
 
			
		
	
		
		
			
				
					
					        return  false ;     
 
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  Core : : ClearKeyBindings ( std : : string  keyspec )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    int  sym ,  mod ; 
 
			
		
	
		
		
			
				
					
					    if  ( ! parseKeySpec ( keyspec ,  & sym ,  & mod ) ) 
 
			
		
	
		
		
			
				
					
					        return  false ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    tthread : : lock_guard < tthread : : mutex >  lock ( * HotkeyMutex ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    std : : vector < KeyBinding >  & bindings  =  key_bindings [ sym ] ; 
 
			
		
	
		
		
			
				
					
					    for  ( int  i  =  bindings . size ( ) - 1 ;  i  > =  0 ;  - - i )  { 
 
			
		
	
		
		
			
				
					
					        if  ( bindings [ i ] . modifiers  = =  mod ) 
 
			
		
	
		
		
			
				
					
					            bindings . erase ( bindings . begin ( ) + i ) ; 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    return  true ; 
 
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					bool  Core : : AddKeyBinding ( std : : string  keyspec ,  std : : string  cmdline )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    int  sym ; 
 
			
		
	
		
		
			
				
					
					    KeyBinding  binding ; 
 
			
		
	
		
		
			
				
					
					    if  ( ! parseKeySpec ( keyspec ,  & sym ,  & binding . modifiers ) ) 
 
			
		
	
		
		
			
				
					
					        return  false ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    cheap_tokenise ( cmdline ,  binding . command ) ; 
 
			
		
	
		
		
			
				
					
					    if  ( binding . command . empty ( ) ) 
 
			
		
	
		
		
			
				
					
					        return  false ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    tthread : : lock_guard < tthread : : mutex >  lock ( * HotkeyMutex ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    // Don't add duplicates
 
 
			
		
	
		
		
			
				
					
					    std : : vector < KeyBinding >  & bindings  =  key_bindings [ sym ] ; 
 
			
		
	
		
		
			
				
					
					    for  ( int  i  =  bindings . size ( ) - 1 ;  i  > =  0 ;  - - i )  { 
 
			
		
	
		
		
			
				
					
					        if  ( bindings [ i ] . modifiers  = =  binding . modifiers  & & 
 
			
		
	
		
		
			
				
					
					            bindings [ i ] . cmdline  = =  cmdline ) 
 
			
		
	
		
		
			
				
					
					            return  true ; 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    binding . cmdline  =  cmdline ; 
 
			
		
	
		
		
			
				
					
					    bindings . push_back ( binding ) ; 
 
			
		
	
		
		
			
				
					
					    return  true ; 
 
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					std : : vector < std : : string >  Core : : ListKeyBindings ( std : : string  keyspec )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
					    int  sym ,  mod ; 
 
			
		
	
		
		
			
				
					
					    std : : vector < std : : string >  rv ; 
 
			
		
	
		
		
			
				
					
					    if  ( ! parseKeySpec ( keyspec ,  & sym ,  & mod ) ) 
 
			
		
	
		
		
			
				
					
					        return  rv ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    tthread : : lock_guard < tthread : : mutex >  lock ( * HotkeyMutex ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    std : : vector < KeyBinding >  & bindings  =  key_bindings [ sym ] ; 
 
			
		
	
		
		
			
				
					
					    for  ( int  i  =  bindings . size ( ) - 1 ;  i  > =  0 ;  - - i )  { 
 
			
		
	
		
		
			
				
					
					        if  ( bindings [ i ] . modifiers  = =  mod ) 
 
			
		
	
		
		
			
				
					
					            rv . push_back ( bindings [ i ] . cmdline ) ; 
 
			
		
	
		
		
			
				
					
					    } 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    return  rv ; 
 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					////////////////
 ////////////////