mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-02-10 01:31:14 +00:00
Before, "gamekey" was the special case, now "textmode" is. We are now more precise about when we activate "textmode", e.g. we only do this when the console, messagemode, or a textfield in the menu are active. The trigger for doing this was this line on the "SDL_StartTextInput" page of the SDL2 wiki: "On some platforms using this function activates the screen keyboard.". Although we currenly support no such platform, it's good te be prepared, and what we do now is more correct anyway. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1066 af15c1b1-3010-417e-b628-4374ebc0bcbd
696 lines
18 KiB
C
696 lines
18 KiB
C
/*
|
||
Copyright (C) 1996-2001 Id Software, Inc.
|
||
Copyright (C) 2002-2005 John Fitzgibbons and others
|
||
Copyright (C) 2007-2008 Kristian Duske
|
||
Copyright (C) 2010-2014 QuakeSpasm developers
|
||
|
||
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 2
|
||
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.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with this program; if not, write to the Free Software
|
||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
|
||
*/
|
||
|
||
#include "quakedef.h"
|
||
#if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG)
|
||
#if defined(USE_SDL2)
|
||
#include <SDL2/SDL.h>
|
||
#else
|
||
#include <SDL/SDL.h>
|
||
#endif
|
||
#else
|
||
#include "SDL.h"
|
||
#endif
|
||
|
||
static qboolean textmode;
|
||
|
||
#ifdef __APPLE__
|
||
/* Mouse acceleration needs to be disabled on OS X */
|
||
#define MACOS_X_ACCELERATION_HACK
|
||
#endif
|
||
|
||
#ifdef MACOS_X_ACCELERATION_HACK
|
||
#include <IOKit/IOTypes.h>
|
||
#include <IOKit/hidsystem/IOHIDLib.h>
|
||
#include <IOKit/hidsystem/IOHIDParameter.h>
|
||
#include <IOKit/hidsystem/event_status_driver.h>
|
||
#endif
|
||
|
||
static qboolean no_mouse = false;
|
||
|
||
static int buttonremap[] =
|
||
{
|
||
K_MOUSE1,
|
||
K_MOUSE3, /* right button */
|
||
K_MOUSE2, /* middle button */
|
||
#if !defined(USE_SDL2) /* mousewheel up/down not counted as buttons in SDL2 */
|
||
K_MWHEELUP,
|
||
K_MWHEELDOWN,
|
||
#endif
|
||
K_MOUSE4,
|
||
K_MOUSE5
|
||
};
|
||
|
||
/* mouse variables */
|
||
cvar_t m_filter = {"m_filter","0",CVAR_NONE};
|
||
|
||
/* total accumulated mouse movement since last frame,
|
||
* gets updated from the main game loop via IN_MouseMove */
|
||
static int total_dx, total_dy = 0;
|
||
|
||
static int IN_FilterMouseEvents (const SDL_Event *event)
|
||
{
|
||
switch (event->type)
|
||
{
|
||
case SDL_MOUSEMOTION:
|
||
// case SDL_MOUSEBUTTONDOWN:
|
||
// case SDL_MOUSEBUTTONUP:
|
||
return 0;
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
#if defined(USE_SDL2)
|
||
static int IN_SDL2_FilterMouseEvents (void *userdata, SDL_Event *event)
|
||
{
|
||
return IN_FilterMouseEvents (event);
|
||
}
|
||
#endif
|
||
|
||
static void IN_BeginIgnoringMouseEvents()
|
||
{
|
||
#if defined(USE_SDL2)
|
||
SDL_EventFilter currentFilter = NULL;
|
||
void *currentUserdata = NULL;
|
||
SDL_GetEventFilter(¤tFilter, ¤tUserdata);
|
||
|
||
if (currentFilter != IN_SDL2_FilterMouseEvents)
|
||
SDL_SetEventFilter(IN_SDL2_FilterMouseEvents, NULL);
|
||
#else
|
||
if (SDL_GetEventFilter() != IN_FilterMouseEvents)
|
||
SDL_SetEventFilter(IN_FilterMouseEvents);
|
||
#endif
|
||
}
|
||
|
||
static void IN_EndIgnoringMouseEvents()
|
||
{
|
||
#if defined(USE_SDL2)
|
||
SDL_EventFilter currentFilter;
|
||
void *currentUserdata;
|
||
if (SDL_GetEventFilter(¤tFilter, ¤tUserdata) == SDL_TRUE)
|
||
SDL_SetEventFilter(NULL, NULL);
|
||
#else
|
||
if (SDL_GetEventFilter() != NULL)
|
||
SDL_SetEventFilter(NULL);
|
||
#endif
|
||
}
|
||
|
||
#ifdef MACOS_X_ACCELERATION_HACK
|
||
static cvar_t in_disablemacosxmouseaccel = {"in_disablemacosxmouseaccel", "1", CVAR_ARCHIVE};
|
||
static double originalMouseSpeed = -1.0;
|
||
|
||
static io_connect_t IN_GetIOHandle(void)
|
||
{
|
||
io_connect_t iohandle = MACH_PORT_NULL;
|
||
io_service_t iohidsystem = MACH_PORT_NULL;
|
||
mach_port_t masterport;
|
||
kern_return_t status;
|
||
|
||
status = IOMasterPort(MACH_PORT_NULL, &masterport);
|
||
if (status != KERN_SUCCESS)
|
||
return 0;
|
||
|
||
iohidsystem = IORegistryEntryFromPath(masterport, kIOServicePlane ":/IOResources/IOHIDSystem");
|
||
if (!iohidsystem)
|
||
return 0;
|
||
|
||
status = IOServiceOpen(iohidsystem, mach_task_self(), kIOHIDParamConnectType, &iohandle);
|
||
IOObjectRelease(iohidsystem);
|
||
|
||
return iohandle;
|
||
}
|
||
|
||
static void IN_DisableOSXMouseAccel (void)
|
||
{
|
||
io_connect_t mouseDev = IN_GetIOHandle();
|
||
if (mouseDev != 0)
|
||
{
|
||
if (IOHIDGetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), &originalMouseSpeed) == kIOReturnSuccess)
|
||
{
|
||
if (IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), -1.0) != kIOReturnSuccess)
|
||
{
|
||
Cvar_Set("in_disablemacosxmouseaccel", "0");
|
||
Con_Printf("WARNING: Could not disable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Cvar_Set("in_disablemacosxmouseaccel", "0");
|
||
Con_Printf("WARNING: Could not disable mouse acceleration (failed at IOHIDGetAccelerationWithKey).\n");
|
||
}
|
||
IOServiceClose(mouseDev);
|
||
}
|
||
else
|
||
{
|
||
Cvar_Set("in_disablemacosxmouseaccel", "0");
|
||
Con_Printf("WARNING: Could not disable mouse acceleration (failed at IO_GetIOHandle).\n");
|
||
}
|
||
}
|
||
|
||
static void IN_ReenableOSXMouseAccel (void)
|
||
{
|
||
io_connect_t mouseDev = IN_GetIOHandle();
|
||
if (mouseDev != 0)
|
||
{
|
||
if (IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), originalMouseSpeed) != kIOReturnSuccess)
|
||
Con_Printf("WARNING: Could not re-enable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
|
||
IOServiceClose(mouseDev);
|
||
}
|
||
else
|
||
{
|
||
Con_Printf("WARNING: Could not re-enable mouse acceleration (failed at IO_GetIOHandle).\n");
|
||
}
|
||
originalMouseSpeed = -1;
|
||
}
|
||
#endif /* MACOS_X_ACCELERATION_HACK */
|
||
|
||
|
||
void IN_Activate (void)
|
||
{
|
||
if (no_mouse)
|
||
return;
|
||
|
||
#ifdef MACOS_X_ACCELERATION_HACK
|
||
/* Save the status of mouse acceleration */
|
||
if (originalMouseSpeed == -1 && in_disablemacosxmouseaccel.value)
|
||
IN_DisableOSXMouseAccel();
|
||
#endif
|
||
|
||
#if defined(USE_SDL2)
|
||
if (SDL_SetRelativeMouseMode(SDL_TRUE) != 0)
|
||
{
|
||
Con_Printf("WARNING: SDL_SetRelativeMouseMode(SDL_TRUE) failed.\n");
|
||
}
|
||
#else
|
||
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_ON)
|
||
{
|
||
SDL_WM_GrabInput(SDL_GRAB_ON);
|
||
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_ON)
|
||
Con_Printf("WARNING: SDL_WM_GrabInput(SDL_GRAB_ON) failed.\n");
|
||
}
|
||
|
||
if (SDL_ShowCursor(SDL_QUERY) != SDL_DISABLE)
|
||
{
|
||
SDL_ShowCursor(SDL_DISABLE);
|
||
if (SDL_ShowCursor(SDL_QUERY) != SDL_DISABLE)
|
||
Con_Printf("WARNING: SDL_ShowCursor(SDL_DISABLE) failed.\n");
|
||
}
|
||
#endif
|
||
|
||
IN_EndIgnoringMouseEvents();
|
||
|
||
total_dx = 0;
|
||
total_dy = 0;
|
||
}
|
||
|
||
void IN_Deactivate (qboolean free_cursor)
|
||
{
|
||
if (no_mouse)
|
||
return;
|
||
|
||
#ifdef MACOS_X_ACCELERATION_HACK
|
||
if (originalMouseSpeed != -1)
|
||
IN_ReenableOSXMouseAccel();
|
||
#endif
|
||
|
||
if (free_cursor)
|
||
{
|
||
#if defined(USE_SDL2)
|
||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||
#else
|
||
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_OFF)
|
||
{
|
||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
||
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_OFF)
|
||
Con_Printf("WARNING: SDL_WM_GrabInput(SDL_GRAB_OFF) failed.\n");
|
||
}
|
||
|
||
if (SDL_ShowCursor(SDL_QUERY) != SDL_ENABLE)
|
||
{
|
||
SDL_ShowCursor(SDL_ENABLE);
|
||
if (SDL_ShowCursor(SDL_QUERY) != SDL_ENABLE)
|
||
Con_Printf("WARNING: SDL_ShowCursor(SDL_ENABLE) failed.\n");
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/* discard all mouse events when input is deactivated */
|
||
IN_BeginIgnoringMouseEvents();
|
||
}
|
||
|
||
void IN_Init (void)
|
||
{
|
||
textmode = Key_InputtingText();
|
||
|
||
#if !defined(USE_SDL2)
|
||
SDL_EnableUNICODE (textmode);
|
||
if (SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL) == -1)
|
||
Con_Printf("Warning: SDL_EnableKeyRepeat() failed.\n");
|
||
#endif
|
||
if (safemode || COM_CheckParm("-nomouse"))
|
||
{
|
||
no_mouse = true;
|
||
/* discard all mouse events when input is deactivated */
|
||
IN_BeginIgnoringMouseEvents();
|
||
}
|
||
|
||
#ifdef MACOS_X_ACCELERATION_HACK
|
||
Cvar_RegisterVariable(&in_disablemacosxmouseaccel);
|
||
#endif
|
||
|
||
IN_Activate();
|
||
}
|
||
|
||
void IN_Shutdown (void)
|
||
{
|
||
IN_Deactivate(true);
|
||
}
|
||
|
||
void IN_Commands (void)
|
||
{
|
||
/* TODO: implement this for joystick support */
|
||
}
|
||
|
||
extern cvar_t cl_maxpitch; /* johnfitz -- variable pitch clamping */
|
||
extern cvar_t cl_minpitch; /* johnfitz -- variable pitch clamping */
|
||
|
||
|
||
void IN_MouseMove(int dx, int dy)
|
||
{
|
||
total_dx += dx;
|
||
total_dy += dy;
|
||
}
|
||
|
||
void IN_Move (usercmd_t *cmd)
|
||
{
|
||
int dmx, dmy;
|
||
|
||
/* TODO: fix this
|
||
if (m_filter.value)
|
||
{
|
||
dmx = (2*mx - dmx) * 0.5;
|
||
dmy = (2*my - dmy) * 0.5;
|
||
}
|
||
*/
|
||
|
||
dmx = total_dx * sensitivity.value;
|
||
dmy = total_dy * sensitivity.value;
|
||
|
||
total_dx = 0;
|
||
total_dy = 0;
|
||
|
||
if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
|
||
cmd->sidemove += m_side.value * dmx;
|
||
else
|
||
cl.viewangles[YAW] -= m_yaw.value * dmx;
|
||
|
||
if (in_mlook.state & 1)
|
||
{
|
||
if (dmx || dmy)
|
||
V_StopPitchDrift ();
|
||
}
|
||
|
||
if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
|
||
{
|
||
cl.viewangles[PITCH] += m_pitch.value * dmy;
|
||
/* johnfitz -- variable pitch clamping */
|
||
if (cl.viewangles[PITCH] > cl_maxpitch.value)
|
||
cl.viewangles[PITCH] = cl_maxpitch.value;
|
||
if (cl.viewangles[PITCH] < cl_minpitch.value)
|
||
cl.viewangles[PITCH] = cl_minpitch.value;
|
||
}
|
||
else
|
||
{
|
||
if ((in_strafe.state & 1) && noclip_anglehack)
|
||
cmd->upmove -= m_forward.value * dmy;
|
||
else
|
||
cmd->forwardmove -= m_forward.value * dmy;
|
||
}
|
||
}
|
||
|
||
void IN_ClearStates (void)
|
||
{
|
||
}
|
||
|
||
void IN_UpdateInputMode (void)
|
||
{
|
||
qboolean want_textmode = Key_InputtingText();
|
||
if (textmode != want_textmode)
|
||
{
|
||
textmode = want_textmode;
|
||
#if !defined(USE_SDL2)
|
||
SDL_EnableUNICODE(textmode);
|
||
#else
|
||
if (textmode)
|
||
SDL_StartTextInput();
|
||
else
|
||
SDL_StopTextInput();
|
||
#endif
|
||
}
|
||
}
|
||
|
||
#if !defined(USE_SDL2)
|
||
static inline int IN_SDL_KeysymToQuakeKey(SDLKey sym)
|
||
{
|
||
if (sym > SDLK_SPACE && sym < SDLK_DELETE)
|
||
return sym;
|
||
|
||
switch (sym)
|
||
{
|
||
case SDLK_TAB: return K_TAB;
|
||
case SDLK_RETURN: return K_ENTER;
|
||
case SDLK_ESCAPE: return K_ESCAPE;
|
||
case SDLK_SPACE: return K_SPACE;
|
||
|
||
case SDLK_BACKSPACE: return K_BACKSPACE;
|
||
case SDLK_UP: return K_UPARROW;
|
||
case SDLK_DOWN: return K_DOWNARROW;
|
||
case SDLK_LEFT: return K_LEFTARROW;
|
||
case SDLK_RIGHT: return K_RIGHTARROW;
|
||
|
||
case SDLK_LALT: return K_ALT;
|
||
case SDLK_RALT: return K_ALT;
|
||
case SDLK_LCTRL: return K_CTRL;
|
||
case SDLK_RCTRL: return K_CTRL;
|
||
case SDLK_LSHIFT: return K_SHIFT;
|
||
case SDLK_RSHIFT: return K_SHIFT;
|
||
|
||
case SDLK_F1: return K_F1;
|
||
case SDLK_F2: return K_F2;
|
||
case SDLK_F3: return K_F3;
|
||
case SDLK_F4: return K_F4;
|
||
case SDLK_F5: return K_F5;
|
||
case SDLK_F6: return K_F6;
|
||
case SDLK_F7: return K_F7;
|
||
case SDLK_F8: return K_F8;
|
||
case SDLK_F9: return K_F9;
|
||
case SDLK_F10: return K_F10;
|
||
case SDLK_F11: return K_F11;
|
||
case SDLK_F12: return K_F12;
|
||
case SDLK_INSERT: return K_INS;
|
||
case SDLK_DELETE: return K_DEL;
|
||
case SDLK_PAGEDOWN: return K_PGDN;
|
||
case SDLK_PAGEUP: return K_PGUP;
|
||
case SDLK_HOME: return K_HOME;
|
||
case SDLK_END: return K_END;
|
||
|
||
case SDLK_NUMLOCK: return K_KP_NUMLOCK;
|
||
case SDLK_KP_DIVIDE: return K_KP_SLASH;
|
||
case SDLK_KP_MULTIPLY: return K_KP_STAR;
|
||
case SDLK_KP_MINUS:return K_KP_MINUS;
|
||
case SDLK_KP7: return K_KP_HOME;
|
||
case SDLK_KP8: return K_KP_UPARROW;
|
||
case SDLK_KP9: return K_KP_PGUP;
|
||
case SDLK_KP_PLUS: return K_KP_PLUS;
|
||
case SDLK_KP4: return K_KP_LEFTARROW;
|
||
case SDLK_KP5: return K_KP_5;
|
||
case SDLK_KP6: return K_KP_RIGHTARROW;
|
||
case SDLK_KP1: return K_KP_END;
|
||
case SDLK_KP2: return K_KP_DOWNARROW;
|
||
case SDLK_KP3: return K_KP_PGDN;
|
||
case SDLK_KP_ENTER: return K_KP_ENTER;
|
||
case SDLK_KP0: return K_KP_INS;
|
||
case SDLK_KP_PERIOD: return K_KP_DEL;
|
||
|
||
case SDLK_LMETA: return K_COMMAND;
|
||
case SDLK_RMETA: return K_COMMAND;
|
||
|
||
case SDLK_BREAK: return K_PAUSE;
|
||
case SDLK_PAUSE: return K_PAUSE;
|
||
|
||
case SDLK_WORLD_18: return '~'; // the '<27>' key
|
||
|
||
default: return 0;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if defined(USE_SDL2)
|
||
static inline int IN_SDL2_ScancodeToQuakeKey(SDL_Scancode scancode)
|
||
{
|
||
switch (scancode)
|
||
{
|
||
case SDL_SCANCODE_TAB: return K_TAB;
|
||
case SDL_SCANCODE_RETURN: return K_ENTER;
|
||
case SDL_SCANCODE_RETURN2: return K_ENTER;
|
||
case SDL_SCANCODE_ESCAPE: return K_ESCAPE;
|
||
case SDL_SCANCODE_SPACE: return K_SPACE;
|
||
|
||
case SDL_SCANCODE_A: return 'a';
|
||
case SDL_SCANCODE_B: return 'b';
|
||
case SDL_SCANCODE_C: return 'c';
|
||
case SDL_SCANCODE_D: return 'd';
|
||
case SDL_SCANCODE_E: return 'e';
|
||
case SDL_SCANCODE_F: return 'f';
|
||
case SDL_SCANCODE_G: return 'g';
|
||
case SDL_SCANCODE_H: return 'h';
|
||
case SDL_SCANCODE_I: return 'i';
|
||
case SDL_SCANCODE_J: return 'j';
|
||
case SDL_SCANCODE_K: return 'k';
|
||
case SDL_SCANCODE_L: return 'l';
|
||
case SDL_SCANCODE_M: return 'm';
|
||
case SDL_SCANCODE_N: return 'n';
|
||
case SDL_SCANCODE_O: return 'o';
|
||
case SDL_SCANCODE_P: return 'p';
|
||
case SDL_SCANCODE_Q: return 'q';
|
||
case SDL_SCANCODE_R: return 'r';
|
||
case SDL_SCANCODE_S: return 's';
|
||
case SDL_SCANCODE_T: return 't';
|
||
case SDL_SCANCODE_U: return 'u';
|
||
case SDL_SCANCODE_V: return 'v';
|
||
case SDL_SCANCODE_W: return 'w';
|
||
case SDL_SCANCODE_X: return 'x';
|
||
case SDL_SCANCODE_Y: return 'y';
|
||
case SDL_SCANCODE_Z: return 'z';
|
||
|
||
case SDL_SCANCODE_1: return '1';
|
||
case SDL_SCANCODE_2: return '2';
|
||
case SDL_SCANCODE_3: return '3';
|
||
case SDL_SCANCODE_4: return '4';
|
||
case SDL_SCANCODE_5: return '5';
|
||
case SDL_SCANCODE_6: return '6';
|
||
case SDL_SCANCODE_7: return '7';
|
||
case SDL_SCANCODE_8: return '8';
|
||
case SDL_SCANCODE_9: return '9';
|
||
case SDL_SCANCODE_0: return '0';
|
||
|
||
case SDL_SCANCODE_MINUS: return '-';
|
||
case SDL_SCANCODE_EQUALS: return '=';
|
||
case SDL_SCANCODE_LEFTBRACKET: return '[';
|
||
case SDL_SCANCODE_RIGHTBRACKET: return ']';
|
||
case SDL_SCANCODE_BACKSLASH: return '\\';
|
||
case SDL_SCANCODE_NONUSHASH: return '#';
|
||
case SDL_SCANCODE_SEMICOLON: return ';';
|
||
case SDL_SCANCODE_APOSTROPHE: return '\'';
|
||
case SDL_SCANCODE_GRAVE: return '`';
|
||
case SDL_SCANCODE_COMMA: return ',';
|
||
case SDL_SCANCODE_PERIOD: return '.';
|
||
case SDL_SCANCODE_SLASH: return '/';
|
||
case SDL_SCANCODE_NONUSBACKSLASH: return '\\';
|
||
|
||
case SDL_SCANCODE_BACKSPACE: return K_BACKSPACE;
|
||
case SDL_SCANCODE_UP: return K_UPARROW;
|
||
case SDL_SCANCODE_DOWN: return K_DOWNARROW;
|
||
case SDL_SCANCODE_LEFT: return K_LEFTARROW;
|
||
case SDL_SCANCODE_RIGHT: return K_RIGHTARROW;
|
||
|
||
case SDL_SCANCODE_LALT: return K_ALT;
|
||
case SDL_SCANCODE_RALT: return K_ALT;
|
||
case SDL_SCANCODE_LCTRL: return K_CTRL;
|
||
case SDL_SCANCODE_RCTRL: return K_CTRL;
|
||
case SDL_SCANCODE_LSHIFT: return K_SHIFT;
|
||
case SDL_SCANCODE_RSHIFT: return K_SHIFT;
|
||
|
||
case SDL_SCANCODE_F1: return K_F1;
|
||
case SDL_SCANCODE_F2: return K_F2;
|
||
case SDL_SCANCODE_F3: return K_F3;
|
||
case SDL_SCANCODE_F4: return K_F4;
|
||
case SDL_SCANCODE_F5: return K_F5;
|
||
case SDL_SCANCODE_F6: return K_F6;
|
||
case SDL_SCANCODE_F7: return K_F7;
|
||
case SDL_SCANCODE_F8: return K_F8;
|
||
case SDL_SCANCODE_F9: return K_F9;
|
||
case SDL_SCANCODE_F10: return K_F10;
|
||
case SDL_SCANCODE_F11: return K_F11;
|
||
case SDL_SCANCODE_F12: return K_F12;
|
||
case SDL_SCANCODE_INSERT: return K_INS;
|
||
case SDL_SCANCODE_DELETE: return K_DEL;
|
||
case SDL_SCANCODE_PAGEDOWN: return K_PGDN;
|
||
case SDL_SCANCODE_PAGEUP: return K_PGUP;
|
||
case SDL_SCANCODE_HOME: return K_HOME;
|
||
case SDL_SCANCODE_END: return K_END;
|
||
|
||
case SDL_SCANCODE_NUMLOCKCLEAR: return K_KP_NUMLOCK;
|
||
case SDL_SCANCODE_KP_DIVIDE: return K_KP_SLASH;
|
||
case SDL_SCANCODE_KP_MULTIPLY: return K_KP_STAR;
|
||
case SDL_SCANCODE_KP_MINUS: return K_KP_MINUS;
|
||
case SDL_SCANCODE_KP_7: return K_KP_HOME;
|
||
case SDL_SCANCODE_KP_8: return K_KP_UPARROW;
|
||
case SDL_SCANCODE_KP_9: return K_KP_PGUP;
|
||
case SDL_SCANCODE_KP_PLUS: return K_KP_PLUS;
|
||
case SDL_SCANCODE_KP_4: return K_KP_LEFTARROW;
|
||
case SDL_SCANCODE_KP_5: return K_KP_5;
|
||
case SDL_SCANCODE_KP_6: return K_KP_RIGHTARROW;
|
||
case SDL_SCANCODE_KP_1: return K_KP_END;
|
||
case SDL_SCANCODE_KP_2: return K_KP_DOWNARROW;
|
||
case SDL_SCANCODE_KP_3: return K_KP_PGDN;
|
||
case SDL_SCANCODE_KP_ENTER: return K_KP_ENTER;
|
||
case SDL_SCANCODE_KP_0: return K_KP_INS;
|
||
case SDL_SCANCODE_KP_PERIOD: return K_KP_DEL;
|
||
|
||
case SDL_SCANCODE_LGUI: return K_COMMAND;
|
||
case SDL_SCANCODE_RGUI: return K_COMMAND;
|
||
|
||
case SDL_SCANCODE_PAUSE: return K_PAUSE;
|
||
|
||
default: return 0;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
void IN_SendKeyEvents (void)
|
||
{
|
||
SDL_Event event;
|
||
int sym;
|
||
#if defined(USE_SDL2)
|
||
static int lastKeyDown = 0;
|
||
#endif
|
||
|
||
while (SDL_PollEvent(&event))
|
||
{
|
||
switch (event.type)
|
||
{
|
||
#if defined(USE_SDL2)
|
||
case SDL_WINDOWEVENT:
|
||
if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||
S_UnblockSound();
|
||
else if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||
S_BlockSound();
|
||
break;
|
||
#else
|
||
case SDL_ACTIVEEVENT:
|
||
if (event.active.state & (SDL_APPINPUTFOCUS|SDL_APPACTIVE))
|
||
{
|
||
if (event.active.gain)
|
||
S_UnblockSound();
|
||
else S_BlockSound();
|
||
}
|
||
break;
|
||
#endif
|
||
#if defined(USE_SDL2)
|
||
case SDL_TEXTINPUT:
|
||
// SDL2: We use SDL_TEXTINPUT for typing in the console / chat.
|
||
// SDL2 uses the local keyboard layout and handles modifiers
|
||
// (shift for uppercase, etc.) for us.
|
||
if (!Key_ConsoleBindable(lastKeyDown))
|
||
{
|
||
int i;
|
||
for (i = 0; event.text.text[i]; i++)
|
||
if ((event.text.text[i] & 0x80) == 0)
|
||
Char_Event (event.text.text[i]);
|
||
}
|
||
break;
|
||
#endif
|
||
case SDL_KEYDOWN:
|
||
if ((event.key.keysym.sym == SDLK_RETURN) &&
|
||
(event.key.keysym.mod & KMOD_ALT))
|
||
{
|
||
VID_Toggle();
|
||
break;
|
||
}
|
||
if ((event.key.keysym.sym == SDLK_ESCAPE) &&
|
||
(event.key.keysym.mod & KMOD_SHIFT))
|
||
{
|
||
Con_ToggleConsole_f();
|
||
break;
|
||
}
|
||
/* fallthrough */
|
||
case SDL_KEYUP:
|
||
#if defined(USE_SDL2)
|
||
// SDL2: we interpret the keyboard as the US layout, so keybindings
|
||
// are based on key position, not the label on the key cap.
|
||
sym = IN_SDL2_ScancodeToQuakeKey(event.key.keysym.scancode);
|
||
|
||
if (event.type == SDL_KEYDOWN)
|
||
lastKeyDown = sym;
|
||
else
|
||
lastKeyDown = 0;
|
||
|
||
Key_Event (sym, event.type == SDL_KEYDOWN);
|
||
break;
|
||
#else
|
||
sym = IN_SDL_KeysymToQuakeKey(event.key.keysym.sym);
|
||
|
||
Key_Event (sym, event.type == SDL_KEYDOWN);
|
||
|
||
if (event.type == SDL_KEYDOWN && !Key_ConsoleBindable(sym) &&
|
||
event.key.keysym.unicode != 0 && (event.key.keysym.unicode & 0xFF80) == 0)
|
||
{
|
||
sym = event.key.keysym.unicode & 0x7F;
|
||
Char_Event (sym);
|
||
}
|
||
break;
|
||
#endif
|
||
case SDL_MOUSEBUTTONDOWN:
|
||
case SDL_MOUSEBUTTONUP:
|
||
if (event.button.button < 1 ||
|
||
event.button.button > sizeof(buttonremap) / sizeof(buttonremap[0]))
|
||
{
|
||
Con_Printf ("Ignored event for mouse button %d\n",
|
||
event.button.button);
|
||
break;
|
||
}
|
||
Key_Event(buttonremap[event.button.button - 1], event.button.state == SDL_PRESSED);
|
||
break;
|
||
|
||
#if defined(USE_SDL2)
|
||
case SDL_MOUSEWHEEL:
|
||
if (event.wheel.y > 0)
|
||
{
|
||
Key_Event(K_MWHEELUP, false);
|
||
Key_Event(K_MWHEELUP, true);
|
||
}
|
||
else if (event.wheel.y < 0)
|
||
{
|
||
Key_Event(K_MWHEELDOWN, false);
|
||
Key_Event(K_MWHEELDOWN, true);
|
||
}
|
||
break;
|
||
#endif
|
||
|
||
case SDL_MOUSEMOTION:
|
||
IN_MouseMove(event.motion.xrel, event.motion.yrel);
|
||
break;
|
||
|
||
case SDL_QUIT:
|
||
CL_Disconnect ();
|
||
Sys_Quit ();
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|