/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #ifndef COMMON_KEYBOARD_H #define COMMON_KEYBOARD_H #include "common/scummsys.h" #if defined(__amigaos4__) || defined(__MORPHOS__) // KEYCODE_LESS and KEYCODE_GREATER are already defined in AmigaOS and MorphOS, // inside "include/include_h/intuition/intuition.h" (fixes bug #5532) #if defined(KEYCODE_LESS) && defined(KEYCODE_GREATER) #undef KEYCODE_LESS #undef KEYCODE_GREATER #endif #endif namespace Common { /** * @defgroup common_keyboard Keyboard * @ingroup common * * @brief API for keyboard operations. * * * @{ */ enum KeyCode { KEYCODE_INVALID = 0, KEYCODE_BACKSPACE = 8, KEYCODE_TAB = 9, KEYCODE_CLEAR = 12, KEYCODE_RETURN = 13, KEYCODE_PAUSE = 19, KEYCODE_ESCAPE = 27, KEYCODE_SPACE = 32, KEYCODE_EXCLAIM = 33, // ! KEYCODE_QUOTEDBL = 34, // " KEYCODE_HASH = 35, // # KEYCODE_DOLLAR = 36, // $ KEYCODE_PERCENT = 37, // % KEYCODE_AMPERSAND = 38, // & KEYCODE_QUOTE = 39, // ' KEYCODE_LEFTPAREN = 40, // ( KEYCODE_RIGHTPAREN = 41, // ) KEYCODE_ASTERISK = 42, // * KEYCODE_PLUS = 43, // + KEYCODE_COMMA = 44, // , KEYCODE_MINUS = 45, // - KEYCODE_PERIOD = 46, // . KEYCODE_SLASH = 47, // / KEYCODE_0 = 48, KEYCODE_1 = 49, KEYCODE_2 = 50, KEYCODE_3 = 51, KEYCODE_4 = 52, KEYCODE_5 = 53, KEYCODE_6 = 54, KEYCODE_7 = 55, KEYCODE_8 = 56, KEYCODE_9 = 57, KEYCODE_COLON = 58, // : KEYCODE_SEMICOLON = 59, // ; KEYCODE_LESS = 60, // < KEYCODE_EQUALS = 61, // = KEYCODE_GREATER = 62, // > KEYCODE_QUESTION = 63, // ? KEYCODE_AT = 64, // @ KEYCODE_LEFTBRACKET = 91, // [ KEYCODE_BACKSLASH = 92, // "\" KEYCODE_RIGHTBRACKET= 93, // ] KEYCODE_CARET = 94, // ^ KEYCODE_UNDERSCORE = 95, // _ KEYCODE_BACKQUOTE = 96, // ` KEYCODE_a = 97, KEYCODE_b = 98, KEYCODE_c = 99, KEYCODE_d = 100, KEYCODE_e = 101, KEYCODE_f = 102, KEYCODE_g = 103, KEYCODE_h = 104, KEYCODE_i = 105, KEYCODE_j = 106, KEYCODE_k = 107, KEYCODE_l = 108, KEYCODE_m = 109, KEYCODE_n = 110, KEYCODE_o = 111, KEYCODE_p = 112, KEYCODE_q = 113, KEYCODE_r = 114, KEYCODE_s = 115, KEYCODE_t = 116, KEYCODE_u = 117, KEYCODE_v = 118, KEYCODE_w = 119, KEYCODE_x = 120, KEYCODE_y = 121, KEYCODE_z = 122, KEYCODE_DELETE = 127, KEYCODE_TILDE = 176, // ~ // Numeric keypad KEYCODE_KP0 = 256, KEYCODE_KP1 = 257, KEYCODE_KP2 = 258, KEYCODE_KP3 = 259, KEYCODE_KP4 = 260, KEYCODE_KP5 = 261, KEYCODE_KP6 = 262, KEYCODE_KP7 = 263, KEYCODE_KP8 = 264, KEYCODE_KP9 = 265, KEYCODE_KP_PERIOD = 266, KEYCODE_KP_DIVIDE = 267, KEYCODE_KP_MULTIPLY = 268, KEYCODE_KP_MINUS = 269, KEYCODE_KP_PLUS = 270, KEYCODE_KP_ENTER = 271, KEYCODE_KP_EQUALS = 272, // Arrows + Home/End pad KEYCODE_UP = 273, KEYCODE_DOWN = 274, KEYCODE_RIGHT = 275, KEYCODE_LEFT = 276, KEYCODE_INSERT = 277, KEYCODE_HOME = 278, KEYCODE_END = 279, KEYCODE_PAGEUP = 280, KEYCODE_PAGEDOWN = 281, // Function keys KEYCODE_F1 = 282, KEYCODE_F2 = 283, KEYCODE_F3 = 284, KEYCODE_F4 = 285, KEYCODE_F5 = 286, KEYCODE_F6 = 287, KEYCODE_F7 = 288, KEYCODE_F8 = 289, KEYCODE_F9 = 290, KEYCODE_F10 = 291, KEYCODE_F11 = 292, KEYCODE_F12 = 293, KEYCODE_F13 = 294, KEYCODE_F14 = 295, KEYCODE_F15 = 296, KEYCODE_F16 = 297, KEYCODE_F17 = 298, KEYCODE_F18 = 299, // Key state modifier keys KEYCODE_NUMLOCK = 300, KEYCODE_CAPSLOCK = 301, KEYCODE_SCROLLOCK = 302, KEYCODE_RSHIFT = 303, KEYCODE_LSHIFT = 304, KEYCODE_RCTRL = 305, KEYCODE_LCTRL = 306, KEYCODE_RALT = 307, KEYCODE_LALT = 308, KEYCODE_RMETA = 309, KEYCODE_LMETA = 310, KEYCODE_LSUPER = 311, // Left "Windows" key KEYCODE_RSUPER = 312, // Right "Windows" key KEYCODE_MODE = 313, // "Alt Gr" key KEYCODE_COMPOSE = 314, // Multi-key compose key // Miscellaneous function keys KEYCODE_HELP = 315, KEYCODE_PRINT = 316, KEYCODE_SYSREQ = 317, KEYCODE_BREAK = 318, KEYCODE_MENU = 319, KEYCODE_POWER = 320, // Power Macintosh power key KEYCODE_EURO = 321, // Some european keyboards KEYCODE_UNDO = 322, // Atari keyboard has Undo KEYCODE_SLEEP = 323, KEYCODE_MUTE = 324, KEYCODE_EJECT = 325, KEYCODE_VOLUMEUP = 326, KEYCODE_VOLUMEDOWN = 327, KEYCODE_LEFTSOFT = 328, KEYCODE_RIGHTSOFT = 329, KEYCODE_CALL = 330, KEYCODE_HANGUP = 331, KEYCODE_CAMERA = 332, KEYCODE_WWW = 333, KEYCODE_MAIL = 334, KEYCODE_CALCULATOR = 335, KEYCODE_CUT = 336, KEYCODE_COPY = 337, KEYCODE_PASTE = 338, KEYCODE_SELECT = 339, KEYCODE_CANCEL = 340, // Action keys KEYCODE_AC_SEARCH = 341, KEYCODE_AC_HOME = 342, KEYCODE_AC_BACK = 343, KEYCODE_AC_FORWARD = 344, KEYCODE_AC_STOP = 345, KEYCODE_AC_REFRESH = 346, KEYCODE_AC_BOOKMARKS = 347, // Audio keys KEYCODE_AUDIONEXT = 348, KEYCODE_AUDIOPREV = 349, KEYCODE_AUDIOSTOP = 350, KEYCODE_AUDIOPLAY = 351, KEYCODE_AUDIOPAUSE = 352, KEYCODE_AUDIOPLAYPAUSE = 353, KEYCODE_AUDIOMUTE = 354, KEYCODE_AUDIOREWIND = 355, KEYCODE_AUDIOFASTFORWARD = 356, KEYCODE_LAST }; /** * List of certain special and some fake 'ascii' values used in keyboard events. * The values for the function keys listed here are based on what certain SCUMM * games expect in their scripts. * @todo Get rid of the function key values, and instead enforce that engines use * the keycode value to handle these. */ enum { ASCII_BACKSPACE = 8, ASCII_TAB = 9, ASCII_RETURN = 13, ASCII_ESCAPE = 27, ASCII_SPACE = 32, ASCII_F1 = 315, ASCII_F2 = 316, ASCII_F3 = 317, ASCII_F4 = 318, ASCII_F5 = 319, ASCII_F6 = 320, ASCII_F7 = 321, ASCII_F8 = 322, ASCII_F9 = 323, ASCII_F10 = 324, ASCII_F11 = 325, ASCII_F12 = 326 }; /** * Keyboard modifier flags, used for Event::kbd::flags. */ enum { // Non-sticky modifier flags KBD_CTRL = 1 << 0, KBD_ALT = 1 << 1, KBD_SHIFT = 1 << 2, KBD_META = 1 << 3, KBD_NON_STICKY = (KBD_CTRL|KBD_ALT|KBD_SHIFT|KBD_META), // Sticky modifier flags KBD_NUM = 1 << 4, KBD_CAPS = 1 << 5, KBD_SCRL = 1 << 6, KBD_STICKY = (KBD_NUM|KBD_CAPS|KBD_SCRL) }; /** * Keyboard status, as used in the Event struct. */ struct KeyState { /** * Abstract key code (will be the same for any given key regardless * of modifiers being held at the same time. */ KeyCode keycode; /** * ASCII-value of the pressed key (if any). * This depends on modifiers, i.e. pressing the 'A' key results in * different values here depending on the status of shift, alt and * caps lock. This should be used rather than keycode for text input * to avoid keyboard layout issues. For example you cannot assume that * KEYCODE_0 without a modifier will be '0' (on AZERTY keyboards it is * not). */ uint16 ascii; /** * Status of the modifier keys. Bits are set in this for each * pressed modifier. * We distinguish 'non-sticky' and 'sticky' modifiers flags. The former * are only set while certain keys (ctrl, alt, shift) are pressed by the * user; the latter (num lock, caps lock, scroll lock) are activated when * certain keys are pressed and released; and deactivated when that key * is pressed and released a second time. * * @see KBD_CTRL, KBD_ALT, KBD_SHIFT, KBD_NUM, KBD_CAPS, KBD_SCRL */ byte flags; KeyState(KeyCode kc = KEYCODE_INVALID) { keycode = kc; ascii = (uint16)kc; flags = 0; } KeyState(KeyCode kc, uint16 asc, byte f = 0) { keycode = kc; ascii = asc; flags = f; } void reset() { keycode = KEYCODE_INVALID; ascii = flags = 0; } /** * Check whether the non-sticky flags are *exactly* as specified by f. * This ignores the sticky flags (KBD_NUM, KBD_CAPS, KBD_SCRL). * Sticky flags should never be passed to this function. * If you just want to check whether a modifier flag is set, just bit-and * the flag. E.g. to check whether the control key modifier is set, * you can write * if (keystate.flags & KBD_CTRL) { ... } */ bool hasFlags(byte f) const { assert(!(f & KBD_STICKY)); return f == (flags & ~KBD_STICKY); } /** * Check if two key states are equal. This implementation ignores the state * of the sticky flags (caps lock, num lock, scroll lock) completely. * @todo is this still being used? */ bool operator==(const KeyState &x) const { // Intentionally ignore ASCII, as the keycode and non-sticky flag // combination should suffice. return keycode == x.keycode && hasFlags(x.flags & ~KBD_STICKY); } }; /** @} */ } // End of namespace Common #endif