home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / amiga / vim46src.lha / vim-4.6 / src / tables.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-06  |  12.5 KB  |  484 lines

  1. /* vi:set ts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *                            This file by Robert Webb
  5.  *
  6.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  7.  * Do ":help credits" in Vim to see a list of people who contributed.
  8.  */
  9.  
  10. /*
  11.  * tables.c: functions that use lookup tables for various things, generally to
  12.  * do with special key codes.
  13.  */
  14.  
  15. #include "vim.h"
  16. #include "globals.h"
  17. #include "proto.h"
  18. #include "option.h"
  19.  
  20. /*
  21.  * Some useful tables.
  22.  */
  23.  
  24. static struct
  25. {
  26.     int        mod_mask;        /* Bit-mask for particular key modifier */
  27.     char_u    name;            /* Single letter name of modifier */
  28. } mod_mask_table[] =
  29. {
  30.     {MOD_MASK_ALT,        (char_u)'M'},
  31.     {MOD_MASK_CTRL,        (char_u)'C'},
  32.     {MOD_MASK_SHIFT,    (char_u)'S'},
  33.     {MOD_MASK_2CLICK,    (char_u)'2'},
  34.     {MOD_MASK_3CLICK,    (char_u)'3'},
  35.     {MOD_MASK_4CLICK,    (char_u)'4'},
  36.     {0x0,                NUL}
  37. };
  38.  
  39. /*
  40.  * Shifted key terminal codes and their unshifted equivalent.
  41.  * Don't add mouse codes here, they are handled seperately!
  42.  */
  43. static char_u shifted_keys_table[] =
  44. {
  45. /*  shifted                 unshifted  */
  46.     '&', '9',                '@', '1',            /* begin */
  47.     '&', '0',                '@', '2',            /* cancel */
  48.     '*', '1',                '@', '4',            /* command */
  49.     '*', '2',                '@', '5',            /* copy */
  50.     '*', '3',                '@', '6',            /* create */
  51.     '*', '4',                'k', 'D',            /* delete char */
  52.     '*', '5',                'k', 'L',            /* delete line */
  53.     '*', '7',                '@', '7',            /* end */
  54.     '*', '9',                '@', '9',            /* exit */
  55.     '*', '0',                '@', '0',            /* find */
  56.     '#', '1',                '%', '1',            /* help */
  57.     '#', '2',                'k', 'h',            /* home */
  58.     '#', '3',                'k', 'I',            /* insert */
  59.     '#', '4',                'k', 'l',            /* left arrow */
  60.     '%', 'a',                '%', '3',            /* message */
  61.     '%', 'b',                '%', '4',            /* move */
  62.     '%', 'c',                '%', '5',            /* next */
  63.     '%', 'd',                '%', '7',            /* options */
  64.     '%', 'e',                '%', '8',            /* previous */
  65.     '%', 'f',                '%', '9',            /* print */
  66.     '%', 'g',                '%', '0',            /* redo */
  67.     '%', 'h',                '&', '3',            /* replace */
  68.     '%', 'i',                'k', 'r',            /* right arrow */
  69.     '%', 'j',                '&', '5',            /* resume */
  70.     '!', '1',                '&', '6',            /* save */
  71.     '!', '2',                '&', '7',            /* suspend */
  72.     '!', '3',                '&', '8',            /* undo */
  73.     KS_EXTRA, KE_S_UP,        'k', 'u',            /* up arrow */
  74.     KS_EXTRA, KE_S_DOWN,    'k', 'd',            /* down arrow */
  75.  
  76.     KS_EXTRA, KE_S_F1,      'k', '1',            /* F1 */
  77.     KS_EXTRA, KE_S_F2,      'k', '2',
  78.     KS_EXTRA, KE_S_F3,      'k', '3',
  79.     KS_EXTRA, KE_S_F4,      'k', '4',
  80.     KS_EXTRA, KE_S_F5,      'k', '5',
  81.     KS_EXTRA, KE_S_F6,      'k', '6',
  82.     KS_EXTRA, KE_S_F7,      'k', '7',
  83.     KS_EXTRA, KE_S_F8,      'k', '8',
  84.     KS_EXTRA, KE_S_F9,      'k', '9',
  85.     KS_EXTRA, KE_S_F10,     'k', ';',            /* F10 */
  86.  
  87.     KS_EXTRA, KE_S_F11,     'F', '1',
  88.     KS_EXTRA, KE_S_F12,     'F', '2',
  89.     KS_EXTRA, KE_S_F13,     'F', '3',
  90.     KS_EXTRA, KE_S_F14,     'F', '4',
  91.     KS_EXTRA, KE_S_F15,     'F', '5',
  92.     KS_EXTRA, KE_S_F16,     'F', '6',
  93.     KS_EXTRA, KE_S_F17,     'F', '7',
  94.     KS_EXTRA, KE_S_F18,     'F', '8',
  95.     KS_EXTRA, KE_S_F19,     'F', '9',
  96.     KS_EXTRA, KE_S_F20,     'F', 'A',
  97.  
  98.     KS_EXTRA, KE_S_F21,     'F', 'B',
  99.     KS_EXTRA, KE_S_F22,     'F', 'C',
  100.     KS_EXTRA, KE_S_F23,     'F', 'D',
  101.     KS_EXTRA, KE_S_F24,     'F', 'E',
  102.     KS_EXTRA, KE_S_F25,     'F', 'F',
  103.     KS_EXTRA, KE_S_F26,     'F', 'G',
  104.     KS_EXTRA, KE_S_F27,     'F', 'H',
  105.     KS_EXTRA, KE_S_F28,     'F', 'I',
  106.     KS_EXTRA, KE_S_F29,     'F', 'J',
  107.     KS_EXTRA, KE_S_F30,     'F', 'K',
  108.  
  109.     KS_EXTRA, KE_S_F31,     'F', 'L',
  110.     KS_EXTRA, KE_S_F32,     'F', 'M',
  111.     KS_EXTRA, KE_S_F33,     'F', 'N',
  112.     KS_EXTRA, KE_S_F34,     'F', 'O',
  113.     KS_EXTRA, KE_S_F35,     'F', 'P',
  114.  
  115.     KS_EXTRA, KE_S_TAB,     KS_EXTRA, KE_TAB,    /* TAB */
  116.     NUL
  117. };
  118.  
  119. static struct key_name_entry
  120. {
  121.     int        key;        /* Special key code or ascii value */
  122.     char_u    *name;        /* Name of key */
  123. } key_names_table[] =
  124. {
  125.     {' ',                (char_u *)"Space"},
  126.     {TAB,                (char_u *)"Tab"},
  127.     {K_TAB,                (char_u *)"Tab"},
  128.     {NL,                (char_u *)"NL"},
  129.     {NL,                (char_u *)"NewLine"},    /* Alternative name */
  130.     {NL,                (char_u *)"LineFeed"},    /* Alternative name */
  131.     {NL,                (char_u *)"LF"},        /* Alternative name */
  132.     {CR,                (char_u *)"CR"},
  133.     {CR,                (char_u *)"Return"},    /* Alternative name */
  134.     {ESC,                (char_u *)"Esc"},
  135.     {'|',                (char_u *)"Bar"},
  136.     {K_UP,                (char_u *)"Up"},
  137.     {K_DOWN,            (char_u *)"Down"},
  138.     {K_LEFT,            (char_u *)"Left"},
  139.     {K_RIGHT,            (char_u *)"Right"},
  140.  
  141.     {K_F1,                 (char_u *)"F1"},
  142.     {K_F2,                 (char_u *)"F2"},
  143.     {K_F3,                 (char_u *)"F3"},
  144.     {K_F4,                 (char_u *)"F4"},
  145.     {K_F5,                 (char_u *)"F5"},
  146.     {K_F6,                 (char_u *)"F6"},
  147.     {K_F7,                 (char_u *)"F7"},
  148.     {K_F8,                 (char_u *)"F8"},
  149.     {K_F9,                 (char_u *)"F9"},
  150.     {K_F10,                (char_u *)"F10"},
  151.  
  152.     {K_F11,                (char_u *)"F11"},
  153.     {K_F12,                (char_u *)"F12"},
  154.     {K_F13,                (char_u *)"F13"},
  155.     {K_F14,                (char_u *)"F14"},
  156.     {K_F15,                (char_u *)"F15"},
  157.     {K_F16,                (char_u *)"F16"},
  158.     {K_F17,                (char_u *)"F17"},
  159.     {K_F18,                (char_u *)"F18"},
  160.     {K_F19,                (char_u *)"F19"},
  161.     {K_F20,                (char_u *)"F20"},
  162.  
  163.     {K_F21,                (char_u *)"F21"},
  164.     {K_F22,                (char_u *)"F22"},
  165.     {K_F23,                (char_u *)"F23"},
  166.     {K_F24,                (char_u *)"F24"},
  167.     {K_F25,                (char_u *)"F25"},
  168.     {K_F26,                (char_u *)"F26"},
  169.     {K_F27,                (char_u *)"F27"},
  170.     {K_F28,                (char_u *)"F28"},
  171.     {K_F29,                (char_u *)"F29"},
  172.     {K_F30,                (char_u *)"F30"},
  173.  
  174.     {K_F31,                (char_u *)"F31"},
  175.     {K_F32,                (char_u *)"F32"},
  176.     {K_F33,                (char_u *)"F33"},
  177.     {K_F34,                (char_u *)"F34"},
  178.     {K_F35,                (char_u *)"F35"},
  179.  
  180.     {K_HELP,            (char_u *)"Help"},
  181.     {K_UNDO,            (char_u *)"Undo"},
  182.     {K_BS,                (char_u *)"BS"},
  183.     {K_BS,                (char_u *)"BackSpace"},    /* Alternative name */
  184.     {K_INS,                (char_u *)"Insert"},
  185.     {K_INS,                (char_u *)"Ins"},        /* Alternative name */
  186.     {K_DEL,                (char_u *)"Del"},
  187.     {K_DEL,                (char_u *)"Delete"},    /* Alternative name */
  188.     {K_HOME,            (char_u *)"Home"},
  189.     {K_END,                (char_u *)"End"},
  190.     {K_PAGEUP,            (char_u *)"PageUp"},
  191.     {K_PAGEDOWN,        (char_u *)"PageDown"},
  192.     {K_KHOME,            (char_u *)"kHome"},
  193.     {K_KEND,            (char_u *)"kEnd"},
  194.     {K_KPAGEUP,            (char_u *)"kPageUp"},
  195.     {K_KPAGEDOWN,        (char_u *)"kPageDown"},
  196.  
  197.     {K_MOUSE,            (char_u *)"Mouse"},
  198.     {K_LEFTMOUSE,        (char_u *)"LeftMouse"},
  199.     {K_LEFTDRAG,        (char_u *)"LeftDrag"},
  200.     {K_LEFTRELEASE,        (char_u *)"LeftRelease"},
  201.     {K_MIDDLEMOUSE,        (char_u *)"MiddleMouse"},
  202.     {K_MIDDLEDRAG,        (char_u *)"MiddleDrag"},
  203.     {K_MIDDLERELEASE,    (char_u *)"MiddleRelease"},
  204.     {K_RIGHTMOUSE,        (char_u *)"RightMouse"},
  205.     {K_RIGHTDRAG,        (char_u *)"RightDrag"},
  206.     {K_RIGHTRELEASE,    (char_u *)"RightRelease"},
  207.     {K_ZERO,            (char_u *)"Nul"},
  208.     {0,                    NULL}
  209. };
  210.  
  211. #define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / sizeof(struct key_name_entry))
  212.  
  213. #ifdef USE_MOUSE
  214. static struct
  215. {
  216.     int        pseudo_code;        /* Code for pseudo mouse event */
  217.     int        button;                /* Which mouse button is it? */
  218.     int        is_click;            /* Is it a mouse button click event? */
  219.     int        is_drag;            /* Is it a mouse drag event? */
  220. } mouse_table[] =
  221. {
  222.     {KE_LEFTMOUSE,        MOUSE_LEFT,        TRUE,    FALSE},
  223.     {KE_LEFTDRAG,        MOUSE_LEFT,        FALSE,    TRUE},
  224.     {KE_LEFTRELEASE,    MOUSE_LEFT,        FALSE,    FALSE},
  225.     {KE_MIDDLEMOUSE,    MOUSE_MIDDLE,    TRUE,    FALSE},
  226.     {KE_MIDDLEDRAG,        MOUSE_MIDDLE,    FALSE,    TRUE},
  227.     {KE_MIDDLERELEASE,    MOUSE_MIDDLE,    FALSE,    FALSE},
  228.     {KE_RIGHTMOUSE,        MOUSE_RIGHT,    TRUE,    FALSE},
  229.     {KE_RIGHTDRAG,        MOUSE_RIGHT,    FALSE,    TRUE},
  230.     {KE_RIGHTRELEASE,    MOUSE_RIGHT,    FALSE,    FALSE},
  231.     {KE_IGNORE,            MOUSE_RELEASE,    FALSE,    TRUE},    /* DRAG without CLICK */
  232.     {KE_IGNORE,            MOUSE_RELEASE,    FALSE,    FALSE}, /* RELEASE without CLICK */
  233.     {0,                    0,                0,        0},
  234. };
  235. #endif /* USE_MOUSE */
  236.  
  237. /*
  238.  * Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
  239.  * modifier name ('S' for Shift, 'C' for Ctrl etc).
  240.  */
  241.     int
  242. name_to_mod_mask(c)
  243.     int        c;
  244. {
  245.     int        i;
  246.  
  247.     for (i = 0; mod_mask_table[i].mod_mask; i++)
  248.         if (TO_LOWER(c) == TO_LOWER(mod_mask_table[i].name))
  249.             return mod_mask_table[i].mod_mask;
  250.     return 0x0;
  251. }
  252.  
  253. /*
  254.  * Decide whether the given key code (K_*) is a shifted special
  255.  * key (by looking at mod_mask).  If it is, then return the appropriate shifted
  256.  * key code, otherwise just return the character as is.
  257.  */
  258.     int
  259. check_shifted_spec_key(c)
  260.     int        c;
  261. {
  262.     int        i;
  263.     int        key0;
  264.     int        key1;
  265.  
  266.     if (mod_mask & MOD_MASK_SHIFT)
  267.     {
  268.         if (c == TAB)            /* TAB is not in the table, K_TAB is */
  269.             return K_S_TAB;
  270.         key0 = KEY2TERMCAP0(c);
  271.         key1 = KEY2TERMCAP1(c);
  272.         for (i = 0; shifted_keys_table[i] != NUL; i += 4)
  273.             if (key0 == shifted_keys_table[i + 2] &&
  274.                                             key1 == shifted_keys_table[i + 3])
  275.                 return TERMCAP2KEY(shifted_keys_table[i],
  276.                                                    shifted_keys_table[i + 1]);
  277.     }
  278.     return c;
  279. }
  280.  
  281. /*
  282.  * Decide whether the given special key is shifted or not.  If it is we
  283.  * return OK and change it to the equivalent unshifted special key code,
  284.  * otherwise we leave it as is and return FAIL.
  285.  */
  286.     int
  287. unshift_special_key(p)
  288.     char_u    *p;
  289. {
  290.     int        i;
  291.  
  292.     for (i = 0; shifted_keys_table[i]; i += 4)
  293.         if (p[0] == shifted_keys_table[i] && p[1] == shifted_keys_table[i + 1])
  294.         {
  295.             p[0] = shifted_keys_table[i + 2];
  296.             p[1] = shifted_keys_table[i + 3];
  297.             return OK;
  298.         }
  299.     return FAIL;
  300. }
  301.  
  302. /*
  303.  * Return a string which contains the name of the given key when the given
  304.  * modifiers are down.
  305.  */
  306.     char_u *
  307. get_special_key_name(c, modifiers)
  308.     int        c;
  309.     int        modifiers;
  310. {
  311.     static char_u string[MAX_KEY_NAME_LEN + 1];
  312.  
  313.     int        i, idx;
  314.     char_u    *s;
  315.     char_u    name[2];
  316.  
  317.     string[0] = '<';
  318.     idx = 1;
  319.  
  320.     /* translate shifted keys into unshifted keys and set modifier */
  321.     if (IS_SPECIAL(c))
  322.     {
  323.         name[0] = KEY2TERMCAP0(c);
  324.         name[1] = KEY2TERMCAP1(c);
  325.         if (unshift_special_key(&name[0]))
  326.             modifiers |= MOD_MASK_SHIFT;
  327.         c = TERMCAP2KEY(name[0], name[1]);
  328.     }
  329.  
  330.     /* translate the modifier into a string */
  331.     for (i = 0; mod_mask_table[i].mod_mask; i++)
  332.         if (modifiers & mod_mask_table[i].mod_mask)
  333.         {
  334.             string[idx++] = mod_mask_table[i].name;
  335.             string[idx++] = (char_u)'-';
  336.         }
  337.  
  338.     /* try to find the key in the special key table */
  339.     i = find_special_key_in_table(c);
  340.     if (i < 0)            /* unknown special key, output t_xx */
  341.     {
  342.         if (IS_SPECIAL(c))
  343.         {
  344.             string[idx++] = 't';
  345.             string[idx++] = '_';
  346.             string[idx++] = KEY2TERMCAP0(c);
  347.             string[idx++] = KEY2TERMCAP1(c);
  348.         }
  349.         /* Not a special key, only modifiers, output directly */
  350.         else
  351.         {
  352.             if (isprintchar(c))
  353.                 string[idx++] = c;
  354.             else
  355.             {
  356.                 s = transchar(c);
  357.                 while (*s)
  358.                     string[idx++] = *s++;
  359.             }
  360.         }
  361.     }
  362.     else                /* use name of special key */
  363.     {
  364.         STRCPY(string + idx, key_names_table[i].name);
  365.         idx = STRLEN(string);
  366.     }
  367.     string[idx++] = '>';
  368.     string[idx] = NUL;
  369.     return string;
  370. }
  371.  
  372. /*
  373.  * Try to find key "c" in the special key table.
  374.  * Return the index when found, -1 when not found.
  375.  */
  376.     int
  377. find_special_key_in_table(c)
  378.     int        c;
  379. {
  380.     int        i;
  381.  
  382.     for (i = 0; key_names_table[i].name != NULL; i++)
  383.         if (c == key_names_table[i].key)
  384.             break;
  385.     if (key_names_table[i].name == NULL)
  386.         i = -1;
  387.     return i;
  388. }
  389.  
  390. /*
  391.  * Find the special key with the given name (the given string does not have to
  392.  * end with NUL, the name is assumed to end before the first non-idchar).
  393.  * If the name starts with "t_" the next two characters are interpreted as a
  394.  * termcap name.
  395.  * Return the key code, or 0 if not found.
  396.  */
  397.     int
  398. get_special_key_code(name)
  399.     char_u    *name;
  400. {
  401.     char_u    *table_name;
  402.     char_u    string[3];
  403.     int        i, j;
  404.  
  405.     /*
  406.      * If it's <t_xx> we get the code for xx from the termcap
  407.      */
  408.     if (name[0] == 't' && name[1] == '_' && name[2] != NUL && name[3] != NUL)
  409.     {
  410.         string[0] = name[2];
  411.         string[1] = name[3];
  412.         string[2] = NUL;
  413.         if (add_termcap_entry(string, FALSE) == OK)
  414.             return TERMCAP2KEY(name[2], name[3]);
  415.     }
  416.     else
  417.         for (i = 0; key_names_table[i].name != NULL; i++)
  418.         {
  419.             table_name = key_names_table[i].name;
  420.             for (j = 0; isidchar(name[j]) && table_name[j] != NUL; j++)
  421.                 if (TO_LOWER(table_name[j]) != TO_LOWER(name[j]))
  422.                     break;
  423.             if (!isidchar(name[j]) && table_name[j] == NUL)
  424.                 return key_names_table[i].key;
  425.         }
  426.     return 0;
  427. }
  428.  
  429.     char_u *
  430. get_key_name(i)
  431.     int        i;
  432. {
  433.     if (i >= KEY_NAMES_TABLE_LEN)
  434.         return NULL;
  435.     return  key_names_table[i].name;
  436. }
  437.  
  438. #ifdef USE_MOUSE
  439. /*
  440.  * Look up the given mouse code to return the relevant information in the other
  441.  * arguments.  Return which button is down or was released.
  442.  */
  443.     int
  444. get_mouse_button(code, is_click, is_drag)
  445.     int        code;
  446.     int        *is_click;
  447.     int        *is_drag;
  448. {
  449.     int        i;
  450.  
  451.     for (i = 0; mouse_table[i].pseudo_code; i++)
  452.         if (code == mouse_table[i].pseudo_code)
  453.         {
  454.             *is_click = mouse_table[i].is_click;
  455.             *is_drag = mouse_table[i].is_drag;
  456.             return mouse_table[i].button;
  457.         }
  458.     return 0;        /* Shouldn't get here */
  459. }
  460.  
  461. /*
  462.  * Return the appropriate pseudo mouse event token (KE_LEFTMOUSE etc) based on
  463.  * the given information about which mouse button is down, and whether the
  464.  * mouse was clicked, dragged or released.
  465.  */
  466.     int
  467. get_pseudo_mouse_code(button, is_click, is_drag)
  468.     int        button;        /* eg MOUSE_LEFT */
  469.     int        is_click;
  470.     int        is_drag;
  471. {
  472.     int        i;
  473.  
  474.     for (i = 0; mouse_table[i].pseudo_code; i++)
  475.         if (button == mouse_table[i].button
  476.             && is_click == mouse_table[i].is_click
  477.             && is_drag == mouse_table[i].is_drag)
  478.         {
  479.             return mouse_table[i].pseudo_code;
  480.         }
  481.     return KE_IGNORE;        /* not recongnized, ignore it */
  482. }
  483. #endif /* USE_MOUSE */
  484.