Mouse4 now acts as a back button in our menus. Binds menu should now report system key names instead of guessed names (better non-qwerty support).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6244 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2022-05-28 17:59:01 +00:00
parent c45b0e5cf8
commit 08aedd4b5b
9 changed files with 197 additions and 137 deletions

View file

@ -1269,6 +1269,7 @@ int Master_FindBestRoute(char *server, char *out, size_t outsize, int *directcos
float CL_KeyState (kbutton_t *key, int pnum, qboolean noslowstart); float CL_KeyState (kbutton_t *key, int pnum, qboolean noslowstart);
const char *Key_KeynumToString (int keynum, int modifier); const char *Key_KeynumToString (int keynum, int modifier);
const char *Key_KeynumToLocalString (int keynum, int modifier);
int Key_StringToKeynum (const char *str, int *modifier); int Key_StringToKeynum (const char *str, int *modifier);
const char *Key_GetBinding(int keynum, int bindmap, int modifier); const char *Key_GetBinding(int keynum, int bindmap, int modifier);
void Key_GetBindMap(int *bindmaps); void Key_GetBindMap(int *bindmaps);

View file

@ -2413,6 +2413,28 @@ void INS_TranslateKeyEvent(WPARAM wParam, LPARAM lParam, qboolean down, int qdev
IN_KeyEvent(qdeviceid, down, qcode, unicode); IN_KeyEvent(qdeviceid, down, qcode, unicode);
} }
qboolean INS_KeyToLocalName(int qkey, char *buf, size_t bufsize)
{
int i;
*buf = 0; //assume failure
for (i = 0; i < countof(scantokey); i++)
{
if (!scantokey[i])
continue; //not a vkey that quake understands
if (scantokey[i] == qkey)
{
wchar_t tmpbuf[64];
if (GetKeyNameTextW(i<<16, tmpbuf, sizeof(tmpbuf)))
{
narrowen(buf, bufsize, tmpbuf); //yay for utf-8
return true;
}
break;
}
}
return false;
}
#ifndef APPCOMMAND_BROWSER_BACKWARD //added in win2k (but was probably used before that too) #ifndef APPCOMMAND_BROWSER_BACKWARD //added in win2k (but was probably used before that too)
#define APPCOMMAND_BROWSER_BACKWARD 1 #define APPCOMMAND_BROWSER_BACKWARD 1

View file

