Change-Id: If881ec130833c7e7e62caa3d31e350a531f5bc8e Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Reviewed-on: http://review.coreboot.org/12398 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
		
			
				
	
	
		
			657 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			657 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Public Domain Curses */
 | |
| 
 | |
| #include "pdcwin.h"
 | |
| 
 | |
| RCSID("$Id: pdckbd.c,v 1.115 2008/07/20 20:12:04 wmcbrine Exp $")
 | |
| 
 | |
| /*man-start**************************************************************
 | |
| 
 | |
|   Name:                                                         pdckbd
 | |
| 
 | |
|   Synopsis:
 | |
|         unsigned long PDC_get_input_fd(void);
 | |
| 
 | |
|   Description:
 | |
|         PDC_get_input_fd() returns the file descriptor that PDCurses
 | |
|         reads its input from. It can be used for select().
 | |
| 
 | |
|   Portability                                X/Open    BSD    SYS V
 | |
|         PDC_get_input_fd                        -       -       -
 | |
| 
 | |
| **man-end****************************************************************/
 | |
| 
 | |
| unsigned long pdc_key_modifiers = 0L;
 | |
| 
 | |
| /* These variables are used to store information about the next
 | |
|    Input Event. */
 | |
| 
 | |
| static INPUT_RECORD save_ip;
 | |
| static MOUSE_STATUS old_mouse_status;
 | |
| static DWORD event_count = 0;
 | |
| static SHORT left_key;
 | |
| static int key_count = 0;
 | |
| static int save_press = 0;
 | |
| 
 | |
| #define KEV save_ip.Event.KeyEvent
 | |
| #define MEV save_ip.Event.MouseEvent
 | |
| 
 | |
| /************************************************************************
 | |
|  *    Table for key code translation of function keys in keypad mode    *
 | |
|  *    These values are for strict IBM keyboard compatibles only         *
 | |
|  ************************************************************************/
 | |
| 
 | |
| typedef struct
 | |
| {
 | |
|     unsigned short normal;
 | |
|     unsigned short shift;
 | |
|     unsigned short control;
 | |
|     unsigned short alt;
 | |
|     unsigned short extended;
 | |
| } KPTAB;
 | |
| 
 | |
| static KPTAB kptab[] =
 | |
