home *** CD-ROM | disk | FTP | other *** search
/ Best Objectech Shareware Selections / UNTITLED.iso / boss / word / text / 019 / keymap.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  21KB  |  743 lines

  1. /*
  2.  *  Copyright (c) 1992 John E. Davis  (davis@amy.tch.harvard.edu)
  3.  *  All Rights Reserved.
  4.  */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <setjmp.h>
  8.  
  9. #ifndef msdos
  10. #ifndef VMS
  11. #include <malloc.h>
  12. #endif
  13. #else
  14. #include <alloc.h>
  15. #endif
  16. #include "buffer.h"
  17. #include "cmds.h"
  18. #include "paste.h"
  19. #include "screen.h"
  20. #include "window.h"
  21. #include "text.h"
  22. #include "ledit.h"
  23. #include "keymap.h"
  24. #include "sysdep.h"
  25. #include "misc.h"
  26. #include "display.h"
  27. #include "file.h"
  28. #include "slang.h"
  29.  
  30. jmp_buf Jump_Buffer;
  31.  
  32. typedef int (*Jed_fp)(void);
  33.  
  34. VOID *Last_Key_Function;
  35. int *Repeat_Factor;                    /* repeats a key sequence if non null */
  36.  
  37. typedef struct Jed_Function_Type
  38.   {
  39.       char *name;
  40.       Jed_fp f;
  41.   }
  42. Jed_Function_Type;
  43.  
  44. Jed_Function_Type Jed_Functions[] =
  45.   {
  46.       {"backward_delete_char", backward_delete_char_cmd},
  47.       {"backward_delete_char_untabify", backward_delete_char_untabify},
  48.       {"beep", beep},
  49.       {"begin_macro", begin_keyboard_macro},
  50.       {"bob", bob},
  51.       {"bol", bol},
  52.       {"brace_bra_cmd", brace_bra_cmd},
  53.       {"brace_ket_cmd", brace_ket_cmd},
  54.       {"capitalize_word", capitalize_word},
  55.       {"center_line", center_line},
  56.       {"copy_region", copy_to_pastebuffer},
  57.       {"delete_char_cmd", delete_char_cmd},
  58.       {"delete_word", delete_word},
  59.       {"digit_arg", digit_arg},
  60.       {"double_line", double_line},
  61.       {"downcase_word", downcase_word},
  62.       {"end_macro", end_keyboard_macro},
  63.       {"enlarge_window", enlarge_window},
  64.       {"eob", eob},
  65.       {"eol_cmd", eol_cmd},
  66.       {"evaluate_cmd", evaluate_cmd},
  67.       {"exchange",exchange_point_mark},
  68.       {"execute_macro", execute_keyboard_macro},
  69.       {"exit_jed", exit_jed},
  70.       {"exit_mini", exit_minibuffer},
  71.       {"find_file", find_file},
  72.       {"format_paragraph", text_format_paragraph},
  73.       {"goto_column", goto_column_cmd},
  74.       {"goto_line", goto_line_cmd},
  75.       {"goto_match", goto_match},
  76.       {"indent_line", indent_line},
  77.       {"insert_file", insert_file_cmd},
  78.       {"kbd_quit", kbd_quit},
  79.       {"kill_buffer", kill_buffer},
  80.       {"kill_line", kill_line},
  81.       {"kill_region", kill_region},
  82.       {"macro_query", macro_query},
  83.       {"mark_spot", mark_spot},
  84.       {"narrow", narrow_to_region},
  85.       {"narrow_paragraph", narrow_paragraph},
  86.       {"newline", newline},
  87.       {"newline_and_indent", newline_and_indent},
  88.       {"next_char_cmd", next_char_cmd},
  89.       {"next_line_cmd", next_line_cmd},
  90.       {"one_window", one_window},
  91.       {"other_window", other_window},
  92.       {"page_down", pagedown_cmd},
  93.       {"page_up", pageup_cmd},
  94.       {"pop_spot", pop_spot},
  95.       {"previous_char_cmd", previous_char_cmd},
  96.       {"previous_line_cmd", previous_line_cmd},
  97.       {"quoted_insert", quoted_insert},
  98.       {"redraw", redraw},
  99.       {"replace", replace},
  100.       {"save_buffers", save_some_buffers},
  101.       {"scroll_left", scroll_left},
  102.       {"scroll_right", scroll_right},
  103.       {"search_backward", search_backward_cmd},
  104.       {"search_forward", search_forward_cmd},
  105.       {"self_insert_cmd", ins_char_cmd},
  106.       {"set_mark_cmd", set_mark_cmd},
  107.       {"split_window", split_window},
  108.       {"switch_to_buffer", get_buffer},
  109.       {"sys_spawn_cmd", sys_spawn_cmd},
  110.       {"text_smart_quote", text_smart_quote},
  111.       {"transpose_lines", transpose_lines},
  112.       {"trim_whitespace", trim_whitespace},
  113.       {"upcase_word", upcase_word},
  114.       {"widen", widen},
  115.       {"write_buffer", write_buffer},
  116.       {"yank", yank},
  117.       {(char *) NULL, NULL}
  118.    };
  119.  
  120. Key_Type Global_Map[128];
  121. Key_Type *Mini_Map;
  122.  
  123. #define MAX_KEYMAP_NAME_LEN 8
  124. typedef struct KeyMap_List_Type
  125. {
  126.    char name[MAX_KEYMAP_NAME_LEN + 1];
  127.    Key_Type *keymap;
  128. }
  129. KeyMap_List_Type;
  130.  
  131. #define MAX_KEYMAPS 10
  132. KeyMap_List_Type KeyMap_List[MAX_KEYMAPS];   /* these better be inited to 0! */
  133.  
  134. int kbd_quit(void)
  135. {
  136.    KeyBoard_Quit = 1;
  137.    msg_error("Quit!");
  138.    return(0);
  139. }
  140.  
  141. void add_keymap(char *name, Key_Type *map)
  142. {
  143.    int i;
  144.  
  145.    for (i = 0; i < MAX_KEYMAPS; i++)
  146.      {
  147.     if (KeyMap_List[i].keymap == NULL)
  148.       {
  149.          KeyMap_List[i].keymap = map;
  150.          strncpy(KeyMap_List[i].name, name, MAX_KEYMAP_NAME_LEN);
  151.          (KeyMap_List[i].name)[MAX_KEYMAP_NAME_LEN] = 0;
  152.          return;
  153.       }
  154.      }
  155.    msg_error("Keymap quota exceeded");
  156. }
  157.  
  158. VOID *find_function(char *name)
  159. {
  160.    Jed_Function_Type *fp;
  161.  
  162.    fp = Jed_Functions;
  163.  
  164.    while((fp != NULL) && (fp->name != NULL))
  165.      {
  166.     if (!strcmp(fp->name, name)) return((VOID *) fp->f);
  167.     fp++;
  168.      }
  169.     return(NULL);
  170. }
  171.  
  172. #define upcase(ch) (((ch <= 'z') && (ch >= 'a')) ? ch & 0xDF : ch)
  173. #define lowcase(ch) (((ch <= 'Z') && (ch >= 'A')) ? ch | 0x20 : ch)
  174.  
  175. /* convert things like "^A" to "\001" with ^@ going to 128 */
  176. char *process_keystring(char *s)
  177. {
  178.     static char str[30], ch;
  179.     int i;
  180.  
  181.     i = 0;
  182.     while (*s != 0)
  183.       {
  184.           ch = *s++;
  185.           if (*s) ch = upcase(ch);
  186.           if (ch == '^')
  187.             {
  188.                 ch = *s++;
  189.                 if (ch == 0)
  190.                   {
  191.                       str[i++] = '^';
  192.                       break;
  193.                   }
  194.                 ch = upcase(ch);
  195.                 if (ch == '?') ch = 127;
  196.         else if (ch == '@') ch = 128; else ch = ch - 'A' + 1;
  197.             }
  198.  
  199.           str[i++] = ch;
  200.       }
  201.     str[i] = 0;
  202.     return(str);
  203. }
  204.  
  205. Key_Type *malloc_key(unsigned char *str)
  206. {
  207.    Key_Type *new;
  208.  
  209.    if (NULL == (new = (Key_Type *) MALLOC(sizeof(Key_Type))))
  210.      {
  211.     exit_error("malloc_key: malloc error.");
  212.      }
  213.    strcpy(new->str, (char *) str);
  214.    return(new);
  215. }
  216.  
  217. static char *Define_Key_Error = "Inconsistency in define key.";
  218.  
  219. void define_key1(char *s, VOID *f, char type, Key_Type *keymap)
  220. {
  221.     int cmp, i, m, n, len;
  222.     Key_Type *key, *last, *new;
  223.     unsigned char *str;
  224.  
  225.     str = (unsigned char *) process_keystring(s);
  226.  
  227.     /* null char gets mapped to 128 */
  228.     /* if (128 == ( i = *str)) i = 0; */
  229.    i = (*str) & 0x7F;
  230.  
  231.     key = (Key_Type *) &(keymap[i]);
  232.     n = strlen((char *) str);
  233.  
  234.     if (n < 2)
  235.       {
  236.           if (key->next != NULL)
  237.         {
  238.            msg_error(Define_Key_Error);
  239.            return;
  240.         }
  241.  
  242.       key->f = f;
  243.       key->type = type;
  244.           if (*str) strcpy(key->str, (char *) str); else *key->str = 0;
  245.           return;
  246.       }
  247.  
  248.     /* insert the key definition */
  249.     while(1)
  250.       {
  251.           last = key;
  252.           key = key->next;
  253.           if ((key == NULL) || (key->str == NULL)) cmp = -1;
  254.           else
  255.             {
  256.                 m = strlen(key->str);
  257.                 len = m;
  258.                 if (m > n) len = n;
  259.                 cmp = strncmp((char *) str, key->str, len);
  260.                 if ((m != n) && !cmp)
  261.                   {
  262.              msg_error(Define_Key_Error);
  263.              return;
  264.                   }
  265.                 if ((m == n) && (!cmp)) cmp = strcmp((char *) str, key->str);
  266.             }
  267.  
  268.           if (cmp == 0)
  269.             {
  270.            key->f = f;
  271.            key->type = type;
  272.            return;
  273.             }
  274.           else if (cmp < 0)
  275.             {
  276.            new = malloc_key(str);
  277.  
  278.            new -> next = key;
  279.            last -> next = new;
  280.  
  281.            new->f = f;
  282.            new->type = type;
  283.            return;
  284.             } /* else cmp > 0 */
  285.       }
  286. }
  287.  
  288. void define_key(char *s, char *funct, Key_Type *keymap)
  289. {
  290.    VOID *f;
  291.    char type;
  292.  
  293.    f = find_function(funct);
  294.    if (f == NULL)                      /* assume interpreted */
  295.      {
  296.     if (NULL == (f = (VOID *) MALLOC(strlen(funct) + 1)))
  297.       {
  298.          exit_error("Malloc error in define key.");
  299.       }
  300.  
  301.     strcpy((char *) f, funct);
  302.     type = F_INTERPRET;
  303.      }
  304.    else type = F_INTRINSIC;
  305.  
  306.    define_key1(s, f, type, keymap);
  307. }
  308.  
  309. void init_keymaps(void)
  310. {
  311.     char simple[2], ch;
  312.     simple[1] = 0;
  313.  
  314.     for (ch = ' '; ch < 127; ch++)
  315.       {
  316.           simple[0] = ch;
  317.           define_key1(simple, (VOID *) ins_char_cmd, F_INTRINSIC, Global_Map);
  318.       }
  319.  
  320.     define_key1("^[1", (VOID *) digit_arg, F_INTRINSIC, Global_Map);
  321.     define_key1("^[2", (VOID *) digi