2018-10-22 00:28:24 +03:00
|
|
|
/*
|
2025-01-31 17:49:07 +03:00
|
|
|
in_sdl.c - SDL input component
|
|
|
|
Copyright (C) 2018-2025 a1batross
|
2018-10-22 00:28:24 +03:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program 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 General Public License for more details.
|
|
|
|
*/
|
|
|
|
#include <SDL.h>
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
#include "keydefs.h"
|
|
|
|
#include "input.h"
|
|
|
|
#include "client.h"
|
|
|
|
#include "vgui_draw.h"
|
|
|
|
#include "events.h"
|
|
|
|
#include "sound.h"
|
|
|
|
#include "vid_common.h"
|
|
|
|
|
2021-01-02 02:08:32 +00:00
|
|
|
#if !SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2019-10-25 17:11:27 +03:00
|
|
|
#define SDL_WarpMouseInWindow( win, x, y ) SDL_WarpMouse( ( x ), ( y ) )
|
2022-04-27 22:32:20 +04:00
|
|
|
#else
|
2022-05-30 03:33:03 +03:00
|
|
|
static struct
|
|
|
|
{
|
|
|
|
qboolean initialized;
|
|
|
|
SDL_Cursor *cursors[dc_last];
|
|
|
|
} cursors;
|
2019-10-25 17:11:27 +03:00
|
|
|
#endif
|
2018-10-22 00:28:24 +03:00
|
|
|
|
2025-02-22 17:35:45 +03:00
|
|
|
static struct
|
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
qboolean pushed;
|
|
|
|
} in_visible_cursor_pos;
|
|
|
|
|
2018-10-22 01:09:43 +03:00
|
|
|
/*
|
|
|
|
=============
|
|
|
|
Platform_GetMousePos
|
|
|
|
|
|
|
|
=============
|
|
|
|
*/
|
2020-01-19 08:15:54 +07:00
|
|
|
void GAME_EXPORT Platform_GetMousePos( int *x, int *y )
|
2018-10-22 01:09:43 +03:00
|
|
|
{
|
|
|
|
SDL_GetMouseState( x, y );
|
2024-02-23 20:54:26 +03:00
|
|
|
|
|
|
|
if( x && window_width.value && window_width.value != refState.width )
|
|
|
|
{
|
|
|
|
float factor = refState.width / window_width.value;
|
|
|
|
*x = *x * factor;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( y && window_height.value && window_height.value != refState.height )
|
|
|
|
{
|
|
|
|
float factor = refState.height / window_height.value;
|
|
|
|
*y = *y * factor;
|
|
|
|
}
|
2018-10-22 01:09:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=============
|
|
|
|
Platform_SetMousePos
|
|
|
|
|
|
|
|
============
|
|
|
|
*/
|
2020-01-19 08:15:54 +07:00
|
|
|
void GAME_EXPORT Platform_SetMousePos( int x, int y )
|
2018-10-22 01:09:43 +03:00
|
|
|
{
|
|
|
|
SDL_WarpMouseInWindow( host.hWnd, x, y );
|
|
|
|
}
|
|
|
|
|
2020-08-21 13:39:01 +03:00
|
|
|
/*
|
|
|
|
========================
|
|
|
|
Platform_MouseMove
|
|
|
|
|
|
|
|
========================
|
|
|
|
*/
|
|
|
|
void Platform_MouseMove( float *x, float *y )
|
|
|
|
{
|
|
|
|
int m_x, m_y;
|
2020-08-24 18:43:15 +03:00
|
|
|
SDL_GetRelativeMouseState( &m_x, &m_y );
|
2020-08-21 13:39:01 +03:00
|
|
|
*x = (float)m_x;
|
|
|
|
*y = (float)m_y;
|
|
|
|
}
|
|
|
|
|
2018-10-22 01:25:29 +03:00
|
|
|
/*
|
|
|
|
=============
|
|
|
|
Platform_GetClipobardText
|
|
|
|
|
|
|
|
=============
|
|
|
|
*/
|
2022-04-22 21:28:19 +04:00
|
|
|
int Platform_GetClipboardText( char *buffer, size_t size )
|
2018-10-22 01:25:29 +03:00
|
|
|
{
|
2019-10-25 17:11:27 +03:00
|
|
|
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2022-04-22 21:28:19 +04:00
|
|
|
int textLength;
|
2018-10-22 01:25:29 +03:00
|
|
|
char *sdlbuffer = SDL_GetClipboardText();
|
|
|
|
|
|
|
|
if( !sdlbuffer )
|
2022-04-22 21:28:19 +04:00
|
|
|
return 0;
|
2018-10-22 01:25:29 +03:00
|
|
|
|
2022-04-22 21:28:19 +04:00
|
|
|
if (buffer && size > 0)
|
|
|
|
{
|
|
|
|
textLength = Q_strncpy( buffer, sdlbuffer, size );
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
textLength = Q_strlen( sdlbuffer );
|
|
|
|
}
|
2018-10-22 01:25:29 +03:00
|
|
|
SDL_free( sdlbuffer );
|
2022-04-22 21:28:19 +04:00
|
|
|
return textLength;
|
2019-10-25 17:11:27 +03:00
|
|
|
#else // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2019-10-24 12:43:17 +03:00
|
|
|
buffer[0] = 0;
|
2019-10-25 17:11:27 +03:00
|
|
|
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2022-04-22 21:28:19 +04:00
|
|
|
return 0;
|
2018-10-22 01:25:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=============
|
|
|
|
Platform_SetClipobardText
|
|
|
|
|
|
|
|
=============
|
|
|
|
*/
|
2022-04-22 21:28:19 +04:00
|
|
|
void Platform_SetClipboardText( const char *buffer )
|
2018-10-22 01:25:29 +03:00
|
|
|
{
|
2019-10-25 17:11:27 +03:00
|
|
|
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2018-10-22 01:25:29 +03:00
|
|
|
SDL_SetClipboardText( buffer );
|
2019-10-25 17:11:27 +03:00
|
|
|
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2018-10-22 01:25:29 +03:00
|
|
|
}
|
|
|
|
|
2023-03-06 22:38:12 +01:00
|
|
|
#if !XASH_PSVITA
|
|
|
|
|
2018-10-22 00:28:24 +03:00
|
|
|
/*
|
|
|
|
=============
|
|
|
|
SDLash_EnableTextInput
|
|
|
|
|
|
|
|
=============
|
|
|
|
*/
|
|
|
|
void Platform_EnableTextInput( qboolean enable )
|
|
|
|
{
|
2019-10-25 17:11:27 +03:00
|
|
|
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2018-10-22 00:28:24 +03:00
|
|
|
enable ? SDL_StartTextInput() : SDL_StopTextInput();
|
2019-10-25 17:11:27 +03:00
|
|
|
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2018-10-22 00:28:24 +03:00
|
|
|
}
|
|
|
|
|
2023-03-06 22:38:12 +01:00
|
|
|
#endif // !XASH_PSVITA
|
|
|
|
|
2022-04-22 21:31:10 +04:00
|
|
|
/*
|
|
|
|
========================
|
|
|
|
SDLash_InitCursors
|
|
|
|
|
|
|
|
========================
|
|
|
|
*/
|
2022-05-30 03:33:03 +03:00
|
|
|
void SDLash_InitCursors( void )
|
2022-04-22 21:31:10 +04:00
|
|
|
{
|
2022-06-13 04:27:54 +03:00
|
|
|
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2022-05-30 03:33:03 +03:00
|
|
|
if( cursors.initialized )
|
|
|
|
SDLash_FreeCursors();
|
|
|
|
|
|
|
|
// load up all default cursors
|
|
|
|
cursors.cursors[dc_none] = NULL;
|
|
|
|
cursors.cursors[dc_arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
|
|
|
cursors.cursors[dc_ibeam] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
|
|
|
|
cursors.cursors[dc_hourglass] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
|
|
|
|
cursors.cursors[dc_crosshair] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR);
|
|
|
|
cursors.cursors[dc_up] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
|
|
|
cursors.cursors[dc_sizenwse] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
|
|
|
|
cursors.cursors[dc_sizenesw] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
|
|
|
|
cursors.cursors[dc_sizewe] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
|
|
|
|
cursors.cursors[dc_sizens] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
|
|
|
|
cursors.cursors[dc_sizeall] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
|
|
|
|
cursors.cursors[dc_no] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
|
|
|
|
cursors.cursors[dc_hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
|
|
|
|
cursors.initialized = true;
|
2022-06-13 04:27:54 +03:00
|
|
|
#endif
|
2022-05-30 03:33:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
========================
|
|
|
|
SDLash_FreeCursors
|
|
|
|
|
|
|
|
========================
|
|
|
|
*/
|
|
|
|
void SDLash_FreeCursors( void )
|
|
|
|
{
|
|
|
|
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
for( ; i < ARRAYSIZE( cursors.cursors ); i++ )
|
|
|
|
{
|
|
|
|
if( cursors.cursors[i] )
|
|
|
|
SDL_FreeCursor( cursors.cursors[i] );
|
|
|
|
cursors.cursors[i] = NULL;
|
2022-04-22 21:31:10 +04:00
|
|
|
}
|
2022-05-30 03:33:03 +03:00
|
|
|
|
|
|
|
cursors.initialized = false;
|
|
|
|
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2022-04-22 21:31:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
========================
|
|
|
|
Platform_SetCursorType
|
|
|
|
|
|
|
|
========================
|
|
|
|
*/
|
2022-04-27 22:32:20 +04:00
|
|
|
void Platform_SetCursorType( VGUI_DefaultCursor type )
|
2022-04-22 21:31:10 +04:00
|
|
|
{
|
|
|
|
qboolean visible;
|
|
|
|
|
|
|
|
switch( type )
|
|
|
|
{
|
2022-04-27 22:32:20 +04:00
|
|
|
case dc_user:
|
|
|
|
case dc_none:
|
2022-04-22 21:31:10 +04:00
|
|
|
visible = false;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
visible = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-10-12 05:18:19 +03:00
|
|
|
// never disable cursor in touch emulation mode
|
2024-07-29 05:06:10 +03:00
|
|
|
if( !visible && Touch_Emulated( ))
|
2022-04-22 21:31:10 +04:00
|
|
|
return;
|
|
|
|
|
2022-10-12 05:18:19 +03:00
|
|
|
host.mouse_visible = visible;
|
2022-11-08 04:03:50 +04:00
|
|
|
VGui_UpdateInternalCursorState( type );
|
2022-10-12 05:18:19 +03:00
|
|
|
|
2022-06-13 04:27:54 +03:00
|
|
|
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2022-07-09 01:21:42 +04:00
|
|
|
if( host.mouse_visible )
|
2022-04-22 21:31:10 +04:00
|
|
|
{
|
2025-02-22 17:35:45 +03:00
|
|
|
if( cursors.initialized )
|
|
|
|
SDL_SetCursor( cursors.cursors[type] );
|
|
|
|
|
2022-04-22 21:31:10 +04:00
|
|
|
SDL_ShowCursor( true );
|
2025-02-22 17:35:45 +03:00
|
|
|
|
|
|
|
// restore the last mouse position
|
|
|
|
if( in_visible_cursor_pos.pushed )
|
|
|
|
{
|
|
|
|
SDL_WarpMouseInWindow( host.hWnd, in_visible_cursor_pos.x, in_visible_cursor_pos.y );
|
|
|
|
in_visible_cursor_pos.pushed = false;
|
|
|
|
}
|
2022-04-22 21:31:10 +04:00
|
|
|
}
|
2022-07-09 01:21:42 +04:00
|
|
|
else
|
2022-04-22 21:31:10 +04:00
|
|
|
{
|
2025-02-22 17:35:45 +03:00
|
|
|
// save last mouse position and warp it to the center
|
|
|
|
if( !in_visible_cursor_pos.pushed )
|
|
|
|
{
|
|
|
|
SDL_GetMouseState( &in_visible_cursor_pos.x, &in_visible_cursor_pos.y );
|
|
|
|
SDL_WarpMouseInWindow( host.hWnd, host.window_center_x, host.window_center_y );
|
|
|
|
in_visible_cursor_pos.pushed = true;
|
|
|
|
}
|
|
|
|
|
2022-04-22 21:31:10 +04:00
|
|
|
SDL_ShowCursor( false );
|
|
|
|
}
|
2022-06-13 04:27:54 +03:00
|
|
|
#else
|
2022-07-09 01:21:42 +04:00
|
|
|
if( host.mouse_visible )
|
2022-06-13 04:27:54 +03:00
|
|
|
{
|
|
|
|
SDL_ShowCursor( true );
|
|
|
|
}
|
2022-07-09 01:21:42 +04:00
|
|
|
else
|
2022-06-13 04:27:54 +03:00
|
|
|
{
|
|
|
|
SDL_ShowCursor( false );
|
|
|
|
}
|
2022-04-22 21:31:10 +04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2022-04-22 21:33:07 +04:00
|
|
|
/*
|
|
|
|
========================
|
|
|
|
Platform_GetKeyModifiers
|
|
|
|
|
|
|
|
========================
|
|
|
|
*/
|
|
|
|
key_modifier_t Platform_GetKeyModifiers( void )
|
|
|
|
{
|
2022-04-27 23:09:20 +04:00
|
|
|
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
2022-04-22 21:33:07 +04:00
|
|
|
SDL_Keymod modFlags;
|
|
|
|
key_modifier_t resultFlags;
|
|
|
|
|
|
|
|
resultFlags = KeyModifier_None;
|
|
|
|
modFlags = SDL_GetModState();
|
|
|
|
if( FBitSet( modFlags, KMOD_LCTRL ))
|
|
|
|
SetBits( resultFlags, KeyModifier_LeftCtrl );
|
|
|
|
if( FBitSet( modFlags, KMOD_RCTRL ))
|
|
|
|
SetBits( resultFlags, KeyModifier_RightCtrl );
|
|
|
|
if( FBitSet( modFlags, KMOD_RSHIFT ))
|
|
|
|
SetBits( resultFlags, KeyModifier_RightShift );
|
|
|
|
if( FBitSet( modFlags, KMOD_LSHIFT ))
|
|
|
|
SetBits( resultFlags, KeyModifier_LeftShift );
|
|
|
|
if( FBitSet( modFlags, KMOD_LALT ))
|
|
|
|
SetBits( resultFlags, KeyModifier_LeftAlt );
|
|
|
|
if( FBitSet( modFlags, KMOD_RALT ))
|
|
|
|
SetBits( resultFlags, KeyModifier_RightAlt );
|
|
|
|
if( FBitSet( modFlags, KMOD_NUM ))
|
|
|
|
SetBits( resultFlags, KeyModifier_NumLock );
|
|
|
|
if( FBitSet( modFlags, KMOD_CAPS ))
|
|
|
|
SetBits( resultFlags, KeyModifier_CapsLock );
|
|
|
|
if( FBitSet( modFlags, KMOD_RGUI ))
|
|
|
|
SetBits( resultFlags, KeyModifier_RightSuper );
|
|
|
|
if( FBitSet( modFlags, KMOD_LGUI ))
|
|
|
|
SetBits( resultFlags, KeyModifier_LeftSuper );
|
|
|
|
|
|
|
|
return resultFlags;
|
2022-04-27 23:09:20 +04:00
|
|
|
#else
|
|
|
|
return KeyModifier_None;
|
|
|
|
#endif
|
2022-04-22 21:33:07 +04:00
|
|
|
}
|