1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * genkeymap.c
4 * Copyright (C) Ádám Wallner 2008 <wallner@bitbaro.hu>
5 *
6 * You may redistribute it and/or modify it under the terms of the
7 * GNU General Public License, as published by the Free Software
8 * Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * main.cc is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with main.cc. If not, write to:
18 * The Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor
20 * Boston, MA 02110-1301, USA
21
22 Updated Jay Sorg 2009
23
24 cs Czech 0x405
25 de German 0x407
26 en-us US English 0x409
27 fr French 0x40c
28 it Italian 0x410
29 br Portuguese (Brazil) 0x416
30 ru Russian 0x419
31 se Swedish 0x41d
32 en-uk UK English 0x809
33 */
34
35 #if defined(HAVE_CONFIG_H)
36 #include <config_ac.h>
37 #endif
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <X11/Xlib.h>
43 #include <X11/Xutil.h>
44 #include <X11/XKBlib.h>
45 #include <locale.h>
46
47 extern int xfree86_to_evdev[137-8+1];
48
main(int argc,char ** argv)49 int main(int argc, char **argv)
50 {
51 const char *programname;
52 char text[256];
53 char *displayname = NULL;
54 char *outfname;
55 const char *sections[8] = {
56 "noshift", "shift", "altgr", "shiftaltgr",
57 "capslock", "capslockaltgr", "shiftcapslock", "shiftcapslockaltgr"
58 };
59 int states[8] = {0, 1, 0x80, 0x81, 2, 0x82, 3, 0x83};
60 int i;
61 int idx;
62 int char_count;
63 int nbytes = 0;
64 int unicode;
65 Display *dpy;
66 KeySym ks;
67 FILE *outf;
68 XKeyPressedEvent e;
69 wchar_t wtext[256];
70 XkbDescPtr kbdesc;
71 char *symatom;
72 int is_evdev;
73
74 setlocale(LC_CTYPE, "");
75 programname = argv[0];
76
77 if (argc != 2)
78 {
79 fprintf(stderr, "Usage: %s out_filename\n", programname);
80 fprintf(stderr, "Example: %s /etc/xrdp/km-00000409.ini\n", programname);
81 return 1;
82 }
83
84 outfname = argv[1];
85 dpy = XOpenDisplay(displayname);
86
87 if (!dpy)
88 {
89 fprintf(stderr, "%s: unable to open display '%s'\n",
90 programname, XDisplayName(displayname));
91 return 1;
92 }
93
94 /* check whether evdev is used */
95 kbdesc = XkbAllocKeyboard();
96 if (!kbdesc)
97 {
98 fprintf(stderr, "%s: unable to allocate keyboard desc\n",
99 programname);
100 XCloseDisplay(dpy);
101 return 1;
102 }
103
104 if (XkbGetNames(dpy, XkbKeycodesNameMask, kbdesc) != Success)
105 {
106 fprintf(stderr, "%s: unable to obtain keycode name for keyboard\n",
107 programname);
108 XkbFreeKeyboard(kbdesc, 0, True);
109 XCloseDisplay(dpy);
110 return 1;
111 }
112
113 symatom = XGetAtomName(dpy, kbdesc->names->keycodes);
114 is_evdev = !strncmp(symatom, "evdev", 5);
115 XFree(symatom);
116 XkbFreeKeyboard(kbdesc, 0, True);
117
118 outf = fopen(outfname, "w");
119
120 if (outf == NULL)
121 {
122 fprintf(stderr, "%s: unable to create file '%s'\n", programname, outfname);
123 XCloseDisplay(dpy);
124 return 1;
125 }
126
127 memset(&e, 0, sizeof(e));
128 e.type = KeyPress;
129 e.serial = 16;
130 e.send_event = True;
131 e.display = dpy;
132 e.same_screen = True;
133
134 for (idx = 0; idx < 8; idx++) /* Sections and states */
135 {
136 fprintf(outf, "[%s]\n", sections[idx]);
137 e.state = states[idx];
138
139 for (i = 8; i < 137; i++) /* Keycodes */
140 {
141 if (is_evdev)
142 e.keycode = xfree86_to_evdev[i-8];
143 else
144 e.keycode = i;
145 nbytes = XLookupString(&e, text, 255, &ks, NULL);
146 text[nbytes] = 0;
147 char_count = mbstowcs(wtext, text, 255);
148 unicode = 0;
149
150 if (char_count == 1)
151 {
152 unicode = wtext[0];
153 }
154
155 fprintf(outf, "Key%d=%d:%d\n", i, (int) ks, unicode);
156 }
157
158 if (idx != 7)
159 {
160 fprintf(outf, "\n");
161 }
162 }
163
164 XCloseDisplay(dpy);
165 fclose(outf);
166 return 0;
167 }
168