⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keytab.c

📁 xorp源码hg
💻 C
📖 第 1 页 / 共 2 页
字号:
 * of '\E' to denote the escape key. Similarly, meta characters can be * given directly in binary or expressed as M- followed by the character. * Meta characters are recorded as two characters in the binary output * string, the first being the escape key, and the second being the key * that was modified by the meta key. This means that binding to * \EA or ^[A or M-A are all equivalent. * * Input: *  keyseq   char *  The key sequence being added. * Input/Output: *  binary   char *  The binary version of the key sequence will be *                   assigned to binary[], which must have at least *                   as many characters as keyseq[] plus the number *                   of embedded binary meta characters. *  nc        int *  The number of characters assigned to binary[] *                   will be recorded in *nc. * Output: *  return    int    0 - OK. *                   1 - Error. */int _kt_parse_keybinding_string(const char *keyseq, char *binary,				       int *nc){  const char *iptr = keyseq;   /* Pointer into keyseq[] */  char *optr = binary;         /* Pointer into binary[] *//* * Parse the input characters until they are exhausted or the * output string becomes full. */  while(*iptr) {/* * Check for special characters. */    switch(*iptr) {    case '^':        /* A control character specification *//* * Convert the caret expression into the corresponding control * character unless no character follows the caret, in which case * record a literal caret. */      if(iptr[1]) {	*optr++ = MAKE_CTRL(iptr[1]);	iptr += 2;      } else {	*optr++ = *iptr++;      };      break;/* * A backslash-escaped character? */    case '\\':/* * Convert the escape sequence to a binary character. */      *optr++ = _kt_backslash_escape(iptr+1, &iptr);      break;/* * Possibly an emacs-style meta character? */    case 'M':      if(_kt_is_emacs_meta(iptr)) {	*optr++ = GL_ESC_CHAR;	iptr += 2;      } else {	*optr++ = *iptr++;      };      break;/* * Possibly an emacs-style control character specification? */    case 'C':      if(_kt_is_emacs_ctrl(iptr)) {	*optr++ = MAKE_CTRL(iptr[2]);	iptr += 3;      } else {	*optr++ = *iptr++;      };      break;    default:/* * Convert embedded meta characters into an escape character followed * by the meta-unmodified character. */      if(IS_META_CHAR(*iptr)) {	*optr++ = GL_ESC_CHAR;	*optr++ = META_TO_CHAR(*iptr);	iptr++;/* * To allow keysequences that start with printable characters to * be distinguished from the cursor-key keywords, prepend a backslash * to the former. This same operation is performed in gl_interpret_char() * before looking up a keysequence that starts with a printable character. */      } else if(iptr==keyseq && !IS_CTRL_CHAR(*iptr) &&		strcmp(keyseq, "up") != 0 && strcmp(keyseq, "down") != 0 &&		strcmp(keyseq, "left") != 0 && strcmp(keyseq, "right") != 0) {	*optr++ = '\\';	*optr++ = *iptr++;      } else {	*optr++ = *iptr++;      };    };  };/* * How many characters were placed in the output array? */  *nc = optr - binary;  return 0;}/*....................................................................... * Add, remove or modify an action. * * Input: *  kt     KeyTab *  The key-binding table. *  action   char *  The name of the action. *  fn    KtKeyFn *  The function that implements the action, or NULL *                   to remove an existing action. * Output: *  return    int    0 - OK. *                   1 - Error. */int _kt_set_action(KeyTab *kt, const char *action, KtKeyFn *fn){  Symbol *sym;   /* The symbol table entry of the action *//* * Check the arguments. */  if(!kt || !action) {    fprintf(stderr, "kt_set_action: NULL argument(s).\n");    return 1;  };/* * If no function was provided, delete an existing action. */  if(!fn) {    sym = _del_HashSymbol(kt->actions, action);    return 0;  };/* * If the action already exists, replace its action function. */  sym = _find_HashSymbol(kt->actions, action);  if(sym) {    sym->fn = (void (*)(void))fn;    return 0;  };/* * Add a new action. */  if(!_new_HashSymbol(kt->actions, action, 0, (void (*)(void))fn, NULL, 0)) {    fprintf(stderr, "Insufficient memory to record new key-binding action.\n");    return 1;  };  return 0;}/*....................................................................... * Compare two strings of specified length which may contain embedded * ascii NUL's. * * Input: *  s1       char *  The first of the strings to be compared. *  n1        int    The length of the string in s1. *  s2       char *  The second of the strings to be compared. *  n2        int    The length of the string in s2. * Output: *  return    int    < 0 if(s1 < s2) *                     0 if(s1 == s2) *                   > 0 if(s1 > s2) */static int _kt_compare_strings(const char *s1, int n1, const char *s2, int n2){  int i;/* * Find the first character where the two strings differ. */  for(i=0; i<n1 && i<n2 && s1[i]==s2[i]; i++)    ;/* * Did we hit the end of either string before finding a difference? */  if(i==n1 || i==n2) {    if(n1 == n2)      return 0;    else if(n1==i)      return -1;    else      return 1;  };/* * Compare the two characters that differed to determine which * string is greatest. */  return s1[i] - s2[i];}/*....................................................................... * Assign a given action function to a binding table entry. * * Input: *  sym       KeySym *  The binding table entry to be modified. *  binder  KtBinder    The source of the binding. *  keyfn    KtKeyFn *  The action function. */static void _kt_assign_action(KeySym *sym, KtBinder binder, KtKeyFn *keyfn){/* * Record the action according to its source. */  switch(binder) {  case KTB_USER:    sym->user_fn = keyfn;    break;  case KTB_TERM:    sym->term_fn = keyfn;    break;  case KTB_NORM:  default:    sym->norm_fn = keyfn;    break;  };/* * Which of the current set of bindings should be used? */  if(sym->user_fn)    sym->keyfn = sym->user_fn;  else if(sym->norm_fn)    sym->keyfn = sym->norm_fn;  else    sym->keyfn = sym->term_fn;  return;}/*....................................................................... * Remove all key bindings that came from a specified source. * * Input: *  kt        KeyTab *  The table of key bindings. *  binder  KtBinder    The source of the bindings to be cleared. */void _kt_clear_bindings(KeyTab *kt, KtBinder binder){  int oldkey;   /* The index of a key in the original binding table */  int newkey;   /* The index of a key in the updated binding table *//* * If there is no table, then no bindings exist to be deleted. */  if(!kt)    return;/* * Clear bindings of the given source. */  for(oldkey=0; oldkey<kt->nkey; oldkey++)    _kt_assign_action(kt->table + oldkey, binder, 0);/* * Delete entries that now don't have a binding from any source. */  newkey = 0;  for(oldkey=0; oldkey<kt->nkey; oldkey++) {    KeySym *sym = kt->table + oldkey;    if(!sym->keyfn) {      _del_StringMemString(kt->smem, sym->keyseq);    } else {      if(oldkey != newkey)	kt->table[newkey] = *sym;      newkey++;    };  };/* * Record the number of keys that were kept. */  kt->nkey = newkey;  return;}/*....................................................................... * Translate a backslash escape sequence to a binary character. * * Input: *  string  const char *   The characters that follow the backslash. * Input/Output: *  endp    const char **  If endp!=NULL, on return *endp will be made to *                         point to the character in string[] which follows *                         the escape sequence. * Output: *  return        char     The binary character. */static char _kt_backslash_escape(const char *string, const char **endp){  char c;  /* The output character *//* * Is the backslash followed by one or more octal digits? */  switch(*string) {  case '0': case '1': case '2': case '3':  case '4': case '5': case '6': case '7':    c = strtol(string, (char **)&string, 8);    break;  case 'a':    c = '\a';    string++;    break;  case 'b':    c = '\b';    string++;    break;  case 'e': case 'E': /* Escape */    c = GL_ESC_CHAR;    string++;    break;  case 'f':    c = '\f';    string++;    break;  case 'n':    c = '\n';    string++;    break;  case 'r':    c = '\r';    string++;    break;  case 't':    c = '\t';    string++;    break;  case 'v':    c = '\v';    string++;    break;  case '\0':    c = '\\';    break;  default:    c = *string++;    break;  };/* * Report the character which follows the escape sequence. */  if(endp)    *endp = string;  return c;}/*....................................................................... * Return non-zero if the next two characters are M- and a third character * follows. Otherwise return 0. * * Input: *  string   const char *  The sub-string to scan. * Output: *  return          int    1 - The next two characters are M- and these *                             are followed by at least one character. *                         0 - The next two characters aren't M- or no *                             character follows a M- pair. */static int _kt_is_emacs_meta(const char *string){  return *string++ == 'M' && *string++ == '-' && *string;}/*....................................................................... * Return non-zero if the next two characters are C- and a third character * follows. Otherwise return 0. * * Input: *  string   const char *  The sub-string to scan. * Output: *  return          int    1 - The next two characters are C- and these *                             are followed by at least one character. *                         0 - The next two characters aren't C- or no *                             character follows a C- pair. */static int _kt_is_emacs_ctrl(const char *string){  return *string++ == 'C' && *string++ == '-' && *string;}/*....................................................................... * Merge an array of bindings with existing bindings. * * Input: *  kt                    KeyTab *  The table of key bindings. *  binder              KtBinder    The source of the bindings. *  bindings  const KtKeyBinding *  The array of bindings. *  n                        int    The number of bindings in bindings[]. * Output: *  return                   int    0 - OK. *                                  1 - Error. */int _kt_add_bindings(KeyTab *kt, KtBinder binder, const KtKeyBinding *bindings,		     unsigned n){  int i;/* * Check the arguments. */  if(!kt || !bindings) {    fprintf(stderr, "_kt_add_bindings: NULL argument(s).\n");    return 1;  };/* * Install the array of bindings. */  for(i=0; i<n; i++) {    if(_kt_set_keybinding(kt, binder, bindings[i].keyseq, bindings[i].action))      return 1;  };  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -