Chameleon

Chameleon Svn Source Tree

Root/trunk/i386/modules/Keylayout/layouts/cham-mklayout.c

1/*
2 * cham-mklayout.c
3 * Chameleon
4 *
5 * Created by JrCs on 30/08/11.
6 * Copyright 2011. All rights reserved.
7 *
8 */
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <getopt.h>
14#include <errno.h>
15#include "stdint.h"
16#include "term.h"
17#include "keylayout.h"
18
19#define PACKAGE_NAME"chameleon"
20#define PROGRAM_VERSION"1.0"
21
22static struct keyboard_layout default_layout = {
23.keyboard_map = {
24/* 0x00 */ 0, KEY_ESC, '1', '2', '3', '4', '5', '6',
25/* 0x08 */ '7', '8', '9', '0', '-', '=', KEY_BKSP, KEY_TAB,
26/* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
27/* 0x18 */ 'o', 'p', '[', ']', KEY_ENTER, 0, 'a', 's',
28/* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
29/* 0x28 */ '\'', '`', 0, '\\', 'z', 'x', 'c', 'v',
30/* 0x30 */ 'b', 'n', 'm', ',', '.', '/', 0, 0
31},
32.keyboard_map_shift = {
33/* 0x00 */ 0, KEY_ESC, '!', '@', '#', '$', '%', '^',
34/* 0x08 */ '&', '*', '(', ')', '_', '+', KEY_BKSP, 0,
35/* 0x10 */ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
36/* 0x18 */ 'O', 'P', '{', '}', KEY_ENTER, 0, 'A', 'S',
37/* 0x20 */ 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
38/* 0x28 */ '"', '~', 0, '|', 'Z', 'X', 'C', 'V',
39/* 0x30 */ 'B', 'N', 'M', '<', '>', '?', 0, 0,
40},
41.keyboard_map_alt = {
42/* 0x00 */ 0, KEY_NOECHO, 0, 0, 0, 0, 0, 0,
43/* 0x08 */ 0, 0, 0, 0, 0, 0, KEY_NOECHO, KEY_NOECHO,
44/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
45/* 0x18 */ 0, 0, KEY_NOECHO, KEY_NOECHO, KEY_NOECHO, KEY_NOECHO, 0, 0,
46/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, KEY_NOECHO,
47/* 0x28 */ KEY_NOECHO, KEY_NOECHO, KEY_NOECHO, KEY_NOECHO, 0, 0, 0, 0,
48/* 0x30 */ 0, 0, 0, KEY_NOECHO, KEY_NOECHO, KEY_NOECHO, KEY_NOECHO, KEY_NOECHO,
49},
50};
51
52const char* program_name;
53
54static struct option options[] = {
55{"input", required_argument, 0, 'i'},
56{"output", required_argument, 0, 'o'},
57{"keysyms", no_argument, 0, 'k'},
58{"help", no_argument, 0, 'h'},
59{"version", no_argument, 0, 'V'},
60{0, 0, 0, 0}
61};
62
63struct hash
64{
65 const char *keysym;
66 int code;
67};
68
69static struct hash keysym_to_code[] = {
70{"BackSpace",KEY_BKSP},
71{"Tab",KEY_TAB},
72{"Linefeed",0x000a},
73{"Space",0x0020},
74{"Exclam",0x0021},
75{"QuoteDbl",0x0022},
76{"NumberSign",0x0023},
77{"Dollar",0x0024},
78{"Percent",0x0025},
79{"Ampersand",0x0026},
80{"Apostrophe",0x0027},
81{"Parenleft",0x0028},
82{"Parenright",0x0029},
83{"Asterisk",0x002a},
84{"Plus",0x002b},
85{"Comma",0x002c},
86{"Minus",0x002d},
87{"Period",0x002e},
88{"Slash",0x002f},
89{"Zero",0x0030},
90{"One",0x0031},
91{"Two",0x0032},
92{"Three",0x0033},
93{"Four",0x0034},
94{"Five",0x0035},
95{"Six",0x0036},
96{"Seven",0x0037},
97{"Eight",0x0038},
98{"Nine",0x0039},
99{"Colon",0x003a},
100{"SemiColon",0x003b},
101{"Less",0x003c},
102{"Equal",0x003d},
103{"Greater",0x003e},
104{"Question",0x003f},
105{"At",0x0040},
106{"BracketLeft", 0x005b},
107{"Backslash",0x005c},
108{"BracketRight",0x005d},
109{"AsciiCircum", 0x005e},
110{"Underscore",0x005f},
111{"Grave",0x0060},
112{"BraceLeft",0x007b},
113{"Bar",0x007c},
114{"BraceRight",0x007d},
115{"AsciiTilde",0x007e},
116{"Enter",KEY_ENTER},
117{"Escape",KEY_ESC},
118{"PrintScreen",KEY_PRTSC},
119{"Left",KEY_LEFT},
120{"Right",KEY_RIGHT},
121{"Up",KEY_UP},
122{"Down",KEY_DOWN},
123{"Home",KEY_HOME},
124{"End",KEY_END},
125{"Center",KEY_CENTER},
126{"Insert",KEY_INS},
127{"Delete",KEY_DEL},
128{"PageUp",KEY_PGUP},
129{"PageDown",KEY_PGDN},
130{"F1",KEY_F1},
131{"F2",KEY_F2},
132{"F3",KEY_F3},
133{"F4",KEY_F4},
134{"F5",KEY_F5},
135{"F6",KEY_F6},
136{"F7",KEY_F7},
137{"F8",KEY_F8},
138{"F9",KEY_F9},
139{"F10",KEY_F10},
140{"F11",KEY_F11},
141{"F12",KEY_F12},
142{"VoidSymbol",KEY_NOECHO},
143{NULL, 0}
144};
145
146
147static void usage (int status) {
148 if (status)
149 fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
150 else
151 printf ("\
152Usage: %s [OPTIONS]\n\
153 -i, --inputset input filename.\n\
154 -o, --outputset output filename.\n\
155 -k, --keysymslist recognized keysyms.\n\
156 -h, --helpdisplay this message and exit.\n\
157 -V, --versionprint version information and exit.\n\
158\n", program_name);
159
160 exit (status);
161}
162
163static void list_keysyms (void) {
164int i;
165for (i = 0; keysym_to_code[i].keysym != NULL; i++) {
166printf("0x%04x\t %s\n", keysym_to_code[i].code, keysym_to_code[i].keysym);
167}
168}
169
170static int hash_lookup (const char *keysym, unsigned int *code) {
171int i;
172for (i = 0; keysym_to_code[i].keysym != NULL; i++) {
173if (strcasecmp (keysym, keysym_to_code[i].keysym) == 0) {
174*code = keysym_to_code[i].code;
175return 0;
176}
177}
178return -1;
179}
180
181static int parse_keysym(const char* str, unsigned int *code) {
182// Single character
183if (strlen(str) == 1) {
184*code=(unsigned char)(str[0]);
185if (*code > ASCII_KEY_MASK)
186return -1;
187return 0;
188}
189
190// Hex character code
191if (sscanf(str, "0x%x", code))
192return 0;
193
194// Keysym
195if (hash_lookup(str, code) == 0)
196return 0;
197
198return -1;
199}
200
201int parse_scancode(int linenum, char* code, unsigned int* scancode) {
202
203char* tmp;
204errno = 0; // clear errno
205
206float parse_value = strtof(code, &tmp);
207int rest = strlen(code) - ((void*) tmp - (void*)code);
208if (rest != 0 || errno != 0) {
209printf("Ignoring line %d: invalid scancode `%s'\n", linenum, code);
210return -1;
211}
212
213*scancode = parse_value;
214
215// Only the first scancodes can be translated
216if (*scancode >= KEYBOARD_MAP_SIZE) {
217printf("Ignoring line %d: invalid scancode 0x%02x. Scancode must be <= 0x%02x.\n", linenum, *scancode,
218 KEYBOARD_MAP_SIZE);
219return -1;
220}
221return 0;
222}
223
224void assign_keycode(int linenum, unsigned int scancode, const char* arg, uint16_t* map) {
225unsigned int value;
226if (parse_keysym(arg, &value) == -1) {
227printf("Warning line %d (keycode 0x%02x): invalid symbol %s (must be a true ascii character)\n",
228 linenum, scancode, arg);
229value = KEY_NOECHO; // VoidSymbol
230}
231map[scancode] = value;
232}
233
234struct keyboard_layout* create_keylayout(FILE* in) {
235char line[128], code[sizeof(line)];
236char arg1[sizeof(line)], arg2[sizeof(line)], arg3[sizeof(line)],
237 arg4[sizeof(line)];
238int n, linenum = 0;
239unsigned int scancode;
240
241struct keyboard_layout* new_layout= malloc(sizeof(*new_layout));
242if (!new_layout)
243return NULL;
244
245// Initialize new keybord layout
246memcpy(new_layout, &default_layout, sizeof(*new_layout));
247
248while(fgets(line, sizeof(line), in)) {
249linenum++;
250n = sscanf (line, "keycode %s = %s %s %s %s", code, arg1, arg2, arg3, arg4);
251if (n > 1) {
252if (parse_scancode(linenum, code, &scancode) == -1)
253continue;
254if (n >= 2)
255assign_keycode(linenum, scancode, arg1,
256 new_layout->keyboard_map);
257if (n >= 3)
258assign_keycode(linenum, scancode, arg2,
259 new_layout->keyboard_map_shift);
260if (n >= 4)
261assign_keycode(linenum, scancode, arg3,
262 new_layout->keyboard_map_alt);
263if (n >= 5)
264assign_keycode(linenum, scancode, arg4,
265 new_layout->keyboard_map_shift_alt);
266} else if (sscanf (line, "shift keycode %s = %s", code, arg1) == 2) {
267if (parse_scancode(linenum, code, &scancode) == -1)
268continue;
269assign_keycode(linenum, scancode, arg1,
270 new_layout->keyboard_map_shift);
271} else if (sscanf (line, "alt keycode %s = %s", code, arg1) == 2) {
272if (parse_scancode(linenum, code, &scancode) == -1)
273continue;
274assign_keycode(linenum, scancode, arg1,
275 new_layout->keyboard_map_alt);
276} else if (sscanf (line, "shift alt keycode %s = %s", code, arg1) == 2) {
277if (parse_scancode(linenum, code, &scancode) == -1)
278continue;
279assign_keycode(linenum, scancode, arg1,
280 new_layout->keyboard_map_shift_alt);
281}
282}
283return new_layout;
284}
285
286void write_layout(struct keyboard_layout* layout, FILE* out) {
287// Create the header
288uint32_t version = KEYBOARD_LAYOUTS_VERSION;
289fwrite(KEYBOARD_LAYOUTS_MAGIC, KEYBOARD_LAYOUTS_MAGIC_SIZE, 1, out);
290fwrite(&version, 1, sizeof(version), out);
291// Seek to start of layout
292fseek(out, KEYBOARD_LAYOUTS_MAP_OFFSET, SEEK_SET);
293// Write layout
294fwrite(layout, sizeof(*layout), 1, out);
295}
296
297void set_program_name(const char* arg) {
298const char* last_slash;
299last_slash = strrchr(arg, '/');
300program_name = (last_slash != NULL) ? last_slash + 1 : arg;
301}
302
303int main (int argc, char *argv[]) {
304int ch;
305char *infile_name = NULL;
306char *outfile_name = NULL;
307FILE *in, *out;
308
309set_program_name (argv[0]);
310
311/* Check for options. */
312while ((ch = getopt_long (argc, argv, "i:o:hkV", options, 0)) != -1) {
313switch (ch) {
314case 'h':
315usage (0);
316break;
317
318case 'k':
319list_keysyms();
320exit(0);
321break;
322
323case 'i':
324infile_name = optarg;
325break;
326
327case 'o':
328outfile_name = optarg;
329break;
330
331case 'V':
332printf ("%s v%s (%s)\n", program_name, PROGRAM_VERSION, PACKAGE_NAME);
333return 0;
334
335default:
336usage (1);
337break;
338}
339}
340
341if (infile_name == NULL) {
342fprintf(stderr, "You must specify an input file\n");
343usage(1);
344}
345
346if (outfile_name == NULL) {
347fprintf(stderr, "You must specify an output file\n");
348usage(1);
349}
350
351in = fopen (infile_name, "r");
352if (!in) {
353fprintf(stderr, "Couldn't open input file `%s': %s\n",
354infile_name, strerror (errno));
355exit(1);
356 }
357
358out = fopen (outfile_name, "wb");
359if (!out) {
360fprintf(stderr, "Couldn't open output file `%s': %s\n",
361outfile_name, strerror (errno));
362exit(1);
363 }
364
365struct keyboard_layout* new_layout = create_keylayout(in);
366if (new_layout)
367write_layout(new_layout, out);
368
369 fclose(out);
370fclose(in);
371
372return 0;
373}
374

Archive Download this file

Revision: 1529