diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cgame/cg_main.c | 4 | ||||
-rw-r--r-- | src/client/cl_keys.c | 7 | ||||
-rw-r--r-- | src/client/cl_main.c | 5 | ||||
-rw-r--r-- | src/client/client.h | 3 | ||||
-rw-r--r-- | src/client/keycodes.h | 3 | ||||
-rw-r--r-- | src/qcommon/common.c | 103 | ||||
-rw-r--r-- | src/sdl/sdl_input.c | 206 | ||||
-rw-r--r-- | src/ui/ui_main.c | 36 | ||||
-rw-r--r-- | src/ui/ui_public.h | 6 |
9 files changed, 290 insertions, 83 deletions
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c index da38ebae..4abe55f1 100644 --- a/src/cgame/cg_main.c +++ b/src/cgame/cg_main.c @@ -77,9 +77,7 @@ intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, return 0; case CG_MOUSE_EVENT: - cgDC.cursorx = cgs.cursorX; - cgDC.cursory = cgs.cursorY; - CG_MouseEvent( arg0, arg1 ); + // cgame doesn't care where the cursor is return 0; case CG_EVENT_HANDLING: diff --git a/src/client/cl_keys.c b/src/client/cl_keys.c index 8b9dcf4d..ee075ce5 100644 --- a/src/client/cl_keys.c +++ b/src/client/cl_keys.c @@ -1124,7 +1124,7 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) { } // console key is hardcoded, so the user can never unbind it - if (key == '`' || key == '~' || + if (key == K_CONSOLE || ( key == K_ESCAPE && keys[K_SHIFT].down ) ) { if (!down) { return; @@ -1259,11 +1259,6 @@ Normal keyboard characters, already shifted / capslocked / etc =================== */ void CL_CharEvent( int key ) { - // the console key should never be used as a char - if ( key == '`' || key == '~' ) { - return; - } - // delete is not a printable character and is // otherwise handled by Field_KeyDownEvent if ( key == 127 ) { diff --git a/src/client/cl_main.c b/src/client/cl_main.c index 0bba97d0..f91c80b2 100644 --- a/src/client/cl_main.c +++ b/src/client/cl_main.c @@ -97,6 +97,8 @@ cvar_t *cl_lanForcePackets; cvar_t *cl_guidServerUniq; +cvar_t *cl_consoleKeys; + clientActive_t cl; clientConnection_t clc; clientStatic_t cls; @@ -3016,6 +3018,9 @@ void CL_Init( void ) { cl_guidServerUniq = Cvar_Get ("cl_guidServerUniq", "1", CVAR_ARCHIVE); + // 0x7e = ~ and 0x60 = ` + cl_consoleKeys = Cvar_Get( "cl_consoleKeys", "0x7e 0x60", CVAR_ARCHIVE); + // userinfo Cvar_Get ("name", Sys_GetCurrentUser( ), CVAR_USERINFO | CVAR_ARCHIVE ); diff --git a/src/client/client.h b/src/client/client.h index d7f430cb..f19c6230 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -401,6 +401,8 @@ extern cvar_t *cl_inGameVideo; extern cvar_t *cl_lanForcePackets; extern cvar_t *cl_autoRecordDemo; +extern cvar_t *cl_consoleKeys; + #ifdef USE_MUMBLE extern cvar_t *cl_useMumble; extern cvar_t *cl_mumbleScale; @@ -489,6 +491,7 @@ void IN_CenterView (void); void CL_VerifyCode( void ); float CL_KeyState (kbutton_t *key); +int Key_StringToKeynum( char *str ); char *Key_KeynumToString (int keynum); // diff --git a/src/client/keycodes.h b/src/client/keycodes.h index ae6f189d..8911b0fc 100644 --- a/src/client/keycodes.h +++ b/src/client/keycodes.h @@ -262,6 +262,9 @@ typedef enum { K_EURO, K_UNDO, + // Pseudo-key that brings the console down + K_CONSOLE, + MAX_KEYS } keyNum_t; diff --git a/src/qcommon/common.c b/src/qcommon/common.c index f16234c2..7c98d45e 100644 --- a/src/qcommon/common.c +++ b/src/qcommon/common.c @@ -2983,37 +2983,52 @@ static char *Field_FindFirstSeparator( char *s ) return NULL; } -#ifndef DEDICATED /* =============== -Field_CompleteKeyname +Field_Complete =============== */ -static void Field_CompleteKeyname( void ) +static qboolean Field_Complete( void ) { - matchCount = 0; - shortestMatch[ 0 ] = 0; - - Key_KeynameCompletion( FindMatches ); + int completionOffset; if( matchCount == 0 ) - return; + return qfalse; + + completionOffset = strlen( completionField->buffer ) - strlen( completionString ); + + Q_strncpyz( &completionField->buffer[ completionOffset ], shortestMatch, + sizeof( completionField->buffer ) - completionOffset ); - Q_strncpyz( &completionField->buffer[ strlen( completionField->buffer ) - - strlen( completionString ) ], shortestMatch, - sizeof( completionField->buffer ) ); completionField->cursor = strlen( completionField->buffer ); if( matchCount == 1 ) { Q_strcat( completionField->buffer, sizeof( completionField->buffer ), " " ); completionField->cursor++; - return; + return qtrue; } Com_Printf( "]%s\n", completionField->buffer ); - - Key_KeynameCompletion( PrintMatches ); + + return qfalse; +} + +#ifndef DEDICATED +/* +=============== +Field_CompleteKeyname +=============== +*/ +static void Field_CompleteKeyname( void ) +{ + matchCount = 0; + shortestMatch[ 0 ] = 0; + + Key_KeynameCompletion( FindMatches ); + + if( !Field_Complete( ) ) + Key_KeynameCompletion( PrintMatches ); } #endif @@ -3030,24 +3045,8 @@ static void Field_CompleteFilename( const char *dir, FS_FilenameCompletion( dir, ext, stripExt, FindMatches ); - if( matchCount == 0 ) - return; - - Q_strncpyz( &completionField->buffer[ strlen( completionField->buffer ) - - strlen( completionString ) ], shortestMatch, - sizeof( completionField->buffer ) ); - completionField->cursor = strlen( completionField->buffer ); - - if( matchCount == 1 ) - { - Q_strcat( completionField->buffer, sizeof( completionField->buffer ), " " ); - completionField->cursor++; - return; - } - - Com_Printf( "]%s\n", completionField->buffer ); - - FS_FilenameCompletion( dir, ext, stripExt, PrintMatches ); + if( !Field_Complete( ) ) + FS_FilenameCompletion( dir, ext, stripExt, PrintMatches ); } /* @@ -3185,13 +3184,19 @@ static void Field_CompleteCommand( char *cmd, Field_CompleteCommand( p, qtrue, qtrue ); } } + else if( !Q_stricmp( baseCmd, "unbind" ) && completionArgument == 2 ) + { + // Skip "unbind " + p = Com_SkipTokens( cmd, 1, " " ); + + if( p > cmd ) + Field_CompleteKeyname( ); + } #endif } } else { - int completionOffset; - if( completionString[0] == '\\' || completionString[0] == '/' ) completionString++; @@ -3207,31 +3212,15 @@ static void Field_CompleteCommand( char *cmd, if( doCvars ) Cvar_CommandCompletion( FindMatches ); - if( matchCount == 0 ) - return; // no matches - - completionOffset = strlen( completionField->buffer ) - strlen( completionString ); - - Q_strncpyz( &completionField->buffer[ completionOffset ], shortestMatch, - sizeof( completionField->buffer ) - completionOffset ); - - completionField->cursor = strlen( completionField->buffer ); - - if( matchCount == 1 ) + if( !Field_Complete( ) ) { - Q_strcat( completionField->buffer, sizeof( completionField->buffer ), " " ); - completionField->cursor++; - return; - } + // run through again, printing matches + if( doCommands ) + Cmd_CommandCompletion( PrintMatches ); - Com_Printf( "]%s\n", completionField->buffer ); - - // run through again, printing matches - if( doCommands ) - Cmd_CommandCompletion( PrintMatches ); - - if( doCvars ) - Cvar_CommandCompletion( PrintCvarMatches ); + if( doCvars ) + Cvar_CommandCompletion( PrintCvarMatches ); + } } } 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; } @@ -280,6 +373,59 @@ static io_connect_t IN_GetIOHandle(void) // mac os x mouse accel hack /* =============== +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 ); + } } /* diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c index d19d5824..304222af 100644 --- a/src/ui/ui_main.c +++ b/src/ui/ui_main.c @@ -139,6 +139,8 @@ void UI_Init( qboolean ); void UI_Shutdown( void ); void UI_KeyEvent( int key, qboolean down ); void UI_MouseEvent( int dx, int dy ); +int UI_MousePosition( void ); +void UI_SetMousePosition( int x, int y ); void UI_Refresh( int realtime ); qboolean UI_IsFullscreen( void ); void UI_SetActiveMenu( uiMenuCommand_t menu ); @@ -167,6 +169,13 @@ intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, UI_MouseEvent( arg0, arg1 ); return 0; + case UI_MOUSE_POSITION: + return UI_MousePosition( ); + + case UI_SET_MOUSE_POSITION: + UI_SetMousePosition( arg0, arg1 ); + return 0; + case UI_REFRESH: UI_Refresh( arg0 ); return 0; @@ -4014,7 +4023,32 @@ void UI_MouseEvent( int dx, int dy ) else if( uiInfo.uiDC.cursory > SCREEN_HEIGHT ) uiInfo.uiDC.cursory = SCREEN_HEIGHT; - if( Menu_Count() > 0 ) + if( Menu_Count( ) > 0 ) + Display_MouseMove( NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory ); +} + +/* +================= +UI_MousePosition +================= +*/ +int UI_MousePosition( void ) +{ + return (int)rint( uiInfo.uiDC.cursorx ) | + (int)rint( uiInfo.uiDC.cursory ) << 16; +} + +/* +================= +UI_SetMousePosition +================= +*/ +void UI_SetMousePosition( int x, int y ) +{ + uiInfo.uiDC.cursorx = x; + uiInfo.uiDC.cursory = y; + + if( Menu_Count( ) > 0 ) Display_MouseMove( NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory ); } diff --git a/src/ui/ui_public.h b/src/ui/ui_public.h index 3de3bc7f..26c6fbd4 100644 --- a/src/ui/ui_public.h +++ b/src/ui/ui_public.h @@ -172,6 +172,12 @@ typedef enum UI_MOUSE_EVENT, // void UI_MouseEvent( int dx, int dy ); + UI_MOUSE_POSITION, + // int UI_MousePosition( void ); + + UI_SET_MOUSE_POSITION, + // void UI_SetMousePosition( int x, int y ); + UI_REFRESH, // void UI_Refresh( int time ); |