/* _al_win_kbd_handle_key_press: * Does stuff when a key is pressed. */ void _al_win_kbd_handle_key_press(int scode, int vcode, BOOL repeated) { int mycode; int ccode; BYTE ks[256]; WCHAR buf[8]; if (!GetKeyboardState(&ks[0])) ccode = 0; /* shound't really happen */ else if (ToUnicode(vcode, scode, ks, buf, 8, 0) == 1) ccode = buf[0]; else ccode = 0; /* Windows doesn't differentiate between the left and right versions of the modifiers. To compensate we read the current keyboard state and use that information to determine which key was actually pressed. We check the last known state of the modifier in question and if it is not down we know that is the key that was pressed. */ if (vcode == VK_SHIFT || vcode == VK_CONTROL || vcode == VK_MENU) { _al_win_kbd_update_shifts(); return; } /* Ignore repeats for Caps Lock */ if (vcode == VK_CAPITAL && repeated && key[KEY_CAPSLOCK]) return; ASSERT(vcode >= 0 && vcode < 256); mycode = hw_to_mycode[vcode]; _handle_key_press(ccode, mycode); }
void _handle_mac_key_press(short keycode) { unsigned int ascii; if(keycode >= KEY_MODIFIERS && keycode<KEY_MAX ){ if(keycode == KEY_SCRLOCK || keycode == KEY_NUMLOCK){ _key_shifts ^= modifier_table[keycode - KEY_MODIFIERS]; } else _key_shifts |= modifier_table[keycode - KEY_MODIFIERS]; ascii=0; } else if(_key_shifts & KB_CTRL_FLAG) ascii=standard_key_control_table[keycode]; else if(_key_shifts & KB_CAPSLOCK_FLAG) ascii=standard_key_capslock_table[keycode]; else if(_key_shifts & KB_SHIFT_FLAG) ascii=standard_key_shift_table[keycode]; else ascii=standard_key_ascii_table[keycode]; if(ascii == 0xFFFF) ascii = _key_shifts & KB_MODIFIERS; _handle_key_press(ascii, keycode); }
/* _xwin_keyboard_handler: * Keyboard "interrupt" handler. */ void _xwin_keyboard_handler(XKeyEvent *event, int dga2_hack) { int keycode; if (!xkeyboard_installed) return; if (_xwin_keyboard_callback) (*_xwin_keyboard_callback)(event->type == KeyPress ? 1 : 0, event->keycode); keycode = _xwin.keycode_to_scancode[event->keycode]; if (keycode == -1) keycode = find_unknown_key_assignment(event->keycode); if (dga2_hack) dga2_update_shifts(event); else update_shifts(event); /* Special case the pause key. */ if (keycode == KEY_PAUSE) { /* Allegro ignore's releasing of the pause key. */ if (event->type == KeyRelease) return; if (pause_key) { event->type = KeyRelease; pause_key = 0; } else { pause_key = 1; } } if (event->type == KeyPress) { /* Key pressed. */ int len; char buffer[16]; char buffer2[16]; int unicode = 0, r = 0; #if defined (ALLEGRO_XWINDOWS_WITH_XIM) && defined(X_HAVE_UTF8_STRING) if (xic) { len = Xutf8LookupString(xic, event, buffer, sizeof buffer, NULL, NULL); } else #endif { /* XLookupString is supposed to only use ASCII. */ len = XLookupString(event, buffer, sizeof buffer, NULL, NULL); } buffer[len] = '\0'; uconvert(buffer, U_UTF8, buffer2, U_UNICODE, sizeof buffer2); unicode = *(unsigned short *)buffer2; #ifdef ALLEGRO_XWINDOWS_WITH_XIM r = XFilterEvent((XEvent *)event, _xwin.window); #endif if (keycode || unicode) { /* If we have a keycode, we want it to go to Allegro immediately, so the * key[] array is updated, and the user callbacks are called. OTOH, a key * should not be added to the keyboard buffer (parameter -1) if it was * filtered out as a compose key, or if it is a modifier key. */ if (r || keycode >= KEY_MODIFIERS) unicode = -1; else { /* Historically, Allegro expects to get only the scancode when Alt is * held down. */ if (_key_shifts & KB_ALT_FLAG) unicode = 0; } _handle_key_press(unicode, keycode); /* Detect Ctrl-Alt-End. */ if (keycode == KEY_END && (_key_shifts & KB_CTRL_FLAG) && (_key_shifts & KB_ALT_FLAG) && (three_finger_flag)) { #ifndef ALLEGRO_HAVE_LIBPTHREAD if (_unix_bg_man == &_bg_man_sigalrm) { _sigalrm_request_abort(); } else #endif { TRACE(PREFIX_W "Three finger combo detected. SIGTERMing " "pid %d\n", main_pid); kill(main_pid, SIGTERM); } } } } else { /* Key release. */ _handle_key_release(keycode); } }
static pascal void key_adb_interrupt(Ptr buffer, TempADBServiceRoutineUPP completionProc, Ptr refCon, long command) { extern short _mac_keyboard_installed; unsigned char origcode; unsigned char keycode; int a; if((command & 0xF) == 0xC){ for(a = 1; a < 3 ; a++ ){ origcode=buffer[a]; keycode=adb_to_allegro[origcode&0x7f]; if(keycode!=0){ if(origcode&0x80){ if(keycode >= KEY_MODIFIERS && keycode<KEY_MAX ) if(keycode != KEY_SCRLOCK && keycode != KEY_NUMLOCK) _key_shifts &= ~modifier_table[keycode - KEY_MODIFIERS]; _handle_key_release(keycode); } else{ unsigned int ascii; if(keycode >= KEY_MODIFIERS && keycode<KEY_MAX ){ if(keycode == KEY_SCRLOCK || keycode == KEY_NUMLOCK){ _key_shifts ^= modifier_table[keycode - KEY_MODIFIERS]; } else _key_shifts |= modifier_table[keycode - KEY_MODIFIERS]; ascii=0; } else if(_key_shifts & KB_CTRL_FLAG) ascii=standard_key_control_table[keycode]; else if(_key_shifts & KB_CAPSLOCK_FLAG) ascii=standard_key_capslock_table[keycode]; else if(_key_shifts & KB_SHIFT_FLAG) ascii=standard_key_shift_table[keycode]; else ascii=standard_key_ascii_table[keycode]; if(ascii == 0xFFFF) ascii = _key_shifts & KB_MODIFIERS; _handle_key_press(ascii,keycode); } } else if(origcode == kk_2nd){ _mouse2nd = TRUE; } else if(origcode == kk_2nd+0x80){ _mouse2nd = FALSE; } // Debug Hack <CTRL-SHIFT-ON> restore system driver else if(origcode == 0x7F && _key_shifts & KB_SHIFT_FLAG && _key_shifts & KB_CTRL_FLAG){ ADBAddress adb_address; ADBSetInfoBlock mySet; ADBDataBlock now_data; adb_address = GetIndADB(&now_data, adb_keyboard_id); mySet.siService = adb_key_save.dbServiceRtPtr; mySet.siDataAreaAddr = adb_key_save.dbDataAreaAddr; SetADBInfo (&mySet,adb_address); _mac_keyboard_installed=TRUE; keyboard_driver = &keyboard_macos; } } } }
/* handle_key_press: [input thread] * Does stuff when a key is pressed. */ static void handle_key_press(unsigned char scancode) { int mycode; int unicode; int n; UINT vkey; BYTE keystate[256]; WCHAR chars[16]; vkey = MapVirtualKey(scancode, 1); GetKeyboardState(keystate); update_shifts(keystate); /* TODO: shouldn't we base the mapping on vkey? */ mycode = hw_to_mycode[scancode]; if (mycode == 0) return; /* MapVirtualKey always returns the arrow key VKEY, so adjust it if num lock is on */ if (keystate[VK_NUMLOCK]) { switch (scancode) { case DIK_NUMPAD0: vkey = VK_NUMPAD0; break; case DIK_NUMPAD1: vkey = VK_NUMPAD1; break; case DIK_NUMPAD2: vkey = VK_NUMPAD2; break; case DIK_NUMPAD3: vkey = VK_NUMPAD3; break; case DIK_NUMPAD4: vkey = VK_NUMPAD4; break; case DIK_NUMPAD5: vkey = VK_NUMPAD5; break; case DIK_NUMPAD6: vkey = VK_NUMPAD6; break; case DIK_NUMPAD7: vkey = VK_NUMPAD7; break; case DIK_NUMPAD8: vkey = VK_NUMPAD8; break; case DIK_NUMPAD9: vkey = VK_NUMPAD9; break; case DIK_DECIMAL: vkey = VK_DECIMAL; break; } } /* what's life without a few special cases */ switch (scancode) { case DIK_DIVIDE: vkey = VK_DIVIDE; break; case DIK_MULTIPLY: vkey = VK_MULTIPLY; break; case DIK_SUBTRACT: vkey = VK_SUBTRACT; break; case DIK_ADD: vkey = VK_ADD; break; case DIK_NUMPADENTER: vkey = VK_RETURN; } /* TODO: is there an advantage using ToUnicode? maybe it would allow * Chinese and so on characters? For now, always ToAscii is used. */ //n = ToUnicode(vkey, scancode, keystate, chars, 16, 0); n = ToAscii(vkey, scancode, keystate, (WORD *)chars, 0); if (n == 1) { WCHAR wstr[2]; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)chars, n, wstr, 2); unicode = wstr[0]; } else { /* Don't generate key presses for modifier keys or dead keys */ if (mycode >= KEY_MODIFIERS || n != 0) unicode = -1; else unicode = 0; } /* When alt key is pressed, any key always must return ASCII 0 in Allegro. */ if (unicode > 0 && (keystate[VK_LMENU] & 0x80)) { unicode = 0; } _handle_key_press(unicode, mycode); }
/* _handle_pckey: * Handles PC keyboard input, in the same format it comes from the * keyboard controller hardware (raw scancodes, top bit set means the * key was released, special escapes for extended keys, pause, etc). * This routine translates the data using the current mapping table, * and calls routines from keyboard.c as required. */ void _handle_pckey(int code) { int origcode, mycode, flag, numflag, i=0; unsigned short *table; if (key_pause_loop) { /* skip multiple codes generated by the pause key */ key_pause_loop--; return; } if (code == 0xE1) { /* the pause key requires special handling */ if (key_paused) _handle_key_release(KEY_PAUSE); else _handle_key_press(0, KEY_PAUSE); key_paused = !key_paused; key_pause_loop = 5; return; } if (code == 0xE0) { /* flag that the next key will be an extended one */ key_extended = TRUE; return; } /* convert from hardware to Allegro format */ if (key_extended) { mycode = hw_to_mycode_ex[code & 0x7F]; key_extended = FALSE; } else mycode = hw_to_mycode[code & 0x7F]; if (!mycode) return; origcode = mycode; if (mycode >= KEY_MODIFIERS) flag = modifier_table[mycode - KEY_MODIFIERS]; else flag = 0; numflag = ((_key_shifts & KB_NUMLOCK_FLAG) != 0) == ((_key_shifts & KB_SHIFT_FLAG) != 0); /* handle released keys */ if (code & 0x80) { if (flag & KB_ALT_FLAG) { /* end of an alt+numpad numeric entry sequence */ if (_key_shifts & KB_INALTSEQ_FLAG) { _key_shifts &= ~KB_INALTSEQ_FLAG; _handle_key_press(key_pad_seq, 0); } } if (flag & KB_MODIFIERS) { /* turn off the shift state for this key */ _key_shifts &= ~flag; if (mycode == KEY_ALTGR) key_altgr = FALSE; } /* update the key array for a released key */ _handle_key_release(mycode); return; } if ((mycode == KEY_F1) && ((_key_shifts & KB_CTRL_ALT) == KB_CTRL_ALT)) { /* switch to the standard keyboard layout */ _handle_key_press(-1, KEY_F1); set_standard_keyboard(); return; } if ((mycode == KEY_F2) && ((_key_shifts & KB_CTRL_ALT) == KB_CTRL_ALT)) { /* switch to the custom keyboard layout */ _handle_key_press(-1, KEY_F2); set_custom_keyboard(); return; } if (flag & KB_MODIFIERS) { /* turn on a modifier key */ _key_shifts |= flag; if (mycode == KEY_ALTGR) key_altgr = TRUE; _handle_key_press(-1, origcode); return; } if ((flag & KB_LED_FLAGS) && (key_led_flag)) { /* toggle caps/num/scroll lock */ _key_shifts ^= flag; _handle_key_press(-1, origcode); return; } /* new ACCENT stuff */ if (!_key_standard_kb) { if ((mycode == _key_accent1) && ((_key_shifts & KB_SH_CTRL_ALT) == _key_accent1_flag)) { _key_shifts |= KB_ACCENT1_FLAG; _handle_key_press(-1, origcode); return; } else if ((mycode == _key_accent2) && ((_key_shifts & KB_SH_CTRL_ALT) == _key_accent2_flag)) { _key_shifts |= KB_ACCENT2_FLAG; _handle_key_press(-1, origcode); return; } else if ((mycode == _key_accent3) && ((_key_shifts & KB_SH_CTRL_ALT) == _key_accent3_flag)) { _key_shifts |= KB_ACCENT3_FLAG; _handle_key_press(-1, origcode); return; } else if ((mycode == _key_accent4) && ((_key_shifts & KB_SH_CTRL_ALT) == _key_accent4_flag)) { _key_shifts |= KB_ACCENT4_FLAG; _handle_key_press(-1, origcode); return; } } if (_key_shifts & KB_ACCENTS) { /* accented character input */ if (((_key_shifts & KB_SHIFT_FLAG) != 0) ^ ((_key_shifts & KB_CAPSLOCK_FLAG) != 0)) { if (_key_shifts & KB_ACCENT1_FLAG) table = _key_accent1_upper_table; else if (_key_shifts & KB_ACCENT2_FLAG) table = _key_accent2_upper_table; else if (_key_shifts & KB_ACCENT3_FLAG) table = _key_accent3_upper_table; else if (_key_shifts & KB_ACCENT4_FLAG) table = _key_accent4_upper_table; else table = NULL; } else { if (_key_shifts & KB_ACCENT1_FLAG) table = _key_accent1_lower_table; else if (_key_shifts & KB_ACCENT2_FLAG) table = _key_accent2_lower_table; else if (_key_shifts & KB_ACCENT3_FLAG) table = _key_accent3_lower_table; else if (_key_shifts & KB_ACCENT4_FLAG) table = _key_accent4_lower_table; else table = NULL; } if (table[mycode]) { /* simple accented char */ _key_shifts &= ~KB_ACCENTS; _handle_key_press(table[mycode], origcode); return; } else { /* add the accent as an individual character */ if (_key_shifts & (KB_ACCENT1_FLAG)) i = _key_accent1; else if (_key_shifts & (KB_ACCENT2_FLAG)) i = _key_accent2; else if (_key_shifts & (KB_ACCENT3_FLAG)) i = _key_accent3; else if (_key_shifts & (KB_ACCENT4_FLAG)) i = _key_accent4; _handle_key_press(_key_ascii_table[i], i); _key_shifts &= ~KB_ACCENTS; } } if (_key_shifts & KB_ALT_FLAG) { if ((mycode >= KEY_0_PAD) && (mycode <= KEY_9_PAD)) { /* alt+numpad numeric entry */ if (_key_shifts & KB_INALTSEQ_FLAG) { key_pad_seq = key_pad_seq*10 + mycode - KEY_0_PAD; } else { _key_shifts |= KB_INALTSEQ_FLAG; key_pad_seq = mycode - KEY_0_PAD; } _handle_key_press(-1, origcode); return; } else { /* alt+key */ if (_key_ascii_table[mycode] == 0xFFFF) i = 0xFFFF; else if (key_altgr) { if (((_key_shifts & KB_SHIFT_FLAG) != 0) ^ ((_key_shifts & KB_CAPSLOCK_FLAG) != 0)) i = _key_altgr_upper_table[mycode]; else i = _key_altgr_lower_table[mycode]; } else i = 0; } } else if ((mycode >= KEY_0_PAD) && (mycode <= KEY_9_PAD)) { /* handle numlock number->arrow conversions */ i = mycode - KEY_0_PAD; if ((_key_shifts & KB_CTRL_FLAG) || (numflag)) { mycode = numlock_table[i]; i = 0xFFFF; } else i = _key_ascii_table[mycode]; } else if (mycode == KEY_DEL_PAD) { /* handle numlock logic for the del key */ if (numflag) { mycode = KEY_DEL; i = 0xFFFF; } else i = _key_ascii_table[KEY_DEL_PAD]; } else if (_key_shifts & KB_CTRL_FLAG) { /* ctrl+key */ i = _key_control_table[mycode]; } else if (_key_shifts & KB_SHIFT_FLAG) { /* shift+key */ if (_key_shifts & KB_CAPSLOCK_FLAG) { if (_key_ascii_table[mycode] == _key_capslock_table[mycode]) i = _key_shift_table[mycode]; else i = _key_ascii_table[mycode]; } else i = _key_shift_table[mycode]; } else if (_key_shifts & KB_CAPSLOCK_FLAG) { /* capslock+key */ i = _key_capslock_table[mycode]; } else { /* normal key */ i = _key_ascii_table[mycode]; } /* use the current modifier state in place of the key code? */ if (i == 0xFFFF) i = _key_shifts & KB_MODIFIERS; _key_shifts &= ~KB_INALTSEQ_FLAG; /* phew! */ _handle_key_press(i, origcode); }