| {
 | |
|    {0,          0,         0,           0,          0   }, /* 0  */
 | |
|    {0,          0,         0,           0,          0   }, /* 1   VK_LBUTTON */
 | |
|    {0,          0,         0,           0,          0   }, /* 2   VK_RBUTTON */
 | |
|    {0,          0,         0,           0,          0   }, /* 3   VK_CANCEL  */
 | |
|    {0,          0,         0,           0,          0   }, /* 4   VK_MBUTTON */
 | |
|    {0,          0,         0,           0,          0   }, /* 5   */
 | |
|    {0,          0,         0,           0,          0   }, /* 6   */
 | |
|    {0,          0,         0,           0,          0   }, /* 7   */
 | |
|    {0x08,       0x08,      0x7F,        ALT_BKSP,   0   }, /* 8   VK_BACK    */
 | |
|    {0x09,       KEY_BTAB,  CTL_TAB,     ALT_TAB,    999 }, /* 9   VK_TAB     */
 | |
|    {0,          0,         0,           0,          0   }, /* 10  */
 | |
|    {0,          0,         0,           0,          0   }, /* 11  */
 | |
|    {KEY_B2,     0x35,      CTL_PAD5,    ALT_PAD5,   0   }, /* 12  VK_CLEAR   */
 | |
|    {0x0D,       0x0D,      CTL_ENTER,   ALT_ENTER,  1   }, /* 13  VK_RETURN  */
 | |
|    {0,          0,         0,           0,          0   }, /* 14  */
 | |
|    {0,          0,         0,           0,          0   }, /* 15  */
 | |
|    {0,          0,         0,           0,          0   }, /* 16  VK_SHIFT   HANDLED SEPARATELY */
 | |
|    {0,          0,         0,           0,          0   }, /* 17  VK_CONTROL HANDLED SEPARATELY */
 | |
|    {0,          0,         0,           0,          0   }, /* 18  VK_MENU    HANDLED SEPARATELY */
 | |
|    {0,          0,         0,           0,          0   }, /* 19  VK_PAUSE   */
 | |
|    {0,          0,         0,           0,          0   }, /* 20  VK_CAPITAL HANDLED SEPARATELY */
 | |
|    {0,          0,         0,           0,          0   }, /* 21  VK_HANGUL  */
 | |
|    {0,          0,         0,           0,          0   }, /* 22  */
 | |
|    {0,          0,         0,           0,          0   }, /* 23  VK_JUNJA   */
 | |
|    {0,          0,         0,           0,          0   }, /* 24  VK_FINAL   */
 | |
|    {0,          0,         0,           0,          0   }, /* 25  VK_HANJA   */
 | |
|    {0,          0,         0,           0,          0   }, /* 26  */
 | |
|    {0x1B,       0x1B,      0x1B,        ALT_ESC,    0   }, /* 27  VK_ESCAPE  */
 | |
|    {0,          0,         0,           0,          0   }, /* 28  VK_CONVERT */
 | |
|    {0,          0,         0,           0,          0   }, /* 29  VK_NONCONVERT */
 | |
|    {0,          0,         0,           0,          0   }, /* 30  VK_ACCEPT  */
 | |
|    {0,          0,         0,           0,          0   }, /* 31  VK_MODECHANGE */
 | |
|    {0x20,       0x20,      0x20,        0x20,       0   }, /* 32  VK_SPACE   */
 | |
|    {KEY_A3,     0x39,      CTL_PAD9,    ALT_PAD9,   3   }, /* 33  VK_PRIOR   */
 | |
|    {KEY_C3,     0x33,      CTL_PAD3,    ALT_PAD3,   4   }, /* 34  VK_NEXT    */
 | |
|    {KEY_C1,     0x31,      CTL_PAD1,    ALT_PAD1,   5   }, /* 35  VK_END     */
 | |
|    {KEY_A1,     0x37,      CTL_PAD7,    ALT_PAD7,   6   }, /* 36  VK_HOME    */
 | |
|    {KEY_B1,     0x34,      CTL_PAD4,    ALT_PAD4,   7   }, /* 37  VK_LEFT    */
 | |
|    {KEY_A2,     0x38,      CTL_PAD8,    ALT_PAD8,   8   }, /* 38  VK_UP      */
 | |
|    {KEY_B3,     0x36,      CTL_PAD6,    ALT_PAD6,   9   }, /* 39  VK_RIGHT   */
 | |
|    {KEY_C2,     0x32,      CTL_PAD2,    ALT_PAD2,   10  }, /* 40  VK_DOWN    */
 | |
|    {0,          0,         0,           0,          0   }, /* 41  VK_SELECT  */
 | |
|    {0,          0,         0,           0,          0   }, /* 42  VK_PRINT   */
 | |
|    {0,          0,         0,           0,          0   }, /* 43  VK_EXECUTE */
 | |
|    {0,          0,         0,           0,          0   }, /* 44  VK_SNAPSHOT*/
 | |
|    {PAD0,       0x30,      CTL_PAD0,    ALT_PAD0,   11  }, /* 45  VK_INSERT  */
 | |
|    {PADSTOP,    0x2E,      CTL_PADSTOP, ALT_PADSTOP,12  }, /* 46  VK_DELETE  */
 | |
|    {0,          0,         0,           0,          0   }, /* 47  VK_HELP    */
 | |
|    {0x30,       0x29,      0,           ALT_0,      0   }, /* 48  */
 | |
|    {0x31,       0x21,      0,           ALT_1,      0   }, /* 49  */
 | |
|    {0x32,       0x40,      0,           ALT_2,      0   }, /* 50  */
 | |
|    {0x33,       0x23,      0,           ALT_3,      0   }, /* 51  */
 | |
|    {0x34,       0x24,      0,           ALT_4,      0   }, /* 52  */
 | |
|    {0x35,       0x25,      0,           ALT_5,      0   }, /* 53  */
 | |
|    {0x36,       0x5E,      0,           ALT_6,      0   }, /* 54  */
 | |
|    {0x37,       0x26,      0,           ALT_7,      0   }, /* 55  */
 | |
|    {0x38,       0x2A,      0,           ALT_8,      0   }, /* 56  */
 | |
|    {0x39,       0x28,      0,           ALT_9,      0   }, /* 57  */
 | |
|    {0,          0,         0,           0,          0   }, /* 58  */
 | |
|    {0,          0,         0,           0,          0   }, /* 59  */
 | |
|    {0,          0,         0,           0,          0   }, /* 60  */
 | |
|    {0,          0,         0,           0,          0   }, /* 61  */
 | |
|    {0,          0,         0,           0,          0   }, /* 62  */
 | |
|    {0,          0,         0,           0,          0   }, /* 63  */
 | |
|    {0,          0,         0,           0,          0   }, /* 64  */
 | |
|    {0x61,       0x41,      0x01,        ALT_A,      0   }, /* 65  */
 | |
|    {0x62,       0x42,      0x02,        ALT_B,      0   }, /* 66  */
 | |
|    {0x63,       0x43,      0x03,        ALT_C,      0   }, /* 67  */
 | |
|    {0x64,       0x44,      0x04,        ALT_D,      0   }, /* 68  */
 | |
|    {0x65,       0x45,      0x05,        ALT_E,      0   }, /* 69  */
 | |
|    {0x66,       0x46,      0x06,        ALT_F,      0   }, /* 70  */
 | |
|    {0x67,       0x47,      0x07,        ALT_G,      0   }, /* 71  */
 | |
|    {0x68,       0x48,      0x08,        ALT_H,      0   }, /* 72  */
 | |
|    {0x69,       0x49,      0x09,        ALT_I,      0   }, /* 73  */
 | |
|    {0x6A,       0x4A,      0x0A,        ALT_J,      0   }, /* 74  */
 | |
|    {0x6B,       0x4B,      0x0B,        ALT_K,      0   }, /* 75  */
 | |
|    {0x6C,       0x4C,      0x0C,        ALT_L,      0   }, /* 76  */
 | |
|    {0x6D,       0x4D,      0x0D,        ALT_M,      0   }, /* 77  */
 | |
|    {0x6E,       0x4E,      0x0E,        ALT_N,      0   }, /* 78  */
 | |
|    {0x6F,       0x4F,      0x0F,        ALT_O,      0   }, /* 79  */
 | |
|    {0x70,       0x50,      0x10,        ALT_P,      0   }, /* 80  */
 | |
|    {0x71,       0x51,      0x11,        ALT_Q,      0   }, /* 81  */
 | |
|    {0x72,       0x52,      0x12,        ALT_R,      0   }, /* 82  */
 | |
|    {0x73,       0x53,      0x13,        ALT_S,      0   }, /* 83  */
 | |
|    {0x74,       0x54,      0x14,        ALT_T,      0   }, /* 84  */
 | |
|    {0x75,       0x55,      0x15,        ALT_U,      0   }, /* 85  */
 | |
|    {0x76,       0x56,      0x16,        ALT_V,      0   }, /* 86  */
 | |
|    {0x77,       0x57,      0x17,        ALT_W,      0   }, /* 87  */
 | |
|    {0x78,       0x58,      0x18,        ALT_X,      0   }, /* 88  */
 | |
|    {0x79,       0x59,      0x19,        ALT_Y,      0   }, /* 89  */
 | |
|    {0x7A,       0x5A,      0x1A,        ALT_Z,      0   }, /* 90  */
 | |
|    {0,          0,         0,           0,          0   }, /* 91  VK_LWIN    */
 | |
|    {0,          0,         0,           0,          0   }, /* 92  VK_RWIN    */
 | |
|    {0,          0,         0,           0,          0   }, /* 93  VK_APPS    */
 | |
|    {0,          0,         0,           0,          0   }, /* 94  */
 | |
|    {0,          0,         0,           0,          0   }, /* 95  */
 | |
|    {0x30,       0,         CTL_PAD0,    ALT_PAD0,   0   }, /* 96  VK_NUMPAD0 */
 | |
|    {0x31,       0,         CTL_PAD1,    ALT_PAD1,   0   }, /* 97  VK_NUMPAD1 */
 | |
|    {0x32,       0,         CTL_PAD2,    ALT_PAD2,   0   }, /* 98  VK_NUMPAD2 */
 | |
|    {0x33,       0,         CTL_PAD3,    ALT_PAD3,   0   }, /* 99  VK_NUMPAD3 */
 | |
|    {0x34,       0,         CTL_PAD4,    ALT_PAD4,   0   }, /* 100 VK_NUMPAD4 */
 | |
|    {0x35,       0,         CTL_PAD5,    ALT_PAD5,   0   }, /* 101 VK_NUMPAD5 */
 | |
|    {0x36,       0,         CTL_PAD6,    ALT_PAD6,   0   }, /* 102 VK_NUMPAD6 */
 | |
|    {0x37,       0,         CTL_PAD7,    ALT_PAD7,   0   }, /* 103 VK_NUMPAD7 */
 | |
|    {0x38,       0,         CTL_PAD8,    ALT_PAD8,   0   }, /* 104 VK_NUMPAD8 */
 | |
|    {0x39,       0,         CTL_PAD9,    ALT_PAD9,   0   }, /* 105 VK_NUMPAD9 */
 | |
|    {PADSTAR,   SHF_PADSTAR,CTL_PADSTAR, ALT_PADSTAR,999 }, /* 106 VK_MULTIPLY*/
 | |
|    {PADPLUS,   SHF_PADPLUS,CTL_PADPLUS, ALT_PADPLUS,999 }, /* 107 VK_ADD     */
 | |
|    {0,          0,         0,           0,          0   }, /* 108 VK_SEPARATOR     */
 | |
|    {PADMINUS, SHF_PADMINUS,CTL_PADMINUS,ALT_PADMINUS,999}, /* 109 VK_SUBTRACT*/
 | |
|    {0x2E,       0,         CTL_PADSTOP, ALT_PADSTOP,0   }, /* 110 VK_DECIMAL */
 | |
|    {PADSLASH,  SHF_PADSLASH,CTL_PADSLASH,ALT_PADSLASH,2 }, /* 111 VK_DIVIDE  */
 | |
|    {KEY_F(1),   KEY_F(13), KEY_F(25),   KEY_F(37),  0   }, /* 112 VK_F1      */
 | |
|    {KEY_F(2),   KEY_F(14), KEY_F(26),   KEY_F(38),  0   }, /* 113 VK_F2      */
 | |
|    {KEY_F(3),   KEY_F(15), KEY_F(27),   KEY_F(39),  0   }, /* 114 VK_F3      */
 | |
|    {KEY_F(4),   KEY_F(16), KEY_F(28),   KEY_F(40),  0   }, /* 115 VK_F4      */
 | |
|    {KEY_F(5),   KEY_F(17), KEY_F(29),   KEY_F(41),  0   }, /* 116 VK_F5      */
 | |
|    {KEY_F(6),   KEY_F(18), KEY_F(30),   KEY_F(42),  0   }, /* 117 VK_F6      */
 | |
|    {KEY_F(7),   KEY_F(19), KEY_F(31),   KEY_F(43),  0   }, /* 118 VK_F7      */
 | |
|    {KEY_F(8),   KEY_F(20), KEY_F(32),   KEY_F(44),  0   }, /* 119 VK_F8      */
 | |
|    {KEY_F(9),   KEY_F(21), KEY_F(33),   KEY_F(45),  0   }, /* 120 VK_F9      */
 | |
|    {KEY_F(10),  KEY_F(22), KEY_F(34),   KEY_F(46),  0   }, /* 121 VK_F10     */
 | |
|    {KEY_F(11),  KEY_F(23), KEY_F(35),   KEY_F(47),  0   }, /* 122 VK_F11     */
 | |
|    {KEY_F(12),  KEY_F(24), KEY_F(36),   KEY_F(48),  0   }, /* 123 VK_F12     */
 | |
| 
 | |
|    /* 124 through 218 */
 | |
| 
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
|    {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
 | |
| 
 | |
|    {0x5B,       0x7B,      0x1B,        ALT_LBRACKET,0  }, /* 219 */
 | |
|    {0x5C,       0x7C,      0x1C,        ALT_BSLASH, 0   }, /* 220 */
 | |
|    {0x5D,       0x7D,      0x1D,        ALT_RBRACKET,0  }, /* 221 */
 | |
|    {0,          0,         0x27,        ALT_FQUOTE, 0   }, /* 222 */
 | |
|    {0,          0,         0,           0,          0   }, /* 223 */
 | |
|    {0,          0,         0,           0,          0   }, /* 224 */
 | |
|    {0,          0,         0,           0,          0   }  /* 225 */
 | |
| };
 | |
| 
 | |
| static KPTAB ext_kptab[] =
 | |
| {
 | |
|    {0,          0,              0,              0,          }, /* MUST BE EMPTY */
 | |
|    {PADENTER,   SHF_PADENTER,   CTL_PADENTER,   ALT_PADENTER}, /* 13 */
 | |
|    {PADSLASH,   SHF_PADSLASH,   CTL_PADSLASH,   ALT_PADSLASH}, /* 111 */
 | |
|    {KEY_PPAGE,  KEY_SPREVIOUS,  CTL_PGUP,       ALT_PGUP    }, /* 33 */
 | |
|    {KEY_NPAGE,  KEY_SNEXT,      CTL_PGDN,       ALT_PGDN    }, /* 34 */
 | |
|    {KEY_END,    KEY_SEND,       CTL_END,        ALT_END     }, /* 35 */
 | |
|    {KEY_HOME,   KEY_SHOME,      CTL_HOME,       ALT_HOME    }, /* 36 */
 | |
|    {KEY_LEFT,   KEY_SLEFT,      CTL_LEFT,       ALT_LEFT    }, /* 37 */
 | |
|    {KEY_UP,     KEY_SUP,        CTL_UP,         ALT_UP      }, /* 38 */
 | |
|    {KEY_RIGHT,  KEY_SRIGHT,     CTL_RIGHT,      ALT_RIGHT   }, /* 39 */
 | |
|    {KEY_DOWN,   KEY_SDOWN,      CTL_DOWN,       ALT_DOWN    }, /* 40 */
 | |
|    {KEY_IC,     KEY_SIC,        CTL_INS,        ALT_INS     }, /* 45 */
 | |
|    {KEY_DC,     KEY_SDC,        CTL_DEL,        ALT_DEL     }, /* 46 */
 | |
|    {PADSLASH,   SHF_PADSLASH,   CTL_PADSLASH,   ALT_PADSLASH}, /* 191 */
 | |
| };
 | |
| 
 | |
| /* End of kptab[] */
 | |
| 
 | |
| unsigned long PDC_get_input_fd(void)
 | |
| {
 | |
|     PDC_LOG(("PDC_get_input_fd() - called\n"));
 | |
| 
 | |
|     return 0L;
 | |
| }
 | |
| 
 | |
| void PDC_set_keyboard_binary(bool on)
 | |
| {
 | |
|     PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
 | |
| }
 | |
| 
 | |
| /* check if a key or mouse event is waiting */
 | |
| 
 | |
| bool PDC_check_key(void)
 | |
| {
 | |
|     if (key_count > 0)
 | |
|         return TRUE;
 | |
| 
 | |
|     GetNumberOfConsoleInputEvents(pdc_con_in, &event_count);
 | |
| 
 | |
|     return (event_count != 0);
 | |
| }
 | |
| 
 | |
| /* _get_key_count returns 0 if save_ip doesn't contain an event which
 | |
|    should be passed back to the user. This function filters "useless"
 | |
|    events.
 | |
| 
 | |
|    The function returns the number of keys waiting. This may be > 1
 | |
|    if the repetition of real keys pressed so far are > 1.
 | |
| 
 | |
|    Returns 0 on NUMLOCK, CAPSLOCK, SCROLLLOCK.
 | |
| 
 | |
|    Returns 1 for SHIFT, ALT, CTRL only if no other key has been pressed
 | |
|    in between, and SP->return_key_modifiers is set; these are returned
 | |
|    on keyup.
 | |
| 
 | |
|    Normal keys are returned on keydown only. The number of repetitions
 | |
|    are returned. Dead keys (diacritics) are omitted. See below for a
 | |
|    description.
 | |
| */
 | |
| 
 | |
| static int _get_key_count(void)
 | |
| {
 | |
|     int num_keys = 0, vk;
 | |
| 
 | |
|     PDC_LOG(("_get_key_count() - called\n"));
 | |
| 
 | |
|     vk = KEV.wVirtualKeyCode;
 | |
| 
 | |
|     if (KEV.bKeyDown)
 | |
|     {
 | |
|         /* key down */
 | |
| 
 | |
|         save_press = 0;
 | |
| 
 | |
|         if (vk == VK_CAPITAL || vk == VK_NUMLOCK || vk == VK_SCROLL)
 | |
|         {
 | |
|             /* throw away these modifiers */
 | |
|         }
 | |
|         else if (vk == VK_SHIFT || vk == VK_CONTROL || vk == VK_MENU)
 | |
|         {
 | |
|             /* These keys are returned on keyup only. */
 | |
| 
 | |
|             save_press = vk;
 | |
|             switch (vk)
 | |
|             {
 | |
|             case VK_SHIFT:
 | |
|                 left_key = GetKeyState(VK_LSHIFT);
 | |
|                 break;
 | |
|             case VK_CONTROL:
 | |
|                 left_key = GetKeyState(VK_LCONTROL);
 | |
|                 break;
 | |
|             case VK_MENU:
 | |
|                 left_key = GetKeyState(VK_LMENU);
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             /* Check for diacritics. These are dead keys. Some locales
 | |
|                have modified characters like umlaut-a, which is an "a"
 | |
|                with two dots on it. In some locales you have to press a
 | |
|                special key (the dead key) immediately followed by the
 | |
|                "a" to get a composed umlaut-a. The special key may have
 | |
|                a normal meaning with different modifiers. */
 | |
| 
 | |
|             if (KEV.uChar.UnicodeChar || !(MapVirtualKey(vk, 2) & 0x80000000))
 | |
|                 num_keys = KEV.wRepeatCount;
 | |
|         }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         /* key up */
 | |
| 
 | |
|         /* Only modifier keys or the results of ALT-numpad entry are
 | |
|            returned on keyup */
 | |
| 
 | |
|         if ((vk == VK_MENU && KEV.uChar.UnicodeChar) ||
 | |
|            ((vk == VK_SHIFT || vk == VK_CONTROL || vk == VK_MENU) &&
 | |
|              vk == save_press))
 | |
|         {
 | |
|             save_press = 0;
 | |
|             num_keys = 1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     PDC_LOG(("_get_key_count() - returning: num_keys %d\n", num_keys));
 | |
| 
 | |
|     return num_keys;
 | |
| }
 | |
| 
 | |
| /* _process_key_event returns -1 if the key in save_ip should be
 | |
|    ignored. Otherwise it returns the keycode which should be returned
 | |
|    by PDC_get_key(). save_ip must be a key event.
 | |
| 
 | |
|    CTRL-ALT support has been disabled, when is it emitted plainly?  */
 | |
| 
 | |
| static int _process_key_event(void)
 | |
| {
 | |
|     int key = (unsigned short)KEV.uChar.UnicodeChar;
 | |
|     WORD vk = KEV.wVirtualKeyCode;
 | |
|     DWORD state = KEV.dwControlKeyState;
 | |
| 
 | |
|     int idx;
 | |
|     BOOL enhanced;
 | |
| 
 | |
|     SP->key_code = TRUE;
 | |
| 
 | |
|     /* Save the key modifiers if required. Do this first to allow to
 | |
|        detect e.g. a pressed CTRL key after a hit of NUMLOCK. */
 | |
| 
 | |
|     if (SP->save_key_modifiers)
 | |
|     {
 | |
|         if (state & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
 | |
|             pdc_key_modifiers |= PDC_KEY_MODIFIER_ALT;
 | |
| 
 | |
|         if (state & SHIFT_PRESSED)
 | |
|             pdc_key_modifiers |= PDC_KEY_MODIFIER_SHIFT;
 | |
| 
 | |
|         if (state & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
 | |
|             pdc_key_modifiers |= PDC_KEY_MODIFIER_CONTROL;
 | |
| 
 | |
|         if (state & NUMLOCK_ON)
 | |
|             pdc_key_modifiers |= PDC_KEY_MODIFIER_NUMLOCK;
 | |
|     }
 | |
| 
 | |
|     /* Handle modifier keys hit by themselves */
 | |
| 
 | |
|     switch (vk)
 | |
|     {
 | |
|     case VK_SHIFT: /* shift */
 | |
|         if (!SP->return_key_modifiers)
 | |
|             return -1;
 | |
| 
 | |
|         return (left_key & 0x8000) ? KEY_SHIFT_L : KEY_SHIFT_R;
 | |
| 
 | |
|     case VK_CONTROL: /* control */
 | |
|         if (!SP->return_key_modifiers)
 | |
|             return -1;
 | |
| 
 | |
|         return (left_key & 0x8000) ? KEY_CONTROL_L : KEY_CONTROL_R;
 | |
| 
 | |
|     case VK_MENU: /* alt */
 | |
|         if (!key)
 | |
|         {
 | |
|             if (!SP->return_key_modifiers)
 | |
|                 return -1;
 | |
| 
 | |
|             return (left_key & 0x8000) ? KEY_ALT_L : KEY_ALT_R;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* The system may emit Ascii or Unicode characters depending on
 | |
|        whether ReadConsoleInputA or ReadConsoleInputW is used.
 | |
| 
 | |
|        Normally, if key != 0 then the system did the translation
 | |
|        successfully. But this is not true for LEFT_ALT (different to
 | |
|        RIGHT_ALT). In case of LEFT_ALT we can get key != 0. So
 | |
|        check for this first. */
 | |
| 
 | |
|     if (key && ( !(state & LEFT_ALT_PRESSED) ||
 | |
|         (state & RIGHT_ALT_PRESSED) ))
 | |
|     {
 | |
|         /* This code should catch all keys returning a printable
 | |
|            character. Characters above 0x7F should be returned as
 | |
|            positive codes. But if'ndef NUMKEYPAD we have to return
 | |
|            extended keycodes for keypad codes. */
 | |
| 
 | |
| #ifndef NUMKEYPAD
 | |
|         if (kptab[vk].extended == 0)
 | |
| #endif
 | |
|         {
 | |
|             SP->key_code = FALSE;
 | |
|             return key;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* This case happens if a functional key has been entered. */
 | |
| 
 | |
|     if ((state & ENHANCED_KEY) && (kptab[vk].extended != 999))
 | |
|     {
 | |
|         enhanced = TRUE;
 | |
|         idx = kptab[vk].extended;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         enhanced = FALSE;
 | |
|         idx = vk;
 | |
|     }
 | |
| 
 | |
|     if (state & SHIFT_PRESSED)
 | |
|         key = enhanced ? ext_kptab[idx].shift : kptab[idx].shift;
 | |
| 
 | |
|     else if (state & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
 | |
|         key = enhanced ? ext_kptab[idx].control : kptab[idx].control;
 | |
| 
 | |
|     else if (state & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
 | |
|         key = enhanced ? ext_kptab[idx].alt : kptab[idx].alt;
 | |
| 
 | |
|     else
 | |
|         key = enhanced ? ext_kptab[idx].normal : kptab[idx].normal;
 | |
| 
 | |
|     if (key < KEY_CODE_YES)
 | |
|         SP->key_code = FALSE;
 | |
| 
 | |
|     return key;
 | |
| }
 | |
| 
 | |
| static int _process_mouse_event(void)
 | |
| {
 | |
|     static const DWORD button_mask[] = {1, 4, 2};
 | |
|     short action, shift_flags = 0;
 | |
|     int i;
 | |
| 
 | |
|     save_press = 0;
 | |
|     SP->key_code = TRUE;
 | |
| 
 | |
|     memset(&pdc_mouse_status, 0, sizeof(MOUSE_STATUS));
 | |
| 
 | |
|     /* Handle scroll wheel */
 | |
| 
 | |
|     if (MEV.dwEventFlags == 4)
 | |
|     {
 | |
|         pdc_mouse_status.changes = (MEV.dwButtonState & 0xFF000000) ?
 | |
|             PDC_MOUSE_WHEEL_DOWN : PDC_MOUSE_WHEEL_UP;
 | |
| 
 | |
|         pdc_mouse_status.x = -1;
 | |
|         pdc_mouse_status.y = -1;
 | |
| 
 | |
|         memset(&old_mouse_status, 0, sizeof(old_mouse_status));
 | |
| 
 | |
|         return KEY_MOUSE;
 | |
|     }
 | |
| 
 | |
|     action = (MEV.dwEventFlags == 2) ? BUTTON_DOUBLE_CLICKED :
 | |
|             ((MEV.dwEventFlags == 1) ? BUTTON_MOVED : BUTTON_PRESSED);
 | |
| 
 | |
|     for (i = 0; i < 3; i++)
 | |
|         pdc_mouse_status.button[i] =
 | |
|             (MEV.dwButtonState & button_mask[i]) ? action : 0;
 | |
| 
 | |
|     if (action == BUTTON_PRESSED && MEV.dwButtonState & 7 && SP->mouse_wait)
 | |
|     {
 | |
|         /* Check for a click -- a PRESS followed immediately by a release */
 | |
| 
 | |
|         if (!event_count)
 | |
|         {
 | |
|             napms(SP->mouse_wait);
 | |
| 
 | |
|             GetNumberOfConsoleInputEvents(pdc_con_in, &event_count);
 | |
|         }
 | |
| 
 | |
|         if (event_count)
 | |
|         {
 | |
|             INPUT_RECORD ip;
 | |
|             DWORD count;
 | |
|             bool have_click = FALSE;
 | |
| 
 | |
|             PeekConsoleInput(pdc_con_in, &ip, 1, &count);
 | |
| 
 | |
|             for (i = 0; i < 3; i++)
 | |
|             {
 | |
|                 if (pdc_mouse_status.button[i] == BUTTON_PRESSED &&
 | |
|                     !(ip.Event.MouseEvent.dwButtonState & button_mask[i]))
 | |
|                 {
 | |
|                     pdc_mouse_status.button[i] = BUTTON_CLICKED;
 | |
|                     have_click = TRUE;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             /* If a click was found, throw out the event */
 | |
| 
 | |
|             if (have_click)
 | |
|                 ReadConsoleInput(pdc_con_in, &ip, 1, &count);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     pdc_mouse_status.x = MEV.dwMousePosition.X;
 | |
|     pdc_mouse_status.y = MEV.dwMousePosition.Y;
 | |
| 
 | |
|     pdc_mouse_status.changes = 0;
 | |
| 
 | |
|     for (i = 0; i < 3; i++)
 | |
|     {
 | |
|         if (old_mouse_status.button[i] != pdc_mouse_status.button[i])
 | |
|             pdc_mouse_status.changes |= (1 << i);
 | |
| 
 | |
|         if (pdc_mouse_status.button[i] == BUTTON_MOVED)
 | |
|         {
 | |
|             /* Discard non-moved "moves" */
 | |
| 
 | |
|             if (pdc_mouse_status.x == old_mouse_status.x &&
 | |
|                 pdc_mouse_status.y == old_mouse_status.y)
 | |
|                 return -1;
 | |
| 
 | |
|             /* Motion events always flag the button as changed */
 | |
| 
 | |
|             pdc_mouse_status.changes |= (1 << i);
 | |
|             pdc_mouse_status.changes |= PDC_MOUSE_MOVED;
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     old_mouse_status = pdc_mouse_status;
 | |
| 
 | |
|     /* Treat click events as release events for comparison purposes */
 | |
| 
 | |
|     for (i = 0; i < 3; i++)
 | |
|     {
 | |
|         if (old_mouse_status.button[i] == BUTTON_CLICKED ||
 | |
|             old_mouse_status.button[i] == BUTTON_DOUBLE_CLICKED)
 | |
|             old_mouse_status.button[i] = BUTTON_RELEASED;
 | |
|     }
 | |
| 
 | |
|     /* Check for SHIFT/CONTROL/ALT */
 | |
| 
 | |
|     if (MEV.dwControlKeyState & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
 | |
|         shift_flags |= BUTTON_ALT;
 | |
| 
 | |
|     if (MEV.dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
 | |
|         shift_flags |= BUTTON_CONTROL;
 | |
| 
 | |
|     if (MEV.dwControlKeyState & SHIFT_PRESSED)
 | |
|         shift_flags |= BUTTON_SHIFT;
 | |
| 
 | |
|     if (shift_flags)
 | |
|     {
 | |
|         for (i = 0; i < 3; i++)
 | |
|         {
 | |
|             if (pdc_mouse_status.changes & (1 << i))
 | |
|                 pdc_mouse_status.button[i] |= shift_flags;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return KEY_MOUSE;
 | |
| }
 | |
| 
 | |
| /* return the next available key or mouse event */
 | |
| 
 | |
| int PDC_get_key(void)
 | |
| {
 | |
|     pdc_key_modifiers = 0L;
 | |
| 
 | |
|     if (!key_count)
 | |
|     {
 | |
|         DWORD count;
 | |
| 
 | |
|         ReadConsoleInput(pdc_con_in, &save_ip, 1, &count);
 | |
|         event_count--;
 | |
| 
 | |
|         if (save_ip.EventType == MOUSE_EVENT)
 | |
|             key_count = 1;
 | |
|         else if (save_ip.EventType == KEY_EVENT)
 | |
|             key_count = _get_key_count();
 | |
|     }
 | |
| 
 | |
|     if (key_count)
 | |
|     {
 | |
|         key_count--;
 | |
| 
 | |
|         switch (save_ip.EventType)
 | |
|         {
 | |
|         case KEY_EVENT:
 | |
|             return _process_key_event();
 | |
| 
 | |
|         case MOUSE_EVENT:
 | |
|             return _process_mouse_event();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return -1;
 | |
| }
 | |
| 
 | |
| /* discard any pending keyboard or mouse input -- this is the core
 | |
|    routine for flushinp() */
 | |
| 
 | |
| void PDC_flushinp(void)
 | |
| {
 | |
|     PDC_LOG(("PDC_flushinp() - called\n"));
 | |
| 
 | |
|     FlushConsoleInputBuffer(pdc_con_in);
 | |
| }
 | |
| 
 | |
| int PDC_mouse_set(void)
 | |
| {
 | |
|     /* If turning on mouse input: Set ENABLE_MOUSE_INPUT, and clear
 | |
|        all other flags, including the extended flags;
 | |
|        If turning off the mouse: Set QuickEdit Mode to the status it
 | |
|        had on startup, and clear all other flags */
 | |
| 
 | |
|     SetConsoleMode(pdc_con_in, SP->_trap_mbe ?
 | |
|                    (ENABLE_MOUSE_INPUT|0x0080) : (pdc_quick_edit|0x0080));
 | |
| 
 | |
|     memset(&old_mouse_status, 0, sizeof(old_mouse_status));
 | |
| 
 | |
|     return OK;
 | |
| }
 | |
| 
 | |
| int PDC_modifiers_set(void)
 | |
| {
 | |
|     return OK;
 | |
| }
 |