@ -68,6 +68,7 @@ void INS_Rumble(int joy, quint16_t amp_low, quint16_t amp_high, quint32_t durati
void INS_RumbleTriggers(int joy, quint16_t left, quint16_t right, quint32_t duration); void INS_RumbleTriggers(int joy, quint16_t left, quint16_t right, quint32_t duration);
void INS_SetLEDColor(int id, vec3_t color); void INS_SetLEDColor(int id, vec3_t color);
void INS_SetTriggerFX(int id, const void *data, size_t size); void INS_SetTriggerFX(int id, const void *data, size_t size);
qboolean INS_KeyToLocalName(int qkey, char *buf, size_t bufsize); //returns a name for the key, according to their keyboard layout AND system language(hopefully), or false on unsupported/error. result may change at any time (eg: tap alt+shift on windows)
#define DEVID_UNSET ~0u #define DEVID_UNSET ~0u

View file

@ -196,6 +196,8 @@ keyname_t keynames[] =
{"MOUSE10", K_MOUSE10}, {"MOUSE10", K_MOUSE10},
{"MWHEELUP", K_MWHEELUP}, {"MWHEELUP", K_MWHEELUP},
{"MWHEELDOWN", K_MWHEELDOWN}, {"MWHEELDOWN", K_MWHEELDOWN},
{"MWHEELLEFT", K_MWHEELLEFT},
{"MWHEELRIGHT", K_MWHEELRIGHT},
{"LWIN", K_LWIN}, //windows name {"LWIN", K_LWIN}, //windows name
{"RWIN", K_RWIN}, //windows name {"RWIN", K_RWIN}, //windows name
@ -2439,6 +2441,39 @@ const char *Key_KeynumToString (int keynum, int modifier)
} }
} }
const char *Key_KeynumToLocalString (int keynum, int modifier)
{
const char *r;
#if defined(_WIN32) || (defined(__linux__)&&!defined(NO_X11)) //not defined in all targets yet...
static char tmp[64];
if (INS_KeyToLocalName(keynum, tmp, sizeof(tmp)))
r = tmp;
else
#endif
r = Key_KeynumToStringRaw(keynum);
if (r[0] == '<' && r[1])
modifier = 0; //would be too weird.
switch(modifier)
{
case KEY_MODIFIER_CTRL|KEY_MODIFIER_ALT|KEY_MODIFIER_SHIFT:
return va("Ctrl+Alt+Shift+%s", r);
case KEY_MODIFIER_ALT|KEY_MODIFIER_SHIFT:
return va("Alt+Shift+%s", r);
case KEY_MODIFIER_CTRL|KEY_MODIFIER_SHIFT:
return va("Ctrl+Shift+%s", r);
case KEY_MODIFIER_CTRL|KEY_MODIFIER_ALT:
return va("Ctrl+Alt+%s", r);
case KEY_MODIFIER_CTRL:
return va("Ctrl+%s", r);
case KEY_MODIFIER_ALT:
return va("Alt+%s", r);
case KEY_MODIFIER_SHIFT:
return va("Shift+%s", r);
default:
return r; //no modifier or a bindmap
}
}
/* /*
=================== ===================
Key_SetBinding Key_SetBinding

View file

@ -104,11 +104,11 @@ typedef enum {
K_KP_STAR, K_KP_STAR,
K_KP_EQUALS, K_KP_EQUALS,
K_MOUSE1, K_MOUSE1, //aka left
K_MOUSE2, K_MOUSE2, //aka right
K_MOUSE3, K_MOUSE3, //aka middle
K_MOUSE4, K_MOUSE4, //aka back
K_MOUSE5, K_MOUSE5, //aka forward
K_MWHEELDOWN, K_MWHEELDOWN,
K_MWHEELUP, K_MWHEELUP,
@ -210,6 +210,10 @@ typedef enum {
K_MOUSE9, K_MOUSE9,
K_MOUSE10, K_MOUSE10,
/*FIXME*/
#define K_MWHEELLEFT K_MOUSE9
#define K_MWHEELRIGHT K_MOUSE10
/* spare joystick button presses */ /* spare joystick button presses */
K_JOY_UP, K_JOY_UP,
K_JOY_DOWN, K_JOY_DOWN,

View file

@ -813,7 +813,7 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
Draw_FunString (x + 8, y, "or"); Draw_FunString (x + 8, y, "or");
x += 32; x += 32;
} }
keyname = Key_KeynumToString (keys[j], keymods[j]); keyname = Key_KeynumToLocalString (keys[j], keymods[j]);
Draw_FunString (x, y, keyname); Draw_FunString (x, y, keyname);
x += strlen(keyname) * 8; x += strlen(keyname) * 8;
} }
@ -2085,7 +2085,8 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
switch(key) switch(key)
{ {
case K_MOUSE2: case K_MOUSE2: //right
case K_MOUSE4: //back
case K_ESCAPE: case K_ESCAPE:
case K_GP_BACK: case K_GP_BACK:
//remove //remove
@ -2190,7 +2191,6 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
} }
case K_MOUSE1: case K_MOUSE1:
case K_MOUSE3: case K_MOUSE3:
case K_MOUSE4:
case K_MOUSE5: case K_MOUSE5:
case K_MOUSE6: case K_MOUSE6:
case K_MOUSE7: case K_MOUSE7:

View file

