00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "../client.h"
00032 #include "../cl_screen.h"
00033 #include "../cl_console.h"
00034 #include "../ui/ui_input.h"
00035 #include "../ui/ui_nodes.h"
00036 #include "../../shared/utf8.h"
00037
00038 char keyLines[MAXKEYLINES][MAXCMDLINE];
00039 int keyLinePos;
00040
00041 static int keyInsert = 1;
00042
00043 int editLine = 0;
00044 int historyLine = 0;
00045
00046 int msgMode;
00047 char msgBuffer[MAXCMDLINE];
00048 size_t msgBufferLen = 0;
00049
00064 char *keyBindings[K_KEY_SIZE];
00065 char *menuKeyBindings[K_KEY_SIZE];
00066 char *battleKeyBindings[K_KEY_SIZE];
00067
00068 static qboolean keyDown[K_KEY_SIZE];
00069
00070 typedef struct {
00071 const char *name;
00072 int keynum;
00073 } keyName_t;
00074
00075 #define M(x) {#x, K_##x}
00076 static const keyName_t keyNames[] = {
00077 M(TAB),
00078 M(ENTER),
00079 M(ESCAPE),
00080 M(SPACE),
00081 M(BACKSPACE),
00082 M(UPARROW),
00083 M(DOWNARROW),
00084 M(LEFTARROW),
00085 M(RIGHTARROW),
00086
00087 M(ALT),
00088 M(CTRL),
00089 M(SHIFT),
00090
00091 M(F1),
00092 M(F2),
00093 M(F3),
00094 M(F4),
00095 M(F5),
00096 M(F6),
00097 M(F7),
00098 M(F8),
00099 M(F9),
00100 M(F10),
00101 M(F11),
00102 M(F12),
00103
00104 M(INS),
00105 M(DEL),
00106 M(PGDN),
00107 M(PGUP),
00108 M(HOME),
00109 M(END),
00110
00111 M(MOUSE1),
00112 M(MOUSE2),
00113 M(MOUSE3),
00114 M(MOUSE4),
00115 M(MOUSE5),
00116
00117 M(AUX1),
00118 M(AUX2),
00119 M(AUX3),
00120 M(AUX4),
00121 M(AUX5),
00122 M(AUX6),
00123 M(AUX7),
00124 M(AUX8),
00125 M(AUX9),
00126 M(AUX10),
00127 M(AUX11),
00128 M(AUX12),
00129 M(AUX13),
00130 M(AUX14),
00131 M(AUX15),
00132 M(AUX16),
00133
00134 M(APPS),
00135
00136 M(KP_HOME),
00137 M(KP_UPARROW),
00138 M(KP_PGUP),
00139 M(KP_LEFTARROW),
00140 M(KP_5),
00141 M(KP_RIGHTARROW),
00142 M(KP_END),
00143 M(KP_DOWNARROW),
00144 M(KP_PGDN),
00145 M(KP_ENTER),
00146 M(KP_INS),
00147 M(KP_DEL),
00148 M(KP_SLASH),
00149 M(KP_MINUS),
00150 M(KP_PLUS),
00151
00152 M(MWHEELUP),
00153 M(MWHEELDOWN),
00154
00155 M(JOY1),
00156 M(JOY2),
00157 M(JOY3),
00158 M(JOY4),
00159 M(JOY5),
00160 M(JOY6),
00161 M(JOY7),
00162 M(JOY8),
00163 M(JOY9),
00164 M(JOY10),
00165 M(JOY11),
00166 M(JOY12),
00167 M(JOY13),
00168 M(JOY14),
00169 M(JOY15),
00170 M(JOY16),
00171 M(JOY17),
00172 M(JOY18),
00173 M(JOY19),
00174 M(JOY20),
00175 M(JOY21),
00176 M(JOY22),
00177 M(JOY23),
00178 M(JOY24),
00179 M(JOY25),
00180 M(JOY26),
00181 M(JOY27),
00182 M(JOY28),
00183 M(JOY29),
00184 M(JOY30),
00185 M(JOY31),
00186 M(JOY32),
00187
00188 M(PAUSE),
00189
00190 {"SEMICOLON", ';'},
00191
00192 M(SUPER),
00193 M(COMPOSE),
00194 M(MODE),
00195 M(HELP),
00196 M(PRINT),
00197 M(SYSREQ),
00198 M(SCROLLOCK),
00199 M(BREAK),
00200 M(MENU),
00201 M(POWER),
00202 M(EURO),
00203 M(UNDO),
00204
00205 {NULL, 0}
00206 };
00207
00208
00209
00210
00211
00212
00213
00219 static void Key_Console (int key, int unicode)
00220 {
00221 int i;
00222
00223 if (keyDown[K_CTRL]) {
00224 switch (toupper(key)) {
00225
00226 case 'L':
00227 Cbuf_AddText("clear\n");
00228 return;
00229
00230 case 'A':
00231 keyLinePos = 1;
00232 return;
00233
00234 case 'E':
00235 keyLinePos = strlen(keyLines[editLine]);
00236 return;
00237 }
00238 }
00239
00240 if (key == K_ENTER || key == K_KP_ENTER) {
00241 if (keyLines[editLine][1] == '\\' || keyLines[editLine][1] == '/')
00242 Cbuf_AddText(keyLines[editLine] + 2);
00243
00244 else if (!keyLines[editLine][1])
00245 return;
00246 else
00247 Cbuf_AddText(keyLines[editLine] + 1);
00248
00249 Cbuf_AddText("\n");
00250 Com_Printf("%s\n", keyLines[editLine] + 1);
00251 editLine = (editLine + 1) & (MAXKEYLINES - 1);
00252 historyLine = editLine;
00253 keyLines[editLine][0] = CONSOLE_PROMPT_CHAR | CONSOLE_COLORED_TEXT_MASK;
00254
00255
00256 keyLines[editLine][1] = '\0';
00257 keyLinePos = 1;
00258
00259
00260 if (cls.state == ca_disconnected)
00261 SCR_UpdateScreen();
00262
00263 return;
00264 }
00265
00266
00267 if (key == K_TAB) {
00268 Com_ConsoleCompleteCommand(&keyLines[editLine][1], keyLines[editLine], MAXCMDLINE, &keyLinePos, 1);
00269 return;
00270 }
00271
00272 if (key == K_BACKSPACE || (key == 'h' && keyDown[K_CTRL])) {
00273 if (keyLinePos > 1) {
00274 strcpy(keyLines[editLine] + keyLinePos - 1, keyLines[editLine] + keyLinePos);
00275 keyLinePos--;
00276 }
00277 return;
00278 }
00279
00280 if (key == K_DEL) {
00281 if (keyLinePos < strlen(keyLines[editLine]))
00282 strcpy(keyLines[editLine] + keyLinePos, keyLines[editLine] + keyLinePos + 1);
00283 return;
00284 }
00285
00286 if (key == K_UPARROW || key == K_KP_UPARROW || (tolower(key) == 'p' && keyDown[K_CTRL])) {
00287 do {
00288 historyLine = (historyLine - 1) & (MAXKEYLINES - 1);
00289 } while (historyLine != editLine && !keyLines[historyLine][1]);
00290
00291 if (historyLine == editLine)
00292 historyLine = (editLine + 1) & (MAXKEYLINES - 1);
00293
00294 Q_strncpyz(keyLines[editLine], keyLines[historyLine], MAXCMDLINE);
00295 keyLinePos = strlen(keyLines[editLine]);
00296 return;
00297 } else if (key == K_DOWNARROW || key == K_KP_DOWNARROW || (tolower(key) == 'n' && keyDown[K_CTRL])) {
00298 if (historyLine == editLine)
00299 return;
00300 do {
00301 historyLine = (historyLine + 1) & (MAXKEYLINES - 1);
00302 } while (historyLine != editLine && !keyLines[historyLine][1]);
00303
00304 if (historyLine == editLine) {
00305 keyLines[editLine][0] = CONSOLE_PROMPT_CHAR | CONSOLE_COLORED_TEXT_MASK;
00306
00307 keyLines[editLine][1] = '\0';
00308 keyLinePos = 1;
00309 } else {
00310 Q_strncpyz(keyLines[editLine], keyLines[historyLine], MAXCMDLINE);
00311 keyLinePos = strlen(keyLines[editLine]);
00312 }
00313 return;
00314 }
00315
00316 if (key == K_LEFTARROW) {
00317 if (keyDown[K_CTRL]) {
00318 while (keyLinePos > 1 && keyLines[editLine][keyLinePos - 1] == ' ')
00319 keyLinePos--;
00320 while (keyLinePos > 1 && keyLines[editLine][keyLinePos - 1] != ' ')
00321 keyLinePos--;
00322 return;
00323 }
00324
00325 if (keyLinePos > 1)
00326 keyLinePos--;
00327 return;
00328 } else if (key == K_RIGHTARROW) {
00329 if ((i = strlen(keyLines[editLine])) == keyLinePos)
00330 return;
00331 if (keyDown[K_CTRL]) {
00332 while (keyLinePos < i && keyLines[editLine][keyLinePos + 1] == ' ')
00333 keyLinePos++;
00334 while (keyLinePos < i && keyLines[editLine][keyLinePos + 1] != ' ')
00335 keyLinePos++;
00336 if (keyLinePos < i)
00337 keyLinePos++;
00338 return;
00339 }
00340 keyLinePos++;
00341 return;
00342 }
00343
00344
00345 if (key == K_INS) {
00346 keyInsert ^= 1;
00347 return;
00348 }
00349
00350 if (key == K_PGUP || key == K_KP_PGUP || key == K_MWHEELUP) {
00351 Con_Scroll(-2);
00352 return;
00353 }
00354
00355 if (key == K_PGDN || key == K_KP_PGDN || key == K_MWHEELDOWN) {
00356 Con_Scroll(2);
00357 return;
00358 }
00359
00360 if (key == K_HOME || key == K_KP_HOME) {
00361 keyLinePos = 1;
00362 return;
00363 }
00364
00365 if (key == K_END || key == K_KP_END) {
00366 keyLinePos = strlen(keyLines[editLine]);
00367 return;
00368 }
00369
00370 switch (key) {
00371 case K_KP_SLASH:
00372 key = '/';
00373 break;
00374 case K_KP_MINUS:
00375 key = '-';
00376 break;
00377 case K_KP_PLUS:
00378 key = '+';
00379 break;
00380 case K_KP_HOME:
00381 key = '7';
00382 break;
00383 case K_KP_UPARROW:
00384 key = '8';
00385 break;
00386 case K_KP_PGUP:
00387 key = '9';
00388 break;
00389 case K_KP_LEFTARROW:
00390 key = '4';
00391 break;
00392 case K_KP_5:
00393 key = '5';
00394 break;
00395 case K_KP_RIGHTARROW:
00396 key = '6';
00397 break;
00398 case K_KP_END:
00399 key = '1';
00400 break;
00401 case K_KP_DOWNARROW:
00402 key = '2';
00403 break;
00404 case K_KP_PGDN:
00405 key = '3';
00406 break;
00407 case K_KP_INS:
00408 key = '0';
00409 break;
00410 case K_KP_DEL:
00411 key = '.';
00412 break;
00413 default:
00414 key = unicode;
00415 break;
00416 }
00417
00419 if (key < 32 || key > 127)
00420 return;
00421
00422 if (keyLinePos < MAXCMDLINE - 1) {
00423 if (keyInsert) {
00424 i = strlen(keyLines[editLine]) - 1;
00425
00426 if (i == MAXCMDLINE - 2)
00427 i--;
00428 for (; i >= keyLinePos; i--)
00429 keyLines[editLine][i + 1] = keyLines[editLine][i];
00430 }
00431 i = keyLines[editLine][keyLinePos];
00432 keyLines[editLine][keyLinePos] = key;
00433 keyLinePos++;
00434 if (!i)
00435 keyLines[editLine][keyLinePos] = 0;
00436 }
00437 }
00438
00445 static void Key_Message (int key)
00446 {
00447 int utf8len;
00448
00449 if (key == K_ENTER || key == K_KP_ENTER) {
00450 qboolean send = qtrue;
00451
00452 switch (msgMode) {
00453 case MSG_SAY:
00454 if (msgBuffer[0])
00455 Cbuf_AddText("say \"");
00456 else
00457 send = qfalse;
00458 break;
00459 case MSG_SAY_TEAM:
00460 if (msgBuffer[0])
00461 Cbuf_AddText("say_team \"");
00462 else
00463 send = qfalse;
00464 break;
00465 default:
00466 Com_Printf("Invalid msg_mode\n");
00467 return;
00468 }
00469 if (send) {
00470 Com_DPrintf(DEBUG_CLIENT, "msg_buffer: %s\n", msgBuffer);
00471 Cbuf_AddText(msgBuffer);
00472 Cbuf_AddText("\"\n");
00473 }
00474
00475 Key_SetDest(key_game);
00476 msgBufferLen = 0;
00477 msgBuffer[0] = 0;
00478 return;
00479 }
00480
00481 if (key == K_ESCAPE) {
00482 if (cls.state != ca_active) {
00483
00484 if (cls.state != ca_disconnected)
00485 Com_Error(ERR_DROP, "Disconnected from server");
00486 }
00487
00488 Key_SetDest(key_game);
00489 msgBufferLen = 0;
00490 msgBuffer[0] = 0;
00491 return;
00492 }
00493
00494 if (key == K_BACKSPACE) {
00495 if (msgBufferLen)
00496 msgBufferLen = UTF8_delete_char(msgBuffer, msgBufferLen - 1);
00497 return;
00498 }
00499
00500 utf8len = UTF8_encoded_len(key);
00501
00503 if (utf8len == 0 || key < 32 || (key >= 127 && key < 192))
00504 return;
00505
00506 if (msgBufferLen + utf8len >= sizeof(msgBuffer))
00507 return;
00508
00509 msgBufferLen += UTF8_insert_char(msgBuffer, sizeof(msgBuffer), msgBufferLen, key);
00510 }
00511
00512
00521 static int Key_StringToKeynum (const char *str)
00522 {
00523 const keyName_t *kn;
00524
00525 if (!str || str[0] == '\0')
00526 return -1;
00527
00528
00529 if (str[1] == '\0')
00530 return str[0];
00531
00532 for (kn = keyNames; kn->name; kn++) {
00533 if (!Q_strcasecmp(str, kn->name))
00534 return kn->keynum;
00535 }
00536 return -1;
00537 }
00538
00546 const char *Key_KeynumToString (int keynum)
00547 {
00548 const keyName_t *kn;
00549 static char tinystr[2];
00550
00551 if (keynum == -1)
00552 return "<KEY NOT FOUND>";
00554 if (keynum > 32 && keynum < 127) {
00555 tinystr[0] = keynum;
00556 tinystr[1] = 0;
00557 return tinystr;
00558 }
00559
00560 for (kn = keyNames; kn->name; kn++)
00561 if (keynum == kn->keynum)
00562 return kn->name;
00563
00564 return "<UNKNOWN KEYNUM>";
00565 }
00566
00573 const char* Key_GetBinding (const char *binding, keyBindSpace_t space)
00574 {
00575 int i;
00576 char **keySpace = NULL;
00577
00578 switch (space) {
00579 case KEYSPACE_UI:
00580 keySpace = menuKeyBindings;
00581 break;
00582 case KEYSPACE_GAME:
00583 keySpace = keyBindings;
00584 break;
00585 case KEYSPACE_BATTLE:
00586 keySpace = battleKeyBindings;
00587 break;
00588 default:
00589 Sys_Error("Unknown key space (%i) given", space);
00590 }
00591
00592 for (i = K_FIRST_KEY; i < K_LAST_KEY; i++)
00593 if (keySpace[i] && *keySpace[i] && !strncmp(keySpace[i], binding, strlen(binding))) {
00594 return Key_KeynumToString(i);
00595 }
00596
00597
00598 return "";
00599 }
00600
00610 void Key_SetBinding (int keynum, const char *binding, keyBindSpace_t space)
00611 {
00612 char **keySpace = NULL;
00613
00614 if (keynum == -1 || keynum >= K_KEY_SIZE)
00615 return;
00616
00617 Com_DPrintf(DEBUG_CLIENT, "Binding for '%s' for space ", binding);
00618 switch (space) {
00619 case KEYSPACE_UI:
00620 keySpace = &menuKeyBindings[keynum];
00621 Com_DPrintf(DEBUG_CLIENT, "menu\n");
00622 break;
00623 case KEYSPACE_GAME:
00624 keySpace = &keyBindings[keynum];
00625 Com_DPrintf(DEBUG_CLIENT, "game\n");
00626 break;
00627 case KEYSPACE_BATTLE:
00628 keySpace = &battleKeyBindings[keynum];
00629 Com_DPrintf(DEBUG_CLIENT, "battle\n");
00630 break;
00631 default:
00632 Com_DPrintf(DEBUG_CLIENT, "failure\n");
00633 return;
00634 }
00635
00636
00637 if (*keySpace) {
00638 Mem_Free(*keySpace);
00639 *keySpace = NULL;
00640 }
00641
00642
00643 if (binding)
00644 *keySpace = Mem_PoolStrDup(binding, com_genericPool, 0);
00645 }
00646
00651 static void Key_Unbind_f (void)
00652 {
00653 int b;
00654
00655 if (Cmd_Argc() != 2) {
00656 Com_Printf("Usage: %s <key> : remove commands from a key\n", Cmd_Argv(0));
00657 return;
00658 }
00659
00660 b = Key_StringToKeynum(Cmd_Argv(1));
00661 if (b == -1) {
00662 Com_Printf("\"%s\" isn't a valid key\n", Cmd_Argv(1));
00663 return;
00664 }
00665
00666 if (!strcmp(Cmd_Argv(0), "unbindmenu"))
00667 Key_SetBinding(b, "", KEYSPACE_UI);
00668 else if (!strcmp(Cmd_Argv(0), "unbindbattle"))
00669 Key_SetBinding(b, "", KEYSPACE_BATTLE);
00670 else
00671 Key_SetBinding(b, "", KEYSPACE_GAME);
00672 }
00673
00678 static void Key_Unbindall_f (void)
00679 {
00680 int i;
00681
00682 for (i = K_FIRST_KEY; i < K_LAST_KEY; i++)
00683 if (keyBindings[i]) {
00684 if (!strcmp(Cmd_Argv(0), "unbindallmenu"))
00685 Key_SetBinding(i, "", KEYSPACE_UI);
00686 else
00687 Key_SetBinding(i, "", KEYSPACE_GAME);
00688 }
00689 }
00690
00695 static void Key_Bind_f (void)
00696 {
00697 int i, c, b;
00698 char cmd[1024];
00699
00700 c = Cmd_Argc();
00701
00702 if (c < 2) {
00703 Com_Printf("Usage: %s <key> [command] : attach a command to a key\n", Cmd_Argv(0));
00704 return;
00705 }
00706 b = Key_StringToKeynum(Cmd_Argv(1));
00707 if (b == -1) {
00708 Com_Printf("\"%s\" isn't a valid key\n", Cmd_Argv(1));
00709 return;
00710 }
00711
00712 if (c == 2) {
00713 if (keyBindings[b])
00714 Com_Printf("\"%s\" = \"%s\"\n", Cmd_Argv(1), keyBindings[b]);
00715 else
00716 Com_Printf("\"%s\" is not bound\n", Cmd_Argv(1));
00717 return;
00718 }
00719
00720
00721 cmd[0] = '\0';
00722 for (i = 2; i < c; i++) {
00723 Q_strcat(cmd, Cmd_Argv(i), sizeof(cmd));
00724 if (i != (c - 1))
00725 Q_strcat(cmd, " ", sizeof(cmd));
00726 }
00727
00728 if (!strcmp(Cmd_Argv(0), "bindui"))
00729 UI_SetKeyBinding(cmd, b);
00730 else if (!strcmp(Cmd_Argv(0), "bindmenu"))
00731 Key_SetBinding(b, cmd, KEYSPACE_UI);
00732 else if (!strcmp(Cmd_Argv(0), "bindbattle"))
00733 Key_SetBinding(b, cmd, KEYSPACE_BATTLE);
00734 else
00735 Key_SetBinding(b, cmd, KEYSPACE_GAME);
00736 }
00737
00743 void Key_WriteBindings (const char* filename)
00744 {
00745 int i;
00746
00747 qboolean deleteFile = qfalse;
00748 qFILE f;
00749 int cnt = 0;
00750
00751 memset(&f, 0, sizeof(f));
00752 FS_OpenFile(filename, &f, FILE_WRITE);
00753 if (!f.f) {
00754 Com_Printf("Couldn't write %s.\n", filename);
00755 return;
00756 }
00757
00758 FS_Printf(&f, "// generated by ufo, do not modify\n");
00759 FS_Printf(&f, "// If you want to know the keyname of a specific key - set in_debug cvar to 1 and press the key\n");
00760 FS_Printf(&f, "unbindallmenu\n");
00761 FS_Printf(&f, "unbindall\n");
00762 FS_Printf(&f, "unbindallbattle\n");
00763
00764 for (i = 0; i < K_LAST_KEY && !deleteFile; i++)
00765 if (menuKeyBindings[i] && menuKeyBindings[i][0]) {
00766 if (FS_Printf(&f, "bindmenu %s \"%s\"\n", Key_KeynumToString(i), menuKeyBindings[i]) < 0)
00767 deleteFile = qtrue;
00768 cnt++;
00769 }
00770 for (i = 0; i < K_LAST_KEY && !deleteFile; i++)
00771 if (keyBindings[i] && keyBindings[i][0]) {
00772 if (FS_Printf(&f, "bind %s \"%s\"\n", Key_KeynumToString(i), keyBindings[i]) < 0)
00773 deleteFile = qtrue;
00774 cnt++;
00775 }
00776 for (i = 0; i < K_LAST_KEY && !deleteFile; i++)
00777 if (battleKeyBindings[i] && battleKeyBindings[i][0]) {
00778 if (FS_Printf(&f, "bindbattle %s \"%s\"\n", Key_KeynumToString(i), battleKeyBindings[i]) < 0)
00779 deleteFile = qtrue;
00780 cnt++;
00781 }
00782
00783 for (i = 0; i < UI_GetKeyBindingCount(); i++) {
00784 const char *path;
00785 uiKeyBinding_t*binding = UI_GetKeyBindingByIndex (i);
00786 if (binding->node == NULL)
00787 continue;
00788 if (binding->property == NULL)
00789 path = va("%s", UI_GetPath(binding->node));
00790 else
00791 path = va("%s@%s", UI_GetPath(binding->node), binding->property->string);
00792
00793 if (FS_Printf(&f, "bindui %s \"%s\"\n", Key_KeynumToString(binding->key), path) < 0)
00794 deleteFile = qtrue;
00795 }
00796
00797 FS_CloseFile(&f);
00798 if (!deleteFile && cnt)
00799 Com_Printf("Wrote %s\n", filename);
00800 else
00801
00802 FS_RemoveFile(va("%s/%s", FS_Gamedir(), filename));
00803 }
00804
00808 static void Key_WriteBindings_f (void)
00809 {
00810 char filename[MAX_QPATH];
00811
00812 if (Cmd_Argc() != 2) {
00813 Com_Printf("Usage: %s <filename>\n", Cmd_Argv(0));
00814 return;
00815 }
00816
00817 Q_strncpyz(filename, Cmd_Argv(1), sizeof(filename));
00818 Com_DefaultExtension(filename, sizeof(filename), ".cfg");
00819 Key_WriteBindings(filename);
00820 }
00821
00825 static void Key_Bindlist_f (void)
00826 {
00827 int i;
00828
00829 Com_Printf("key space: game\n");
00830 for (i = K_FIRST_KEY; i < K_LAST_KEY; i++)
00831 if (keyBindings[i] && keyBindings[i][0])
00832 Com_Printf("- %s \"%s\"\n", Key_KeynumToString(i), keyBindings[i]);
00833 Com_Printf("key space: menu\n");
00834 for (i = K_FIRST_KEY; i < K_LAST_KEY; i++)
00835 if (menuKeyBindings[i] && menuKeyBindings[i][0])
00836 Com_Printf("- %s \"%s\"\n", Key_KeynumToString(i), menuKeyBindings[i]);
00837 Com_Printf("key space: battle\n");
00838 for (i = 0; i < K_LAST_KEY; i++)
00839 if (battleKeyBindings[i] && battleKeyBindings[i][0])
00840 Com_Printf("- %s \"%s\"\n", Key_KeynumToString(i), battleKeyBindings[i]);
00841
00842 }
00843
00844 static int Key_CompleteKeyName (const char *partial, const char **match)
00845 {
00846 int matches = 0;
00847 const char *localMatch[MAX_COMPLETE];
00848 size_t len;
00849 const keyName_t *kn;
00850
00851 len = strlen(partial);
00852 if (!len) {
00853 for (kn = keyNames; kn->name; kn++) {
00854 Com_Printf("%s\n", kn->name);
00855 }
00856 return 0;
00857 }
00858
00859
00860 for (kn = keyNames; kn->name; kn++) {
00861 if (!strncmp(partial, kn->name, len)) {
00862 Com_Printf("%s\n", kn->name);
00863 localMatch[matches++] = kn->name;
00864 if (matches >= MAX_COMPLETE)
00865 break;
00866 }
00867 }
00868
00869 return Cmd_GenericCompleteFunction(len, match, matches, localMatch);
00870 }
00871
00872 void Key_Init (void)
00873 {
00874 int i;
00875
00876 for (i = 0; i < MAXKEYLINES; i++) {
00877 keyLines[i][0] = CONSOLE_PROMPT_CHAR | CONSOLE_COLORED_TEXT_MASK;
00878 keyLines[i][1] = 0;
00879 }
00880 keyLinePos = 1;
00881
00882
00883 Cmd_AddCommand("bindui", Key_Bind_f, "Bind a key to a ui node");
00884 Cmd_AddCommand("bindmenu", Key_Bind_f, "Bind a key to a console command - only executed when hovering a menu");
00885 Cmd_AddCommand("bind", Key_Bind_f, "Bind a key to a console command");
00886 Cmd_AddCommand("bindbattle", Key_Bind_f, "Bind a key to a console command - only executed when in battlescape");
00887 Cmd_AddCommand("unbindmenu", Key_Unbind_f, "Unbind a key");
00888 Cmd_AddCommand("unbind", Key_Unbind_f, "Unbind a key");
00889 Cmd_AddCommand("unbindbattle", Key_Unbind_f, "Unbind a key");
00890 Cmd_AddParamCompleteFunction("bind", Key_CompleteKeyName);
00891 Cmd_AddParamCompleteFunction("unbind", Key_CompleteKeyName);
00892 Cmd_AddParamCompleteFunction("bindmenu", Key_CompleteKeyName);
00893 Cmd_AddParamCompleteFunction("unbindmenu", Key_CompleteKeyName);
00894 Cmd_AddParamCompleteFunction("bindbattle", Key_CompleteKeyName);
00895 Cmd_AddParamCompleteFunction("unbindbattle", Key_CompleteKeyName);
00896 Cmd_AddCommand("unbindallmenu", Key_Unbindall_f, "Delete all key bindings for the menu");
00897 Cmd_AddCommand("unbindall", Key_Unbindall_f, "Delete all key bindings");
00898 Cmd_AddCommand("unbindallbattle", Key_Unbindall_f, "Delete all key bindings for battlescape");
00899 Cmd_AddCommand("bindlist", Key_Bindlist_f, "Show all bindings on the game console");
00900 Cmd_AddCommand("savebind", Key_WriteBindings_f, "Saves key bindings to keys.cfg");
00901 }
00902
00907 void Key_SetDest (int keyDest)
00908 {
00909 cls.keyDest = keyDest;
00910 if (cls.keyDest == key_console) {
00911
00912 UI_ReleaseInput();
00913 }
00914 }
00915
00921 void Key_Event (unsigned int key, unsigned short unicode, qboolean down, unsigned time)
00922 {
00923 char cmd[MAX_STRING_CHARS];
00924
00925
00926 if (key >= K_KEY_SIZE)
00927 return;
00928
00929
00930
00931 if (cls.keyDest == key_game && down) {
00932 if (UI_KeyPressed(key, unicode))
00933 return;
00934 }
00935
00936
00937 if (key == K_ESCAPE) {
00938 if (!down)
00939 return;
00940
00941 switch (cls.keyDest) {
00942 case key_message:
00943 Key_Message(unicode);
00944 break;
00945 case key_console:
00946 Con_ToggleConsole_f();
00947 break;
00948 default:
00949 Com_Error(ERR_FATAL, "Bad cls.key_dest");
00950 }
00951 return;
00952 }
00953
00954
00955 keyDown[key] = down;
00956 if (!down) {
00957 int i;
00958
00959
00960
00961
00962
00963 const char *kb = menuKeyBindings[key];
00964
00965 for (i = 0; i < 3; i++) {
00966 if (kb && kb[0] == '+') {
00967
00968
00969
00970
00971
00972 Com_sprintf(cmd, sizeof(cmd), "-%s %i %i\n", kb + 1, key, time);
00973 Cbuf_AddText(cmd);
00974 }
00975 if (i == 0)
00976 kb = keyBindings[key];
00977 else
00978 kb = battleKeyBindings[key];
00979 }
00980 return;
00981 }
00982
00983
00984 if (cls.keyDest == key_game || (key >= K_MOUSE1 && key <= K_MWHEELUP)) {
00985
00986
00987
00988 const char *kb = NULL;
00989 if (mouseSpace == MS_UI && unicode >= 32 && unicode < 127)
00990 kb = menuKeyBindings[unicode];
00991 if (!kb && mouseSpace == MS_UI)
00992 kb = menuKeyBindings[key];
00993 if (!kb && unicode >= 32 && unicode < 127)
00994 kb = keyBindings[unicode];
00995 if (!kb)
00996 kb = keyBindings[key];
00997 if (!kb && CL_OnBattlescape())
00998 kb = battleKeyBindings[key];
00999 if (kb) {
01000 if (kb[0] == '+') {
01001
01002
01003
01004 Com_sprintf(cmd, sizeof(cmd), "%s %i %i\n", kb, key, time);
01005 Cbuf_AddText(cmd);
01006 } else {
01007 Cbuf_AddText(kb);
01008 Cbuf_AddText("\n");
01009 }
01010 if (cls.keyDest == key_game)
01011 return;
01012 }
01013 }
01014
01015 if (!down)
01016 return;
01017
01018 switch (cls.keyDest) {
01019 case key_message:
01020 Key_Message(unicode);
01021 break;
01022 case key_game:
01023 case key_console:
01024 Key_Console(key, unicode);
01025 break;
01026 default:
01027 Com_Error(ERR_FATAL, "Bad cls.key_dest");
01028 }
01029 }