"Fossies" - the Fresh Open Source Software Archive

Member "PDCurses-3.9/os2/pdckbd.c" (4 Sep 2019, 13039 Bytes) of package /linux/misc/PDCurses-3.9.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pdckbd.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.8_vs_3.9.

    1 /* PDCurses */
    2 
    3 #if defined(__EMX__) || defined(__WATCOMC__) || defined(__IBMC__) || \
    4 defined(__TURBOC__)
    5 # define HAVE_SIGNAL
    6 # include <signal.h>
    7 #endif
    8 
    9 #include "pdcos2.h"
   10 
   11 /*man-start**************************************************************
   12 
   13 pdckbd
   14 ------
   15 
   16 ### Synopsis
   17 
   18     unsigned long PDC_get_input_fd(void);
   19 
   20 ### Description
   21 
   22    PDC_get_input_fd() returns the file descriptor that PDCurses reads
   23    its input from. It can be used for select().
   24 
   25 ### Portability
   26                              X/Open  ncurses  NetBSD
   27     PDC_get_input_fd            -       -       -
   28 
   29 **man-end****************************************************************/
   30 
   31 static KBDINFO kbdinfo;     /* default keyboard mode */
   32 static HMOU mouse_handle = 0;
   33 static MOUSE_STATUS old_mouse_status;
   34 static USHORT old_shift = 0;
   35 static bool key_pressed = FALSE;
   36 static int mouse_events = 0;
   37 
   38 /************************************************************************
   39  *    Table for key code translation of function keys in keypad mode    *
   40  *    These values are for strict IBM keyboard compatibles only         *
   41  ************************************************************************/
   42 
   43 static short key_table[] =
   44 {
   45     -1,             ALT_ESC,        -1,             0,
   46     -1,             -1,             -1,             -1,
   47     -1,             -1,             -1,             -1,
   48     -1,             -1,             ALT_BKSP,       KEY_BTAB,
   49     ALT_Q,          ALT_W,          ALT_E,          ALT_R,
   50     ALT_T,          ALT_Y,          ALT_U,          ALT_I,
   51     ALT_O,          ALT_P,          ALT_LBRACKET,   ALT_RBRACKET,
   52     ALT_ENTER,      -1,             ALT_A,          ALT_S,
   53     ALT_D,          ALT_F,          ALT_G,          ALT_H,
   54     ALT_J,          ALT_K,          ALT_L,          ALT_SEMICOLON,
   55     ALT_FQUOTE,     ALT_BQUOTE,     -1,             ALT_BSLASH,
   56     ALT_Z,          ALT_X,          ALT_C,          ALT_V,
   57     ALT_B,          ALT_N,          ALT_M,          ALT_COMMA,
   58     ALT_STOP,       ALT_FSLASH,     -1,             ALT_PADSTAR,
   59     -1,             -1,             -1,             KEY_F(1),
   60     KEY_F(2),       KEY_F(3),       KEY_F(4),       KEY_F(5),
   61     KEY_F(6),       KEY_F(7),       KEY_F(8),       KEY_F(9),
   62     KEY_F(10),      -1,             -1,             KEY_HOME,
   63     KEY_UP,         KEY_PPAGE,      ALT_PADMINUS,   KEY_LEFT,
   64     KEY_B2,         KEY_RIGHT,      ALT_PADPLUS,    KEY_END,
   65     KEY_DOWN,       KEY_NPAGE,      KEY_IC,         KEY_DC,
   66     KEY_F(13),      KEY_F(14),      KEY_F(15),      KEY_F(16),
   67     KEY_F(17),      KEY_F(18),      KEY_F(19),      KEY_F(20),
   68     KEY_F(21),      KEY_F(22),      KEY_F(25),      KEY_F(26),
   69     KEY_F(27),      KEY_F(28),      KEY_F(29),      KEY_F(30),
   70     KEY_F(31),      KEY_F(32),      KEY_F(33),      KEY_F(34),
   71     KEY_F(37),      KEY_F(38),      KEY_F(39),      KEY_F(40),
   72     KEY_F(41),      KEY_F(42),      KEY_F(43),      KEY_F(44),
   73     KEY_F(45),      KEY_F(46),      -1,             CTL_LEFT,
   74     CTL_RIGHT,      CTL_END,        CTL_PGDN,       CTL_HOME,
   75     ALT_1,          ALT_2,          ALT_3,          ALT_4,
   76     ALT_5,          ALT_6,          ALT_7,          ALT_8,
   77     ALT_9,          ALT_0,          ALT_MINUS,      ALT_EQUAL,
   78     CTL_PGUP,       KEY_F(11),      KEY_F(12),      KEY_F(23),
   79     KEY_F(24),      KEY_F(35),      KEY_F(36),      KEY_F(47),
   80     KEY_F(48),      CTL_UP,         CTL_PADMINUS,   CTL_PADCENTER,
   81     CTL_PADPLUS,    CTL_DOWN,       CTL_INS,        CTL_DEL,
   82     CTL_TAB,        CTL_PADSLASH,   CTL_PADSTAR,    ALT_HOME,
   83     ALT_UP,         ALT_PGUP,       -1,             ALT_LEFT,
   84     -1,             ALT_RIGHT,      -1,             ALT_END,
   85     ALT_DOWN,       ALT_PGDN,       ALT_INS,        ALT_DEL,
   86     ALT_PADSLASH,   ALT_TAB,        ALT_PADENTER,   -1
   87 };
   88 
   89 unsigned long PDC_get_input_fd(void)
   90 {
   91     PDC_LOG(("PDC_get_input_fd() - called\n"));
   92 
   93     return (unsigned long)fileno(stdin);
   94 }
   95 
   96 void PDC_get_keyboard_info(void)
   97 {
   98     kbdinfo.cb = sizeof(kbdinfo);
   99     KbdGetStatus(&kbdinfo, 0);
  100 }
  101 
  102 void PDC_set_keyboard_default(void)
  103 {
  104     KbdSetStatus(&kbdinfo, 0);
  105 }
  106 
  107 void PDC_set_keyboard_binary(bool on)
  108 {
  109     PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
  110 
  111     if (on)
  112     {
  113         kbdinfo.fsMask &= ~(KEYBOARD_ASCII_MODE);
  114         kbdinfo.fsMask |= KEYBOARD_BINARY_MODE;
  115     }
  116     else
  117     {
  118         kbdinfo.fsMask &= ~(KEYBOARD_BINARY_MODE);
  119         kbdinfo.fsMask |= KEYBOARD_ASCII_MODE;
  120     }
  121 
  122     KbdSetStatus(&kbdinfo, 0);
  123 
  124 #ifdef HAVE_SIGNAL
  125     signal(SIGBREAK, on ? SIG_IGN : SIG_DFL);
  126 #endif
  127 }
  128 
  129 /* check if a key or mouse event is waiting */
  130 
  131 bool PDC_check_key(void)
  132 {
  133     KBDKEYINFO keyInfo = {0};
  134 
  135     KbdGetStatus(&kbdinfo, 0);
  136 
  137     if (mouse_handle)
  138     {
  139         MOUQUEINFO queue;
  140 
  141         MouGetNumQueEl(&queue, mouse_handle);
  142         mouse_events = queue.cEvents;
  143 
  144         if (mouse_events)
  145             return TRUE;
  146     }
  147 
  148     if (old_shift && !kbdinfo.fsState)  /* modifier released */
  149     {
  150         if (!key_pressed && SP->return_key_modifiers)
  151             return TRUE;
  152     }
  153     else if (!old_shift && kbdinfo.fsState) /* modifier pressed */
  154         key_pressed = FALSE;
  155 
  156     old_shift = kbdinfo.fsState;
  157 
  158     KbdPeek(&keyInfo, 0);   /* peek at keyboard  */
  159     return (keyInfo.fbStatus != 0);
  160 }
  161 
  162 static int _process_mouse_events(void)
  163 {
  164     MOUEVENTINFO event;
  165     static const USHORT button_mask[] = {6, 96, 24},
  166                         move_mask[] = {2, 32, 8},
  167                         press_mask[] = {4, 64, 16};
  168     USHORT count = 1;
  169     short shift_flags = 0;
  170     int i;
  171 
  172     MouReadEventQue(&event, &count, mouse_handle);
  173     mouse_events--;
  174 
  175     for (i = 0; i < 3; i++)
  176     {
  177         SP->mouse_status.button[i] =
  178             ((event.fs & move_mask[i]) ? BUTTON_MOVED : 0) |
  179             ((event.fs & press_mask[i]) ? BUTTON_PRESSED : 0);
  180 
  181         /* PRESS events are sometimes mistakenly reported as MOVE
  182            events. A MOVE should always follow a PRESS, so treat a MOVE
  183            immediately after a RELEASE as a PRESS. */
  184 
  185         if ((SP->mouse_status.button[i] == BUTTON_MOVED) &&
  186             (old_mouse_status.button[i] == BUTTON_RELEASED))
  187         {
  188             SP->mouse_status.button[i] = BUTTON_PRESSED;
  189         }
  190 
  191         if (SP->mouse_status.button[i] == BUTTON_PRESSED && SP->mouse_wait)
  192         {
  193             /* Check for a click -- a PRESS followed immediately by a
  194                release */
  195 
  196             if (!mouse_events)
  197             {
  198                 MOUQUEINFO queue;
  199 
  200                 napms(SP->mouse_wait);
  201 
  202                 MouGetNumQueEl(&queue, mouse_handle);
  203                 mouse_events = queue.cEvents;
  204             }
  205 
  206             if (mouse_events)
  207             {
  208                 MouReadEventQue(&event, &count, mouse_handle);
  209 
  210                 if (!(event.fs & button_mask[i]))
  211                     SP->mouse_status.button[i] = BUTTON_CLICKED;
  212             }
  213         }
  214     }
  215 
  216     SP->mouse_status.x = event.col;
  217     SP->mouse_status.y = event.row;
  218 
  219     SP->mouse_status.changes = 0;
  220 
  221     for (i = 0; i < 3; i++)
  222     {
  223         if (old_mouse_status.button[i] != SP->mouse_status.button[i])
  224             SP->mouse_status.changes |= (1 << i);
  225 
  226         if (SP->mouse_status.button[i] == BUTTON_MOVED)
  227         {
  228             /* Discard non-moved "moves" */
  229 
  230             if (SP->mouse_status.x == old_mouse_status.x &&
  231                 SP->mouse_status.y == old_mouse_status.y)
  232                 return -1;
  233 
  234             /* Motion events always flag the button as changed */
  235 
  236             SP->mouse_status.changes |= (1 << i);
  237             SP->mouse_status.changes |= PDC_MOUSE_MOVED;
  238             break;
  239         }
  240     }
  241 
  242     old_mouse_status = SP->mouse_status;
  243 
  244     /* Treat click events as release events for comparison purposes */
  245 
  246     for (i = 0; i < 3; i++)
  247     {
  248         if (old_mouse_status.button[i] == BUTTON_CLICKED)
  249             old_mouse_status.button[i] = BUTTON_RELEASED;
  250     }
  251 
  252     /* Check for SHIFT/CONTROL/ALT */
  253 
  254     if (kbdinfo.fsState & KBDSTF_ALT)
  255         shift_flags |= BUTTON_ALT;
  256 
  257     if (kbdinfo.fsState & KBDSTF_CONTROL)
  258         shift_flags |= BUTTON_CONTROL;
  259 
  260     if (kbdinfo.fsState & (KBDSTF_LEFTSHIFT|KBDSTF_RIGHTSHIFT))
  261         shift_flags |= BUTTON_SHIFT;
  262 
  263     if (shift_flags)
  264     {
  265         for (i = 0; i < 3; i++)
  266         {
  267             if (SP->mouse_status.changes & (1 << i))
  268                 SP->mouse_status.button[i] |= shift_flags;
  269         }
  270     }
  271 
  272     old_shift = kbdinfo.fsState;
  273     key_pressed = TRUE;
  274 
  275     SP->key_code = TRUE;
  276     return KEY_MOUSE;
  277 }
  278 
  279 /* return the next available key or mouse event */
  280 
  281 int PDC_get_key(void)
  282 {
  283     int key, scan;
  284     KBDKEYINFO keyInfo = {0};
  285 
  286     SP->key_modifiers = 0L;
  287 
  288     if (mouse_handle && mouse_events)
  289         return _process_mouse_events();
  290 
  291     if (old_shift && !kbdinfo.fsState)
  292     {
  293         key = -1;
  294 
  295         if (old_shift & KBDSTF_LEFTALT)
  296         {
  297             key = KEY_ALT_L;
  298         }
  299         else if (old_shift & KBDSTF_RIGHTALT)
  300         {
  301             key = KEY_ALT_R;
  302         }
  303         else if (old_shift & KBDSTF_LEFTCONTROL)
  304         {
  305             key = KEY_CONTROL_L;
  306         }
  307         else if (old_shift & KBDSTF_RIGHTCONTROL)
  308         {
  309             key = KEY_CONTROL_R;
  310         }
  311         else if (old_shift & KBDSTF_LEFTSHIFT)
  312         {
  313             key = KEY_SHIFT_L;
  314         }
  315         else if (old_shift & KBDSTF_RIGHTSHIFT)
  316         {
  317             key = KEY_SHIFT_R;
  318         }
  319 
  320         key_pressed = FALSE;
  321         old_shift = kbdinfo.fsState;
  322 
  323         SP->key_code = TRUE;
  324         return key;
  325     }
  326 
  327     KbdCharIn(&keyInfo, IO_WAIT, 0);    /* get a character */
  328 
  329     key = keyInfo.chChar;
  330     scan = keyInfo.chScan;
  331 
  332     if (keyInfo.fsState & KBDSTF_ALT)
  333         SP->key_modifiers |= PDC_KEY_MODIFIER_ALT;
  334 
  335     if (keyInfo.fsState & KBDSTF_CONTROL)
  336         SP->key_modifiers |= PDC_KEY_MODIFIER_CONTROL;
  337 
  338     if (keyInfo.fsState & KBDSTF_NUMLOCK_ON)
  339         SP->key_modifiers |= PDC_KEY_MODIFIER_NUMLOCK;
  340 
  341     if (keyInfo.fsState & (KBDSTF_LEFTSHIFT|KBDSTF_RIGHTSHIFT))
  342         SP->key_modifiers |= PDC_KEY_MODIFIER_SHIFT;
  343 
  344     if (scan == 0x1c && key == 0x0a)    /* ^Enter */
  345         key = CTL_ENTER;
  346     else if (scan == 0xe0 && key == 0x0d)   /* PadEnter */
  347         key = PADENTER;
  348     else if (scan == 0xe0 && key == 0x0a)   /* ^PadEnter */
  349         key = CTL_PADENTER;
  350     else if (scan == 0x37 && key == 0x2a)   /* Star */
  351         key = PADSTAR;
  352     else if (scan == 0x4a && key == 0x2d)   /* Minus */
  353         key = PADMINUS;
  354     else if (scan == 0x4e && key == 0x2b)   /* Plus */
  355         key = PADPLUS;
  356     else if (scan == 0xe0 && key == 0x2f)   /* Slash */
  357         key = PADSLASH;
  358     else if (key == 0x00 || (key == 0xe0 && scan > 53 && scan != 86))
  359         key = (scan > 0xa7) ? -1 : key_table[scan];
  360 
  361     if (keyInfo.fsState & (KBDSTF_LEFTSHIFT|KBDSTF_RIGHTSHIFT))
  362     {
  363         switch (key)
  364         {
  365         case KEY_HOME:  /* Shift Home */
  366             key = KEY_SHOME;
  367             break;
  368         case KEY_UP:    /* Shift Up */
  369             key = KEY_SUP;
  370             break;
  371         case KEY_PPAGE: /* Shift PgUp */
  372             key = KEY_SPREVIOUS;
  373             break;
  374         case KEY_LEFT:  /* Shift Left */
  375             key = KEY_SLEFT;
  376             break;
  377         case KEY_RIGHT: /* Shift Right */
  378             key = KEY_SRIGHT;
  379             break;
  380         case KEY_END:   /* Shift End */
  381             key = KEY_SEND;
  382             break;
  383         case KEY_DOWN:  /* Shift Down */
  384             key = KEY_SDOWN;
  385             break;
  386         case KEY_NPAGE: /* Shift PgDn */
  387             key = KEY_SNEXT;
  388             break;
  389         case KEY_IC:    /* Shift Ins */
  390             key = KEY_SIC;
  391             break;
  392         case KEY_DC:    /* Shift Del */
  393             key = KEY_SDC;
  394         }
  395     }
  396 
  397     key_pressed = TRUE;
  398     SP->key_code = ((unsigned)key >= 256);
  399 
  400     return key;
  401 }
  402 
  403 /* discard any pending keyboard or mouse input -- this is the core
  404    routine for flushinp() */
  405 
  406 void PDC_flushinp(void)
  407 {
  408     PDC_LOG(("PDC_flushinp() - called\n"));
  409 
  410     if (mouse_handle)
  411         MouFlushQue(mouse_handle);
  412 
  413     KbdFlushBuffer(0);
  414 }
  415 
  416 bool PDC_has_mouse(void)
  417 {
  418     if (!mouse_handle)
  419     {
  420         memset(&old_mouse_status, 0, sizeof(MOUSE_STATUS));
  421         MouOpen(NULL, &mouse_handle);
  422     }
  423 
  424     return !!mouse_handle;
  425 }
  426 
  427 int PDC_mouse_set(void)
  428 {
  429     unsigned long mbe = SP->_trap_mbe;
  430 
  431     if (mbe && !mouse_handle)
  432     {
  433         if (PDC_has_mouse())
  434             MouDrawPtr(mouse_handle);
  435     }
  436     else if (!mbe && mouse_handle)
  437     {
  438         MouClose(mouse_handle);
  439         mouse_handle = 0;
  440     }
  441 
  442     if (mbe && mouse_handle)
  443     {
  444         USHORT mask = ((mbe & (BUTTON1_PRESSED | BUTTON1_CLICKED |
  445                                BUTTON1_MOVED)) ? 6 : 0) |
  446 
  447                       ((mbe & (BUTTON3_PRESSED | BUTTON3_CLICKED |
  448                                BUTTON3_MOVED)) ? 24 : 0) |
  449 
  450                       ((mbe & (BUTTON2_PRESSED | BUTTON2_CLICKED |
  451                                BUTTON2_MOVED)) ? 96 : 0);
  452 
  453         MouSetEventMask(&mask, mouse_handle);
  454     }
  455 
  456     return OK;
  457 }
  458 
  459 int PDC_modifiers_set(void)
  460 {
  461     key_pressed = FALSE;
  462 
  463     return OK;
  464 }