Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: HEAD