Any script can now register a unique key combination as part of its bpy header. For...
authorIan Thompson <quornian@googlemail.com>
Tue, 15 Jul 2008 07:04:31 +0000 (07:04 +0000)
committerIan Thompson <quornian@googlemail.com>
Tue, 15 Jul 2008 07:04:31 +0000 (07:04 +0000)
Space types that are to support shortcuts like this should call BPY_menu_do_shortcut(...) from the event queue read method (See winqreadtextspace in drawtext.c for example)

release/scripts/textplugin_suggest.py
source/blender/include/BIF_keyval.h
source/blender/python/BPY_extern.h
source/blender/python/BPY_interface.c
source/blender/python/BPY_menus.c
source/blender/python/BPY_menus.h
source/blender/src/drawtext.c
source/blender/src/keyval.c

index 6bb703faa8355f50975dda6614b26b3cf89cd411..c4fce9ad7a9e755469939c26d57778c8949fc0d2 100644 (file)
@@ -3,6 +3,7 @@
 Name: 'Suggest'
 Blender: 243
 Group: 'TextPlugin'
 Name: 'Suggest'
 Blender: 243
 Group: 'TextPlugin'
+Shortcut: 'Ctrl+Space'
 Tooltip: 'Suggests completions for the word at the cursor in a python script'
 """
 
 Tooltip: 'Suggests completions for the word at the cursor in a python script'
 """
 
@@ -72,6 +73,70 @@ def getCompletionSymbols(txt):
        return line[c-a:c].split('.')
 
 
        return line[c-a:c].split('.')
 
 
+def getImports(txt):
+       imports = []
+       
+       # Unfortunately, tokenize may fail if the script leaves brackets or strings
+       # open. For now we return an empty list until I have a better idea. Maybe
+       # parse manually.
+       try:
+               tokens = getTokens(txt)
+       except:
+               return []
+       
+       for i in range(1, len(tokens)):
+               
+               # Handle all import statements
+               if tokens[i-1][TK_TOKEN] == 'import':
+                       
+                       # Find 'from' if it exists
+                       fr = -1
+                       for a in range(1, i):
+                               if tokens[i-a][TK_TYPE] == token.NEWLINE: break
+                               if tokens[i-a][TK_TOKEN] == 'from':
+                                       fr = i-a
+                                       break
+                       
+                       # Handle: import ___[.___][,___[.___]]
+                       if fr<0:
+                               parent = ''
+                       
+                       # Handle: from ___[.___] import ___[,___]
+                       else: # fr>=0:
+                               parent = ''.join([t[TK_TOKEN] for t in tokens[fr+1:i-1]])
+                       
+                       module = ''
+                       while i < len(tokens)-1:
+                               if tokens[i][TK_TYPE] == token.NAME:
+                               
+                                       # Get the module name
+                                       module = module + tokens[i][TK_TOKEN]
+                                       
+                                       if tokens[i+1][TK_TOKEN] == '.':
+                                               module += '.'
+                                               i += 1
+                                       else:
+                                               # Add the module name and parent to the dict
+                                               imports.append((module, parent))
+                                               module = ''
+                                       
+                               elif tokens[i][TK_TOKEN]!=',':
+                                       break
+                               
+                               i += 1
+                               
+       # Process imports for: from ___ import *
+       for imp,frm in imports:
+               print imp, frm
+               if frm == '':
+                       try: __import__(imp)
+                       except: print '^ERR^'
+               else:
+                       try: __import__(frm, globals(), locals(), [imp])
+                       except: print '^ERR^'
+       
+
+
 # Returns a list of tuples of symbol names and their types (name, type) where
 # type is one of:
 #   m (module/class)  Has its own members (includes classes)
 # Returns a list of tuples of symbol names and their types (name, type) where
 # type is one of:
 #   m (module/class)  Has its own members (includes classes)
index 70d248ded91b83b872c92717794fe01894dfef2c..9693684e42559c7a1aac06f2c17c84d7d5d7e73f 100644 (file)
@@ -31,6 +31,9 @@
 #define BIF_KEYVAL_H
 
 char *key_event_to_string(unsigned short event);
 #define BIF_KEYVAL_H
 
 char *key_event_to_string(unsigned short event);
