00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #include <string.h>
00022 #include <ctype.h>  
00023 #include <tcl.h>
00024 #include "config.h"
00025 #include "Mouse.h"
00026 #include "utilities.h"
00027 #include "DisplayDevice.h"
00028 #include "JString.h"
00029 #include "VMDApp.h"
00030 
00031 static int check_canonical_form(const char *s) {
00032   
00033   if (!strcmp(s, "Escape")) return TRUE;
00034   if (!strcmp(s, "Up")) return TRUE;
00035   if (!strcmp(s, "Down")) return TRUE;
00036   if (!strcmp(s, "Left")) return TRUE;
00037   if (!strcmp(s, "Right")) return TRUE;
00038   if (!strcmp(s, "Page_Up")) return TRUE;
00039   if (!strcmp(s, "Page_Down")) return TRUE;
00040   if (!strcmp(s, "Home")) return TRUE;
00041   if (!strcmp(s, "End")) return TRUE;
00042   if (!strcmp(s, "Insert")) return TRUE;
00043   if (!strcmp(s, "Delete")) return TRUE;
00044 
00045   
00046   if (s[0] == 'A') {
00047     
00048     s++;
00049     if (*s == 0) {
00050       return TRUE;
00051     }
00052 
00053     
00054     if (*s != 'l' && *s != 'u') {
00055       return FALSE;
00056     }
00057 
00058     if (*s == 'l') {
00059       s++;
00060       if (*s++ != 't') return FALSE;
00061       if (*s++ != '-') return FALSE;
00062     } else if (*s == 'u') {
00063       s++;
00064       if (*s++ != 'x') return FALSE;
00065       if (*s++ != '-') return FALSE;
00066     }
00067   }
00068 
00069   if (s[0] == 'C') {
00070     
00071     s++;
00072     if (*s == 0) {
00073       return TRUE;
00074     }
00075     
00076     if (*s++ != 'o') return FALSE;
00077     if (*s++ != 'n') return FALSE;
00078     if (*s++ != 't') return FALSE;
00079     if (*s++ != 'r') return FALSE;
00080     if (*s++ != 'o') return FALSE;
00081     if (*s++ != 'l') return FALSE;
00082     if (*s++ != '-') return FALSE;
00083   }
00084 
00085   if (s[0] == 'F') {
00086     
00087     s++;
00088     if (*s == 0) {
00089       return TRUE;
00090     }
00091     
00092     if ((*s) >= '0' && (*s) <= '9') {
00093       s++;
00094       if (*s == 0) {
00095         return TRUE;
00096       }
00097       if (*s >= '0' && *s <= '2') {
00098         s++;
00099         if (*s == 0) {
00100           return TRUE;
00101         }
00102       }
00103       return FALSE;
00104     }
00105   }
00106 
00107   
00108   if (s[0] == 0) return FALSE; 
00109 
00110   if (s[1] == 0) return TRUE; 
00111 
00112   return FALSE; 
00113 }
00114 
00115 int text_cmd_user(ClientData cd, Tcl_Interp *interp, int argc,
00116                             const char *argv[]) {
00117 
00118   VMDApp *app = (VMDApp *)cd;
00119 
00120   if(argc < 3) {
00121     Tcl_SetResult(interp, 
00122       (char *)
00123       "user list keys\n"
00124       "user print keys\n"
00125       "user add key <character> <command>",
00126       TCL_STATIC);
00127     return TCL_ERROR;
00128   }
00129 
00130   if(!strupncmp(argv[1], "add", CMDLEN)) {
00131     if (!strupncmp(argv[2], "key", CMDLEN)) {
00132       if(argc < 5)
00133         return TCL_ERROR;
00134       
00135       if (check_canonical_form(argv[3])) {
00136         const char *combstr = argv[4];
00137         const char *desc = NULL;
00138         if (argc > 5) desc = argv[5];
00139         int indx = app->userKeys.typecode(argv[3]);
00140         if (indx < 0) {
00141           app->userKeys.add_name(argv[3], stringdup(combstr));
00142         } else {
00143           delete [] app->userKeys.data(indx);
00144           app->userKeys.set_data(indx, stringdup(combstr));
00145         }
00146         if (desc) {
00147           indx = app->userKeyDesc.typecode(argv[3]);
00148           if (indx < 0) {
00149             app->userKeyDesc.add_name(argv[3], stringdup(desc));
00150           } else {
00151             delete [] app->userKeyDesc.data(indx);
00152             app->userKeys.set_data(indx, stringdup(desc));
00153           }
00154         }
00155       } else {
00156         Tcl_AppendResult(interp, "user key ", argv[3], " is not valid",
00157                          NULL);
00158         return TCL_ERROR;
00159       }
00160     }  else
00161       return TCL_ERROR;
00162 
00163   } else if(!strupncmp(argv[1], "list", CMDLEN)) {
00164     
00165     if (argc != 3) {
00166       return TCL_ERROR;
00167     }
00168     if (!strcmp(argv[2], "keys")) {
00169       int num = app->userKeys.num();
00170       for (int i=0; i<num; i++) {
00171         
00172         Tcl_AppendResult(interp, i==0?"":" ", "{", NULL);
00173         Tcl_AppendElement(interp,  app->userKeys.name(i));
00174         Tcl_AppendElement(interp, 
00175            (const char *) app->userKeys.data(i));
00176         int desc_typecode = app->userKeyDesc.typecode(app->userKeys.name(i));
00177         if (desc_typecode >= 0) {
00178           Tcl_AppendElement(interp,
00179              (const char *) app->userKeyDesc.data(i));
00180         } else {
00181           Tcl_AppendElement(interp, "");
00182         } 
00183         Tcl_AppendResult(interp, "}", NULL);
00184       }
00185       return TCL_OK;
00186     } else {
00187       return TCL_ERROR;
00188     }
00189     
00190 
00191   } else if(!strupncmp(argv[1], "print", CMDLEN)) {
00192     
00193     Tcl_AppendResult(interp, 
00194         "Keyboard shortcuts:\n",
00195         "-------------------\n", NULL);
00196     for (int i=0; i<app->userKeys.num(); i++) {
00197       const char *key = app->userKeys.name(i);
00198       Tcl_AppendResult(interp, "'", key, "' : ", app->userKeys.data(i), "\n",
00199           NULL);
00200       if (app->userKeyDesc.typecode(key) >= 0) {
00201         Tcl_AppendResult(interp, "     Description: ", 
00202             app->userKeyDesc.data(key), NULL);
00203       }
00204     }
00205   } else
00206     return TCL_ERROR;
00207     
00208   
00209   return TCL_OK;
00210 }
00211