home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / util / jade-3.0.lha / Jade / src / x11_keys.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-19  |  8.6 KB  |  307 lines

  1. /* x11_keys.c -- Event translation for X11
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4. This file is part of Jade.
  5.  
  6. Jade is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. Jade is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with Jade; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22.  
  23. #include <string.h>
  24. #include <X11/keysym.h>
  25. #include <X11/Xutil.h>
  26.  
  27. #ifdef SWAP_DELETE_KEYS
  28. # define XK_DELETE XK_BackSpace
  29. # define XK_BACKSPACE XK_Delete
  30. #else
  31. # define XK_DELETE XK_Delete
  32. # define XK_BACKSPACE XK_BackSpace
  33. #endif
  34.  
  35. _PR void translateevent(Event *, XEvent *);
  36. _PR int cookkey(void *, u_char *, int);
  37. _PR bool lookupevent(EventDef *, u_char *);
  38.  
  39. static void
  40. translatemods(EventDef *evd, unsigned int state)
  41. {
  42.     if(state & ShiftMask)
  43.     evd->evd_Mods |= EV_MOD_SHIFT;
  44.     if(state & LockMask)
  45.     evd->evd_Mods ^= EV_MOD_SHIFT;
  46.     if(state & ControlMask)
  47.     evd->evd_Mods |= EV_MOD_CTRL;
  48.     if(state & Mod1Mask)
  49.     evd->evd_Mods |= EV_MOD_MOD1;
  50.     if(state & Mod2Mask)
  51.     evd->evd_Mods |= EV_MOD_MOD2;
  52.     if(state & Mod3Mask)
  53.     evd->evd_Mods |= EV_MOD_MOD3;
  54.     if(state & Mod4Mask)
  55.     evd->evd_Mods |= EV_MOD_MOD4;
  56.     if(state & Mod5Mask)
  57.     evd->evd_Mods |= EV_MOD_MOD5;
  58.     if(state & Button1Mask)
  59.     evd->evd_Mods |= EV_MOD_BUTTON1;
  60.     if(state & Button2Mask)
  61.     evd->evd_Mods |= EV_MOD_BUTTON2;
  62.     if(state & Button3Mask)
  63.     evd->evd_Mods |= EV_MOD_BUTTON3;
  64.     if(state & Button4Mask)
  65.     evd->evd_Mods |= EV_MOD_BUTTON4;
  66.     if(state & Button5Mask)
  67.     evd->evd_Mods |= EV_MOD_BUTTON5;
  68. }
  69.  
  70. void
  71. translateevent(Event *ev, XEvent *xev)
  72. {
  73.     static Time LastClick;
  74.     switch(xev->type)
  75.     {
  76.     case KeyPress:
  77.     translatemods(&ev->ev_EventDef, xev->xkey.state);
  78.     if(ev->ev_EventDef.evd_Mods & EV_MOD_SHIFT)
  79.     {
  80.         /*
  81.          * some keys don't have keysym at index 1, if not treat it as
  82.          * normal keysym shifted
  83.          */
  84.         ev->ev_EventDef.evd_Code = XKeycodeToKeysym(XDisplay,
  85.                             xev->xkey.keycode, 1);
  86.         if(ev->ev_EventDef.evd_Code == NoSymbol)
  87.         {
  88.         ev->ev_EventDef.evd_Code = XKeycodeToKeysym(XDisplay,
  89.                                 xev->xkey.keycode,
  90.                                 0);
  91.         }
  92.         else
  93.         ev->ev_EventDef.evd_Mods &= ~EV_MOD_SHIFT;
  94.     }
  95.     else
  96.     {
  97.         ev->ev_EventDef.evd_Code = XKeycodeToKeysym(XDisplay,
  98.                             xev->xkey.keycode, 0);
  99.     }
  100.     if((ev->ev_EventDef.evd_Code != NoSymbol)
  101.        && (!IsModifierKey(ev->ev_EventDef.evd_Code)))
  102.     {
  103.         ev->ev_EventDef.evd_Type = EV_TYPE_KEYBD;
  104.     }
  105.     break;
  106.     case ButtonPress:
  107.     if(xev->xbutton.time < (LastClick + DOUBLE_CLICK_TIME))
  108.         ev->ev_EventDef.evd_Code = EV_CODE_MOUSE_CLICK2;
  109.     else
  110.         ev->ev_EventDef.evd_Code = EV_CODE_MOUSE_CLICK1;
  111.     LastClick = xev->xbutton.time;
  112.     goto button;
  113.     break;
  114.     case ButtonRelease:
  115.     ev->ev_EventDef.evd_Code = EV_CODE_MOUSE_UP;
  116. button:
  117.     ev->ev_EventDef.evd_Type = EV_TYPE_MOUSE;
  118.     ev->ev_Data_MouseX = xev->xbutton.x;
  119.     ev->ev_Data_MouseY = xev->xbutton.y;
  120.     translatemods(&ev->ev_EventDef, xev->xbutton.state);
  121.     switch(xev->xbutton.button)
  122.     {
  123.     case Button1:
  124.         ev->ev_EventDef.evd_Mods |= EV_MOD_BUTTON1;
  125.         break;
  126.     case Button2:
  127.         ev->ev_EventDef.evd_Mods |= EV_MOD_BUTTON2;
  128.         break;
  129.     case Button3:
  130.         ev->ev_EventDef.evd_Mods |= EV_MOD_BUTTON3;
  131.         break;
  132.     case Button4:
  133.         ev->ev_EventDef.evd_Mods |= EV_MOD_BUTTON4;
  134.         break;
  135.     case Button5:
  136.         ev->ev_EventDef.evd_Mods |= EV_MOD_BUTTON5;
  137.         break;
  138.     }
  139.     break;
  140.     }
  141. }
  142.  
  143. int
  144. cookkey(void *event, u_char *buf, int buflen)
  145. {
  146.     XKeyEvent *xk = event;
  147.     KeySym ks;
  148.     return(XLookupString(xk, buf, buflen, &ks, NULL));
  149. }
  150.  
  151. /*
  152.  * Stuff to translate textual key descriptions into key codes
  153.  */
  154.  
  155. typedef struct
  156. {
  157.     u_char     *kd_Name;
  158.     EventDef      kd_Event;
  159. } KeyDesc;
  160.  
  161. static const KeyDesc KeyDescr[] =
  162. {
  163.     "SHIFT",    { 0, EV_MOD_SHIFT, 0 },
  164.     "SFT",      { 0, EV_MOD_SHIFT, 0 },
  165.     "CONTROL",  { 0, EV_MOD_CTRL, 0 },
  166.     "CTRL",     { 0, EV_MOD_CTRL, 0 },
  167.     "CTL",      { 0, EV_MOD_CTRL, 0 },
  168.     "MOD1",     { 0, EV_MOD_MOD1, 0 },
  169.     "META",     { 0, EV_MOD_META, 0 },
  170.     "MOD2",     { 0, EV_MOD_MOD2, 0 },
  171.     "AMIGA",    { 0, EV_MOD_MOD2, 0 },
  172.     "MOD3",     { 0, EV_MOD_MOD3, 0 },
  173.     "MOD4",     { 0, EV_MOD_MOD4, 0 },
  174.     "BUTTON1",  { 0, EV_MOD_BUTTON1, 0 },
  175.     "LMB",      { 0, EV_MOD_LMB, 0 },
  176.     "BUTTON2",  { 0, EV_MOD_BUTTON2, 0 },
  177.     "MMB",      { 0, EV_MOD_MMB, 0 },
  178.     "BUTTON3",  { 0, EV_MOD_BUTTON3, 0 },
  179.     "RMB",      { 0, EV_MOD_RMB, 0 },
  180.     "BUTTON4",  { 0, EV_MOD_BUTTON4, 0 },
  181.     "BUTTON5",  { 0, EV_MOD_BUTTON5, 0 },
  182.  
  183.     "SPACE",    { EV_TYPE_KEYBD, 0, XK_space },
  184.     "SPACEBAR", { EV_TYPE_KEYBD, 0, XK_space },
  185.     "SPC",      { EV_TYPE_KEYBD, 0, XK_space },
  186.     "TAB",      { EV_TYPE_KEYBD, 0, XK_Tab },
  187.     "RETURN",   { EV_TYPE_KEYBD, 0, XK_Return },
  188.     "RET",      { EV_TYPE_KEYBD, 0, XK_Return },
  189.     "ESC",      { EV_TYPE_KEYBD, 0, XK_Escape },
  190.     "ESCAPE",   { EV_TYPE_KEYBD, 0, XK_Escape },
  191.     "BACKSPACE", { EV_TYPE_KEYBD, 0, XK_BACKSPACE },
  192.     "BS",       { EV_TYPE_KEYBD, 0, XK_BACKSPACE },
  193.     "DEL",      { EV_TYPE_KEYBD, 0, XK_DELETE },
  194.     "DELETE",   { EV_TYPE_KEYBD, 0, XK_DELETE },
  195.     "HELP",     { EV_TYPE_KEYBD, 0, XK_Help },
  196.     "UP",       { EV_TYPE_KEYBD, 0, XK_Up },
  197.     "DOWN",     { EV_TYPE_KEYBD, 0, XK_Down },
  198.     "RIGHT",    { EV_TYPE_KEYBD, 0, XK_Right },
  199.     "LEFT",     { EV_TYPE_KEYBD, 0, XK_Left },
  200.  
  201.     /*
  202.      * X defines lots of long names for these simple keys...
  203.      */
  204.     " ",        { EV_TYPE_KEYBD, 0, XK_space },
  205.     "!",        { EV_TYPE_KEYBD, 0, XK_exclam },
  206.     "\"",       { EV_TYPE_KEYBD, 0, XK_quotedbl },
  207.     "#",        { EV_TYPE_KEYBD, 0, XK_numbersign },
  208.     "$",        { EV_TYPE_KEYBD, 0, XK_dollar },
  209.     "%",        { EV_TYPE_KEYBD, 0, XK_percent },
  210.     "&",        { EV_TYPE_KEYBD, 0, XK_ampersand },
  211.     "'",        { EV_TYPE_KEYBD, 0, XK_quoteright },
  212.     "(",        { EV_TYPE_KEYBD, 0, XK_parenleft },
  213.     ")",        { EV_TYPE_KEYBD, 0, XK_parenright },
  214.     "*",        { EV_TYPE_KEYBD, 0, XK_asterisk },
  215.     "+",        { EV_TYPE_KEYBD, 0, XK_plus },
  216.     ",",        { EV_TYPE_KEYBD, 0, XK_comma },
  217.     "-",        { EV_TYPE_KEYBD, 0, XK_minus },
  218.     ".",        { EV_TYPE_KEYBD, 0, XK_period },
  219.     "/",        { EV_TYPE_KEYBD, 0, XK_slash },
  220.     ":",        { EV_TYPE_KEYBD, 0, XK_colon },
  221.     ";",        { EV_TYPE_KEYBD, 0, XK_semicolon },
  222.     "<",        { EV_TYPE_KEYBD, 0, XK_less },
  223.     "=",        { EV_TYPE_KEYBD, 0, XK_equal },
  224.     ">",        { EV_TYPE_KEYBD, 0, XK_greater },
  225.     "?",        { EV_TYPE_KEYBD, 0, XK_question },
  226.     "@",        { EV_TYPE_KEYBD, 0, XK_at },
  227.     "[",        { EV_TYPE_KEYBD, 0, XK_bracketleft },
  228.     "\\",       { EV_TYPE_KEYBD, 0, XK_backslash },
  229.     "]",        { EV_TYPE_KEYBD, 0, XK_bracketright },
  230.     "^",        { EV_TYPE_KEYBD, 0, XK_asciicircum },
  231.     "_",        { EV_TYPE_KEYBD, 0, XK_underscore },
  232.     "`",        { EV_TYPE_KEYBD, 0, XK_quoteleft },
  233.     "{",        { EV_TYPE_KEYBD, 0, XK_braceleft },
  234.     "|",        { EV_TYPE_KEYBD, 0, XK_bar },
  235.     "}",        { EV_TYPE_KEYBD, 0, XK_braceright },
  236.     "~",        { EV_TYPE_KEYBD, 0, XK_asciitilde },
  237.     "£",        { EV_TYPE_KEYBD, 0, XK_sterling },
  238.  
  239.     /* mouse events
  240.      */
  241.     "CLICK1",   { EV_TYPE_MOUSE, 0, EV_CODE_MOUSE_CLICK1 },
  242.     "CLICK2",   { EV_TYPE_MOUSE, 0, EV_CODE_MOUSE_CLICK2 },
  243.     "OFF",      { EV_TYPE_MOUSE, 0, EV_CODE_MOUSE_UP },
  244.     "MOVE",     { EV_TYPE_MOUSE, 0, EV_CODE_MOUSE_MOVE },
  245.  
  246.     NULL, 0, 0
  247. };
  248.  
  249. /*
  250.  */
  251. bool
  252. lookupevent(EventDef *ie, u_char *desc)
  253. {
  254.     u_char *str = desc;
  255.     bool rc = TRUE;
  256.     for(;;)
  257.     {
  258.     u_char buff[100];
  259.     u_char *tmp = buff;
  260.     u_char c;
  261.     const KeyDesc *kd = KeyDescr;
  262.     /*
  263.      * get this one token
  264.      */
  265.     while((c = *str) && (c != '-') && (c != ' '))
  266.     {
  267.         if(c == '\\')
  268.         str++;
  269.         *tmp++ = *str++;
  270.     }
  271.     *tmp = 0;
  272.     if(*str)
  273.         str++;
  274.     while(kd->kd_Name)
  275.     {
  276.         if(!strcasecmp(kd->kd_Name, buff))
  277.         {
  278.         ie->evd_Type = kd->kd_Event.evd_Type;
  279.         ie->evd_Mods |= kd->kd_Event.evd_Mods;
  280.         ie->evd_Code = kd->kd_Event.evd_Code;
  281.         if(ie->evd_Type)
  282.             goto end;
  283.         break;
  284.         }
  285.         kd++;
  286.     }
  287.     if(!kd->kd_Name)
  288.     {
  289.         unsigned int ks;
  290.         if((ks = XStringToKeysym(buff)) != NoSymbol)
  291.         {
  292.         ie->evd_Type = EV_TYPE_KEYBD;
  293.         ie->evd_Code = ks;
  294.         goto end;
  295.         }
  296.         else
  297.         {
  298.         cmd_signal(sym_bad_event_desc, LIST_1(valstrdup(desc)));
  299.         rc = FALSE;
  300.         goto end;
  301.         }
  302.     }
  303.     }
  304. end:
  305.     return(rc);
  306. }
  307.