From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/systems/sdl/sdlinput.c | 571 +++++++++++++++++++++++++++++++++ 1 file changed, 571 insertions(+) create mode 100755 Source/DirectFB/systems/sdl/sdlinput.c (limited to 'Source/DirectFB/systems/sdl/sdlinput.c') diff --git a/Source/DirectFB/systems/sdl/sdlinput.c b/Source/DirectFB/systems/sdl/sdlinput.c new file mode 100755 index 0000000..4b94b14 --- /dev/null +++ b/Source/DirectFB/systems/sdl/sdlinput.c @@ -0,0 +1,571 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include "sdl.h" + +#include + + +DFB_INPUT_DRIVER( sdlinput ) + +/* + * declaration of private data + */ +typedef struct { + CoreInputDevice *device; + DirectThread *thread; + DFBSDL *dfb_sdl; + int stop; +} SDLInputData; + + +static DFBInputEvent motionX = { + .type = DIET_UNKNOWN, + .axisabs = 0, +}; + +static DFBInputEvent motionY = { + .type = DIET_UNKNOWN, + .axisabs = 0, +}; + +static void +motion_compress( int x, int y ) +{ + if (motionX.axisabs != x) { + motionX.type = DIET_AXISMOTION; + motionX.flags = DIEF_AXISABS; + motionX.axis = DIAI_X; + motionX.axisabs = x; + } + + if (motionY.axisabs != y) { + motionY.type = DIET_AXISMOTION; + motionY.flags = DIEF_AXISABS; + motionY.axis = DIAI_Y; + motionY.axisabs = y; + } +} + +static void +motion_realize( SDLInputData *data ) +{ + if (motionX.type != DIET_UNKNOWN) { + if (motionY.type != DIET_UNKNOWN) { + /* let DirectFB know two events are coming */ + motionX.flags |= DIEF_FOLLOW; + } + + dfb_input_dispatch( data->device, &motionX ); + + motionX.type = DIET_UNKNOWN; + } + + if (motionY.type != DIET_UNKNOWN) { + dfb_input_dispatch( data->device, &motionY ); + + motionY.type = DIET_UNKNOWN; + } +} + +static bool +translate_key( SDLKey key, DFBInputEvent *evt ) +{ + evt->flags = DIEF_KEYID; + /* Numeric keypad */ + if (key >= SDLK_KP0 && key <= SDLK_KP9) { + evt->key_id = DIKI_KP_0 + key - SDLK_KP0; + return true; + } + + /* Function keys */ + if (key >= SDLK_F1 && key <= SDLK_F12) { + evt->key_id = DIKI_F1 + key - SDLK_F1; + return true; + } + + /* letter keys */ + if (key >= SDLK_a && key <= SDLK_z) { + evt->key_id = DIKI_A + key - SDLK_a; + return true; + } + + if (key >= SDLK_0 && key <= SDLK_9) { + evt->key_id = DIKI_0 + key - SDLK_0; + return true; + } + + switch (key) { + case SDLK_QUOTE: + evt->key_id = DIKI_QUOTE_RIGHT; + return true; + case SDLK_BACKQUOTE: + evt->key_id = DIKI_QUOTE_LEFT; + return true; + case SDLK_COMMA: + evt->key_id = DIKI_COMMA; + return true; + case SDLK_MINUS: + evt->key_id = DIKI_MINUS_SIGN; + return true; + case SDLK_PERIOD: + evt->key_id = DIKI_PERIOD; + return true; + case SDLK_SLASH: + evt->key_id = DIKI_SLASH; + return true; + case SDLK_SEMICOLON: + evt->key_id = DIKI_SEMICOLON; + return true; + case SDLK_LESS: + evt->key_id = DIKI_LESS_SIGN; + return true; + case SDLK_EQUALS: + evt->key_id = DIKI_EQUALS_SIGN; + return true; + case SDLK_LEFTBRACKET: + evt->key_id = DIKI_BRACKET_LEFT; + return true; + case SDLK_RIGHTBRACKET: + evt->key_id = DIKI_BRACKET_RIGHT; + return true; + case SDLK_BACKSLASH: + evt->key_id = DIKI_BACKSLASH; + return true; + /* Numeric keypad */ + case SDLK_KP_PERIOD: + evt->key_id = DIKI_KP_DECIMAL; + return true; + + case SDLK_KP_DIVIDE: + evt->key_id = DIKI_KP_DIV; + return true; + + case SDLK_KP_MULTIPLY: + evt->key_id = DIKI_KP_MULT; + return true; + + case SDLK_KP_MINUS: + evt->key_id = DIKI_KP_MINUS; + return true; + case SDLK_KP_PLUS: + evt->key_id = DIKI_KP_PLUS; + return true; + case SDLK_KP_ENTER: + evt->key_id = DIKI_KP_ENTER; + return true; + + case SDLK_KP_EQUALS: + evt->key_id = DIKI_KP_EQUAL; + return true; + case SDLK_ESCAPE: + evt->key_id = DIKI_ESCAPE; + return true; + case SDLK_TAB: + evt->key_id = DIKI_TAB; + return true; + case SDLK_RETURN: + evt->key_id = DIKI_ENTER; + return true; + case SDLK_SPACE: + evt->key_id = DIKI_SPACE; + return true; + case SDLK_BACKSPACE: + evt->key_id = DIKI_BACKSPACE; + return true; + case SDLK_INSERT: + evt->key_id = DIKI_INSERT; + return true; + case SDLK_DELETE: + evt->key_id = DIKI_DELETE; + return true; + case SDLK_PRINT: + evt->key_id = DIKI_PRINT; + return true; + case SDLK_PAUSE: + evt->key_id = DIKI_PAUSE; + return true; + /* Arrows + Home/End pad */ + case SDLK_UP: + evt->key_id = DIKI_UP; + return true; + + case SDLK_DOWN: + evt->key_id = DIKI_DOWN; + return true; + + case SDLK_RIGHT: + evt->key_id = DIKI_RIGHT; + return true; + case SDLK_LEFT: + evt->key_id = DIKI_LEFT; + return true; + case SDLK_HOME: + evt->key_id = DIKI_HOME; + return true; + case SDLK_END: + evt->key_id = DIKI_END; + return true; + + case SDLK_PAGEUP: + evt->key_id = DIKI_PAGE_UP; + return true; + + case SDLK_PAGEDOWN: + evt->key_id = DIKI_PAGE_DOWN; + return true; + + + /* Key state modifier keys */ + case SDLK_NUMLOCK: + evt->key_id = DIKI_NUM_LOCK; + return true; + + case SDLK_CAPSLOCK: + evt->key_id = DIKI_CAPS_LOCK; + return true; + case SDLK_SCROLLOCK: + evt->key_id = DIKI_SCROLL_LOCK; + return true; + case SDLK_RSHIFT: + evt->key_id = DIKI_SHIFT_R; + return true; + + case SDLK_LSHIFT: + evt->key_id = DIKI_SHIFT_L; + return true; + case SDLK_RCTRL: + evt->key_id = DIKI_CONTROL_R; + return true; + + case SDLK_LCTRL: + evt->key_id = DIKI_CONTROL_L; + return true; + + case SDLK_RALT: + evt->key_id = DIKI_ALT_R; + return true; + + case SDLK_LALT: + evt->key_id = DIKI_ALT_L; + return true; + + case SDLK_RMETA: + evt->key_id = DIKI_META_R; + return true; + + case SDLK_LMETA: + evt->key_id = DIKI_META_L; + return true; + + case SDLK_LSUPER: + evt->key_id = DIKI_SUPER_L; + return true; + + case SDLK_RSUPER: + evt->key_id = DIKI_SUPER_R; + return true; + + case SDLK_MODE: + evt->key_id = DIKI_ALT_R; + evt->flags |= DIEF_KEYSYMBOL; + evt->key_symbol = DIKS_ALTGR; + return true; + default: + break; + } + + evt->flags = DIEF_NONE; + return false; +} + +/* + * Input thread reading from device. + * Generates events on incoming data. + */ +static void* +sdlEventThread( DirectThread *thread, void *driver_data ) +{ + SDLInputData *data = (SDLInputData*) driver_data; + DFBSDL *dfb_sdl = data->dfb_sdl; + + while (!data->stop) { + DFBInputEvent evt; + SDL_Event event; + + fusion_skirmish_prevail( &dfb_sdl->lock ); + + /* Check for events */ + while ( SDL_PollEvent(&event) ) { + fusion_skirmish_dismiss( &dfb_sdl->lock ); + + switch (event.type) { + case SDL_MOUSEMOTION: + motion_compress( event.motion.x, event.motion.y ); + break; + + case SDL_MOUSEBUTTONUP: + case SDL_MOUSEBUTTONDOWN: + motion_realize( data ); + + if (event.type == SDL_MOUSEBUTTONDOWN) + evt.type = DIET_BUTTONPRESS; + else + evt.type = DIET_BUTTONRELEASE; + + evt.flags = DIEF_NONE; + + switch (event.button.button) { + case SDL_BUTTON_LEFT: + evt.button = DIBI_LEFT; + break; + case SDL_BUTTON_MIDDLE: + evt.button = DIBI_MIDDLE; + break; + case SDL_BUTTON_RIGHT: + evt.button = DIBI_RIGHT; + break; + case SDL_BUTTON_WHEELUP: + case SDL_BUTTON_WHEELDOWN: + if (event.type != SDL_MOUSEBUTTONDOWN) { + fusion_skirmish_prevail( &dfb_sdl->lock ); + continue; + } + evt.type = DIET_AXISMOTION; + evt.flags = DIEF_AXISREL; + evt.axis = DIAI_Z; + if (event.button.button == SDL_BUTTON_WHEELUP) + evt.axisrel = -1; + else + evt.axisrel = 1; + break; + default: + fusion_skirmish_prevail( &dfb_sdl->lock ); + continue; + } + + dfb_input_dispatch( data->device, &evt ); + break; + + case SDL_KEYUP: + case SDL_KEYDOWN: + if (event.type == SDL_KEYDOWN) + evt.type = DIET_KEYPRESS; + else + evt.type = DIET_KEYRELEASE; + + /* Get a key id first */ + translate_key( event.key.keysym.sym, &evt ); + + /* If SDL provided a symbol, use it */ + if (event.key.keysym.unicode) { + evt.flags |= DIEF_KEYSYMBOL; + evt.key_symbol = event.key.keysym.unicode; + + /** + * Hack to translate the Control+[letter] + * combination to + * Modifier: CONTROL, Key Symbol: [letter] + * A side effect here is that Control+Backspace + * produces Control+h + */ + if (evt.modifiers == DIMM_CONTROL && + evt.key_symbol >= 1 && evt.key_symbol <= ('z'-'a'+1)) + { + evt.key_symbol += 'a'-1; + } + } + + dfb_input_dispatch( data->device, &evt ); + break; + case SDL_QUIT: + evt.type = DIET_KEYPRESS; + evt.flags = DIEF_KEYSYMBOL; + evt.key_symbol = DIKS_ESCAPE; + + dfb_input_dispatch( data->device, &evt ); + + evt.type = DIET_KEYRELEASE; + evt.flags = DIEF_KEYSYMBOL; + evt.key_symbol = DIKS_ESCAPE; + + dfb_input_dispatch( data->device, &evt ); + break; + + default: + break; + } + + fusion_skirmish_prevail( &dfb_sdl->lock ); + } + + fusion_skirmish_dismiss( &dfb_sdl->lock ); + + motion_realize( data ); + + usleep(10000); + + direct_thread_testcancel( thread ); + } + + return NULL; +} + +/* exported symbols */ + +/* + * Return the number of available devices. + * Called once during initialization of DirectFB. + */ +static int +driver_get_available( void ) +{ + if (dfb_system_type() == CORE_SDL) + return 1; + + return 0; +} + +/* + * Fill out general information about this driver. + * Called once during initialization of DirectFB. + */ +static void +driver_get_info( InputDriverInfo *info ) +{ + /* fill driver info structure */ + snprintf ( info->name, + DFB_INPUT_DRIVER_INFO_NAME_LENGTH, "SDL Input Driver" ); + snprintf ( info->vendor, + DFB_INPUT_DRIVER_INFO_VENDOR_LENGTH, "Denis Oliver Kropp" ); + + info->version.major = 0; + info->version.minor = 1; +} + +/* + * Open the device, fill out information about it, + * allocate and fill private data, start input thread. + * Called during initialization, resuming or taking over mastership. + */ +static DFBResult +driver_open_device( CoreInputDevice *device, + unsigned int number, + InputDeviceInfo *info, + void **driver_data ) +{ + SDLInputData *data; + DFBSDL *dfb_sdl = dfb_system_data(); + + fusion_skirmish_prevail( &dfb_sdl->lock ); + + SDL_EnableUNICODE( true ); + + SDL_EnableKeyRepeat( 250, 40 ); + + fusion_skirmish_dismiss( &dfb_sdl->lock ); + + /* set device name */ + snprintf( info->desc.name, + DFB_INPUT_DEVICE_DESC_NAME_LENGTH, "SDL Input" ); + + /* set device vendor */ + snprintf( info->desc.vendor, + DFB_INPUT_DEVICE_DESC_VENDOR_LENGTH, "SDL" ); + + /* set one of the primary input device IDs */ + info->prefered_id = DIDID_KEYBOARD; + + /* set type flags */ + info->desc.type = DIDTF_JOYSTICK | DIDTF_KEYBOARD | DIDTF_MOUSE; + + /* set capabilities */ + info->desc.caps = DICAPS_ALL; + + + /* allocate and fill private data */ + data = D_CALLOC( 1, sizeof(SDLInputData) ); + + data->device = device; + data->dfb_sdl = dfb_sdl; + + /* start input thread */ + data->thread = direct_thread_create( DTT_INPUT, sdlEventThread, data, "SDL Input" ); + + /* set private data pointer */ + *driver_data = data; + + return DFB_OK; +} + +/* + * Fetch one entry from the device's keymap if supported. + */ +static DFBResult +driver_get_keymap_entry( CoreInputDevice *device, + void *driver_data, + DFBInputDeviceKeymapEntry *entry ) +{ + return DFB_UNSUPPORTED; +} +/* + * End thread, close device and free private data. + */ +static void +driver_close_device( void *driver_data ) +{ + SDLInputData *data = (SDLInputData*) driver_data; + + /* stop input thread */ + data->stop = 1; + + direct_thread_join( data->thread ); + direct_thread_destroy( data->thread ); + + /* free private data */ + D_FREE ( data ); +} + -- cgit