+int decode_key_string(char *str, unsigned short *key, unsigned short *qual);
 
 #endif
 
 
 #endif
 
+
+
index f6a27b807334566508d515d162e249c600d6d42b..3a826d495426d604484948e5d3c8e40cacf797a5 100644 (file)
@@ -91,6 +91,8 @@ extern "C" {
 
        int BPY_txt_do_python_Text( struct Text *text );
        int BPY_menu_do_python( short menutype, int event );
 
        int BPY_txt_do_python_Text( struct Text *text );
        int BPY_menu_do_python( short menutype, int event );
+       int BPY_menu_do_shortcut( short menutype, unsigned short key, unsigned short modifiers );
+       int BPY_menu_invoke( struct BPyMenu *pym, short menutype );
        void BPY_run_python_script( char *filename );
        int BPY_run_script(struct Script *script);
        void BPY_free_compiled_text( struct Text *text );
        void BPY_run_python_script( char *filename );
        int BPY_run_script(struct Script *script);
        void BPY_free_compiled_text( struct Text *text );
index 360c8fd7f04ebf9635fd50d0175a1f62ff4ec179..e9600e9369f5e4f5be5dba77f321cac4c6ad7589 100644 (file)
@@ -972,8 +972,38 @@ int BPY_run_script(Script *script)
 *****************************************************************************/
 int BPY_menu_do_python( short menutype, int event )
 {
 *****************************************************************************/
 int BPY_menu_do_python( short menutype, int event )
 {
-       char *argstr = NULL;
        BPyMenu *pym;
        BPyMenu *pym;
+       pym = BPyMenu_GetEntry( menutype, ( short ) event );
+       return BPY_menu_invoke( pym, menutype );
+}
+       
+/****************************************************************************
+* Description: This function executes the script by its shortcut.
+* Notes:       It is called by the ui code in src/???.c when a user presses an
+*              unassigned key combination. Scripts are searched in the BPyMenuTable,
+*              using the given menutype and event values to know which one to invoke.
+*****************************************************************************/
+int BPY_menu_do_shortcut( short menutype, unsigned short key, unsigned short qual )
+{
+       BPyMenu *pym;
+       pym = BPyMenu_GetEntry( menutype, 0 );
+
+       while ( pym ) {
+               if ( pym->key && pym->key == key && pym->qual == qual ) {
+                       return BPY_menu_invoke( pym, menutype );
+               }
+               pym = pym->next;
+       }
+       
+       return 0;
+}
+
+/****************************************************************************
+* Description: This function executes the script described by a menu item.
+*****************************************************************************/
+int BPY_menu_invoke( BPyMenu *pym, short menutype )
+{
+       char *argstr = NULL;
        BPySubMenu *pysm;
        char scriptname[21];
        Script *script = NULL;
        BPySubMenu *pysm;
        char scriptname[21];
        Script *script = NULL;
@@ -981,8 +1011,6 @@ int BPY_menu_do_python( short menutype, int event )
        PyGILState_STATE gilstate;
        char filestr[FILE_MAX];
 
        PyGILState_STATE gilstate;
        char filestr[FILE_MAX];
 
-       pym = BPyMenu_GetEntry( menutype, ( short ) event );
-
        if( !pym )
                return 0;
 
        if( !pym )
                return 0;
 
index 08691973a928968ffdaf838655b6df6961203f82..69b50e5c47abb944dfbaf231ffd62fef929798c2 100644 (file)
@@ -42,6 +42,7 @@
 #endif
 #include "BKE_global.h"
 #include "BKE_utildefines.h"
 #endif
 #include "BKE_global.h"
 #include "BKE_utildefines.h"
+#include "BIF_keyval.h"
 #include "BLI_blenlib.h"
 #include "MEM_guardedalloc.h"
 #include "DNA_userdef_types.h" /* for U.pythondir */
 #include "BLI_blenlib.h"
 #include "MEM_guardedalloc.h"
 #include "DNA_userdef_types.h" /* for U.pythondir */
@@ -333,6 +334,23 @@ static void bpymenu_set_tooltip( BPyMenu * pymenu, char *tip )
        return;
 }
 
        return;
 }
 
+static void bpymenu_set_shortcut( BPyMenu * pymenu, char *combi )
+{
+       unsigned short key, qual;
+
+       if( !pymenu )
+               return;
+
+       if (!decode_key_string(combi, &key, &qual)) {
+               return; /* TODO: Print some error */
+       }
+
+       pymenu->key = key;
+       pymenu->qual = qual;
+
+       return;
+}
+
 /* bpymenu_AddEntry:
  * try to find an existing pymenu entry with the given type and name;
  * if found, update it with new info, otherwise create a new one and fill it.
 /* bpymenu_AddEntry:
  * try to find an existing pymenu entry with the given type and name;
  * if found, update it with new info, otherwise create a new one and fill it.
@@ -693,6 +711,7 @@ void BPyMenu_PrintAllEntries( void )
  * # Blender: <code>short int</code> (minimal Blender version)
  * # Group: 'group name' (defines menu)
  * # Submenu: 'submenu name' related_1word_arg
  * # Blender: <code>short int</code> (minimal Blender version)
  * # Group: 'group name' (defines menu)
  * # Submenu: 'submenu name' related_1word_arg
+ * # Shortcut: Modifier+Key (optional shortcut combination for supported groups)
  * # Tooltip: 'tooltip for the menu'
  * # \"\"\"
  *
  * # Tooltip: 'tooltip for the menu'
  * # \"\"\"
  *
@@ -801,13 +820,19 @@ static int bpymenu_ParseFile(FILE *file, char *fname, int is_userdir)
                                        if ((matches == 3) && (strstr(head, "Submenu:") != NULL)) {
                                                bpymenu_AddSubEntry(scriptMenu, middle, tail);
                                        } else {
                                        if ((matches == 3) && (strstr(head, "Submenu:") != NULL)) {
                                                bpymenu_AddSubEntry(scriptMenu, middle, tail);
                                        } else {
-                                               /* Tooltip: 'tooltip for the menu */
+                                               /* Shortcut: 'key+combination' */
                                                matches = sscanf(line, "%[^']'%[^']'%c", head, middle, tail);
                                                matches = sscanf(line, "%[^']'%[^']'%c", head, middle, tail);
-                                               if ((matches == 3) && ((strstr(head, "Tooltip:") != NULL) ||
-                                                       (strstr(head, "Tip:") != NULL))) {
-                                                       bpymenu_set_tooltip(scriptMenu, middle);
+                                               if ((matches == 3) && (strstr(head, "Shortcut:") != NULL)) {
+                                                       bpymenu_set_shortcut(scriptMenu, middle);
+                                               } else {
+                                                       /* Tooltip: 'tooltip for the menu */
+                                                       matches = sscanf(line, "%[^']'%[^']'%c", head, middle, tail);
+                                                       if ((matches == 3) && ((strstr(head, "Tooltip:") != NULL) ||
+                                                               (strstr(head, "Tip:") != NULL))) {
+                                                               bpymenu_set_tooltip(scriptMenu, middle);
+                                                       }
+                                                       parser_state = 0;
                                                }
                                                }
-                                               parser_state = 0;
                                        }
                                        break;
 
                                        }
                                        break;
 
