From 8e412322448053080c00a67f92fda4de183df7fa Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Sat, 3 Oct 2009 11:59:51 +0000 Subject: * Merge ioq3-r1464 * Use WM cursor when running windowed and UI module has input --- src/sdl/sdl_input.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 190 insertions(+), 16 deletions(-) (limited to 'src/sdl') diff --git a/src/sdl/sdl_input.c b/src/sdl/sdl_input.c index c209f0a5..98f8525a 100644 --- a/src/sdl/sdl_input.c +++ b/src/sdl/sdl_input.c @@ -77,7 +77,7 @@ static cvar_t *in_joystickNo = NULL; IN_PrintKey =============== */ -static void IN_PrintKey( const SDL_keysym *keysym, int key, qboolean down ) +static void IN_PrintKey( const SDL_keysym *keysym, keyNum_t key, qboolean down ) { if( down ) Com_Printf( "+ " ); @@ -100,15 +100,108 @@ static void IN_PrintKey( const SDL_keysym *keysym, int key, qboolean down ) if( keysym->mod & KMOD_MODE ) Com_Printf( " KMOD_MODE" ); if( keysym->mod & KMOD_RESERVED ) Com_Printf( " KMOD_RESERVED" ); + Com_Printf( " Q:%d(%s)", key, Key_KeynumToString( key ) ); + if( keysym->unicode ) { - Com_Printf( " %d", keysym->unicode ); + Com_Printf( " U:%d", keysym->unicode ); if( keysym->unicode > ' ' && keysym->unicode < '~' ) Com_Printf( "(%c)", (char)keysym->unicode ); } - Com_Printf( " %d(%s)\n", key, Key_KeynumToString( key ) ); + Com_Printf( "\n" ); +} + +#define MAX_CONSOLE_KEYS 16 + +/* +=============== +IN_IsConsoleKey +=============== +*/ +static qboolean IN_IsConsoleKey( keyNum_t key, const char character ) +{ + typedef struct consoleKey_s + { + enum + { + KEY, + CHARACTER + } type; + + union + { + keyNum_t key; + char character; + } u; + } consoleKey_t; + + static consoleKey_t consoleKeys[ MAX_CONSOLE_KEYS ]; + static int numConsoleKeys = 0; + int i; + + // Only parse the variable when it changes + if( cl_consoleKeys->modified ) + { + char *text_p, *token; + + cl_consoleKeys->modified = qfalse; + text_p = cl_consoleKeys->string; + numConsoleKeys = 0; + + while( numConsoleKeys < MAX_CONSOLE_KEYS ) + { + consoleKey_t *c = &consoleKeys[ numConsoleKeys ]; + char *keyName; + + token = COM_Parse( &text_p ); + if( !token[ 0 ] ) + break; + + c->u.key = Key_StringToKeynum( token ); + + // 0 isn't a key + if( c->u.key == 0 ) + continue; + + keyName = Key_KeynumToString( c->u.key ); + + if( strlen( keyName ) == 1 ) + { + c->type = CHARACTER; + c->u.character = *keyName; + } + else + c->type = KEY; + + numConsoleKeys++; + } + } + + // Use the character in preference to the key name + if( character != '\0' ) + key = 0; + + for( i = 0; i < numConsoleKeys; i++ ) + { + consoleKey_t *c = &consoleKeys[ i ]; + + switch( c->type ) + { + case KEY: + if( key && c->u.key == key ) + return qtrue; + break; + + case CHARACTER: + if( c->u.character == character ) + return qtrue; + break; + } + } + + return qfalse; } /* @@ -117,7 +210,7 @@ IN_TranslateSDLToQ3Key =============== */ static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym, - int *key, qboolean down ) + keyNum_t *key, qboolean down ) { static char buf[ 2 ] = { '\0', '\0' }; @@ -131,7 +224,7 @@ static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym, } else { - switch (keysym->sym) + switch( keysym->sym ) { case SDLK_PAGEUP: *key = K_PGUP; break; case SDLK_KP9: *key = K_KP_PGUP; break; @@ -218,15 +311,12 @@ static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym, } } - if( down && !( keysym->unicode & 0xFF80 ) ) + if( down && keysym->unicode && !( keysym->unicode & 0xFF80 ) ) { char ch = (char)keysym->unicode & 0x7F; switch( ch ) { - // So the key marked ~ always drops the console - case '~': *key = '~'; break; - case 127: // ASCII delete if( *key != K_DEL ) { @@ -240,13 +330,16 @@ static const char *IN_TranslateSDLToQ3Key( SDL_keysym *keysym, } } - // Never allow a '~' SE_CHAR event to be generated - if( *key == '~' ) - *buf = '\0'; - if( in_keyboardDebug->integer ) IN_PrintKey( keysym, *key, down ); + if( IN_IsConsoleKey( *key, *buf ) ) + { + // Console keys can't be bound or generate characters + *key = K_CONSOLE; + *buf = '\0'; + } + return buf; } @@ -278,6 +371,59 @@ static io_connect_t IN_GetIOHandle(void) // mac os x mouse accel hack } #endif +/* +=============== +IN_GobbleMotionEvents +=============== +*/ +static void IN_GobbleMotionEvents( void ) +{ + SDL_Event dummy[ 1 ]; + + // Gobble any mouse motion events + SDL_PumpEvents( ); + while( SDL_PeepEvents( dummy, 1, SDL_GETEVENT, + SDL_EVENTMASK( SDL_MOUSEMOTION ) ) ) { } +} + +/* +=============== +IN_GetUIMousePosition +=============== +*/ +static void IN_GetUIMousePosition( int *x, int *y ) +{ + if( uivm ) + { + int pos = VM_Call( uivm, UI_MOUSE_POSITION ); + *x = pos & 0xFFFF; + *y = ( pos >> 16 ) & 0xFFFF; + + *x = glConfig.vidWidth * *x / 640; + *y = glConfig.vidHeight * *y / 480; + } + else + { + *x = glConfig.vidWidth / 2; + *y = glConfig.vidHeight / 2; + } +} + +/* +=============== +IN_SetUIMousePosition +=============== +*/ +static void IN_SetUIMousePosition( int x, int y ) +{ + if( uivm ) + { + x = x * 640 / glConfig.vidWidth; + y = y * 480 / glConfig.vidHeight; + VM_Call( uivm, UI_SET_MOUSE_POSITION, x, y ); + } +} + /* =============== IN_ActivateMouse @@ -333,6 +479,8 @@ static void IN_ActivateMouse( void ) SDL_ShowCursor( 0 ); #endif SDL_WM_GrabInput( SDL_GRAB_ON ); + + IN_GobbleMotionEvents( ); } // in_nograb makes no sense in fullscreen mode @@ -365,7 +513,13 @@ static void IN_DeactivateMouse( void ) // Always show the cursor when the mouse is disabled, // but not when fullscreen if( !r_fullscreen->integer ) - SDL_ShowCursor( 1 ); + { + if( ( Key_GetCatcher( ) == KEYCATCH_UI ) && + ( SDL_GetAppState( ) & (SDL_APPMOUSEFOCUS|SDL_APPINPUTFOCUS) ) == (SDL_APPMOUSEFOCUS|SDL_APPINPUTFOCUS) ) + SDL_ShowCursor( 0 ); + else + SDL_ShowCursor( 1 ); + } if( !mouseAvailable ) return; @@ -391,11 +545,17 @@ static void IN_DeactivateMouse( void ) if( mouseActive ) { + IN_GobbleMotionEvents( ); + SDL_WM_GrabInput( SDL_GRAB_OFF ); // Don't warp the mouse unless the cursor is within the window if( SDL_GetAppState( ) & SDL_APPMOUSEFOCUS ) - SDL_WarpMouse( glConfig.vidWidth / 2, glConfig.vidHeight / 2 ); + { + int x, y; + IN_GetUIMousePosition( &x, &y ); + SDL_WarpMouse( x, y ); + } mouseActive = qfalse; } @@ -706,7 +866,7 @@ static void IN_ProcessEvents( void ) { SDL_Event e; const char *p = NULL; - int key = 0; + keyNum_t key = 0; if( !SDL_WasInit( SDL_INIT_VIDEO ) ) return; @@ -787,12 +947,15 @@ IN_Frame void IN_Frame( void ) { qboolean loading; + qboolean cursorShowing; + int x, y; IN_JoyMove( ); IN_ProcessEvents( ); // If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading loading = !!( cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE ); + cursorShowing = Key_GetCatcher( ) & KEYCATCH_UI; if( !r_fullscreen->integer && ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) ) { @@ -804,6 +967,11 @@ void IN_Frame( void ) // Loading in windowed mode IN_DeactivateMouse( ); } + else if( !r_fullscreen->integer && cursorShowing ) + { + // Use WM cursor when not fullscreen + IN_DeactivateMouse( ); + } else if( !( SDL_GetAppState() & SDL_APPINPUTFOCUS ) ) { // Window not got focus @@ -811,6 +979,12 @@ void IN_Frame( void ) } else IN_ActivateMouse( ); + + if( !mouseActive ) + { + SDL_GetMouseState( &x, &y ); + IN_SetUIMousePosition( x, y ); + } } /* -- cgit