Mercurial > sdl-ios-xcode
diff src/video/bwindow/SDL_sysevents.cc @ 0:74212992fb08
Initial revision
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Thu, 26 Apr 2001 16:45:43 +0000 |
parents | |
children | cf2af46e9e2a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/bwindow/SDL_sysevents.cc Thu Apr 26 16:45:43 2001 +0000 @@ -0,0 +1,433 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include <support/UTF8.h> +#include <stdio.h> +#include <string.h> +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_BWin.h" +#include "SDL_lowvideo.h" + +extern "C" { + +#include "SDL_events_c.h" +#include "SDL_sysevents.h" +#include "SDL_sysevents_c.h" + +/* A note on why the polling loops are necessary. + The BeOS Preview 2 implementation of BView->MouseMoved() only notifies + the view when the mouse enters or leaves the view. The documentation + says that you should loop and use GetMouse() to detect mouse motion. + The BeOS Preview 2 implementation of BView->KeyDown() and BView->KeyUp() + are only called for keys that generate ASCII characters. Since we want + to act like a low level raw keyboard, we need to poll the state of the + keys instead of catching the keys in callbacks. + These are documented portions of the BeBook for Preview Release 2 +*/ + +/* Table to convert scancodes to SDL virtual keys */ +static SDLKey keymap[128]; + +/* Function to convert from a key scancode to a UNICODE character */ +static key_map *be_keymap; +static int32 *option_caps_map[2], *option_map[2], *caps_map[2], *normal_map[2]; +static char *unicode_map; +static Uint16 TranslateScancode(int scancode) +{ + SDLMod modstate; + int shifted; + int32 index; /* Index into system unicode map */ + Uint16 unicode; + + /* Set the default character -- no character */ + unicode = 0; + + /* See whether or not the shift state is set */ + modstate = SDL_GetModState(); + if ( modstate & KMOD_SHIFT ) { + shifted = 1; + } else { + shifted = 0; + } + + if ( modstate & KMOD_NUM ) { + /* If numlock is on, numeric keypad keys have shift state inverted */ + switch (keymap[scancode]) { + case SDLK_KP0: + case SDLK_KP1: + case SDLK_KP2: + case SDLK_KP3: + case SDLK_KP4: + case SDLK_KP5: + case SDLK_KP6: + case SDLK_KP7: + case SDLK_KP8: + case SDLK_KP9: + case SDLK_KP_PERIOD: + case SDLK_KP_DIVIDE: + case SDLK_KP_MULTIPLY: + case SDLK_KP_MINUS: + case SDLK_KP_PLUS: + case SDLK_KP_ENTER: + case SDLK_KP_EQUALS: + shifted = !shifted; + break; + default: + break; + } + } + + /* Get the index based on modifier state */ + if ( modstate & KMOD_CTRL ) + index = be_keymap->control_map[scancode]; + else + if ( (modstate & KMOD_META) && (modstate & KMOD_CAPS) ) + index = option_caps_map[shifted][scancode]; + else + if ( modstate & KMOD_META ) + index = option_map[shifted][scancode]; + else + if ( modstate & KMOD_CAPS ) + index = caps_map[shifted][scancode]; + else + index = normal_map[shifted][scancode]; + + /* If there is a mapping, convert character from UTF-8 to UNICODE */ + if ( unicode_map[index] ) { + int32 state, srclen, dstlen; + unsigned char destbuf[2]; + + state = 0; + srclen = unicode_map[index++]; + dstlen = sizeof(destbuf); + convert_from_utf8(B_UNICODE_CONVERSION, + &unicode_map[index], &srclen, (char *)destbuf, &dstlen, + &state); + unicode = destbuf[0]; + unicode <<= 8; + unicode |= destbuf[1]; + + /* Keyboard input maps newline to carriage return */ + if ( unicode == '\n' ) { + unicode = '\r'; + } + + /* For some reason function keys map to control characters */ +# define CTRL(X) ((X)-'@') + switch (unicode) { + case CTRL('A'): + case CTRL('B'): + case CTRL('C'): + case CTRL('D'): + case CTRL('E'): + case CTRL('K'): + case CTRL('L'): + case CTRL('P'): + if ( ! (modstate & KMOD_CTRL) ) + unicode = 0; + break; + default: + break; + } + } + return(unicode); +} + +/* Function to translate a keyboard transition and queue the key event */ +static void QueueKey(int scancode, int pressed) +{ + SDL_keysym keysym; + + /* Set the keysym information */ + keysym.scancode = scancode; + keysym.sym = keymap[scancode]; + keysym.mod = KMOD_NONE; + if ( SDL_TranslateUNICODE ) { + keysym.unicode = TranslateScancode(scancode); + } else { + keysym.unicode = 0; + } + + /* NUMLOCK and CAPSLOCK are implemented as double-presses in reality */ + if ( (keysym.sym == SDLK_NUMLOCK) || (keysym.sym == SDLK_CAPSLOCK) ) { + pressed = 1; + } + + /* Queue the key event */ + if ( pressed ) { + SDL_PrivateKeyboard(SDL_PRESSED, &keysym); + } else { + SDL_PrivateKeyboard(SDL_RELEASED, &keysym); + } +} + +/* This is special because we know it will be run in a loop in a separate + thread. Normally this function should loop as long as there are input + states changing, i.e. new events arriving. +*/ +void BE_PumpEvents(_THIS) +{ + BView *view; + BRect bounds; + BPoint point; + uint32 buttons; + const uint32 button_masks[3] = { + B_PRIMARY_MOUSE_BUTTON, + B_TERTIARY_MOUSE_BUTTON, + B_SECONDARY_MOUSE_BUTTON, + }; + unsigned int i, j; + + /* Check out the mouse buttons and position (slight race condition) */ + if ( SDL_Win->Lock() ) { + /* Don't do anything if we have no view */ + view = SDL_Win->View(); + if ( ! view ) { + SDL_Win->Unlock(); + return; + } + bounds = view->Bounds(); + /* Get new input state, if still active */ + if ( SDL_Win->IsActive() ) { + key_flip = !key_flip; + get_key_info(&keyinfo[key_flip]); + view->GetMouse(&point, &buttons, true); + } else { + key_flip = key_flip; + point = last_point; + buttons = last_buttons; + } + SDL_Win->Unlock(); + } else { + return; + } + + /* If our view is active, we'll find key changes here */ + if ( memcmp(keyinfo[0].key_states, keyinfo[1].key_states, 16) != 0 ) { + for ( i=0; i<16; ++i ) { + Uint8 new_state, transition; + + new_state = keyinfo[key_flip].key_states[i]; + transition = keyinfo[!key_flip].key_states[i] ^ + keyinfo[ key_flip].key_states[i]; + for ( j=0; j<8; ++j ) { + if ( transition&0x80 ) + QueueKey(i*8+j, new_state&0x80); + transition <<= 1; + new_state <<= 1; + } + } + } + + /* We check keyboard, but not mouse if mouse isn't in window */ + if ( ! bounds.Contains(point) ) { + /* Mouse moved outside our view? */ + if ( SDL_GetAppState() & SDL_APPMOUSEFOCUS ) { + SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); + be_app->SetCursor(B_HAND_CURSOR); + } + return; + } + /* Has the mouse moved back into our view? */ + if ( ! (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { + /* Reset the B_HAND_CURSOR to our own */ + SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); + SDL_SetCursor(NULL); + } + + /* Check for mouse motion */ + if ( point != last_point ) { + SDL_PrivateMouseMotion(0, 0, (int)point.x, (int)point.y); + } + last_point = point; + + /* Add any mouse button events */ + for ( i=0; i<SDL_TABLESIZE(button_masks); ++i ) { + if ( (buttons ^ last_buttons) & button_masks[i] ) { + if ( buttons & button_masks[i] ) { + SDL_PrivateMouseButton(SDL_PRESSED, 1+i, 0, 0); + } else { + SDL_PrivateMouseButton(SDL_RELEASED, 1+i, 0, 0); + } + } + } + last_buttons = buttons; +} + +void BE_InitOSKeymap(_THIS) +{ + unsigned int i; + + /* Initialize all the key states as "up" */ + key_flip = 0; + memset(keyinfo[key_flip].key_states, 0, 16); + + /* Initialize the BeOS key translation table */ + /* Source: <be/interface/InterfaceDefs.h> and BeOS keyboard info */ + for ( i=0; i<SDL_TABLESIZE(keymap); ++i ) + keymap[i] = SDLK_UNKNOWN; + + keymap[0x01] = SDLK_ESCAPE; + keymap[B_F1_KEY] = SDLK_F1; + keymap[B_F2_KEY] = SDLK_F2; + keymap[B_F3_KEY] = SDLK_F3; + keymap[B_F4_KEY] = SDLK_F4; + keymap[B_F5_KEY] = SDLK_F5; + keymap[B_F6_KEY] = SDLK_F6; + keymap[B_F7_KEY] = SDLK_F7; + keymap[B_F8_KEY] = SDLK_F8; + keymap[B_F9_KEY] = SDLK_F9; + keymap[B_F10_KEY] = SDLK_F10; + keymap[B_F11_KEY] = SDLK_F11; + keymap[B_F12_KEY] = SDLK_F12; + keymap[B_PRINT_KEY] = SDLK_PRINT; + //keymap[B_SCROLL_KEY] = SDLK_SCROLLOCK; + keymap[B_PAUSE_KEY] = SDLK_PAUSE; + keymap[0x11] = SDLK_BACKQUOTE; + keymap[0x12] = SDLK_1; + keymap[0x13] = SDLK_2; + keymap[0x14] = SDLK_3; + keymap[0x15] = SDLK_4; + keymap[0x16] = SDLK_5; + keymap[0x17] = SDLK_6; + keymap[0x18] = SDLK_7; + keymap[0x19] = SDLK_8; + keymap[0x1a] = SDLK_9; + keymap[0x1b] = SDLK_0; + keymap[0x1c] = SDLK_MINUS; + keymap[0x1d] = SDLK_EQUALS; + keymap[0x1e] = SDLK_BACKSPACE; + keymap[0x1f] = SDLK_INSERT; + keymap[0x20] = SDLK_HOME; + keymap[0x21] = SDLK_PAGEUP; + //keymap[0x22] = SDLK_NUMLOCK; + keymap[0x23] = SDLK_KP_DIVIDE; + keymap[0x24] = SDLK_KP_MULTIPLY; + keymap[0x25] = SDLK_KP_MINUS; + keymap[0x26] = SDLK_TAB; + keymap[0x27] = SDLK_q; + keymap[0x28] = SDLK_w; + keymap[0x29] = SDLK_e; + keymap[0x2a] = SDLK_r; + keymap[0x2b] = SDLK_t; + keymap[0x2c] = SDLK_y; + keymap[0x2d] = SDLK_u; + keymap[0x2e] = SDLK_i; + keymap[0x2f] = SDLK_o; + keymap[0x30] = SDLK_p; + keymap[0x31] = SDLK_LEFTBRACKET; + keymap[0x32] = SDLK_RIGHTBRACKET; + keymap[0x33] = SDLK_BACKSLASH; + keymap[0x34] = SDLK_DELETE; + keymap[0x35] = SDLK_END; + keymap[0x36] = SDLK_PAGEDOWN; + keymap[0x37] = SDLK_KP7; + keymap[0x38] = SDLK_KP8; + keymap[0x39] = SDLK_KP9; + keymap[0x3a] = SDLK_KP_PLUS; + //keymap[0x3b] = SDLK_CAPSLOCK; + keymap[0x3c] = SDLK_a; + keymap[0x3d] = SDLK_s; + keymap[0x3e] = SDLK_d; + keymap[0x3f] = SDLK_f; + keymap[0x40] = SDLK_g; + keymap[0x41] = SDLK_h; + keymap[0x42] = SDLK_j; + keymap[0x43] = SDLK_k; + keymap[0x44] = SDLK_l; + keymap[0x45] = SDLK_SEMICOLON; + keymap[0x46] = SDLK_QUOTE; + keymap[0x47] = SDLK_RETURN; + keymap[0x48] = SDLK_KP4; + keymap[0x49] = SDLK_KP5; + keymap[0x4a] = SDLK_KP6; + keymap[0x4b] = SDLK_LSHIFT; + keymap[0x4c] = SDLK_z; + keymap[0x4d] = SDLK_x; + keymap[0x4e] = SDLK_c; + keymap[0x4f] = SDLK_v; + keymap[0x50] = SDLK_b; + keymap[0x51] = SDLK_n; + keymap[0x52] = SDLK_m; + keymap[0x53] = SDLK_COMMA; + keymap[0x54] = SDLK_PERIOD; + keymap[0x55] = SDLK_SLASH; + keymap[0x56] = SDLK_RSHIFT; + keymap[0x57] = SDLK_UP; + keymap[0x58] = SDLK_KP1; + keymap[0x59] = SDLK_KP2; + keymap[0x5a] = SDLK_KP3; + keymap[0x5b] = SDLK_KP_ENTER; + //keymap[0x5c] = SDLK_LCTRL; + //keymap[0x5d] = SDLK_LALT; + keymap[0x5e] = SDLK_SPACE; + //keymap[0x5f] = SDLK_RALT; + //keymap[0x60] = SDLK_RCTRL; + keymap[0x61] = SDLK_LEFT; + keymap[0x62] = SDLK_DOWN; + keymap[0x63] = SDLK_RIGHT; + keymap[0x64] = SDLK_KP0; + keymap[0x65] = SDLK_KP_PERIOD; + //keymap[0x66] = SDLK_LMETA; + //keymap[0x67] = SDLK_RMETA; + //keymap[0x68] = SDLK_MENU; + keymap[0x69] = SDLK_EURO; + keymap[0x6a] = SDLK_KP_EQUALS; + keymap[0x6b] = SDLK_POWER; + + /* Get the system keymap and UNICODE table. + Note that this leaks memory since the maps are never freed. + */ + get_key_map(&be_keymap, &unicode_map); + + /* Set the modifier keys from the system keymap */ + keymap[be_keymap->caps_key] = SDLK_CAPSLOCK; + keymap[be_keymap->scroll_key] = SDLK_SCROLLOCK; + keymap[be_keymap->num_key] = SDLK_NUMLOCK; + keymap[be_keymap->left_shift_key] = SDLK_LSHIFT; + keymap[be_keymap->right_shift_key] = SDLK_RSHIFT; + keymap[be_keymap->left_command_key] = SDLK_LALT; + keymap[be_keymap->right_command_key] = SDLK_RALT; + keymap[be_keymap->left_control_key] = SDLK_LCTRL; + keymap[be_keymap->right_control_key] = SDLK_RCTRL; + keymap[be_keymap->left_option_key] = SDLK_LMETA; + keymap[be_keymap->right_option_key] = SDLK_RMETA; + keymap[be_keymap->menu_key] = SDLK_MENU; + + /* Set the modifier map pointers */ + option_caps_map[0] = be_keymap->option_caps_map; + option_caps_map[1] = be_keymap->option_caps_shift_map; + option_map[0] = be_keymap->option_map; + option_map[1] = be_keymap->option_shift_map; + caps_map[0] = be_keymap->caps_map; + caps_map[1] = be_keymap->caps_shift_map; + normal_map[0] = be_keymap->normal_map; + normal_map[1] = be_keymap->shift_map; +} + +}; /* Extern C */