|
|
1.1 root 1: /*
2: Hatari - dlgKeyboard.c
3:
1.1.1.8 root 4: This file is distributed under the GNU General Public License, version 2
5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6: */
1.1.1.7 root 7: const char DlgKeyboard_fileid[] = "Hatari dlgKeyboard.c : " __DATE__ " " __TIME__;
1.1 root 8:
9: #include <unistd.h>
10:
11: #include "main.h"
12: #include "configuration.h"
13: #include "dialog.h"
14: #include "sdlgui.h"
15: #include "file.h"
16: #include "screen.h"
1.1.1.10! root 17: #include "str.h"
! 18: #include "keymap.h"
1.1 root 19:
1.1.1.10! root 20: #define DLGKEY_SYMBOLIC 4
! 21: #define DLGKEY_SCANCODE 5
! 22: #define DLGKEY_FROMFILE 6
! 23: #define DLGKEY_MAPNAME 8
! 24: #define DLGKEY_MAPBROWSE 9
! 25: #define DLGKEY_SCPREV 13
! 26: #define DLGKEY_SCNAME 14
! 27: #define DLGKEY_SCNEXT 15
! 28: #define DLGKEY_SCMODVAL 17
! 29: #define DLGKEY_SCMODDEF 18
! 30: #define DLGKEY_SCNOMODVAL 20
! 31: #define DLGKEY_SCNOMODDEF 21
! 32: #define DLGKEY_DISREPEAT 22
! 33: #define DLGKEY_EXIT 23
1.1 root 34:
1.1.1.10! root 35: static char sc_modval[16];
! 36: static char sc_nomodval[16];
1.1 root 37:
38: /* The keyboard dialog: */
39: static SGOBJ keyboarddlg[] =
40: {
1.1.1.10! root 41: { SGBOX, 0, 0, 0,0, 46,24, NULL },
1.1.1.5 root 42: { SGTEXT, 0, 0, 16,1, 14,1, "Keyboard setup" },
1.1.1.10! root 43:
! 44: { SGBOX, 0, 0, 1,3, 44,7, NULL },
1.1.1.4 root 45: { SGTEXT, 0, 0, 2,3, 17,1, "Keyboard mapping:" },
1.1.1.9 root 46: { SGRADIOBUT, 0, 0, 4,5, 10,1, "_Symbolic" },
47: { SGRADIOBUT, 0, 0, 17,5, 10,1, "S_cancode" },
48: { SGRADIOBUT, 0, 0, 30,5, 11,1, "_From file" },
1.1.1.4 root 49: { SGTEXT, 0, 0, 2,7, 13,1, "Mapping file:" },
1.1.1.5 root 50: { SGTEXT, 0, 0, 2,8, 42,1, NULL },
1.1.1.9 root 51: { SGBUTTON, 0, 0, 36, 7, 8,1, "_Browse" },
1.1.1.10! root 52:
! 53: { SGBOX, 0, 0, 1,11, 44,8, NULL },
! 54: { SGTEXT, 0, 0, 2,11, 12,1, "Shortcuts:" },
! 55: { SGBOX, 0, 0, 2,13, 42,1, NULL },
! 56: { SGBUTTON, 0, 0, 2,13, 1,1, "\x04", SG_SHORTCUT_LEFT },
! 57: { SGTEXT, 0, 0, 4,13, 20,1, NULL },
! 58: { SGBUTTON, 0, 0, 43,13, 1,1, "\x03", SG_SHORTCUT_RIGHT },
! 59: { SGTEXT, 0, 0, 2,15, 17,1, "With modifier:" },
! 60: { SGTEXT, 0, 0, 20,15, 12,1, sc_modval },
! 61: { SGBUTTON, 0, 0, 36,15, 8,1, "_Define" },
! 62: { SGTEXT, 0, 0, 2,17, 17,1, "Without modifier:" },
! 63: { SGTEXT, 0, 0, 20,17, 12,1, sc_nomodval },
! 64: { SGBUTTON, 0, 0, 36,17, 8,1, "D_efine" },
! 65:
! 66: { SGCHECKBOX, 0, 0, 2,20, 41,1, "Disable key _repeat in fast forward mode" },
! 67: { SGBUTTON, SG_DEFAULT, 0, 13,22, 20,1, "Back to main menu" },
! 68: { SGSTOP, 0, 0, 0,0, 0,0, NULL }
! 69: };
! 70:
! 71:
! 72: static char *sc_names[SHORTCUT_KEYS] = {
! 73: "Edit settings",
! 74: "Toggle fullscreen",
! 75: "Grab mouse",
! 76: "Cold reset",
! 77: "Warm reset",
! 78: "Take screenshot",
! 79: "Boss key",
! 80: "Joystick cursor emulation",
! 81: "Fast forward",
! 82: "Record animation",
! 83: "Record sound",
! 84: "Toggle sound",
! 85: "Enter debugger",
! 86: "Pause emulation",
! 87: "Quit emulator",
! 88: "Load memory snapshot",
! 89: "Save memory snapshot",
! 90: "Insert disk A:",
! 91: "Toggle joystick 0",
! 92: "Toggle joystick 1",
! 93: "Toggle joypad A",
! 94: "Toggle joypad B"
! 95: };
! 96:
! 97: static char sScKeyType[28];
! 98: static char sScKeyName[28];
! 99:
! 100: static SGOBJ sckeysdlg[] =
! 101: {
! 102: { SGBOX, 0, 0, 0,0, 30,6, NULL },
! 103: { SGTEXT, 0, 0, 2,1, 28,1, "Press key for:" },
! 104: { SGTEXT, 0, 0, 2,2, 28,1, sScKeyType },
! 105: { SGTEXT, 0, 0, 2,4, 28,1, sScKeyName },
! 106: { SGSTOP, 0, 0, 0,0, 0,0, NULL }
1.1 root 107: };
108:
109:
1.1.1.10! root 110: /**
! 111: * Show dialogs for defining shortcut keys and wait for a key press.
! 112: */
! 113: static void DlgKbd_DefineShortcutKey(int sc, bool withMod)
! 114: {
! 115: SDL_Event sdlEvent;
! 116: int *pscs;
! 117: int i;
! 118:
! 119: if (bQuitProgram)
! 120: return;
! 121:
! 122: SDLGui_CenterDlg(sckeysdlg);
! 123:
! 124: if (withMod)
! 125: pscs = ConfigureParams.Shortcut.withModifier;
! 126: else
! 127: pscs = ConfigureParams.Shortcut.withoutModifier;
! 128:
! 129: snprintf(sScKeyType, sizeof(sScKeyType), "'%s'", sc_names[sc]);
! 130: snprintf(sScKeyName, sizeof(sScKeyName), "(was: '%s')", Keymap_GetKeyName(pscs[sc]));
! 131:
! 132: SDLGui_DrawDialog(sckeysdlg);
! 133:
! 134: /* drain buffered key events */
! 135: SDL_Delay(200);
! 136: while (SDL_PollEvent(&sdlEvent))
! 137: {
! 138: if (sdlEvent.type == SDL_KEYUP || sdlEvent.type == SDL_KEYDOWN)
! 139: break;
! 140: }
! 141:
! 142: /* get the real key */
! 143: do
! 144: {
! 145: SDL_WaitEvent(&sdlEvent);
! 146: switch (sdlEvent.type)
! 147: {
! 148: case SDL_KEYDOWN:
! 149: pscs[sc] = sdlEvent.key.keysym.sym;
! 150: snprintf(sScKeyName, sizeof(sScKeyName), "(now: '%s')",
! 151: Keymap_GetKeyName(sdlEvent.key.keysym.sym));
! 152: SDLGui_DrawDialog(sckeysdlg);
! 153: break;
! 154: case SDL_MOUSEBUTTONDOWN:
! 155: if (sdlEvent.button.button == SDL_BUTTON_RIGHT)
! 156: {
! 157: pscs[sc] = 0;
! 158: return;
! 159: }
! 160: else if (sdlEvent.button.button == SDL_BUTTON_LEFT)
! 161: {
! 162: return;
! 163: }
! 164: break;
! 165: case SDL_QUIT:
! 166: bQuitProgram = true;
! 167: return;
! 168: }
! 169: } while (sdlEvent.type != SDL_KEYUP);
! 170:
! 171: /* Make sure that no other shortcut key has the same value */
! 172: for (i = 0; i < SHORTCUT_KEYS; i++)
! 173: {
! 174: if (i == sc)
! 175: continue;
! 176: if (pscs[i] == pscs[sc])
! 177: {
! 178: pscs[i] = 0;
! 179: DlgAlert_Notice("Removing key from other shortcut!");
! 180: }
! 181: }
! 182: }
! 183:
! 184:
! 185: /**
! 186: * Set name for given sortcut, or show it's unset
! 187: */
! 188: static void DlgKbd_SetName(char *str, size_t maxlen, int keysym)
! 189: {
! 190: if (keysym)
! 191: strlcpy(str, Keymap_GetKeyName(keysym), maxlen);
! 192: else
! 193: strlcpy(str, "<not set>", maxlen);
! 194: }
! 195:
! 196:
! 197: /**
! 198: * Refresh the shortcut texts in the dialog
! 199: */
! 200: static void DlgKbd_RefreshShortcuts(int sc)
! 201: {
! 202: int keysym;
! 203:
! 204: /* with modifier */
! 205: keysym = ConfigureParams.Shortcut.withModifier[sc];
! 206: DlgKbd_SetName(sc_modval, sizeof(sc_modval), keysym);
! 207:
! 208: /* without modifier */
! 209: keysym = ConfigureParams.Shortcut.withoutModifier[sc];
! 210: DlgKbd_SetName(sc_nomodval, sizeof(sc_nomodval), keysym);
! 211:
! 212: keyboarddlg[DLGKEY_SCNAME].txt = sc_names[sc];
! 213: }
! 214:
1.1.1.4 root 215: /**
216: * Show and process the "Keyboard" dialog.
217: */
1.1 root 218: void Dialog_KeyboardDlg(void)
219: {
1.1.1.4 root 220: int i, but;
1.1.1.5 root 221: char dlgmapfile[44];
1.1.1.10! root 222: int cur_sc = 0;
1.1 root 223:
1.1.1.4 root 224: SDLGui_CenterDlg(keyboarddlg);
225:
226: /* Set up dialog from actual values: */
227: for (i = DLGKEY_SYMBOLIC; i <= DLGKEY_FROMFILE; i++)
228: {
229: keyboarddlg[i].state &= ~SG_SELECTED;
230: }
1.1.1.5 root 231: keyboarddlg[DLGKEY_SYMBOLIC+ConfigureParams.Keyboard.nKeymapType].state |= SG_SELECTED;
1.1.1.4 root 232:
1.1.1.5 root 233: File_ShrinkName(dlgmapfile, ConfigureParams.Keyboard.szMappingFileName,
1.1.1.4 root 234: keyboarddlg[DLGKEY_MAPNAME].w);
235: keyboarddlg[DLGKEY_MAPNAME].txt = dlgmapfile;
236:
1.1.1.10! root 237: DlgKbd_RefreshShortcuts(cur_sc);
! 238:
1.1.1.5 root 239: if (ConfigureParams.Keyboard.bDisableKeyRepeat)
240: keyboarddlg[DLGKEY_DISREPEAT].state |= SG_SELECTED;
241: else
242: keyboarddlg[DLGKEY_DISREPEAT].state &= ~SG_SELECTED;
243:
1.1.1.4 root 244: /* Show the dialog: */
245: do
246: {
1.1.1.9 root 247: but = SDLGui_DoDialog(keyboarddlg, NULL, false);
1.1.1.4 root 248:
1.1.1.10! root 249: switch (but)
1.1.1.4 root 250: {
1.1.1.10! root 251: case DLGKEY_MAPBROWSE:
1.1.1.9 root 252: SDLGui_FileConfSelect("Keyboard mapping file:", dlgmapfile,
1.1.1.5 root 253: ConfigureParams.Keyboard.szMappingFileName,
1.1.1.7 root 254: keyboarddlg[DLGKEY_MAPNAME].w, false);
1.1.1.10! root 255: break;
! 256: case DLGKEY_SCPREV:
! 257: if (cur_sc > 0)
! 258: {
! 259: --cur_sc;
! 260: DlgKbd_RefreshShortcuts(cur_sc);
! 261: }
! 262: break;
! 263: case DLGKEY_SCNEXT:
! 264: if (cur_sc < SHORTCUT_KEYS-1)
! 265: {
! 266: ++cur_sc;
! 267: DlgKbd_RefreshShortcuts(cur_sc);
! 268: }
! 269: break;
! 270: case DLGKEY_SCMODDEF:
! 271: DlgKbd_DefineShortcutKey(cur_sc, true);
! 272: DlgKbd_RefreshShortcuts(cur_sc);
! 273: break;
! 274: case DLGKEY_SCNOMODDEF:
! 275: DlgKbd_DefineShortcutKey(cur_sc, false);
! 276: DlgKbd_RefreshShortcuts(cur_sc);
! 277: break;
1.1.1.4 root 278: }
279: }
280: while (but != DLGKEY_EXIT && but != SDLGUI_QUIT
281: && but != SDLGUI_ERROR && !bQuitProgram);
282:
283: /* Read values from dialog: */
284: if (keyboarddlg[DLGKEY_SYMBOLIC].state & SG_SELECTED)
1.1.1.5 root 285: ConfigureParams.Keyboard.nKeymapType = KEYMAP_SYMBOLIC;
1.1.1.4 root 286: else if (keyboarddlg[DLGKEY_SCANCODE].state & SG_SELECTED)
1.1.1.5 root 287: ConfigureParams.Keyboard.nKeymapType = KEYMAP_SCANCODE;
1.1.1.4 root 288: else
1.1.1.5 root 289: ConfigureParams.Keyboard.nKeymapType = KEYMAP_LOADED;
290:
291: ConfigureParams.Keyboard.bDisableKeyRepeat = (keyboarddlg[DLGKEY_DISREPEAT].state & SG_SELECTED);
1.1 root 292: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.