Chameleon

Chameleon Svn Source Tree

Root/trunk/i386/modules/Keylayout/Keylayout.c

1/*
2 * Keymapper.c
3 * Chameleon
4 *
5 * Created by JrCs on 28/08/11.
6 * Copyright 2011. All rights reserved.
7 *
8 */
9
10#include "libsaio.h"
11#include "term.h"
12#include "modules.h"
13#include "Keylayout.h"
14#include "bootstruct.h"
15
16#ifndef DEBUG_KLAYOUT
17#define DEBUG_KLAYOUT 0
18#endif
19
20#if DEBUG_KLAYOUT
21#define DBG(x...)printf(x)
22#else
23#define DBG(x...)
24#endif
25
26#define kKeyboardLayout "KeyboardLayout"
27
28struct keyboard_layout *current_layout = NULL;
29int getchar_replacement();
30
31int getchar_replacement() {
32int code = bgetc();
33int status = readKeyboardShiftFlags();
34uint8_t scancode = code >> 8;
35
36// Special scancode sent when alt + some keys are pressed
37if (scancode >= 0x78 && scancode <= 0x83)
38scancode -= 0x76;
39
40if (scancode < KEYBOARD_MAP_SIZE && !(status & (STATUS_LCTRL| STATUS_RCTRL))) {
41int key;
42if ((status & (STATUS_LALT|STATUS_RALT)) &&
43(status & (STATUS_LSHIFT|STATUS_RSHIFT|STATUS_CAPS))) {
44key=current_layout->keyboard_map_shift_alt[scancode];
45}
46else if (status & (STATUS_LSHIFT|STATUS_RSHIFT|STATUS_CAPS))
47key=current_layout->keyboard_map_shift[scancode];
48else if (status & (STATUS_LALT|STATUS_RALT))
49key=current_layout->keyboard_map_alt[scancode];
50else
51key=current_layout->keyboard_map[scancode];
52
53if (key != 0) // do the mapping
54code = key;
55}
56
57if (ASCII_KEY(code) != 0) // if ascii not null return it
58code = ASCII_KEY(code);
59
60//printf("Code: %04x\n",code);
61return (code);
62}
63
64static uint32_t load_keyboard_layout_file(const char *filename)
65{
66int fd;
67char magic[KEYBOARD_LAYOUTS_MAGIC_SIZE];
68uint32_t version;
69
70if ((fd = open_bvdev("bt(0,0)", filename, 0)) < 0)
71{
72goto fail; // fail
73}
74
75if (read(fd, magic, sizeof(magic)) != sizeof(magic))
76{
77printf("Can't find magic in keyboard layout file: %s\n", filename);
78goto fail;
79}
80
81if (memcmp (magic, KEYBOARD_LAYOUTS_MAGIC, KEYBOARD_LAYOUTS_MAGIC_SIZE) != 0)
82{
83printf("Invalid magic code in keyboard layout file: %s\n", filename);
84goto fail;
85}
86
87if (read(fd, (char*) &version, sizeof(version)) != sizeof(version))
88{
89printf("Can't get version of keyboard layout file: %s\n", filename);
90goto fail;
91}
92
93if (version != KEYBOARD_LAYOUTS_VERSION)
94{
95verbose("Bad version for keyboard layout file %s expected v%d found v%d\n",
96filename, KEYBOARD_LAYOUTS_VERSION, version);
97goto fail;
98}
99
100if (current_layout)
101{
102free(current_layout);
103}
104
105current_layout = malloc(sizeof(*current_layout));
106if (!current_layout)
107{
108goto fail;
109}
110
111b_lseek(fd, KEYBOARD_LAYOUTS_MAP_OFFSET, 0);
112
113if (read(fd, (char*) current_layout, sizeof(*current_layout)) != sizeof(*current_layout))
114{
115printf("Wrong keyboard layout file %s size\n", filename);
116goto fail;
117}
118
119close(fd);
120
121return 1;
122
123fail:
124
125if (current_layout)
126{
127free(current_layout);
128current_layout = NULL;
129}
130return 0;
131}
132
133void Keylayout_start()
134{
135char layoutPath[512];
136const char*val;
137intlen;
138
139if (getValueForKey("KeyLayout", &val, &len, &bootInfo->chameleonConfig))
140{
141sprintf(layoutPath, "/Extra/Keymaps/%s", val);
142// Add the extension if needed
143if (len <= 4 || strcmp(val+len-4,".lyt") != 0)
144strncat(layoutPath, ".lyt", sizeof(layoutPath) - strlen(layoutPath) - 1);
145
146if (!load_keyboard_layout_file(layoutPath))
147{
148DBG("Can't load %s keyboard layout file. Keylayout will not be used !\n",
149 layoutPath);
150sleep(2);
151}
152else if (!replace_function("_getchar", &getchar_replacement))
153{
154printf("Can't replace function getchar: Keylayout module can't be used !\n");
155sleep(2);
156}
157}
158}
159

Archive Download this file

Revision: 2582