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 | ␊ |
28 | //==========================================================================␊ |
29 | // lseek() - Reposition the byte offset of the file descriptor from the␊ |
30 | // beginning of the file. Returns the relocated offset.␊ |
31 | ␊ |
32 | int key_b_lseek(int fdesc, int offset, int ptr)␊ |
33 | {␊ |
34 | struct iob * io;␊ |
35 | ␉␊ |
36 | if ((io = iob_from_fdesc(fdesc)) == NULL)␊ |
37 | return (-1);␊ |
38 | ␉␊ |
39 | io->i_offset = offset;␊ |
40 | ␉␊ |
41 | return offset;␊ |
42 | }␊ |
43 | ␊ |
44 | struct keyboard_layout *current_layout = NULL;␊ |
45 | int getchar_replacement(void);␊ |
46 | ␊ |
47 | int getchar_replacement(void) {␊ |
48 | ␉int code = bgetc();␊ |
49 | ␉int status = readKeyboardShiftFlags();␊ |
50 | ␉uint8_t scancode = code >> 8;␊ |
51 | ␉␊ |
52 | ␉// Special scancode sent when alt + some keys are pressed␊ |
53 | ␉if (scancode >= 0x78 && scancode <= 0x83)␊ |
54 | ␉␉scancode -= 0x76;␊ |
55 | ␉␊ |
56 | ␉if (scancode < KEYBOARD_MAP_SIZE && !(status & (STATUS_LCTRL| STATUS_RCTRL))) {␊ |
57 | ␉␉int key;␊ |
58 | ␉␉if ((status & (STATUS_LALT|STATUS_RALT)) &&␊ |
59 | ␉␉␉(status & (STATUS_LSHIFT|STATUS_RSHIFT|STATUS_CAPS))) {␊ |
60 | ␉␉␉key=current_layout->keyboard_map_shift_alt[scancode];␊ |
61 | ␉␉}␊ |
62 | ␉␉else if (status & (STATUS_LSHIFT|STATUS_RSHIFT|STATUS_CAPS))␊ |
63 | ␉␉␉key=current_layout->keyboard_map_shift[scancode];␊ |
64 | ␉␉else if (status & (STATUS_LALT|STATUS_RALT))␊ |
65 | ␉␉␉key=current_layout->keyboard_map_alt[scancode];␊ |
66 | ␉␉else␊ |
67 | ␉␉␉key=current_layout->keyboard_map[scancode];␊ |
68 | ␉␉␊ |
69 | ␉␉if (key != 0) // do the mapping␊ |
70 | ␉␉␉code = key;␊ |
71 | ␉}␊ |
72 | ␉␊ |
73 | ␉if (ASCII_KEY(code) != 0) // if ascii not null return it␊ |
74 | ␉␉code = ASCII_KEY(code);␊ |
75 | ␉␊ |
76 | ␉//printf("Code: %04x\n",code);␊ |
77 | ␉return (code);␊ |
78 | }␊ |
79 | ␊ |
80 | static uint32_t load_keyboard_layout_file(const char *filename) {␊ |
81 | ␉int fd;␊ |
82 | ␉char magic[KEYBOARD_LAYOUTS_MAGIC_SIZE];␊ |
83 | ␉uint32_t version;␊ |
84 | ␉␊ |
85 | ␉␊ |
86 | ␉if ((fd = open_bvdev("bt(0,0)", filename)) < 0) {␉␉␊ |
87 | ␉␉goto fail; // fail␊ |
88 | ␉}␊ |
89 | ␉␊ |
90 | ␉if (read(fd, magic, sizeof(magic)) != sizeof(magic)) {␊ |
91 | ␉␉printf("Can't find magic in keyboard layout file: %s\n", filename);␊ |
92 | ␉␉goto fail;␊ |
93 | ␉}␊ |
94 | ␉␊ |
95 | ␉if (memcmp (magic, KEYBOARD_LAYOUTS_MAGIC, KEYBOARD_LAYOUTS_MAGIC_SIZE) != 0) {␊ |
96 | ␉␉printf("Invalid magic code in keyboard layout file: %s\n", filename);␊ |
97 | ␉␉goto fail;␊ |
98 | }␊ |
99 | ␉␊ |
100 | ␉if (read(fd, (char*) &version, sizeof(version)) != sizeof(version)) {␊ |
101 | ␉␉printf("Can't get version of keyboard layout file: %s\n", filename);␊ |
102 | ␉␉goto fail;␊ |
103 | ␉}␊ |
104 | ␉␊ |
105 | ␉if (version != KEYBOARD_LAYOUTS_VERSION) {␊ |
106 | ␉␉verbose("Bad version for keyboard layout file %s expected v%d found v%d\n",␊ |
107 | ␉␉␉␉filename, KEYBOARD_LAYOUTS_VERSION, version);␊ |
108 | ␉␉goto fail;␊ |
109 | ␉}␊ |
110 | ␉␊ |
111 | ␉if (current_layout)␊ |
112 | ␉␉free(current_layout);␊ |
113 | ␉␊ |
114 | ␉current_layout = malloc(sizeof(struct keyboard_layout));␊ |
115 | ␉if (!current_layout)␊ |
116 | ␉␉goto fail;␊ |
117 | ␉bzero(current_layout,sizeof(struct keyboard_layout));␊ |
118 | ␉␊ |
119 | ␉key_b_lseek(fd, KEYBOARD_LAYOUTS_MAP_OFFSET, 0);␊ |
120 | ␉␊ |
121 | ␉if (read(fd, (char*) current_layout, sizeof(struct keyboard_layout)) != sizeof(struct keyboard_layout)) {␊ |
122 | ␉␉printf("Wrong keyboard layout file %s size\n", filename);␊ |
123 | ␉␉goto fail;␊ |
124 | ␉}␊ |
125 | ␉␊ |
126 | ␉close(fd);␊ |
127 | ␉␊ |
128 | ␉return 1;␊ |
129 | ␉␊ |
130 | fail:␊ |
131 | ␊ |
132 | ␉if (current_layout) {␊ |
133 | ␉␉free(current_layout);␊ |
134 | ␉␉current_layout = NULL;␊ |
135 | ␉}␊ |
136 | ␉return 0;␊ |
137 | }␊ |
138 | ␊ |
139 | uint32_t Keylayout_real_start(void)␊ |
140 | {␊ |
141 | ␉char layoutPath[512];␊ |
142 | ␉const char␉*val;␊ |
143 | ␉int␉␉␉len;␊ |
144 | ␉␊ |
145 | ␉if (getValueForKey("KeyLayout", &val, &len, DEFAULT_BOOT_CONFIG))␊ |
146 | ␉{␊ |
147 | ␉␉snprintf(layoutPath, sizeof(layoutPath),"/Extra/Keymaps/%s", val);␊ |
148 | ␉␉// Add the extension if needed␊ |
149 | ␉␉if (len <= 4 || strncmp(val+len-4,".lyt", sizeof(".lyt")) != 0)␊ |
150 | ␉␉␉strlcat(layoutPath, ".lyt", sizeof(layoutPath));␊ |
151 | ␉␉␊ |
152 | ␉␉if (!load_keyboard_layout_file(layoutPath))␊ |
153 | ␉␉{␊ |
154 | ␉␉␉DBG("Can't load %s keyboard layout file. Keylayout will not be used !\n",␊ |
155 | ␉␉␉␉layoutPath);␊ |
156 | ␉␉␉return 0;␊ |
157 | ␉␉} ␊ |
158 | ␉␉␊ |
159 | ␉␉␊ |
160 | ␉␉if (replace_system_function("_getc", &getchar_replacement) != EFI_SUCCESS ) ␊ |
161 | ␉␉{␊ |
162 | ␉␉␉printf("no function getc() to replace. Keylayout will not be used ! \n");␊ |
163 | ␉␉␉return 0;␊ |
164 | ␉␉}␊ |
165 | ␉␉␊ |
166 | ␉␉return 1;␊ |
167 | ␉␉␊ |
168 | ␉}␊ |
169 | ␉return 0;␊ |
170 | }␊ |
171 | ␊ |
172 | void Keylayout_start(void);␊ |
173 | void Keylayout_start(void)␊ |
174 | {␊ |
175 | ␉Keylayout_real_start();␊ |
176 | } |