📄 sdl_sysevents.cc
字号:
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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@libsdl.org
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_sysevents.cc,v 1.4 2002/04/22 21:38:04 wmay Exp $";
#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 ) {
int x, y;
SDL_Win->GetXYOffset(x, y);
x = (int)point.x - x;
y = (int)point.y - y;
SDL_PrivateMouseMotion(0, 0, x, 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 the keyboard state */
key_flip = 0;
get_key_info(&keyinfo[key_flip]);
memcpy(keyinfo[!key_flip].key_states,
keyinfo[key_flip].key_states,
SDL_TABLESIZE(keyinfo[key_flip].key_states));
/* 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -