home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d3xx / d352 / mg.lha / MG / src.LZH / mg / kbd.c < prev    next >
C/C++ Source or Header  |  1990-05-23  |  9KB  |  415 lines

  1. /*
  2.  * Terminal independent keyboard handling. 
  3.  */
  4. #include    "no_macro.h"
  5. #include    "no_metakey.h"
  6. #include    "no_dprompt.h"
  7. #include    "bsmap.h"
  8. #ifndef        NO_METAKEY
  9. #include    "metabit.h"
  10. #endif
  11.  
  12. #include    "def.h"
  13. #include    "kbd.h"
  14. #include    "line.h"
  15. #include    "buffer.h"
  16. #include    "window.h"
  17. #ifndef NO_MACRO
  18. #include "macro.h"
  19. #endif
  20.  
  21. #define EXTERN
  22. #include    "key.h"
  23.  
  24.  
  25. #ifndef    NO_METAKEY
  26. int             use_metakey = TRUE;
  27. /*
  28.  * Toggle the value of use_metakey 
  29.  */
  30. do_meta(f, n)
  31. {
  32.     if (f & FFARG)
  33.         use_metakey = n > 0;
  34.     else
  35.         use_metakey = !use_metakey;
  36.     ewprintf("Meta keys %sabled", use_metakey ? "en" : "dis");
  37.     return TRUE;
  38. }
  39. #endif
  40.  
  41. #ifdef    BSMAP
  42. static int      bs_map = BSMAP;
  43. /*
  44.  * Toggle backspace mapping 
  45.  */
  46. bsmap(f, n)
  47. {
  48.     if (f & FFARG)
  49.         bs_map = n > 0;
  50.     else
  51.         bs_map = !bs_map;
  52.     ewprintf("Backspace mapping %sabled", bs_map ? "en" : "dis");
  53.     return TRUE;
  54. }
  55. #endif
  56.  
  57. #ifndef NO_DPROMPT
  58. #define PROMPTL 80
  59. char            prompt[PROMPTL], *promptp;
  60. #endif
  61.  
  62. static int      pushed = FALSE;
  63. static int      pushedc;
  64.  
  65. VOID
  66. ungetkey(c)
  67.     int             c;
  68. {
  69. #ifndef    NO_METAKEY
  70.     if (use_metakey && pushed && c == CCHR('['))
  71.         pushedc |= METABIT;
  72.     else
  73. #endif
  74.         pushedc = c;
  75.     pushed = TRUE;
  76. }
  77.  
  78. int
  79. getkey(flags)
  80.     int             flags;
  81. {
  82.     int             c;
  83.     char           *keyname();
  84. #ifndef    NO_MACRO
  85.     extern struct macro kbdmacro;
  86. #endif
  87.  
  88. #ifndef NO_DPROMPT
  89.     if ((flags & PROMPT) && !pushed && !inmacro) {
  90.         if (prompt[0] != '\0' && ttwait()) {
  91.             ewprintf("%s", prompt);    /* avoid problems with % */
  92.             update();    /* put the cursor back     */
  93.             epresf = ERASE;
  94.         }
  95.         if (promptp > prompt)
  96.             *(promptp - 1) = ' ';
  97.     }
  98. #endif
  99.     if (pushed) {
  100.         c = pushedc;
  101.         pushed = FALSE;
  102. #ifndef    NO_MACRO
  103.     } else if (inmacro) {
  104.         if (inmacro->m_cur - inmacro->m_text >= inmacro->m_count)
  105.             return CCHR('G');
  106.         else {
  107.             c = *(inmacro->m_cur++);
  108.             if (!(flags & CRFLAGS))
  109.                 c = (c == SOFTCR ? CCHR('M') : c);
  110.             else if (flags & DISSCR) {
  111.                 if (c == SOFTCR)
  112.                     return getkey(flags);
  113.                 else if (*inmacro->m_cur == SOFTCR)
  114.                     inmacro->m_cur++;
  115.             }    /* else flags & SEESCR, so we pass it as is */
  116.         }
  117. #endif
  118.     } else
  119.         c = getkbd();
  120. #ifndef    NO_METAKEY
  121.     if (use_metakey && (c & METABIT)) {
  122.         pushedc = c & ~METABIT;
  123.         pushed = TRUE;
  124.         c = CCHR('[');
  125.     }
  126. #endif
  127. #ifndef    NO_MACRO
  128.     if (macrodef && !inmacro)
  129.         add_key_to_macro((KCHAR) c, &kbdmacro);
  130. #endif
  131. #ifdef     BSMAP
  132.     if (bs_map)
  133.         if (c == CCHR('H'))
  134.             c = CCHR('?');
  135.         else if (c == CCHR('?'))
  136.             c = CCHR('H');
  137. #endif
  138. #ifndef NO_DPROMPT
  139.     if ((flags & PROMPT) && promptp < &prompt[PROMPTL - 5]) {
  140.         promptp = keyname(promptp, c);
  141.         *promptp++ = '-';
  142.         *promptp = '\0';
  143.     }
  144. #endif
  145.     return c;
  146. }
  147.  
  148. /*
  149.  * doscan scans a keymap for a keyboard character and returns a pointer to
  150.  * the function associated with that character.  Sets ele to the keymap
  151.  * element the keyboard was found in as a side effect. 
  152.  */
  153.  
  154. struct map_element *ele;
  155.  
  156. struct function
  157.                *
  158. doscan(map, c)
  159.     register struct keymap *map;
  160.     register int    c;
  161. {
  162.     register struct map_element *elec = &map->map_element[0];    /* local register copy
  163.                                      * for faster access */
  164.     register struct map_element *last = &map->map_element[map->map_num];
  165.  
  166.     while (elec < last && c > elec->k_num)
  167.         elec++;
  168.     ele = elec;        /* used by prefix and binding code     */
  169.     if (elec >= last || c < elec->k_base)
  170.         return map->map_default;
  171.     return &elec->k_entry[c - elec->k_base];
  172. }
  173.  
  174. doin()
  175. {
  176.     struct keymap  *curmap;
  177.     struct function *funct;
  178.  
  179. #ifndef NO_DPROMPT
  180.     *(promptp = prompt) = '\0';
  181. #endif
  182.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  183.     key.k_count = 0;
  184.  
  185.     while ((funct =
  186.         doscan(curmap, (key.k_chars[key.k_count++] = getkey(PROMPT))))->f_type
  187.            == F_PREFIX)
  188.         curmap = (struct keymap *) funct->f_pref;
  189. #ifndef    NO_MACRO
  190.     if (funct->f_type == F_MACRO)
  191.         return runmacro((struct macro *) funct->f_macro, 0, 1, FALSE);
  192.     else
  193. #endif
  194.         return (*(funct->f_funcp)) (0, 1);
  195. }
  196.  
  197. rescan(f, n)
  198.     int             f, n;
  199. {
  200.     int             c;
  201.     register struct keymap *curmap;
  202.     int             i;
  203.     struct function *fp;
  204.     int             mode = curbp->b_nmodes;
  205.  
  206.     for (;;) {
  207.         if (ISUPPER(key.k_chars[key.k_count - 1])) {
  208.             c = TOLOWER(key.k_chars[key.k_count - 1]);
  209.             curmap = curbp->b_modes[mode]->p_map;
  210.             for (i = 0; i < key.k_count - 1; i++) {
  211.                 if ((fp = doscan(curmap, (key.k_chars[i])))->f_type != F_PREFIX)
  212.                     break;
  213.                 curmap = (struct keymap *) fp->f_pref;
  214.             }
  215.             if (fp->f_type == F_PREFIX) {
  216.                 if ((fp = doscan(curmap, c))->f_type == F_PREFIX)
  217.                     while ((fp = doscan(curmap, key.k_chars[key.k_count++] =
  218.                     getkey(PROMPT)))->f_type == F_PREFIX)
  219.                         curmap = (struct keymap *) fp->f_pref;
  220. #ifndef    NO_MACRO
  221.                 if (fp->f_type == F_MACRO)
  222.                     return runmacro((struct macro *) fp->f_macro, f, n, FALSE);
  223.                 else
  224. #endif
  225.                 if (fp->f_funcp != rescan)
  226.                     return (*(fp->f_funcp)) (f, n);
  227.             }
  228.         }
  229.         /* try previous mode */
  230.         if (--mode < 0)
  231.             return ABORT;
  232.         curmap = curbp->b_modes[mode]->p_map;
  233.         for (i = 0; i < key.k_count; i++) {
  234.             if ((fp = doscan(curmap, (key.k_chars[i])))->f_type != F_PREFIX)
  235.                 break;
  236.             curmap = (struct keymap *) fp->f_pref;
  237.         }
  238.         if (fp->f_type == F_PREFIX) {
  239.             while ((fp = doscan(curmap, key.k_chars[i++] = getkey(PROMPT)))->f_type
  240.                    == F_PREFIX)
  241.                 curmap = (struct keymap *) fp->f_pref;
  242.             key.k_count = i;
  243.         }
  244.         if (i >= key.k_count - 1)
  245. #ifndef    NO_MACRO
  246.             if (fp->f_type == F_MACRO)
  247.                 return runmacro((struct macro *) fp->f_macro, f, n, FALSE);
  248.             else
  249. #endif
  250.             if (fp->f_funcp != rescan)
  251.                 return (*(fp->f_funcp)) (f, n);
  252.     }
  253. }
  254.  
  255. universal_argument(f, n)
  256.     int             f, n;
  257. {
  258.     int             c, nn = 4;
  259.     struct keymap  *curmap;
  260.     struct function *funct;
  261.  
  262.     if (f & FFUNIV)
  263.         nn *= n;
  264.     for (;;) {
  265.         key.k_chars[0] = c = getkey(PROMPT);
  266.         key.k_count = 1;
  267.         if (c == '-')
  268.             return negative_argument(f, 4);
  269.         if (c >= '0' && c <= '9')
  270.             return digit_argument(f, nn);
  271.         curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  272.         while ((funct = doscan(curmap, c))->f_type == F_PREFIX) {
  273.             curmap = (struct keymap *) funct->f_pref;
  274.             key.k_chars[key.k_count++] = c = getkey(PROMPT);
  275.         }
  276. #ifndef    NO_MACRO
  277.         if (funct->f_type == F_MACRO)
  278.             return runmacro((struct macro *) funct->f_macro, FFUNIV, nn, FALSE);
  279.         else
  280. #endif
  281.         if (funct->f_funcp != universal_argument)
  282.             return (*(funct->f_funcp)) (FFUNIV, nn);
  283.         nn *= 4;
  284.     }
  285. }
  286.  
  287. /* ARGSUSED */
  288. digit_argument(f, n)
  289.     int             f, n;
  290. {
  291.     int             nn, c;
  292.     struct keymap  *curmap;
  293.     struct function *funct;
  294.  
  295.     nn = key.k_chars[key.k_count - 1] - '0';
  296.     for (;;) {
  297.         c = getkey(PROMPT);
  298.         if (c < '0' || c > '9')
  299.             break;
  300.         nn *= 10;
  301.         nn += c - '0';
  302.     }
  303.     key.k_chars[0] = c;
  304.     key.k_count = 1;
  305.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  306.     while ((funct = doscan(curmap, c))->f_type == F_PREFIX) {
  307.         curmap = (struct keymap *) funct->f_pref;
  308.         key.k_chars[key.k_count++] = c = getkey(PROMPT);
  309.     }
  310. #ifndef    NO_MACRO
  311.     if (funct->f_type == F_MACRO)
  312.         return runmacro((struct macro *) funct->f_macro, FFOTHARG, nn, FALSE);
  313.     else
  314. #endif
  315.         return (*(funct->f_funcp)) (FFOTHARG, nn);
  316. }
  317.  
  318. negative_argument(f, n)
  319.     int             f, n;
  320. {
  321.     int             nn = 0, c;
  322.     struct keymap  *curmap;
  323.     struct function *funct;
  324.  
  325.     for (;;) {
  326.         c = getkey(PROMPT);
  327.         if (c < '0' || c > '9')
  328.             break;
  329.         nn *= 10;
  330.         nn += c - '0';
  331.     }
  332.     if (nn)
  333.         nn = -nn;
  334.     else
  335.         nn = -n;
  336.     key.k_chars[0] = c;
  337.     key.k_count = 1;
  338.     curmap = curbp->b_modes[curbp->b_nmodes]->p_map;
  339.     while ((funct = doscan(curmap, c))->f_type == F_PREFIX) {
  340.         curmap = (struct keymap *) funct->f_pref;
  341.         key.k_chars[key.k_count++] = c = getkey(PROMPT);
  342.     }
  343. #ifndef    NO_MACRO
  344.     if (funct->f_type == F_MACRO)
  345.         return runmacro((struct macro *) funct->f_macro, FFOTHARG, nn, FALSE);
  346.     else
  347. #endif
  348.         return (*(funct->f_funcp)) (FFNEGARG, nn);
  349. }
  350.  
  351. /*
  352.  * Insert a character. 
  353.  */
  354.  
  355. selfinsert(f, n)
  356.     int             f, n;
  357. {
  358.     register int    c;
  359.     int             count;
  360.     VOID            lchange();
  361.  
  362.     if (n < 0)
  363.         return FALSE;
  364.     if (n == 0)
  365.         return TRUE;
  366.     c = key.k_chars[key.k_count - 1];
  367.     if (c == '\n') {
  368.         do {
  369.             count = lnewline();
  370.         } while (--n && count == TRUE);
  371.         return count;
  372.     }
  373.     if (curbp->b_flag & BFOVERWRITE) {    /* Overwrite mode     */
  374.         lchange(WFEDIT);
  375.         while (curwp->w_doto < llength(curwp->w_dotp) && n--)
  376.             lputc(curwp->w_dotp, curwp->w_doto++, c);
  377.         if (n <= 0)
  378.             return TRUE;
  379.     }
  380.     return linsert(n, c);
  381. }
  382.  
  383. /*
  384.  * this could be implemented as a keymap with everthing defined as
  385.  * self-insert. (well, not quite - it needs to deal with ^Q###). 
  386.  */
  387. quote(f, n)
  388. {
  389.     register int    c;
  390.  
  391. #ifndef    NO_METAKEY
  392.     int             save_metakey = use_metakey;
  393.  
  394.     use_metakey = FALSE;
  395. #endif
  396.     key.k_count = 1;
  397.     if ((key.k_chars[0] = getkey(PROMPT | DISSCR)) >= '0' && key.k_chars[0] <= '7') {
  398.         key.k_chars[0] -= '0';
  399.         if ((c = getkey(PROMPT | DISSCR)) >= '0' && c <= '7') {
  400.             key.k_chars[0] *= 8;
  401.             key.k_chars[0] += c - '0';
  402.             if ((c = getkey(PROMPT | DISSCR)) >= '0' && c <= '7') {
  403.                 key.k_chars[0] *= 8;
  404.                 key.k_chars[0] += c - '0';
  405.             } else
  406.                 ungetkey(c);
  407.         } else
  408.             ungetkey(c);
  409.     }
  410. #ifndef    NO_METAKEY
  411.     use_metakey = save_metakey;
  412. #endif
  413.     return selfinsert(f, n);
  414. }
  415.