index e8bca09d50eafda009e359008b8bd922acd77a90..576d7b8dcd64615c0e306c9dcfbc8a93017bc540 100644 (file)
@@ -59,6 +59,7 @@ typedef struct BPyMenu {
        char *name;
        char *filename;
        char *tooltip;
        char *name;
        char *filename;
        char *tooltip;
+       unsigned short key, qual;       /* Registered shortcut key */
        short version;          /* Blender version */
        int dir;                /* 0: default, 1: U.pythondir */
        struct BPySubMenu *submenus;
        short version;          /* Blender version */
        int dir;                /* 0: default, 1: U.pythondir */
        struct BPySubMenu *submenus;
index c76ac47ffb71465257512eea7f4a85ff3067dfef..b8cf99383a04cc574bdb4cbe46b0bf1e2e072b84 100644 (file)
@@ -81,6 +81,7 @@
 #include "BSE_filesel.h"
 
 #include "BPY_extern.h"
 #include "BSE_filesel.h"
 
 #include "BPY_extern.h"
+#include "BPY_menus.h"
 
 #include "mydevice.h"
 #include "blendef.h" 
 
 #include "mydevice.h"
 #include "blendef.h" 
@@ -1833,10 +1834,17 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                        if (st->showsyntax) get_format_string(st);
                        pop_space_text(st);
                        do_draw= 1;
                        if (st->showsyntax) get_format_string(st);
                        pop_space_text(st);
                        do_draw= 1;
-                       do_suggest= 1;
+                       if (suggesting && ispunct(ascii)) {
+                               confirm_suggestion(text);
+                               if (st->showsyntax) get_format_string(st);
+                               do_suggest= 0;
+                       } else {
+                               do_suggest= 1;
+                       }
                }
        } else if (val) {
                }
        } else if (val) {
-               do_suggest= -1;
+               do_suggest= -1; /* Note that the default label sets this to 0,
+                                               so -1 only applies to the explicit cases below */
                switch (event) {
                case AKEY:
                        if (G.qual & LR_ALTKEY) {
                switch (event) {
                case AKEY:
                        if (G.qual & LR_ALTKEY) {
@@ -2102,6 +2110,12 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                case ESCKEY:
                        do_suggest= -1;
                        break;
                case ESCKEY:
                        do_suggest= -1;
                        break;
+               case SPACEKEY:
+                       if (suggesting) {
+                               confirm_suggestion(text);
+                               if (st->showsyntax) get_format_string(st);
+                       }
+                       break;
                case TABKEY:
                        if (text && text->id.lib) {
                                error_libdata();
                case TABKEY:
                        if (text && text->id.lib) {
                                error_libdata();
@@ -2300,6 +2314,12 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                }
        }
 
                }
        }
 
+       if (event && val) {
+               if (BPY_menu_do_shortcut(PYMENU_TEXTPLUGIN, event, G.qual)) {
+                       do_draw= 1;
+               }
+       }
+
        if (last_check_time < PIL_check_seconds_timer() - 1.0) {
                switch (txt_file_modified(text)) {
                case 1:
        if (last_check_time < PIL_check_seconds_timer() - 1.0) {
                switch (txt_file_modified(text)) {
                case 1:
index dab4b4ae8394d1530f72b91393115ddfe919deaa..f59cce0da8fe998b0dbfb03138fc30afa14425e1 100644 (file)
  * ***** END GPL LICENSE BLOCK *****
  */
 
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include "stdio.h"
+#include "ctype.h"
+#include "string.h"
+
+#include "BKE_global.h"
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BIF_keyval.h"
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BIF_keyval.h"
@@ -349,3 +354,193 @@ char *key_event_to_string(unsigned short event)
        
        return "";
 }
        
        return "";
 }
+
+/* 
+ * Decodes key combination strings [qual1+[qual2+[...]]]keyname
+ * The '+'s may be replaced by '-' or ' ' characters to support different
+ * formats. No additional whitespace is allowed. The keyname may be an internal
+ * name, like "RETKEY", or a more common name, like "Return". Decoding is case-
+ * insensitive.
+ *
+ * Example strings: "Ctrl+L", "ALT-ESC", "Shift A"
+ *
+ * Returns 1 if successful. 
+ */
+int decode_key_string(char *str, unsigned short *key, unsigned short *qual)
+{
+       int i, prev, len, invalid=0;
+
+       len= strlen(str);
+       *key= *qual= 0;
+
+       /* Convert to upper case */
+       for (i=0; i<len; i++) {
+               str[i]= toupper(str[i]);
+       }
+
+       /* Handle modifiers */
+       for (prev=i=0; i<len; i++) {
+               if (str[i]==' ' || str[i]=='+' || str[i]=='-') {
+                       if (!strncmp(str+prev, "CTRL", i-prev)) *qual |= LR_CTRLKEY;
+                       else if (!strncmp(str+prev, "ALT", i-prev)) *qual |= LR_ALTKEY;
+                       else if (!strncmp(str+prev, "SHIFT", i-prev)) *qual |= LR_SHIFTKEY;
+                       else if (!strncmp(str+prev, "COMMAND", i-prev)) *qual |= LR_COMMANDKEY;
+                       prev=i+1;
+               }
+       }
+
+       /* Compare last part against key names */
+       if (len-prev==1 || len-prev==4 && !strncmp(str+prev, "KEY", 3)) {
+               
+               if (str[prev]>='A' && str[prev]<='Z') {
+                       *key= str[prev]-'A'+AKEY;
+               } else if (str[prev]>='0' && str[prev]<='9') {
+                       *key= str[prev]-'0'+ZEROKEY;
+               } else {
+                       invalid= 1;
+               }
+       
+       } else if (!strncmp(str+prev, "ZEROKEY", len-prev) || !strncmp(str+prev, "ZERO", len-prev)) {
+               *key= ZEROKEY;
+       } else if (!strncmp(str+prev, "ONEKEY", len-prev) || !strncmp(str+prev, "ONE", len-prev)) {
+               *key= ONEKEY;
+       } else if (!strncmp(str+prev, "TWOKEY", len-prev) || !strncmp(str+prev, "TWO", len-prev)) {
+               *key= TWOKEY;
+       } else if (!strncmp(str+prev, "THREEKEY", len-prev) || !strncmp(str+prev, "THREE", len-prev)) {
+               *key= THREEKEY;
+       } else if (!strncmp(str+prev, "FOURKEY", len-prev) || !strncmp(str+prev, "FOUR", len-prev)) {
+               *key= FOURKEY;
+       } else if (!strncmp(str+prev, "FIVEKEY", len-prev) || !strncmp(str+prev, "FIVE", len-prev)) {
+               *key= FIVEKEY;
+       } else if (!strncmp(str+prev, "SIZEKEY", len-prev) || !strncmp(str+prev, "SIX", len-prev)) {
+               *key= SIXKEY;
+       } else if (!strncmp(str+prev, "SEVENKEY", len-prev) || !strncmp(str+prev, "SEVEN", len-prev)) {
+               *key= SEVENKEY;
+       } else if (!strncmp(str+prev, "EIGHTKEY", len-prev) || !strncmp(str+prev, "EIGHT", len-prev)) {
+               *key= EIGHTKEY;
+       } else if (!strncmp(str+prev, "NINEKEY", len-prev) || !strncmp(str+prev, "NINE", len-prev)) {
+               *key= NINEKEY;
+
+       } else if (!strncmp(str+prev, "ESCKEY", len-prev) || !strncmp(str+prev, "ESC", len-prev)) {
+               *key= ESCKEY;
+       } else if (!strncmp(str+prev, "TABKEY", len-prev) || !strncmp(str+prev, "TAB", len-prev)) {
+               *key= TABKEY;
+       } else if (!strncmp(str+prev, "RETKEY", len-prev) || !strncmp(str+prev, "RETURN", len-prev) || !strncmp(str+prev, "ENTER", len-prev)) {
+               *key= RETKEY;
+       } else if (!strncmp(str+prev, "SPACEKEY", len-prev) || !strncmp(str+prev, "SPACE", len-prev)) {
+               *key= SPACEKEY;
+       } else if (!strncmp(str+prev, "LINEFEEDKEY", len-prev) || !strncmp(str+prev, "LINEFEED", len-prev)) {
+               *key= LINEFEEDKEY;
+       } else if (!strncmp(str+prev, "BACKSPACEKEY", len-prev) || !strncmp(str+prev, "BACKSPACE", len-prev)) {
+               *key= BACKSPACEKEY;
+       } else if (!strncmp(str+prev, "DELKEY", len-prev) || !strncmp(str+prev, "DELETE", len-prev)) {
+               *key= DELKEY;
+       
+       } else if (!strncmp(str+prev, "SEMICOLONKEY", len-prev) || !strncmp(str+prev, "SEMICOLON", len-prev)) {
+               *key= SEMICOLONKEY;
+       } else if (!strncmp(str+prev, "PERIODKEY", len-prev) || !strncmp(str+prev, "PERIOD", len-prev)) {
+               *key= PERIODKEY;
+       } else if (!strncmp(str+prev, "COMMAKEY", len-prev) || !strncmp(str+prev, "COMMA", len-prev)) {
+               *key= COMMAKEY;
+       } else if (!strncmp(str+prev, "QUOTEKEY", len-prev) || !strncmp(str+prev, "QUOTE", len-prev)) {
+               *key= QUOTEKEY;
+       } else if (!strncmp(str+prev, "ACCENTGRAVEKEY", len-prev) || !strncmp(str+prev, "ACCENTGRAVE", len-prev)) {
+               *key= ACCENTGRAVEKEY;
+       } else if (!strncmp(str+prev, "MINUSKEY", len-prev) || !strncmp(str+prev, "MINUS", len-prev)) {
+               *key= MINUSKEY;
+       } else if (!strncmp(str+prev, "SLASHKEY", len-prev) || !strncmp(str+prev, "SLASH", len-prev)) {
+               *key= SLASHKEY;
+       } else if (!strncmp(str+prev, "BACKSLASHKEY", len-prev) || !strncmp(str+prev, "BACKSLASH", len-prev)) {
+               *key= BACKSLASHKEY;
+       } else if (!strncmp(str+prev, "EQUALKEY", len-prev) || !strncmp(str+prev, "EQUAL", len-prev)) {
+               *key= EQUALKEY;
+       } else if (!strncmp(str+prev, "LEFTBRACKETKEY", len-prev) || !strncmp(str+prev, "LEFTBRACKET", len-prev)) {
+               *key= LEFTBRACKETKEY;
+       } else if (!strncmp(str+prev, "RIGHTBRACKETKEY", len-prev) || !strncmp(str+prev, "RIGHTBRACKET", len-prev)) {
+               *key= RIGHTBRACKETKEY;
+       } else if (!strncmp(str+prev, "DELKEY", len-prev) || !strncmp(str+prev, "DELETE", len-prev)) {
+               *key= DELKEY;
+       
+       } else if (!strncmp(str+prev, "LEFTARROWKEY", len-prev) || !strncmp(str+prev, "LEFTARROW", len-prev)) {
+               *key= LEFTARROWKEY;
+       } else if (!strncmp(str+prev, "DOWNARROWKEY", len-prev) || !strncmp(str+prev, "DOWNARROW", len-prev)) {
+               *key= DOWNARROWKEY;
+       } else if (!strncmp(str+prev, "RIGHTARROWKEY", len-prev) || !strncmp(str+prev, "RIGHTARROW", len-prev)) {
+               *key= RIGHTARROWKEY;
+       } else if (!strncmp(str+prev, "UPARROWKEY", len-prev) || !strncmp(str+prev, "UPARROW", len-prev)) {
+               *key= UPARROWKEY;
+
+       } else if (!strncmp(str+prev, "PAD", 3)) {
+               
+               if (len-prev<=4) {
+               
+                       if (str[prev]>='0' && str[prev]<='9') {
+                               *key= str[prev]-'0'+ZEROKEY;
+                       } else {
+                               invalid= 1;
+                       }
+               
+               } else if (!strncmp(str+prev+3, "PERIODKEY", len-prev-3) || !strncmp(str+prev+3, "PERIOD", len-prev-3)) {
+                       *key= PADPERIOD;
+               } else if (!strncmp(str+prev+3, "SLASHKEY", len-prev-3) || !strncmp(str+prev+3, "SLASH", len-prev-3)) {
+                       *key= PADSLASHKEY;
+               } else if (!strncmp(str+prev+3, "ASTERKEY", len-prev-3) || !strncmp(str+prev+3, "ASTERISK", len-prev-3)) {
+                       *key= PADASTERKEY;
+               } else if (!strncmp(str+prev+3, "MINUSKEY", len-prev-3) || !strncmp(str+prev+3, "MINUS", len-prev-3)) {
+                       *key= PADMINUS;
+               } else if (!strncmp(str+prev+3, "ENTERKEY", len-prev-3) || !strncmp(str+prev+3, "ENTER", len-prev-3)) {
+                       *key= PADENTER;
+               } else if (!strncmp(str+prev+3, "PLUSKEY", len-prev-3) || !strncmp(str+prev+3, "PLUS", len-prev-3)) {
+                       *key= PADPLUSKEY;
+               } else {
+                       invalid= 1;
+               }
+
+       } else if (!strncmp(str+prev, "F1KEY", len-prev) || !strncmp(str+prev, "F1", len-prev)) {
+               *key= F1KEY;
+       } else if (!strncmp(str+prev, "F2KEY", len-prev) || !strncmp(str+prev, "F2", len-prev)) {
+               *key= F2KEY;
+       } else if (!strncmp(str+prev, "F3KEY", len-prev) || !strncmp(str+prev, "F3", len-prev)) {
+               *key= F3KEY;
+       } else if (!strncmp(str+prev, "F4KEY", len-prev) || !strncmp(str+prev, "F4", len-prev)) {
+               *key= F4KEY;
+       } else if (!strncmp(str+prev, "F5KEY", len-prev) || !strncmp(str+prev, "F5", len-prev)) {
+               *key= F5KEY;
+       } else if (!strncmp(str+prev, "F6KEY", len-prev) || !strncmp(str+prev, "F6", len-prev)) {
+               *key= F6KEY;
+       } else if (!strncmp(str+prev, "F7KEY", len-prev) || !strncmp(str+prev, "F7", len-prev)) {
+               *key= F7KEY;
+       } else if (!strncmp(str+prev, "F8KEY", len-prev) || !strncmp(str+prev, "F8", len-prev)) {
+               *key= F8KEY;
+       } else if (!strncmp(str+prev, "F9KEY", len-prev) || !strncmp(str+prev, "F9", len-prev)) {
+               *key= F9KEY;
+       } else if (!strncmp(str+prev, "F10KEY", len-prev) || !strncmp(str+prev, "F10", len-prev)) {
+               *key= F10KEY;
+       } else if (!strncmp(str+prev, "F11KEY", len-prev) || !strncmp(str+prev, "F11", len-prev)) {
+               *key= F11KEY;
+       } else if (!strncmp(str+prev, "F12KEY", len-prev) || !strncmp(str+prev, "F12", len-prev)) {
+               *key= F12KEY;
+
+       } else if (!strncmp(str+prev, "PAUSEKEY", len-prev) || !strncmp(str+prev, "PAUSE", len-prev)) {
+               *key= PAUSEKEY;
+       } else if (!strncmp(str+prev, "INSERTKEY", len-prev) || !strncmp(str+prev, "INSERT", len-prev)) {
+               *key= INSERTKEY;
+       } else if (!strncmp(str+prev, "HOMEKEY", len-prev) || !strncmp(str+prev, "HOME", len-prev)) {
+               *key= HOMEKEY;
+       } else if (!strncmp(str+prev, "PAGEUPKEY", len-prev) || !strncmp(str+prev, "PAGEUP", len-prev)) {
+               *key= PAGEUPKEY;
+       } else if (!strncmp(str+prev, "PAGEDOWNKEY", len-prev) || !strncmp(str+prev, "PAGEDOWN", len-prev)) {
+               *key= PAGEDOWNKEY;
+       } else if (!strncmp(str+prev, "ENDKEY", len-prev) || !strncmp(str+prev, "END", len-prev)) {
+               *key= ENDKEY;
+       
+       } else {
+               invalid= 1;
+       }
+
+       if (!invalid && *key) {
+               return 1;
+       }
+       
+       return 0;
+}