ws_KbdMap.c revision d49df8ba
1/* $NetBSD: ws_KbdMap.c,v 1.1 2023/11/07 14:29:00 tsutsui Exp $	*/
2/* $XConsortium: sunKeyMap.c,v 4.22 94/05/18 11:16:07 kaleb Exp $ */
3/************************************************************
4Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
5
6                    All Rights Reserved
7
8Permission  to  use,  copy,  modify,  and  distribute   this
9software  and  its documentation for any purpose and without
10fee is hereby granted, provided that the above copyright no-
11tice  appear  in all copies and that both that copyright no-
12tice and this permission notice appear in  supporting  docu-
13mentation,  and  that the names of Sun or X Consortium
14not be used in advertising or publicity pertaining to
15distribution  of  the software  without specific prior
16written permission. Sun and X Consortium make no
17representations about the suitability of this software for
18any purpose. It is provided "as is" without any express or
19implied warranty.
20
21SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
22INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
23NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
24ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
25ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
26PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
27OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
28THE USE OR PERFORMANCE OF THIS SOFTWARE.
29
30********************************************************/
31
32/*
33 * Generate XKB keymap from wskbd keymap provided by WSKBDIO_GETMAP ioctl
34 *
35 * Taken from:
36 * 	xsrc/xfree/xc/programs/Xserver/hw/netbsd/hpc/hpcKeymap.c
37 * 	NetBSD: hpcKeymap.c,v 1.2 2004/07/22 18:08:59 uch Exp
38 */
39
40#ifdef HAVE_CONFIG_H
41#include "config.h"
42#endif
43
44#include "xf86.h"
45#include "xf86OSKbd.h"
46#include "atKeynames.h"
47#include "xf86Keymap.h"
48#include "xkbsrv.h"
49
50#include "bsd_kbd.h"
51
52#include <sys/ioctl.h>
53#include <dev/wscons/wsconsio.h>
54#include <dev/wscons/wsksymdef.h>
55
56static void KeymapSetSymbol(KeySym *, CARD8 *, struct wscons_keymap *);
57
58static KeySym wsksym_to_xkeysym[] = {
59	[KS_BackSpace] = XK_BackSpace,
60	[KS_Tab] = XK_Tab,
61	[KS_Linefeed] = XK_Linefeed,
62	[KS_Clear] = XK_Clear,
63	[KS_Return] = XK_Return,
64	[KS_Escape] = XK_Escape,
65	[KS_space] = XK_space,
66	[KS_exclam] = XK_exclam,
67	[KS_quotedbl] = XK_quotedbl,
68	[KS_numbersign] = XK_numbersign,
69	[KS_dollar] = XK_dollar,
70	[KS_percent] = XK_percent,
71	[KS_ampersand] = XK_ampersand,
72	[KS_apostrophe] = XK_apostrophe,
73	[KS_parenleft] = XK_parenleft,
74	[KS_parenright] = XK_parenright,
75	[KS_asterisk] = XK_asterisk,
76	[KS_plus] = XK_plus,
77	[KS_comma] = XK_comma,
78	[KS_minus] = XK_minus,
79	[KS_period] = XK_period,
80	[KS_slash] = XK_slash,
81	[KS_0] = XK_0,
82	[KS_1] = XK_1,
83	[KS_2] = XK_2,
84	[KS_3] = XK_3,
85	[KS_4] = XK_4,
86	[KS_5] = XK_5,
87	[KS_6] = XK_6,
88	[KS_7] = XK_7,
89	[KS_8] = XK_8,
90	[KS_9] = XK_9,
91	[KS_colon] = XK_colon,
92	[KS_semicolon] = XK_semicolon,
93	[KS_less] = XK_less,
94	[KS_equal] = XK_equal,
95	[KS_greater] = XK_greater,
96	[KS_question] = XK_question,
97	[KS_at] = XK_at,
98	[KS_A] = XK_A,
99	[KS_B] = XK_B,
100	[KS_C] = XK_C,
101	[KS_D] = XK_D,
102	[KS_E] = XK_E,
103	[KS_F] = XK_F,
104	[KS_G] = XK_G,
105	[KS_H] = XK_H,
106	[KS_I] = XK_I,
107	[KS_J] = XK_J,
108	[KS_K] = XK_K,
109	[KS_L] = XK_L,
110	[KS_M] = XK_M,
111	[KS_N] = XK_N,
112	[KS_O] = XK_O,
113	[KS_P] = XK_P,
114	[KS_Q] = XK_Q,
115	[KS_R] = XK_R,
116	[KS_S] = XK_S,
117	[KS_T] = XK_T,
118	[KS_U] = XK_U,
119	[KS_V] = XK_V,
120	[KS_W] = XK_W,
121	[KS_X] = XK_X,
122	[KS_Y] = XK_Y,
123	[KS_Z] = XK_Z,
124	[KS_bracketleft] = XK_bracketleft,
125	[KS_backslash] = XK_backslash,
126	[KS_bracketright] = XK_bracketright,
127	[KS_asciicircum] = XK_asciicircum,
128	[KS_underscore] = XK_underscore,
129	[KS_grave] = XK_grave,
130	[KS_a] = XK_a,
131	[KS_b] = XK_b,
132	[KS_c] = XK_c,
133	[KS_d] = XK_d,
134	[KS_e] = XK_e,
135	[KS_f] = XK_f,
136	[KS_g] = XK_g,
137	[KS_h] = XK_h,
138	[KS_i] = XK_i,
139	[KS_j] = XK_j,
140	[KS_k] = XK_k,
141	[KS_l] = XK_l,
142	[KS_m] = XK_m,
143	[KS_n] = XK_n,
144	[KS_o] = XK_o,
145	[KS_p] = XK_p,
146	[KS_q] = XK_q,
147	[KS_r] = XK_r,
148	[KS_s] = XK_s,
149	[KS_t] = XK_t,
150	[KS_u] = XK_u,
151	[KS_v] = XK_v,
152	[KS_w] = XK_w,
153	[KS_x] = XK_x,
154	[KS_y] = XK_y,
155	[KS_z] = XK_z,
156	[KS_braceleft] = XK_braceleft,
157	[KS_bar] = XK_bar,
158	[KS_braceright] = XK_braceright,
159	[KS_asciitilde] = XK_asciitilde,
160	[KS_Delete] = XK_Delete,
161	[KS_nobreakspace] = XK_nobreakspace,
162	[KS_exclamdown] = XK_exclamdown,
163	[KS_cent] = XK_cent,
164	[KS_sterling] = XK_sterling,
165	[KS_currency] = XK_currency,
166	[KS_yen] = XK_yen,
167	[KS_brokenbar] = XK_brokenbar,
168	[KS_section] = XK_section,
169	[KS_diaeresis] = XK_diaeresis,
170	[KS_copyright] = XK_copyright,
171	[KS_ordfeminine] = XK_ordfeminine,
172	[KS_guillemotleft] = XK_guillemotleft,
173	[KS_notsign] = XK_notsign,
174	[KS_hyphen] = XK_hyphen,
175	[KS_registered] = XK_registered,
176	[KS_macron] = XK_macron,
177	[KS_degree] = XK_degree,
178	[KS_plusminus] = XK_plusminus,
179	[KS_twosuperior] = XK_twosuperior,
180	[KS_threesuperior] = XK_threesuperior,
181	[KS_acute] = XK_acute,
182	[KS_mu] = XK_mu,
183	[KS_paragraph] = XK_paragraph,
184	[KS_periodcentered] = XK_periodcentered,
185	[KS_cedilla] = XK_cedilla,
186	[KS_onesuperior] = XK_onesuperior,
187	[KS_masculine] = XK_masculine,
188	[KS_guillemotright] = XK_guillemotright,
189	[KS_onequarter] = XK_onequarter,
190	[KS_onehalf] = XK_onehalf,
191	[KS_threequarters] = XK_threequarters,
192	[KS_questiondown] = XK_questiondown,
193	[KS_Agrave] = XK_Agrave,
194	[KS_Aacute] = XK_Aacute,
195	[KS_Acircumflex] = XK_Acircumflex,
196	[KS_Atilde] = XK_Atilde,
197	[KS_Adiaeresis] = XK_Adiaeresis,
198	[KS_Aring] = XK_Aring,
199	[KS_AE] = XK_AE,
200	[KS_Ccedilla] = XK_Ccedilla,
201	[KS_Egrave] = XK_Egrave,
202	[KS_Eacute] = XK_Eacute,
203	[KS_Ecircumflex] = XK_Ecircumflex,
204	[KS_Ediaeresis] = XK_Ediaeresis,
205	[KS_Igrave] = XK_Igrave,
206	[KS_Iacute] = XK_Iacute,
207	[KS_Icircumflex] = XK_Icircumflex,
208	[KS_Idiaeresis] = XK_Idiaeresis,
209	[KS_ETH] = XK_ETH,
210	[KS_Ntilde] = XK_Ntilde,
211	[KS_Ograve] = XK_Ograve,
212	[KS_Oacute] = XK_Oacute,
213	[KS_Ocircumflex] = XK_Ocircumflex,
214	[KS_Otilde] = XK_Otilde,
215	[KS_Odiaeresis] = XK_Odiaeresis,
216	[KS_multiply] = XK_multiply,
217	[KS_Ooblique] = XK_Ooblique,
218	[KS_Ugrave] = XK_Ugrave,
219	[KS_Uacute] = XK_Uacute,
220	[KS_Ucircumflex] = XK_Ucircumflex,
221	[KS_Udiaeresis] = XK_Udiaeresis,
222	[KS_Yacute] = XK_Yacute,
223	[KS_THORN] = XK_THORN,
224	[KS_ssharp] = XK_ssharp,
225	[KS_agrave] = XK_agrave,
226	[KS_aacute] = XK_aacute,
227	[KS_acircumflex] = XK_acircumflex,
228	[KS_atilde] = XK_atilde,
229	[KS_adiaeresis] = XK_adiaeresis,
230	[KS_aring] = XK_aring,
231	[KS_ae] = XK_ae,
232	[KS_ccedilla] = XK_ccedilla,
233	[KS_egrave] = XK_egrave,
234	[KS_eacute] = XK_eacute,
235	[KS_ecircumflex] = XK_ecircumflex,
236	[KS_ediaeresis] = XK_ediaeresis,
237	[KS_igrave] = XK_igrave,
238	[KS_iacute] = XK_iacute,
239	[KS_icircumflex] = XK_icircumflex,
240	[KS_idiaeresis] = XK_idiaeresis,
241	[KS_eth] = XK_eth,
242	[KS_ntilde] = XK_ntilde,
243	[KS_ograve] = XK_ograve,
244	[KS_oacute] = XK_oacute,
245	[KS_ocircumflex] = XK_ocircumflex,
246	[KS_otilde] = XK_otilde,
247	[KS_odiaeresis] = XK_odiaeresis,
248	[KS_division] = XK_division,
249	[KS_oslash] = XK_oslash,
250	[KS_ugrave] = XK_ugrave,
251	[KS_uacute] = XK_uacute,
252	[KS_ucircumflex] = XK_ucircumflex,
253	[KS_udiaeresis] = XK_udiaeresis,
254	[KS_yacute] = XK_yacute,
255	[KS_thorn] = XK_thorn,
256	[KS_ydiaeresis] = XK_ydiaeresis,
257	[KS_Odoubleacute] = XK_Odoubleacute,
258	[KS_odoubleacute] = XK_odoubleacute,
259	[KS_Udoubleacute] = XK_Udoubleacute,
260	[KS_udoubleacute] = XK_udoubleacute,
261	[KS_dead_grave] = XK_dead_grave,
262	[KS_dead_acute] = XK_dead_acute,
263	[KS_dead_circumflex] = XK_dead_circumflex,
264	[KS_dead_tilde] = XK_dead_tilde,
265	[KS_dead_diaeresis] = XK_dead_diaeresis,
266	[KS_dead_abovering] = XK_dead_abovering,
267	[KS_dead_cedilla] = XK_dead_cedilla,
268	[KS_Shift_L] = XK_Shift_L,
269	[KS_Shift_R] = XK_Shift_R,
270	[KS_Control_L] = XK_Control_L,
271	[KS_Control_R] = XK_Control_R,
272	[KS_Caps_Lock] = XK_Caps_Lock,
273	[KS_Shift_Lock] = XK_Shift_Lock,
274	[KS_Alt_L] = XK_Alt_L,
275	[KS_Alt_R] = XK_Alt_R,
276	[KS_Multi_key] = XK_Multi_key,
277	[KS_Mode_switch] = XK_Mode_switch,
278	[KS_Num_Lock] = XK_Num_Lock,
279	[KS_Meta_L] = XK_Meta_L,
280	[KS_Meta_R] = XK_Meta_R,
281	[KS_Zenkaku_Hankaku] = XK_Zenkaku_Hankaku,
282	[KS_Hiragana_Katakana] = XK_Hiragana_Katakana,
283	[KS_Henkan_Mode] = XK_Henkan_Mode,
284	[KS_Henkan] = XK_Henkan,
285	[KS_Muhenkan] = XK_Muhenkan,
286	[KS_KP_F1] = XK_KP_F1,
287	[KS_KP_F2] = XK_KP_F2,
288	[KS_KP_F3] = XK_KP_F3,
289	[KS_KP_F4] = XK_KP_F4,
290	[KS_KP_Home] = XK_KP_Home,
291	[KS_KP_Left] = XK_KP_Left,
292	[KS_KP_Up] = XK_KP_Up,
293	[KS_KP_Right] = XK_KP_Right,
294	[KS_KP_Down] = XK_KP_Down,
295	[KS_KP_Prior] = XK_KP_Prior,
296	[KS_KP_Next] = XK_KP_Next,
297	[KS_KP_End] = XK_KP_End,
298	[KS_KP_Begin] = XK_KP_Begin,
299	[KS_KP_Insert] = XK_KP_Insert,
300	[KS_KP_Delete] = XK_KP_Delete,
301	[KS_KP_Space] = XK_KP_Space,
302	[KS_KP_Tab] = XK_KP_Tab,
303	[KS_KP_Enter] = XK_KP_Enter,
304	[KS_KP_Equal] = XK_KP_Equal,
305	[KS_KP_Numbersign] = XK_numbersign,
306	[KS_KP_Multiply] = XK_KP_Multiply,
307	[KS_KP_Add] = XK_KP_Add,
308	[KS_KP_Separator] = XK_KP_Separator,
309	[KS_KP_Subtract] = XK_KP_Subtract,
310	[KS_KP_Decimal] = XK_KP_Decimal,
311	[KS_KP_Divide] = XK_KP_Divide,
312	[KS_KP_0] = XK_KP_0,
313	[KS_KP_1] = XK_KP_1,
314	[KS_KP_2] = XK_KP_2,
315	[KS_KP_3] = XK_KP_3,
316	[KS_KP_4] = XK_KP_4,
317	[KS_KP_5] = XK_KP_5,
318	[KS_KP_6] = XK_KP_6,
319	[KS_KP_7] = XK_KP_7,
320	[KS_KP_8] = XK_KP_8,
321	[KS_KP_9] = XK_KP_9,
322	[KS_f1] = XK_F1,
323	[KS_f2] = XK_F2,
324	[KS_f3] = XK_F3,
325	[KS_f4] = XK_F4,
326	[KS_f5] = XK_F5,
327	[KS_f6] = XK_F6,
328	[KS_f7] = XK_F7,
329	[KS_f8] = XK_F8,
330	[KS_f9] = XK_F9,
331	[KS_f10] = XK_F10,
332	[KS_f11] = XK_F11,
333	[KS_f12] = XK_F12,
334	[KS_f13] = XK_F13,
335	[KS_f14] = XK_F14,
336	[KS_f15] = XK_F15,
337	[KS_f16] = XK_F16,
338	[KS_f17] = XK_F17,
339	[KS_f18] = XK_F18,
340	[KS_f19] = XK_F19,
341	[KS_f20] = XK_F20,
342	[KS_F1] = XK_F1,
343	[KS_F2] = XK_F2,
344	[KS_F3] = XK_F3,
345	[KS_F4] = XK_F4,
346	[KS_F5] = XK_F5,
347	[KS_F6] = XK_F6,
348	[KS_F7] = XK_F7,
349	[KS_F8] = XK_F8,
350	[KS_F9] = XK_F9,
351	[KS_F10] = XK_F10,
352	[KS_F11] = XK_F11,
353	[KS_F12] = XK_F12,
354	[KS_F13] = XK_F13,
355	[KS_F14] = XK_F14,
356	[KS_F15] = XK_F15,
357	[KS_F16] = XK_F16,
358	[KS_F17] = XK_F17,
359	[KS_F18] = XK_F18,
360	[KS_F19] = XK_F19,
361	[KS_F20] = XK_F20,
362	[KS_Home] = XK_Home,
363	[KS_Prior] = XK_Prior,
364	[KS_Next] = XK_Next,
365	[KS_Up] = XK_Up,
366	[KS_Down] = XK_Down,
367	[KS_Left] = XK_Left,
368	[KS_Right] = XK_Right,
369	[KS_End] = XK_End,
370	[KS_Insert] = XK_Insert,
371	[KS_Help] = XK_Help,
372	[KS_Execute] = XK_Execute,
373	[KS_Find] = XK_Find,
374	[KS_Select] = XK_Select,
375	[KS_Undo] = XK_Undo,
376	[KS_Menu] = XK_Menu,
377	[KS_Pause] = XK_Pause,
378	[0xffff] = NoSymbol,
379};
380
381void
382KbdGetMappingFromWsksym(InputInfoPtr pInfo, KeySymsPtr pKeySyms, CARD8 *pModMap)
383{
384	struct wskbd_map_data map_data;
385	struct wscons_keymap *wscons_keymap, *wscons_key;
386	KeySym *x_key;
387	CARD8 *x_mod;
388	int i;
389
390	wscons_keymap =
391	    malloc(sizeof(struct wscons_keymap) * WSKBDIO_MAXMAPLEN);
392	if (wscons_keymap == NULL) {
393		xf86Msg(X_ERROR, "%s: can't allocate wscons keymap memory\n",
394		    pInfo->name);
395		return;
396	}
397	memset(wscons_keymap, 0,
398	    sizeof(struct wscons_keymap) * WSKBDIO_MAXMAPLEN);
399	map_data.maplen = WSKBDIO_MAXMAPLEN;
400	map_data.map = wscons_keymap;
401
402	/* Get console keymap */
403	if (ioctl(pInfo->fd, WSKBDIO_GETMAP, &map_data) == -1) {
404		xf86Msg(X_ERROR, "%s: can't get wskbd keymap\n", pInfo->name);
405		return;
406	}
407	for (i = 0;
408	    i < sizeof wsksym_to_xkeysym / sizeof(wsksym_to_xkeysym[0]); i++)
409		if (wsksym_to_xkeysym[i] == 0)
410			wsksym_to_xkeysym[i] = NoSymbol;
411
412	pKeySyms->map        = map;
413	pKeySyms->mapWidth   = GLYPHS_PER_KEY;
414	pKeySyms->minKeyCode = MIN_KEYCODE;
415	pKeySyms->maxKeyCode = pKeySyms->minKeyCode + map_data.maplen - 1;
416
417	xf86Msg(X_INFO, "%s: Using keysyms via WSKBDIO_GETMAP\n", pInfo->name);
418	xf86Msg(X_INFO, "%s: total %d wskbd keysyms\n",
419	    pInfo->name, map_data.maplen);
420
421	/* Reconstruct keymap */
422	x_key = &pKeySyms->map[0];
423	x_mod = &pModMap[pKeySyms->minKeyCode];
424	wscons_key = wscons_keymap;
425	for (i = 0; i < map_data.maplen; i++) {
426		/* assume GLYPHS_PER_KEY is 4 */
427		if (i == NUM_KEYCODES) {
428			xf86Msg(X_WARNING, "%s: too many wskbd keysyms\n",
429			    pInfo->name);
430			break;
431		}
432		KeymapSetSymbol(x_key, x_mod, wscons_key);
433		x_key += GLYPHS_PER_KEY;
434		x_mod++;
435		wscons_key++;
436	}
437	free(wscons_keymap);
438}
439
440static void
441KeymapSetSymbol(KeySym *xmap, CARD8 *pModMap, struct wscons_keymap *keymap)
442{
443
444	xmap[0] = wsksym_to_xkeysym[keymap->group1[0]];
445	xmap[1] = wsksym_to_xkeysym[keymap->group1[1]];
446	xmap[2] = wsksym_to_xkeysym[keymap->group2[0]];
447	xmap[3] = wsksym_to_xkeysym[keymap->group2[1]];
448
449	*pModMap = NoSymbol;
450	switch (xmap[0]) {
451	case XK_Shift_L:
452	case XK_Shift_R:
453		*pModMap = ShiftMask;
454		break;
455	case XK_Control_L:
456	case XK_Control_R:
457		*pModMap = ControlMask;
458		break;
459	case XK_Caps_Lock:
460		*pModMap = LockMask;
461		break;
462	case XK_Alt_L:
463		*pModMap = AltMask;
464		xmap[1] = XK_Meta_L;
465		break;
466	case XK_Alt_R:
467		*pModMap = AltMask;
468		xmap[1] = XK_Meta_R;
469		break;
470	case XK_Num_Lock:
471		*pModMap = NumLockMask;
472		break;
473	case XK_Scroll_Lock:
474		*pModMap = ScrollLockMask;
475		break;
476	case XK_Kana_Lock:
477	case XK_Kana_Shift:
478		*pModMap = KanaMask;
479		break;
480	case XK_Mode_switch:	/* XXX */
481		*pModMap = AltLangMask;
482		break;
483	default:
484		break;
485	}
486}
487