@ -774,7 +774,7 @@ static qboolean SL_Key (int key, emenu_t *menu)
serverinfo_t *server = selectedserver.inuse?Master_InfoForServer(&selectedserver.adr, selectedserver.brokerid):NULL; serverinfo_t *server = selectedserver.inuse?Master_InfoForServer(&selectedserver.adr, selectedserver.brokerid):NULL;
qboolean ctrldown = keydown[K_LCTRL] || keydown[K_RCTRL]; qboolean ctrldown = keydown[K_LCTRL] || keydown[K_RCTRL];
if (key == K_ESCAPE || key == K_GP_BACK || key == K_MOUSE2) if (key == K_ESCAPE || key == K_GP_BACK || key == K_MOUSE2 || key == K_MOUSE4)
{ {
serverpreview = SVPV_NO; serverpreview = SVPV_NO;
return true; return true;

View file

@ -487,7 +487,7 @@ static qboolean Prompt_MenuKeyEvent(struct menu_s *gm, qboolean isdown, unsigned
} }
return true; return true;
} }
else if (key == K_ESCAPE || key == K_GP_BACK || key == K_MOUSE2) else if (key == K_ESCAPE || key == K_GP_BACK || key == K_MOUSE2 || key == K_MOUSE4)
action = PROMPT_CANCEL; action = PROMPT_CANCEL;
else if (key == K_ENTER || key == K_KP_ENTER || key == K_MOUSE1 || key == K_GP_A) else if (key == K_ENTER || key == K_KP_ENTER || key == K_MOUSE1 || key == K_GP_A)
{ {
@ -1070,6 +1070,7 @@ qboolean M_Help_Key (int key, emenu_t *m)
case K_ESCAPE: case K_ESCAPE:
case K_GP_BACK: case K_GP_BACK:
case K_MOUSE2: case K_MOUSE2:
case K_MOUSE4:
M_RemoveMenu(m); M_RemoveMenu(m);
return true; return true;

View file

@ -218,6 +218,9 @@ static struct
int (*pXGrabServer)(Display *display); int (*pXGrabServer)(Display *display);
int (*pXUngrabServer)(Display *display); int (*pXUngrabServer)(Display *display);
char *(*pXKeysymToString)(KeySym);
KeySym *(*pXGetKeyboardMapping)(Display *display, KeyCode first_keycode, int keycode_count, int *keysyms_per_keycode_return);
#define XI_RESOURCENAME "FTEQW" #define XI_RESOURCENAME "FTEQW"
#define XI_RESOURCECLASS "FTEQW" #define XI_RESOURCECLASS "FTEQW"
char *(*pXSetLocaleModifiers)(char *modifier_list); char *(*pXSetLocaleModifiers)(char *modifier_list);
@ -315,6 +318,9 @@ static qboolean x11_initlib(void)
{(void**)&x11.pXMatchVisualInfo, "XMatchVisualInfo"}, {(void**)&x11.pXMatchVisualInfo, "XMatchVisualInfo"},
{(void**)&x11.pXGetVisualInfo, "XGetVisualInfo"}, {(void**)&x11.pXGetVisualInfo, "XGetVisualInfo"},
{(void**)&x11.pXKeysymToString, "XKeysymToString"},
{(void**)&x11.pXGetKeyboardMapping, "XGetKeyboardMapping"},
{(void**)&x11.pXGrabServer, "XGrabServer"}, {(void**)&x11.pXGrabServer, "XGrabServer"},
{(void**)&x11.pXUngrabServer, "XUngrabServer"}, {(void**)&x11.pXUngrabServer, "XUngrabServer"},
@ -2484,6 +2490,97 @@ static long X_InitUnicode(void)
return requiredevents; return requiredevents;
} }
#define XKEY_QUAKE_MAP() \
XKQM(XK_KP_Page_Up, K_KP_PGUP) \
XKQM(XK_Page_Up, K_PGUP) \
XKQM(XK_KP_Page_Down, K_KP_PGDN) \
XKQM(XK_Page_Down, K_PGDN) \
XKQM(XK_KP_Home, K_KP_HOME) \
XKQM(XK_Home, K_HOME) \
XKQM(XK_KP_End, K_KP_END) \
XKQM(XK_End, K_END) \
XKQM(XK_KP_Left, K_KP_LEFTARROW) \
XKQM(XK_Left, K_LEFTARROW) \
XKQM(XK_KP_Right, K_KP_RIGHTARROW)\
XKQM(XK_Right, K_RIGHTARROW) \
XKQM(XK_KP_Down, K_KP_DOWNARROW) \
XKQM(XK_Down, K_DOWNARROW) \
XKQM(XK_KP_Up, K_KP_UPARROW) \
XKQM(XK_Up, K_UPARROW) \
XKQM(XK_Escape, K_ESCAPE) \
XKQM(XK_KP_Enter, K_KP_ENTER) \
XKQM(XK_Return, K_ENTER) \
XKQM(XK_Num_Lock, K_KP_NUMLOCK) \
XKQM(XK_Caps_Lock, K_CAPSLOCK) \
XKQM(XK_Scroll_Lock, K_SCRLCK) \
XKQM(XK_Print, K_PRINTSCREEN) \
XKQM(XK_Super_L, K_LWIN) \
XKQM(XK_Super_R, K_RWIN) \
XKQM(XK_Tab, K_TAB) \
XKQM(XK_F1, K_F1) \
XKQM(XK_F2, K_F2) \
XKQM(XK_F3, K_F3) \
XKQM(XK_F4, K_F4) \
XKQM(XK_F5, K_F5) \
XKQM(XK_F6, K_F6) \
XKQM(XK_F7, K_F7) \
XKQM(XK_F8, K_F8) \
XKQM(XK_F9, K_F9) \
XKQM(XK_F10, K_F10) \
XKQM(XK_F11, K_F11) \
XKQM(XK_F12, K_F12) \
XKQM(XK_F13, K_F13) \
XKQM(XK_F14, K_F14) \
XKQM(XK_F15, K_F15) \
XKQM(XK_BackSpace, K_BACKSPACE) \
XKQM(XK_KP_Delete, K_KP_DEL) \
XKQM(XK_Delete, K_DEL) \
XKQM(XK_Pause, K_PAUSE) \
XKQM(XK_Shift_L, K_LSHIFT) \
XKQM(XK_Shift_R, K_RSHIFT) \
/*XKQM2(XK_Execute, K_LCTRL)*/ \
XKQM(XK_Control_L, K_LCTRL) \
XKQM(XK_Control_R, K_RCTRL) \
XKQM(XK_Alt_L, K_LALT) \
/*XKQM2(XK_Meta_L, K_LWIN)*/ \
XKQM(XK_Alt_R, K_RALT) \
/*XKQM2(XK_Meta_R, K_RWIN)*/ \
XKQM(XK_Menu, K_APP) \
XKQM(XK_KP_Begin, K_KP_5) \
XKQM(XK_KP_Insert, K_KP_INS) \
XKQM(XK_Insert, K_INS) \
XKQM(XK_KP_Multiply, K_KP_STAR) \
XKQM(XK_KP_Add, K_KP_PLUS) \
XKQM(XK_KP_Subtract, K_KP_MINUS) \
XKQM(XK_KP_Divide, K_KP_SLASH)
qboolean INS_KeyToLocalName(int qkey, char *buf, size_t bufsize)
{
char *s;
int xk;
*buf = 0;
if(vid_dpy)
{
switch(qkey)
{
#define XKQM(x,q) case q: xk = x; break;
XKEY_QUAKE_MAP()
#undef XKQM
default:
if (qkey >= K_SPACE && qkey < 127)
xk = qkey; //printable ascii is identity-mapped in both
else
return false; //don't know how to map this. might not be a keyboard key.
break;
}
s = x11.pXKeysymToString(xk);
if (s)
Q_strncpyz(buf, s, bufsize);
}
return !!*buf;
}
static void X_KeyEvent(XKeyEvent *ev, qboolean pressed, qboolean filtered) static void X_KeyEvent(XKeyEvent *ev, qboolean pressed, qboolean filtered)
{ {
int i; int i;
@ -2552,112 +2649,9 @@ static void X_KeyEvent(XKeyEvent *ev, qboolean pressed, qboolean filtered)
switch(keysym) switch(keysym)
{ {
case XK_KP_Page_Up: key = K_KP_PGUP; break; #define XKQM(x,q) case x: key = q; break;
case XK_Page_Up: key = K_PGUP; break; XKEY_QUAKE_MAP()
#undef XKQM
case XK_KP_Page_Down: key = K_KP_PGDN; break;
case XK_Page_Down: key = K_PGDN; break;
case XK_KP_Home: key = K_KP_HOME; break;
case XK_Home: key = K_HOME; break;
case XK_KP_End: key = K_KP_END; break;
case XK_End: key = K_END; break;
case XK_KP_Left: key = K_KP_LEFTARROW; break;
case XK_Left: key = K_LEFTARROW; break;
case XK_KP_Right: key = K_KP_RIGHTARROW; break;
case XK_Right: key = K_RIGHTARROW; break;
case XK_KP_Down: key = K_KP_DOWNARROW; break;
case XK_Down: key = K_DOWNARROW; break;
case XK_KP_Up: key = K_KP_UPARROW; break;
case XK_Up: key = K_UPARROW; break;
case XK_Escape: key = K_ESCAPE; break;
case XK_KP_Enter: key = K_KP_ENTER; break;
case XK_Return: key = K_ENTER; break;
case XK_Num_Lock: key = K_KP_NUMLOCK; break;
case XK_Caps_Lock: key = K_CAPSLOCK; break;
case XK_Scroll_Lock: key = K_SCRLCK; break;
case XK_Print: key = K_PRINTSCREEN; break;
case XK_Super_L: key = K_LWIN; break;
case XK_Super_R: key = K_RWIN; break;
case XK_Tab: key = K_TAB; break;
case XK_F1: key = K_F1; break;
case XK_F2: key = K_F2; break;
case XK_F3: key = K_F3; break;
case XK_F4: key = K_F4; break;
case XK_F5: key = K_F5; break;
case XK_F6: key = K_F6; break;
case XK_F7: key = K_F7; break;
case XK_F8: key = K_F8; break;
case XK_F9: key = K_F9; break;
case XK_F10: key = K_F10; break;
case XK_F11: key = K_F11; break;
case XK_F12: key = K_F12; break;
case XK_F13: key = K_F13; break;
case XK_F14: key = K_F14; break;
case XK_F15: key = K_F15; break;
case XK_BackSpace: key = K_BACKSPACE; break;
case XK_KP_Delete: key = K_KP_DEL; break;
case XK_Delete: key = K_DEL; break;
case XK_Pause: key = K_PAUSE; break;
case XK_Shift_L: key = K_LSHIFT; break;
case XK_Shift_R: key = K_RSHIFT; break;
case XK_Execute: key = K_LCTRL; break;
case XK_Control_L: key = K_LCTRL; break;
case XK_Control_R: key = K_RCTRL; break;
case XK_Alt_L: key = K_LALT; break;
case XK_Meta_L: key = K_LALT; break;
case XK_Alt_R: key = K_RALT; break;
case XK_Meta_R: key = K_RALT; break;
case XK_Menu: key = K_APP; break;
case XK_KP_Begin: key = K_KP_5; break;
case XK_KP_Insert: key = K_KP_INS; break;
case XK_Insert: key = K_INS; break;
case XK_KP_Multiply: key = K_KP_STAR; break;
case XK_KP_Add: key = K_KP_PLUS; break;
case XK_KP_Subtract: key = K_KP_MINUS; break;
case XK_KP_Divide: key = K_KP_SLASH; break;
#if 0
case 0x021: key = '1';break;/* [!] */
case 0x040: key = '2';break;/* [@] */
case 0x023: key = '3';break;/* [#] */
case 0x024: key = '4';break;/* [$] */
case 0x025: key = '5';break;/* [%] */
case 0x05e: key = '6';break;/* [^] */
case 0x026: key = '7';break;/* [&] */
case 0x02a: key = '8';break;/* [*] */
case 0x028: key = '9';;break;/* [(] */
case 0x029: key = '0';break;/* [)] */
case 0x05f: key = '-';break;/* [_] */
case 0x02b: key = '=';break;/* [+] */
case 0x07c: key = '\'';break;/* [|] */
case 0x07d: key = '[';break;/* [}] */
case 0x07b: key = ']';break;/* [{] */
case 0x022: key = '\'';break;/* ["] */
case 0x03a: key = ';';break;/* [:] */
case 0x03f: key = '/';break;/* [?] */
case 0x03e: key = '.';break;/* [>] */
case 0x03c: key = ',';break;/* [<] */
#endif
default: default:
key = keysym; key = keysym;
@ -2853,13 +2847,15 @@ static void GetEvent(void)
case 3: button = K_MOUSE2; break; case 3: button = K_MOUSE2; break;
case 4: button = K_MWHEELUP; break; //so much for 'raw'. case 4: button = K_MWHEELUP; break; //so much for 'raw'.
case 5: button = K_MWHEELDOWN; break; case 5: button = K_MWHEELDOWN; break;
case 6: button = K_MOUSE4; break; case 6: button = K_MWHEELLEFT; break; //so much for 'raw'.
case 7: button = K_MOUSE5; break; case 7: button = K_MWHEELRIGHT; break;
case 8: button = K_MOUSE6; break; case 8: button = K_MOUSE4; break;
case 9: button = K_MOUSE7; break; case 9: button = K_MOUSE5; break;
case 10: button = K_MOUSE8; break; case 10: button = K_MOUSE6; break;
case 11: button = K_MOUSE9; break; case 11: button = K_MOUSE7; break;
case 12: button = K_MOUSE10; break; case 12: button = K_MOUSE8; break;
case 13: button = K_MOUSE9; break;
case 14: button = K_MOUSE10; break;
default:button = 0; break; default:button = 0; break;
} }
if (button) if (button)
@ -3006,19 +3002,19 @@ static void GetEvent(void)
//note, the x11 protocol does not support more than 5 mouse buttons //note, the x11 protocol does not support more than 5 mouse buttons
//which is a bit of a shame, but hey. //which is a bit of a shame, but hey.
else if (event.xbutton.button == 6) else if (event.xbutton.button == 6)
b = x11violations?K_MOUSE4:-1; b = x11violations?K_MWHEELLEFT:-1;
else if (event.xbutton.button == 7) else if (event.xbutton.button == 7)
b = x11violations?K_MOUSE5:-1; b = x11violations?K_MWHEELRIGHT:-1;
else if (event.xbutton.button == 8) else if (event.xbutton.button == 8)
b = x11violations?K_MOUSE6:-1; b = x11violations?K_MOUSE4:-1;
else if (event.xbutton.button == 9) else if (event.xbutton.button == 9)
b = x11violations?K_MOUSE7:-1; b = x11violations?K_MOUSE5:-1;
else if (event.xbutton.button == 10) else if (event.xbutton.button == 10)
b = x11violations?K_MOUSE8:-1; b = x11violations?K_MOUSE6:-1;
else if (event.xbutton.button == 11) else if (event.xbutton.button == 11)
b = x11violations?K_MOUSE9:-1; b = x11violations?K_MOUSE7:-1;
else if (event.xbutton.button == 12) else if (event.xbutton.button == 12)
b = x11violations?K_MOUSE10:-1; b = x11violations?K_MOUSE8:-1;
if (b>=0) if (b>=0)
IN_KeyEvent(x11_mouseqdev, true, b, 0); IN_KeyEvent(x11_mouseqdev, true, b, 0);
@ -3051,19 +3047,19 @@ static void GetEvent(void)
//note, the x11 protocol does not support more than 5 mouse buttons //note, the x11 protocol does not support more than 5 mouse buttons
//which is a bit of a shame, but hey. //which is a bit of a shame, but hey.
else if (event.xbutton.button == 6) else if (event.xbutton.button == 6)
b = x11violations?K_MOUSE4:-1; b = x11violations?K_MWHEELLEFT:-1;
else if (event.xbutton.button == 7) else if (event.xbutton.button == 7)
b = x11violations?K_MOUSE5:-1; b = x11violations?K_MWHEELRIGHT:-1;
else if (event.xbutton.button == 8) else if (event.xbutton.button == 8)
b = x11violations?K_MOUSE6:-1; b = x11violations?K_MOUSE4:-1;
else if (event.xbutton.button == 9) else if (event.xbutton.button == 9)
b = x11violations?K_MOUSE7:-1; b = x11violations?K_MOUSE5:-1;
else if (event.xbutton.button == 10) else if (event.xbutton.button == 10)
b = x11violations?K_MOUSE8:-1; b = x11violations?K_MOUSE6:-1;
else if (event.xbutton.button == 11) else if (event.xbutton.button == 11)
b = x11violations?K_MOUSE9:-1; b = x11violations?K_MOUSE7:-1;
else if (event.xbutton.button == 12) else if (event.xbutton.button == 12)
b = x11violations?K_MOUSE10:-1; b = x11violations?K_MOUSE8:-1;
if (b>=0) if (b>=0)
IN_KeyEvent(x11_mouseqdev, false, b, 0); IN_KeyEvent(x11_mouseqdev, false, b, 0);