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