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