Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* PDCurses */
  2.  
  3. #include "pdcsdl.h"
  4.  
  5. #include <string.h>
  6.  
  7. static SDL_Event event;
  8. static SDLKey oldkey;
  9. static MOUSE_STATUS old_mouse_status;
  10.  
  11. static struct
  12. {
  13.     SDLKey keycode;
  14.     bool numkeypad;
  15.     unsigned short normal;
  16.     unsigned short shifted;
  17.     unsigned short control;
  18.     unsigned short alt;
  19. } key_table[] =
  20. {
  21. /* keycode      keypad  normal       shifted       control      alt*/
  22.  {SDLK_LEFT,    FALSE,  KEY_LEFT,    KEY_SLEFT,    CTL_LEFT,    ALT_LEFT},
  23.  {SDLK_RIGHT,   FALSE,  KEY_RIGHT,   KEY_SRIGHT,   CTL_RIGHT,   ALT_RIGHT},
  24.  {SDLK_UP,      FALSE,  KEY_UP,      KEY_SUP,      CTL_UP,      ALT_UP},
  25.  {SDLK_DOWN,    FALSE,  KEY_DOWN,    KEY_SDOWN,    CTL_DOWN,    ALT_DOWN},
  26.  {SDLK_HOME,    FALSE,  KEY_HOME,    KEY_SHOME,    CTL_HOME,    ALT_HOME},
  27.  {SDLK_END,     FALSE,  KEY_END,     KEY_SEND,     CTL_END,     ALT_END},
  28.  {SDLK_PAGEUP,  FALSE,  KEY_PPAGE,   KEY_SPREVIOUS,CTL_PGUP,    ALT_PGUP},
  29.  {SDLK_PAGEDOWN,FALSE,  KEY_NPAGE,   KEY_SNEXT,    CTL_PGDN,    ALT_PGDN},
  30.  {SDLK_INSERT,  FALSE,  KEY_IC,      KEY_SIC,      CTL_INS,     ALT_INS},
  31.  {SDLK_DELETE,  FALSE,  KEY_DC,      KEY_SDC,      CTL_DEL,     ALT_DEL},
  32.  {SDLK_F1,      FALSE,  KEY_F(1),    KEY_F(13),    KEY_F(25),   KEY_F(37)},
  33.  {SDLK_F2,      FALSE,  KEY_F(2),    KEY_F(14),    KEY_F(26),   KEY_F(38)},
  34.  {SDLK_F3,      FALSE,  KEY_F(3),    KEY_F(15),    KEY_F(27),   KEY_F(39)},
  35.  {SDLK_F4,      FALSE,  KEY_F(4),    KEY_F(16),    KEY_F(28),   KEY_F(40)},
  36.  {SDLK_F5,      FALSE,  KEY_F(5),    KEY_F(17),    KEY_F(29),   KEY_F(41)},
  37.  {SDLK_F6,      FALSE,  KEY_F(6),    KEY_F(18),    KEY_F(30),   KEY_F(42)},
  38.  {SDLK_F7,      FALSE,  KEY_F(7),    KEY_F(19),    KEY_F(31),   KEY_F(43)},
  39.  {SDLK_F8,      FALSE,  KEY_F(8),    KEY_F(20),    KEY_F(32),   KEY_F(44)},
  40.  {SDLK_F9,      FALSE,  KEY_F(9),    KEY_F(21),    KEY_F(33),   KEY_F(45)},
  41.  {SDLK_F10,     FALSE,  KEY_F(10),   KEY_F(22),    KEY_F(34),   KEY_F(46)},
  42.  {SDLK_F11,     FALSE,  KEY_F(11),   KEY_F(23),    KEY_F(35),   KEY_F(47)},
  43.  {SDLK_F12,     FALSE,  KEY_F(12),   KEY_F(24),    KEY_F(36),   KEY_F(48)},
  44.  {SDLK_F13,     FALSE,  KEY_F(13),   KEY_F(25),    KEY_F(37),   KEY_F(49)},
  45.  {SDLK_F14,     FALSE,  KEY_F(14),   KEY_F(26),    KEY_F(38),   KEY_F(50)},
  46.  {SDLK_F15,     FALSE,  KEY_F(15),   KEY_F(27),    KEY_F(39),   KEY_F(51)},
  47.  {SDLK_BACKSPACE,FALSE, 0x08,        0x08,         CTL_BKSP,    ALT_BKSP},
  48.  {SDLK_TAB,     FALSE,  0x09,        KEY_BTAB,     CTL_TAB,     ALT_TAB},
  49.  {SDLK_PRINT,   FALSE,  KEY_PRINT,   KEY_SPRINT,   KEY_PRINT,   KEY_PRINT},
  50.  {SDLK_PAUSE,   FALSE,  KEY_SUSPEND, KEY_SSUSPEND, KEY_SUSPEND, KEY_SUSPEND},
  51.  {SDLK_CLEAR,   FALSE,  KEY_CLEAR,   KEY_CLEAR,    KEY_CLEAR,   KEY_CLEAR},
  52.  {SDLK_BREAK,   FALSE,  KEY_BREAK,   KEY_BREAK,    KEY_BREAK,   KEY_BREAK},
  53.  {SDLK_HELP,    FALSE,  KEY_HELP,    KEY_SHELP,    KEY_LHELP,   KEY_HELP},
  54.  {SDLK_MENU,    FALSE,  KEY_OPTIONS, KEY_SOPTIONS, KEY_OPTIONS, KEY_OPTIONS},
  55.  {SDLK_ESCAPE,  FALSE,  0x1B,        0x1B,         0x1B,        ALT_ESC},
  56.  {SDLK_KP_ENTER,TRUE,   PADENTER,    PADENTER,     CTL_PADENTER,ALT_PADENTER},
  57.  {SDLK_KP_PLUS, TRUE,   PADPLUS,     '+',          CTL_PADPLUS, ALT_PADPLUS},
  58.  {SDLK_KP_MINUS,TRUE,   PADMINUS,    '-',          CTL_PADMINUS,ALT_PADMINUS},
  59.  {SDLK_KP_MULTIPLY,TRUE,PADSTAR,     '*',          CTL_PADSTAR, ALT_PADSTAR},
  60.  {SDLK_KP_DIVIDE,TRUE,  PADSLASH,    '/',          CTL_PADSLASH,ALT_PADSLASH},
  61.  {SDLK_KP_PERIOD,TRUE,  PADSTOP,     '.',          CTL_PADSTOP, ALT_PADSTOP},
  62.  {SDLK_KP0,     TRUE,   PAD0,        '0',          CTL_PAD0,    ALT_PAD0},
  63.  {SDLK_KP1,     TRUE,   KEY_C1,      '1',          CTL_PAD1,    ALT_PAD1},
  64.  {SDLK_KP2,     TRUE,   KEY_C2,      '2',          CTL_PAD2,    ALT_PAD2},
  65.  {SDLK_KP3,     TRUE,   KEY_C3,      '3',          CTL_PAD3,    ALT_PAD3},
  66.  {SDLK_KP4,     TRUE,   KEY_B1,      '4',          CTL_PAD4,    ALT_PAD4},
  67.  {SDLK_KP5,     TRUE,   KEY_B2,      '5',          CTL_PAD5,    ALT_PAD5},
  68.  {SDLK_KP6,     TRUE,   KEY_B3,      '6',          CTL_PAD6,    ALT_PAD6},
  69.  {SDLK_KP7,     TRUE,   KEY_A1,      '7',          CTL_PAD7,    ALT_PAD7},
  70.  {SDLK_KP8,     TRUE,   KEY_A2,      '8',          CTL_PAD8,    ALT_PAD8},
  71.  {SDLK_KP9,     TRUE,   KEY_A3,      '9',          CTL_PAD9,    ALT_PAD9},
  72.  {0,            0,      0,           0,            0,           0}
  73. };
  74.  
  75. void PDC_set_keyboard_binary(bool on)
  76. {
  77.     PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
  78. }
  79.  
  80. /* check if a key or mouse event is waiting */
  81.  
  82. bool PDC_check_key(void)
  83. {
  84.     int haveevent = SDL_PollEvent(&event);
  85.  
  86.     return haveevent;
  87. }
  88.  
  89. static int _process_key_event(void)
  90. {
  91.     int i, key = 0;
  92.  
  93.     SP->key_modifiers = 0L;
  94.     SP->key_code = FALSE;
  95.  
  96.     if (event.type == SDL_KEYUP)
  97.     {
  98.         if (SP->return_key_modifiers && event.key.keysym.sym == oldkey)
  99.         {
  100.             SP->key_code = TRUE;
  101.  
  102.             switch (oldkey)
  103.             {
  104.             case SDLK_RSHIFT:
  105.                 return KEY_SHIFT_R;
  106.             case SDLK_LSHIFT:
  107.                 return KEY_SHIFT_L;
  108.             case SDLK_RCTRL:
  109.                 return KEY_CONTROL_R;
  110.             case SDLK_LCTRL:
  111.                 return KEY_CONTROL_L;
  112.             case SDLK_RALT:
  113.                 return KEY_ALT_R;
  114.             case SDLK_LALT:
  115.                 return KEY_ALT_L;
  116.             default:
  117.                 break;
  118.             }
  119.  
  120.             SP->key_code = FALSE;
  121.         }
  122.  
  123.         return -1;
  124.     }
  125.  
  126.     oldkey = event.key.keysym.sym;
  127.  
  128.     if (event.key.keysym.mod & KMOD_NUM)
  129.         SP->key_modifiers |= PDC_KEY_MODIFIER_NUMLOCK;
  130.  
  131.     if (event.key.keysym.mod & KMOD_SHIFT)
  132.         SP->key_modifiers |= PDC_KEY_MODIFIER_SHIFT;
  133.  
  134.     if (event.key.keysym.mod & KMOD_CTRL)
  135.         SP->key_modifiers |= PDC_KEY_MODIFIER_CONTROL;
  136.  
  137.     if (event.key.keysym.mod & KMOD_ALT)
  138.         SP->key_modifiers |= PDC_KEY_MODIFIER_ALT;
  139.  
  140.     for (i = 0; key_table[i].keycode; i++)
  141.     {
  142.         if (key_table[i].keycode == event.key.keysym.sym)
  143.         {
  144.             if ((event.key.keysym.mod & KMOD_SHIFT) ||
  145.                 (key_table[i].numkeypad && (event.key.keysym.mod & KMOD_NUM)))
  146.             {
  147.                 key = key_table[i].shifted;
  148.             }
  149.             else if (event.key.keysym.mod & KMOD_CTRL)
  150.             {
  151.                 key = key_table[i].control;
  152.             }
  153.             else if (event.key.keysym.mod & KMOD_ALT)
  154.             {
  155.                 key = key_table[i].alt;
  156.             }
  157.  
  158.             /* To get here, we ignore all other modifiers */
  159.  
  160.             else
  161.                 key = key_table[i].normal;
  162.  
  163.             SP->key_code = (key > 0x100);
  164.             break;
  165.         }
  166.     }
  167.  
  168.     if (!key)
  169.     {
  170.         key = event.key.keysym.unicode;
  171.  
  172.         if (key > 0x7f)
  173.             key = 0;
  174.     }
  175.  
  176.     /* Handle ALT letters and numbers */
  177.  
  178.     if (event.key.keysym.mod & KMOD_ALT)
  179.     {
  180.         if (key >= 'A' && key <= 'Z')
  181.         {
  182.             key += ALT_A - 'A';
  183.             SP->key_code = TRUE;
  184.         }
  185.  
  186.         if (key >= 'a' && key <= 'z')
  187.         {
  188.             key += ALT_A - 'a';
  189.             SP->key_code = TRUE;
  190.         }
  191.  
  192.         if (key >= '0' && key <= '9')
  193.         {
  194.             key += ALT_0 - '0';
  195.             SP->key_code = TRUE;
  196.         }
  197.     }
  198.  
  199.     return key ? key : -1;
  200. }
  201.  
  202. static int _process_mouse_event(void)
  203. {
  204.     SDLMod keymods;
  205.     short shift_flags = 0;
  206.  
  207.     memset(&SP->mouse_status, 0, sizeof(MOUSE_STATUS));
  208.  
  209.     keymods = SDL_GetModState();
  210.  
  211.     if (keymods & KMOD_SHIFT)
  212.         shift_flags |= BUTTON_SHIFT;
  213.  
  214.     if (keymods & KMOD_CTRL)
  215.         shift_flags |= BUTTON_CONTROL;
  216.  
  217.     if (keymods & KMOD_ALT)
  218.         shift_flags |= BUTTON_ALT;
  219.  
  220.     if (event.type == SDL_MOUSEMOTION)
  221.     {
  222.         int i;
  223.  
  224.         SP->mouse_status.x = (event.motion.x - pdc_xoffset) / pdc_fwidth;
  225.         SP->mouse_status.y = (event.motion.y - pdc_yoffset) / pdc_fheight;
  226.  
  227.         if (!event.motion.state ||
  228.            (SP->mouse_status.x == old_mouse_status.x &&
  229.             SP->mouse_status.y == old_mouse_status.y))
  230.             return -1;
  231.  
  232.         SP->mouse_status.changes = PDC_MOUSE_MOVED;
  233.  
  234.         for (i = 0; i < 3; i++)
  235.         {
  236.             if (event.motion.state & SDL_BUTTON(i + 1))
  237.             {
  238.                 SP->mouse_status.button[i] = BUTTON_MOVED | shift_flags;
  239.                 SP->mouse_status.changes |= (1 << i);
  240.             }
  241.         }
  242.     }
  243.     else
  244.     {
  245.         short action = (event.button.state == SDL_PRESSED) ?
  246.                        BUTTON_PRESSED : BUTTON_RELEASED;
  247.         Uint8 btn = event.button.button;
  248.  
  249.         /* handle scroll wheel */
  250.  
  251.         if ((btn >= 4 && btn <= 7) && action == BUTTON_RELEASED)
  252.         {
  253.             SP->mouse_status.x = SP->mouse_status.y = -1;
  254.  
  255.             switch (btn)
  256.             {
  257.             case 4:
  258.                 SP->mouse_status.changes = PDC_MOUSE_WHEEL_UP;
  259.                 break;
  260.             case 5:
  261.                 SP->mouse_status.changes = PDC_MOUSE_WHEEL_DOWN;
  262.                 break;
  263.             case 6:
  264.                 SP->mouse_status.changes = PDC_MOUSE_WHEEL_LEFT;
  265.                 break;
  266.             case 7:
  267.                 SP->mouse_status.changes = PDC_MOUSE_WHEEL_RIGHT;
  268.             }
  269.  
  270.             SP->key_code = TRUE;
  271.             return KEY_MOUSE;
  272.         }
  273.  
  274.         if (btn < 1 || btn > 3)
  275.             return -1;
  276.  
  277.         /* check for a click -- a press followed immediately by a release */
  278.  
  279.         if (action == BUTTON_PRESSED && SP->mouse_wait)
  280.         {
  281.             SDL_Event rel;
  282.  
  283.             napms(SP->mouse_wait);
  284.  
  285.             if (SDL_PollEvent(&rel))
  286.             {
  287.                 if (rel.type == SDL_MOUSEBUTTONUP && rel.button.button == btn)
  288.                     action = BUTTON_CLICKED;
  289.                 else
  290.                     SDL_PushEvent(&rel);
  291.             }
  292.         }
  293.  
  294.         SP->mouse_status.x = (event.button.x - pdc_xoffset) / pdc_fwidth;
  295.         SP->mouse_status.y = (event.button.y - pdc_yoffset) / pdc_fheight;
  296.  
  297.         btn--;
  298.  
  299.         SP->mouse_status.button[btn] = action | shift_flags;
  300.         SP->mouse_status.changes = (1 << btn);
  301.     }
  302.  
  303.     old_mouse_status = SP->mouse_status;
  304.  
  305.     SP->key_code = TRUE;
  306.     return KEY_MOUSE;
  307. }
  308.  
  309. /* return the next available key or mouse event */
  310.  
  311. int PDC_get_key(void)
  312. {
  313.     switch (event.type)
  314.     {
  315.     case SDL_QUIT:
  316.         exit(1);
  317.     case SDL_VIDEORESIZE:
  318.         if (pdc_own_screen &&
  319.            (event.resize.h / pdc_fheight != LINES ||
  320.             event.resize.w / pdc_fwidth != COLS))
  321.         {
  322.             pdc_sheight = event.resize.h;
  323.             pdc_swidth = event.resize.w;
  324.  
  325.             if (!SP->resized)
  326.             {
  327.                 SP->resized = TRUE;
  328.                 SP->key_code = TRUE;
  329.                 return KEY_RESIZE;
  330.             }
  331.         }
  332.         break;
  333.     case SDL_MOUSEMOTION:
  334.         SDL_ShowCursor(SDL_ENABLE);
  335.     case SDL_MOUSEBUTTONUP:
  336.     case SDL_MOUSEBUTTONDOWN:
  337.         oldkey = SDLK_SPACE;
  338.         return _process_mouse_event();
  339.     case SDL_KEYUP:
  340.     case SDL_KEYDOWN:
  341.         PDC_mouse_set();
  342.         return _process_key_event();
  343.     case SDL_USEREVENT:
  344.         PDC_blink_text();
  345.     }
  346.  
  347.     return -1;
  348. }
  349.  
  350. /* discard any pending keyboard or mouse input -- this is the core
  351.    routine for flushinp() */
  352.  
  353. void PDC_flushinp(void)
  354. {
  355.     PDC_LOG(("PDC_flushinp() - called\n"));
  356.  
  357.     while (PDC_check_key());
  358. }
  359.  
  360. bool PDC_has_mouse(void)
  361. {
  362.     return TRUE;
  363. }
  364.  
  365. int PDC_mouse_set(void)
  366. {
  367.     SDL_ShowCursor(SP->_trap_mbe ? SDL_ENABLE : SDL_DISABLE);
  368.  
  369.     return OK;
  370. }
  371.  
  372. int PDC_modifiers_set(void)
  373. {
  374.     return OK;
  375. }
  376.