1 /////////////////////////////////////////////////////////////////////////
2 // $Id: keymap.cc,v 1.23 2008/02/15 22:05:40 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2002 MandrakeSoft S.A.
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 2 of the License, or (at your option) any later version.
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // Lesser General Public License for more details.
17 // You should have received a copy of the GNU Lesser General Public
18 // License along with this library; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /////////////////////////////////////////////////////////////////////////
24 // . Currently supported by sdl, wxGTK and x11. Check if other guis need mapping.
25 // . Tables look-up should be optimised.
30 // Table of bochs "BX_KEY_*" symbols
31 // the table must be in BX_KEY_* order
32 const char *bx_key_symbol
[BX_KEY_NBKEYS
] = {
33 "BX_KEY_CTRL_L", "BX_KEY_SHIFT_L", "BX_KEY_F1",
34 "BX_KEY_F2", "BX_KEY_F3", "BX_KEY_F4",
35 "BX_KEY_F5", "BX_KEY_F6", "BX_KEY_F7",
36 "BX_KEY_F8", "BX_KEY_F9", "BX_KEY_F10",
37 "BX_KEY_F11", "BX_KEY_F12", "BX_KEY_CTRL_R",
38 "BX_KEY_SHIFT_R", "BX_KEY_CAPS_LOCK", "BX_KEY_NUM_LOCK",
39 "BX_KEY_ALT_L", "BX_KEY_ALT_R", "BX_KEY_A",
40 "BX_KEY_B", "BX_KEY_C", "BX_KEY_D",
41 "BX_KEY_E", "BX_KEY_F", "BX_KEY_G",
42 "BX_KEY_H", "BX_KEY_I", "BX_KEY_J",
43 "BX_KEY_K", "BX_KEY_L", "BX_KEY_M",
44 "BX_KEY_N", "BX_KEY_O", "BX_KEY_P",
45 "BX_KEY_Q", "BX_KEY_R", "BX_KEY_S",
46 "BX_KEY_T", "BX_KEY_U", "BX_KEY_V",
47 "BX_KEY_W", "BX_KEY_X", "BX_KEY_Y",
48 "BX_KEY_Z", "BX_KEY_0", "BX_KEY_1",
49 "BX_KEY_2", "BX_KEY_3", "BX_KEY_4",
50 "BX_KEY_5", "BX_KEY_6", "BX_KEY_7",
51 "BX_KEY_8", "BX_KEY_9", "BX_KEY_ESC",
52 "BX_KEY_SPACE", "BX_KEY_SINGLE_QUOTE", "BX_KEY_COMMA",
53 "BX_KEY_PERIOD", "BX_KEY_SLASH", "BX_KEY_SEMICOLON",
54 "BX_KEY_EQUALS", "BX_KEY_LEFT_BRACKET", "BX_KEY_BACKSLASH",
55 "BX_KEY_RIGHT_BRACKET", "BX_KEY_MINUS", "BX_KEY_GRAVE",
56 "BX_KEY_BACKSPACE", "BX_KEY_ENTER", "BX_KEY_TAB",
57 "BX_KEY_LEFT_BACKSLASH", "BX_KEY_PRINT", "BX_KEY_SCRL_LOCK",
58 "BX_KEY_PAUSE", "BX_KEY_INSERT", "BX_KEY_DELETE",
59 "BX_KEY_HOME", "BX_KEY_END", "BX_KEY_PAGE_UP",
60 "BX_KEY_PAGE_DOWN", "BX_KEY_KP_ADD", "BX_KEY_KP_SUBTRACT",
61 "BX_KEY_KP_END", "BX_KEY_KP_DOWN", "BX_KEY_KP_PAGE_DOWN",
62 "BX_KEY_KP_LEFT", "BX_KEY_KP_RIGHT", "BX_KEY_KP_HOME",
63 "BX_KEY_KP_UP", "BX_KEY_KP_PAGE_UP", "BX_KEY_KP_INSERT",
64 "BX_KEY_KP_DELETE", "BX_KEY_KP_5", "BX_KEY_UP",
65 "BX_KEY_DOWN", "BX_KEY_LEFT", "BX_KEY_RIGHT",
66 "BX_KEY_KP_ENTER", "BX_KEY_KP_MULTIPLY", "BX_KEY_KP_DIVIDE",
67 "BX_KEY_WIN_L", "BX_KEY_WIN_R", "BX_KEY_MENU",
68 "BX_KEY_ALT_SYSREQ", "BX_KEY_CTRL_BREAK", "BX_KEY_INT_BACK",
69 "BX_KEY_INT_FORWARD", "BX_KEY_INT_STOP", "BX_KEY_INT_MAIL",
70 "BX_KEY_INT_SEARCH", "BX_KEY_INT_FAV", "BX_KEY_INT_HOME",
71 "BX_KEY_POWER_MYCOMP", "BX_KEY_POWER_CALC", "BX_KEY_POWER_SLEEP",
72 "BX_KEY_POWER_POWER", "BX_KEY_POWER_WAKE",
75 bx_keymap_c bx_keymap
;
77 #define LOG_THIS bx_keymap.
79 bx_keymap_c::bx_keymap_c(void)
84 keymapTable
= (BXKeyEntry
*)NULL
;
87 bx_keymap_c::~bx_keymap_c(void)
89 if(keymapTable
!= NULL
) {
91 keymapTable
= (BXKeyEntry
*)NULL
;
96 void bx_keymap_c::loadKeymap(Bit32u
stringToSymbol(const char*))
98 if (SIM
->get_param_bool(BXPN_KBD_USEMAPPING
)->get()) {
99 loadKeymap(stringToSymbol
, SIM
->get_param_string(BXPN_KBD_KEYMAP
)->getptr());
103 bx_bool
bx_keymap_c::isKeymapLoaded ()
105 return (keymapCount
> 0);
110 // I'll add these to the keymap object in a minute.
111 static unsigned char *lineptr
= NULL
;
112 static int lineCount
;
114 static void init_parse()
119 static void init_parse_line(char *line_to_parse
)
122 lineptr
= (unsigned char *)line_to_parse
;
124 if ((nl
= strchr(line_to_parse
,'\n')) != NULL
) {
129 static Bit32s
get_next_word(char *output
)
131 char *copyp
= output
;
132 // find first nonspace
133 while (*lineptr
&& isspace(*lineptr
))
136 return -1; // nothing but spaces until end of line
138 return -1; // nothing but a comment
139 // copy nonspaces into the output
140 while (*lineptr
&& !isspace(*lineptr
))
141 *copyp
++ = *lineptr
++;
142 *copyp
=0; // null terminate the copy
143 // there must be at least one nonspace, since that's why we stopped the
145 BX_ASSERT (copyp
!= output
);
149 static Bit32s
get_next_keymap_line (FILE *fp
, char *bxsym
, char *modsym
, Bit32s
*ascii
, char *hostsym
)
156 if (!fgets(line
, sizeof(line
)-1, fp
)) return -1; // EOF
157 init_parse_line (line
);
158 if (get_next_word (bxsym
) >= 0) {
161 if ((p
= strchr (bxsym
, '+')) != NULL
) {
162 *p
= 0; // truncate bxsym.
163 p
++; // move one char beyond the +
164 strcpy (modsym
, p
); // copy the rest to modsym
166 if (get_next_word (buf
) < 0) {
167 BX_PANIC (("keymap line %d: expected 3 columns", lineCount
));
170 if (buf
[0] == '\'' && buf
[2] == '\'' && buf
[3]==0) {
171 *ascii
= (Bit8u
) buf
[1];
172 } else if (!strcmp(buf
, "space")) {
174 } else if (!strcmp(buf
, "return")) {
176 } else if (!strcmp(buf
, "tab")) {
178 } else if (!strcmp(buf
, "backslash")) {
180 } else if (!strcmp(buf
, "apostrophe")) {
182 } else if (!strcmp(buf
, "none")) {
185 BX_PANIC (("keymap line %d: ascii equivalent is \"%s\" but it must be char constant like 'x', or one of space,tab,return,none", lineCount
, buf
));
187 if (get_next_word (hostsym
) < 0) {
188 BX_PANIC (("keymap line %d: expected 3 columns", lineCount
));
193 // no words on this line, keep reading.
197 void bx_keymap_c::loadKeymap(Bit32u
stringToSymbol(const char*), const char* filename
)
200 char baseSym
[256], modSym
[256], hostSym
[256];
202 Bit32u baseKey
, modKey
, hostKey
;
205 if (stat(filename
, &status
)) {
206 BX_PANIC(("Can not stat keymap file '%s'.",filename
));
209 if (!(S_ISREG(status
.st_mode
))) {
210 BX_PANIC(("Keymap file '%s' is not a file",filename
));
213 if((keymapFile
= fopen(filename
,"r"))==NULL
) {
214 BX_PANIC(("Can not open keymap file '%s'.",filename
));
217 BX_INFO(("Loading keymap from '%s'",filename
));
220 // Read keymap file one line at a time
222 if (get_next_keymap_line (keymapFile
,
223 baseSym
, modSym
, &ascii
, hostSym
) < 0) { break; }
225 // convert X_KEY_* symbols to values
226 baseKey
= convertStringToBXKey(baseSym
);
227 modKey
= convertStringToBXKey(modSym
);
229 if (stringToSymbol
!= NULL
)
230 hostKey
= stringToSymbol(hostSym
);
232 BX_DEBUG(("baseKey='%s' (%d), modSym='%s' (%d), ascii=%d, guisym='%s' (%d)", baseSym
, baseKey
, modSym
, modKey
, ascii
, hostSym
, hostKey
));
234 // Check if data is valid
235 if (baseKey
==BX_KEYMAP_UNKNOWN
) {
236 BX_PANIC (("line %d: unknown BX_KEY constant '%s'",lineCount
,baseSym
));
240 if (hostKey
==BX_KEYMAP_UNKNOWN
) {
241 BX_PANIC (("line %d: unknown host key name '%s' (wrong keymap ?)",lineCount
,hostSym
));
245 keymapTable
=(BXKeyEntry
*)realloc(keymapTable
,(keymapCount
+1) * sizeof(BXKeyEntry
));
247 if (keymapTable
==NULL
)
248 BX_PANIC(("Can not allocate memory for keymap table."));
250 keymapTable
[keymapCount
].baseKey
=baseKey
;
251 keymapTable
[keymapCount
].modKey
=modKey
;
252 keymapTable
[keymapCount
].ascii
=ascii
;
253 keymapTable
[keymapCount
].hostKey
=hostKey
;
258 BX_INFO(("Loaded %d symbols",keymapCount
));
263 Bit32u
bx_keymap_c::convertStringToBXKey(const char* string
)
265 // We look through the bx_key_symbol table to find the searched string
266 for (Bit16u i
=0; i
<BX_KEY_NBKEYS
; i
++) {
267 if (strcmp(string
,bx_key_symbol
[i
])==0) {
273 return BX_KEYMAP_UNKNOWN
;
276 BXKeyEntry
*bx_keymap_c::findHostKey(Bit32u key
)
278 // We look through the keymap table to find the searched key
279 for (Bit16u i
=0; i
<keymapCount
; i
++) {
280 if (keymapTable
[i
].hostKey
== key
) {
281 BX_DEBUG (("key 0x%02x matches hostKey for entry #%d", key
, i
));
282 return &keymapTable
[i
];
285 BX_DEBUG(("key %02x matches no entries", key
));
291 BXKeyEntry
*bx_keymap_c::findAsciiChar(Bit8u ch
)
293 BX_DEBUG (("findAsciiChar (0x%02x)", ch
));
295 // We look through the keymap table to find the searched key
296 for (Bit16u i
=0; i
<keymapCount
; i
++) {
297 if (keymapTable
[i
].ascii
== ch
) {
298 BX_DEBUG (("key %02x matches ascii for entry #%d", ch
, i
));
299 return &keymapTable
[i
];
302 BX_DEBUG (("key 0x%02x matches no entries", ch
));
308 const char *bx_keymap_c::getBXKeyName(Bit32u key
)
310 return bx_key_symbol
[key
& 0x7fffffff];