~darkmuggle-deactivatedaccount/ubuntu/quantal/grub2/fix-872244

« back to all changes in this revision

Viewing changes to util/grub-mklayout.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  GRUB  --  GRand Unified Bootloader
 
3
 *  Copyright (C) 2010 Free Software Foundation, Inc.
 
4
 *
 
5
 *  GRUB is free software: you can redistribute it and/or modify
 
6
 *  it under the terms of the GNU General Public License as published by
 
7
 *  the Free Software Foundation, either version 3 of the License, or
 
8
 *  (at your option) any later version.
 
9
 *
 
10
 *  GRUB is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 
17
 */
 
18
 
 
19
#include <config.h>
 
20
 
 
21
#include <grub/util/misc.h>
 
22
#include <grub/i18n.h>
 
23
#include <grub/term.h>
 
24
#include <grub/keyboard_layouts.h>
 
25
 
 
26
#include <stdio.h>
 
27
#include <stdlib.h>
 
28
#include <string.h>
 
29
#include <getopt.h>
 
30
#include <unistd.h>
 
31
#include <errno.h>
 
32
 
 
33
#include "progname.h"
 
34
 
 
35
#define CKBCOMP "ckbcomp"
 
36
 
 
37
static struct option options[] = {
 
38
  {"output", required_argument, 0, 'o'},
 
39
  {"help", no_argument, 0, 'h'},
 
40
  {"version", no_argument, 0, 'V'},
 
41
  {"verbose", no_argument, 0, 'v'},
 
42
  {0, 0, 0, 0}
 
43
};
 
44
 
 
45
struct console_grub_equivalence
 
46
{
 
47
  char *layout;
 
48
  grub_uint32_t grub;
 
49
};
 
50
 
 
51
static struct console_grub_equivalence console_grub_equivalences_shift[] = {
 
52
  {"KP_0", '0'},
 
53
  {"KP_1", '1'},
 
54
  {"KP_2", '2'},
 
55
  {"KP_3", '3'},
 
56
  {"KP_4", '4'},
 
57
  {"KP_5", '5'},
 
58
  {"KP_6", '6'},
 
59
  {"KP_7", '7'},
 
60
  {"KP_8", '8'},
 
61
  {"KP_9", '9'},
 
62
  {"KP_Period", '.'},
 
63
};
 
64
 
 
65
static struct console_grub_equivalence console_grub_equivalences_unshift[] = {
 
66
  {"KP_0", GRUB_TERM_KEY_INSERT},
 
67
  {"KP_1", GRUB_TERM_KEY_END},
 
68
  {"KP_2", GRUB_TERM_KEY_DOWN},
 
69
  {"KP_3", GRUB_TERM_KEY_NPAGE},
 
70
  {"KP_4", GRUB_TERM_KEY_LEFT},
 
71
  {"KP_5", GRUB_TERM_KEY_CENTER},
 
72
  {"KP_6", GRUB_TERM_KEY_RIGHT},
 
73
  {"KP_7", GRUB_TERM_KEY_HOME},
 
74
  {"KP_8", GRUB_TERM_KEY_UP},
 
75
  {"KP_9", GRUB_TERM_KEY_PPAGE},
 
76
  {"KP_Period", GRUB_TERM_KEY_DC},
 
77
};
 
78
 
 
79
static struct console_grub_equivalence console_grub_equivalences_common[] = {
 
80
  {"Escape", GRUB_TERM_ESC},
 
81
  {"Tab", GRUB_TERM_TAB},
 
82
  {"Delete", GRUB_TERM_BACKSPACE},
 
83
 
 
84
  {"KP_Enter", '\n'},
 
85
  {"Return", '\n'},
 
86
 
 
87
  {"KP_Multiply", '*'},
 
88
  {"KP_Subtract", '-'},
 
89
  {"KP_Add", '+'},
 
90
  {"KP_Divide", '/'},
 
91
 
 
92
  {"F1", GRUB_TERM_KEY_F1},
 
93
  {"F2", GRUB_TERM_KEY_F2},
 
94
  {"F3", GRUB_TERM_KEY_F3},
 
95
  {"F4", GRUB_TERM_KEY_F4},
 
96
  {"F5", GRUB_TERM_KEY_F5},
 
97
  {"F6", GRUB_TERM_KEY_F6},
 
98
  {"F7", GRUB_TERM_KEY_F7},
 
99
  {"F8", GRUB_TERM_KEY_F8},
 
100
  {"F9", GRUB_TERM_KEY_F9},
 
101
  {"F10", GRUB_TERM_KEY_F10},
 
102
  {"F11", GRUB_TERM_KEY_F11},
 
103
  {"F12", GRUB_TERM_KEY_F12},
 
104
  {"F13", GRUB_TERM_KEY_F1 | GRUB_TERM_SHIFT},
 
105
  {"F14", GRUB_TERM_KEY_F2 | GRUB_TERM_SHIFT},
 
106
  {"F15", GRUB_TERM_KEY_F3 | GRUB_TERM_SHIFT},
 
107
  {"F16", GRUB_TERM_KEY_F4 | GRUB_TERM_SHIFT},
 
108
  {"F17", GRUB_TERM_KEY_F5 | GRUB_TERM_SHIFT},
 
109
  {"F18", GRUB_TERM_KEY_F6 | GRUB_TERM_SHIFT},
 
110
  {"F19", GRUB_TERM_KEY_F7 | GRUB_TERM_SHIFT},
 
111
  {"F20", GRUB_TERM_KEY_F8 | GRUB_TERM_SHIFT},
 
112
  {"F21", GRUB_TERM_KEY_F9 | GRUB_TERM_SHIFT},
 
113
  {"F22", GRUB_TERM_KEY_F10 | GRUB_TERM_SHIFT},
 
114
  {"F23", GRUB_TERM_KEY_F11 | GRUB_TERM_SHIFT},
 
115
  {"F24", GRUB_TERM_KEY_F12 | GRUB_TERM_SHIFT},
 
116
  {"Console_13", GRUB_TERM_KEY_F1 | GRUB_TERM_ALT},
 
117
  {"Console_14", GRUB_TERM_KEY_F2 | GRUB_TERM_ALT},
 
118
  {"Console_15", GRUB_TERM_KEY_F3 | GRUB_TERM_ALT},
 
119
  {"Console_16", GRUB_TERM_KEY_F4 | GRUB_TERM_ALT},
 
120
  {"Console_17", GRUB_TERM_KEY_F5 | GRUB_TERM_ALT},
 
121
  {"Console_18", GRUB_TERM_KEY_F6 | GRUB_TERM_ALT},
 
122
  {"Console_19", GRUB_TERM_KEY_F7 | GRUB_TERM_ALT},
 
123
  {"Console_20", GRUB_TERM_KEY_F8 | GRUB_TERM_ALT},
 
124
  {"Console_21", GRUB_TERM_KEY_F9 | GRUB_TERM_ALT},
 
125
  {"Console_22", GRUB_TERM_KEY_F10 | GRUB_TERM_ALT},
 
126
  {"Console_23", GRUB_TERM_KEY_F11 | GRUB_TERM_ALT},
 
127
  {"Console_24", GRUB_TERM_KEY_F12 | GRUB_TERM_ALT},
 
128
  {"Console_25", GRUB_TERM_KEY_F1 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
129
  {"Console_26", GRUB_TERM_KEY_F2 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
130
  {"Console_27", GRUB_TERM_KEY_F3 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
131
  {"Console_28", GRUB_TERM_KEY_F4 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
132
  {"Console_29", GRUB_TERM_KEY_F5 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
133
  {"Console_30", GRUB_TERM_KEY_F6 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
134
  {"Console_31", GRUB_TERM_KEY_F7 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
135
  {"Console_32", GRUB_TERM_KEY_F8 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
136
  {"Console_33", GRUB_TERM_KEY_F9 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
137
  {"Console_34", GRUB_TERM_KEY_F10 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
138
  {"Console_35", GRUB_TERM_KEY_F11 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
139
  {"Console_36", GRUB_TERM_KEY_F12 | GRUB_TERM_SHIFT | GRUB_TERM_ALT},
 
140
 
 
141
  {"Insert", GRUB_TERM_KEY_INSERT},
 
142
  {"Down", GRUB_TERM_KEY_DOWN},
 
143
  {"Up", GRUB_TERM_KEY_UP},
 
144
  {"Home", GRUB_TERM_KEY_HOME},
 
145
  {"End", GRUB_TERM_KEY_END},
 
146
  {"Right", GRUB_TERM_KEY_RIGHT},
 
147
  {"Left", GRUB_TERM_KEY_LEFT},
 
148
  {"Next", GRUB_TERM_KEY_NPAGE},
 
149
  {"Prior", GRUB_TERM_KEY_PPAGE},
 
150
  {"Remove", GRUB_TERM_KEY_DC},
 
151
  {"VoidSymbol", 0},
 
152
 
 
153
  /* "Undead" keys since no dead key support in GRUB.  */
 
154
  {"dead_acute", '\''},
 
155
  {"dead_circumflex", '^'},
 
156
  {"dead_grave", '`'},
 
157
  {"dead_tilde", '~'},
 
158
  {"dead_diaeresis", '"'},
 
159
  
 
160
  /* Following ones don't provide any useful symbols for shell.  */
 
161
  {"dead_cedilla", 0},
 
162
  {"dead_ogonek", 0},
 
163
  {"dead_caron", 0},
 
164
  {"dead_breve", 0},
 
165
  {"dead_doubleacute", 0},
 
166
 
 
167
  /* Unused in GRUB.  */
 
168
  {"Pause", 0},
 
169
  {"Scroll_Forward", 0},
 
170
  {"Scroll_Backward", 0},
 
171
  {"Hex_0", 0},
 
172
  {"Hex_1", 0},
 
173
  {"Hex_2", 0},
 
174
  {"Hex_3", 0},
 
175
  {"Hex_4", 0},
 
176
  {"Hex_5", 0},
 
177
  {"Hex_6", 0},
 
178
  {"Hex_7", 0},
 
179
  {"Hex_8", 0},
 
180
  {"Hex_9", 0},
 
181
  {"Hex_A", 0},
 
182
  {"Hex_B", 0},
 
183
  {"Hex_C", 0},
 
184
  {"Hex_D", 0},
 
185
  {"Hex_E", 0},
 
186
  {"Hex_F", 0},
 
187
  {"Scroll_Lock", 0},
 
188
  {"Show_Memory", 0},
 
189
  {"Show_Registers", 0},
 
190
  {"Control_backslash", 0},
 
191
  {"Compose", 0},
 
192
 
 
193
  {NULL, '\0'}
 
194
};
 
195
 
 
196
static grub_uint8_t linux_to_usb_map[128] = {
 
197
  /* 0x00 */ 0 /* Unused  */,               GRUB_KEYBOARD_KEY_ESCAPE, 
 
198
  /* 0x02 */ GRUB_KEYBOARD_KEY_1,           GRUB_KEYBOARD_KEY_2, 
 
199
  /* 0x04 */ GRUB_KEYBOARD_KEY_3,           GRUB_KEYBOARD_KEY_4, 
 
200
  /* 0x06 */ GRUB_KEYBOARD_KEY_5,           GRUB_KEYBOARD_KEY_6, 
 
201
  /* 0x08 */ GRUB_KEYBOARD_KEY_7,           GRUB_KEYBOARD_KEY_8, 
 
202
  /* 0x0a */ GRUB_KEYBOARD_KEY_9,           GRUB_KEYBOARD_KEY_0, 
 
203
  /* 0x0c */ GRUB_KEYBOARD_KEY_DASH,        GRUB_KEYBOARD_KEY_EQUAL, 
 
204
  /* 0x0e */ GRUB_KEYBOARD_KEY_BACKSPACE,   GRUB_KEYBOARD_KEY_TAB, 
 
205
  /* 0x10 */ GRUB_KEYBOARD_KEY_Q,           GRUB_KEYBOARD_KEY_W, 
 
206
  /* 0x12 */ GRUB_KEYBOARD_KEY_E,           GRUB_KEYBOARD_KEY_R, 
 
207
  /* 0x14 */ GRUB_KEYBOARD_KEY_T,           GRUB_KEYBOARD_KEY_Y, 
 
208
  /* 0x16 */ GRUB_KEYBOARD_KEY_U,           GRUB_KEYBOARD_KEY_I, 
 
209
  /* 0x18 */ GRUB_KEYBOARD_KEY_O,           GRUB_KEYBOARD_KEY_P, 
 
210
  /* 0x1a */ GRUB_KEYBOARD_KEY_LBRACKET,    GRUB_KEYBOARD_KEY_RBRACKET, 
 
211
  /* 0x1c */ GRUB_KEYBOARD_KEY_ENTER,       GRUB_KEYBOARD_KEY_LEFT_CTRL, 
 
212
  /* 0x1e */ GRUB_KEYBOARD_KEY_A,           GRUB_KEYBOARD_KEY_S, 
 
213
  /* 0x20 */ GRUB_KEYBOARD_KEY_D,           GRUB_KEYBOARD_KEY_F, 
 
214
  /* 0x22 */ GRUB_KEYBOARD_KEY_G,           GRUB_KEYBOARD_KEY_H, 
 
215
  /* 0x24 */ GRUB_KEYBOARD_KEY_J,           GRUB_KEYBOARD_KEY_K, 
 
216
  /* 0x26 */ GRUB_KEYBOARD_KEY_L,           GRUB_KEYBOARD_KEY_SEMICOLON, 
 
217
  /* 0x28 */ GRUB_KEYBOARD_KEY_DQUOTE,      GRUB_KEYBOARD_KEY_RQUOTE, 
 
218
  /* 0x2a */ GRUB_KEYBOARD_KEY_LEFT_SHIFT,  GRUB_KEYBOARD_KEY_BACKSLASH, 
 
219
  /* 0x2c */ GRUB_KEYBOARD_KEY_Z,           GRUB_KEYBOARD_KEY_X, 
 
220
  /* 0x2e */ GRUB_KEYBOARD_KEY_C,           GRUB_KEYBOARD_KEY_V, 
 
221
  /* 0x30 */ GRUB_KEYBOARD_KEY_B,           GRUB_KEYBOARD_KEY_N, 
 
222
  /* 0x32 */ GRUB_KEYBOARD_KEY_M,           GRUB_KEYBOARD_KEY_COMMA, 
 
223
  /* 0x34 */ GRUB_KEYBOARD_KEY_DOT,         GRUB_KEYBOARD_KEY_SLASH, 
 
224
  /* 0x36 */ GRUB_KEYBOARD_KEY_RIGHT_SHIFT, GRUB_KEYBOARD_KEY_NUMMUL, 
 
225
  /* 0x38 */ GRUB_KEYBOARD_KEY_LEFT_ALT,    GRUB_KEYBOARD_KEY_SPACE, 
 
226
  /* 0x3a */ GRUB_KEYBOARD_KEY_CAPS_LOCK,   GRUB_KEYBOARD_KEY_F1, 
 
227
  /* 0x3c */ GRUB_KEYBOARD_KEY_F2,          GRUB_KEYBOARD_KEY_F3, 
 
228
  /* 0x3e */ GRUB_KEYBOARD_KEY_F4,          GRUB_KEYBOARD_KEY_F5, 
 
229
  /* 0x40 */ GRUB_KEYBOARD_KEY_F6,          GRUB_KEYBOARD_KEY_F7, 
 
230
  /* 0x42 */ GRUB_KEYBOARD_KEY_F8,          GRUB_KEYBOARD_KEY_F9, 
 
231
  /* 0x44 */ GRUB_KEYBOARD_KEY_F10,         GRUB_KEYBOARD_KEY_NUM_LOCK, 
 
232
  /* 0x46 */ GRUB_KEYBOARD_KEY_SCROLL_LOCK, GRUB_KEYBOARD_KEY_NUM7, 
 
233
  /* 0x48 */ GRUB_KEYBOARD_KEY_NUM8,        GRUB_KEYBOARD_KEY_NUM9, 
 
234
  /* 0x4a */ GRUB_KEYBOARD_KEY_NUMMINUS,    GRUB_KEYBOARD_KEY_NUM4, 
 
235
  /* 0x4c */ GRUB_KEYBOARD_KEY_NUM5,        GRUB_KEYBOARD_KEY_NUM6, 
 
236
  /* 0x4e */ GRUB_KEYBOARD_KEY_NUMPLUS,     GRUB_KEYBOARD_KEY_NUM1, 
 
237
  /* 0x50 */ GRUB_KEYBOARD_KEY_NUM2,        GRUB_KEYBOARD_KEY_NUM3, 
 
238
  /* 0x52 */ GRUB_KEYBOARD_KEY_NUMDOT,      GRUB_KEYBOARD_KEY_NUMDOT, 
 
239
  /* 0x54 */ 0,                             0, 
 
240
  /* 0x56 */ GRUB_KEYBOARD_KEY_102ND,       GRUB_KEYBOARD_KEY_F11, 
 
241
  /* 0x58 */ GRUB_KEYBOARD_KEY_F12,         0,
 
242
  /* 0x5a */ 0,                             0,
 
243
  /* 0x5c */ 0,                             0,
 
244
  /* 0x5e */ 0,                             0,
 
245
  /* 0x60 */ GRUB_KEYBOARD_KEY_NUMENTER,    GRUB_KEYBOARD_KEY_RIGHT_CTRL,
 
246
  /* 0x62 */ GRUB_KEYBOARD_KEY_NUMSLASH,    0,
 
247
  /* 0x64 */ GRUB_KEYBOARD_KEY_RIGHT_ALT,   0,
 
248
  /* 0x66 */ GRUB_KEYBOARD_KEY_HOME,        GRUB_KEYBOARD_KEY_UP,
 
249
  /* 0x68 */ GRUB_KEYBOARD_KEY_PPAGE,       GRUB_KEYBOARD_KEY_LEFT,
 
250
  /* 0x6a */ GRUB_KEYBOARD_KEY_RIGHT,       GRUB_KEYBOARD_KEY_END,
 
251
  /* 0x6c */ GRUB_KEYBOARD_KEY_DOWN,        GRUB_KEYBOARD_KEY_NPAGE, 
 
252
  /* 0x6e */ GRUB_KEYBOARD_KEY_INSERT,      GRUB_KEYBOARD_KEY_DELETE
 
253
}; 
 
254
 
 
255
static void
 
256
usage (int status)
 
257
{
 
258
  if (status)
 
259
    fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
 
260
  else
 
261
    printf ("\
 
262
Usage: %s [OPTIONS] LAYOUT\n\
 
263
  -o, --output          set output base name file. Default is LAYOUT.gkb\n\
 
264
  -h, --help            display this message and exit.\n\
 
265
  -V, --version         print version information and exit.\n\
 
266
  -v, --verbose         print verbose messages.\n\
 
267
\n\
 
268
Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT);
 
269
 
 
270
  exit (status);
 
271
}
 
272
 
 
273
static void
 
274
add_special_keys (struct grub_keyboard_layout *layout)
 
275
{
 
276
  (void) layout;
 
277
}
 
278
 
 
279
static unsigned
 
280
lookup (char *code, int shift)
 
281
{
 
282
  int i;
 
283
  struct console_grub_equivalence *pr;
 
284
 
 
285
  if (shift)
 
286
    pr = console_grub_equivalences_shift;
 
287
  else
 
288
    pr =  console_grub_equivalences_unshift;
 
289
 
 
290
  for (i = 0; pr[i].layout != NULL; i++)
 
291
    if (strcmp (code, pr[i].layout) == 0)
 
292
      return pr[i].grub;
 
293
 
 
294
  for (i = 0; console_grub_equivalences_common[i].layout != NULL; i++)
 
295
    if (strcmp (code, console_grub_equivalences_common[i].layout) == 0)
 
296
      return console_grub_equivalences_common[i].grub;
 
297
 
 
298
  fprintf (stderr, "Unknown key %s\n", code);
 
299
 
 
300
  return '\0';
 
301
}
 
302
 
 
303
static unsigned int
 
304
get_grub_code (char *layout_code, int shift)
 
305
{
 
306
  unsigned int code;
 
307
 
 
308
  if (strncmp (layout_code, "U+", sizeof ("U+") - 1) == 0)
 
309
    sscanf (layout_code, "U+%x", &code);
 
310
  else if (strncmp (layout_code, "+U+", sizeof ("+U+") - 1) == 0)
 
311
    sscanf (layout_code, "+U+%x", &code);
 
312
  else
 
313
    code = lookup (layout_code, shift);
 
314
  return code;
 
315
}
 
316
 
 
317
static void
 
318
write_file (FILE *out, struct grub_keyboard_layout *layout)
 
319
{
 
320
  grub_uint32_t version;
 
321
  unsigned i;
 
322
 
 
323
  version = grub_cpu_to_le32 (GRUB_KEYBOARD_LAYOUTS_VERSION);
 
324
  
 
325
  for (i = 0; i < ARRAY_SIZE (layout->keyboard_map); i++)
 
326
    layout->keyboard_map[i] = grub_cpu_to_le32(layout->keyboard_map[i]);
 
327
 
 
328
  for (i = 0; i < ARRAY_SIZE (layout->keyboard_map_shift); i++)
 
329
    layout->keyboard_map_shift[i]
 
330
      = grub_cpu_to_le32(layout->keyboard_map_shift[i]);
 
331
 
 
332
  for (i = 0; i < ARRAY_SIZE (layout->keyboard_map_l3); i++)
 
333
    layout->keyboard_map_l3[i]
 
334
      = grub_cpu_to_le32(layout->keyboard_map_l3[i]);
 
335
 
 
336
  for (i = 0; i < ARRAY_SIZE (layout->keyboard_map_shift_l3); i++)
 
337
    layout->keyboard_map_shift_l3[i]
 
338
      = grub_cpu_to_le32(layout->keyboard_map_shift_l3[i]);
 
339
 
 
340
  fwrite (GRUB_KEYBOARD_LAYOUTS_FILEMAGIC, 1,
 
341
          GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE, out);
 
342
  fwrite (&version, sizeof (version), 1, out);
 
343
  fwrite (layout, 1, sizeof (*layout), out);
 
344
}
 
345
 
 
346
static void
 
347
write_keymaps (FILE *in, FILE *out)
 
348
{
 
349
  struct grub_keyboard_layout layout;
 
350
  char line[2048];
 
351
  int ok;
 
352
 
 
353
  memset (&layout, 0, sizeof (layout));
 
354
 
 
355
  /* Process the ckbcomp output and prepare the layouts.  */
 
356
  ok = 0;
 
357
  while (fgets (line, sizeof (line), in))
 
358
    {
 
359
      if (strncmp (line, "keycode", sizeof ("keycode") - 1) == 0)
 
360
        {
 
361
          unsigned keycode_linux;
 
362
          unsigned keycode_usb;
 
363
          char normal[64];
 
364
          char shift[64];
 
365
          char normalalt[64];
 
366
          char shiftalt[64];
 
367
 
 
368
          sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode_linux,
 
369
                  normal, shift, normalalt, shiftalt);
 
370
 
 
371
          /* Not used.  */
 
372
          if (keycode_linux == 0x77 /* Pause */
 
373
              /* Some obscure keys */
 
374
              || keycode_linux == 0x63 || keycode_linux == 0x7d
 
375
              || keycode_linux == 0x7e)
 
376
            continue;
 
377
 
 
378
          /* Not remappable.  */
 
379
          if (keycode_linux == 0x1d /* Left CTRL */
 
380
              || keycode_linux == 0x61 /* Right CTRL */
 
381
              || keycode_linux == 0x2a /* Left Shift. */
 
382
              || keycode_linux == 0x36 /* Right Shift. */
 
383
              || keycode_linux == 0x38 /* Left ALT. */
 
384
              || keycode_linux == 0x64 /* Right ALT. */
 
385
              || keycode_linux == 0x3a /* CapsLock. */
 
386
              || keycode_linux == 0x45 /* NumLock. */
 
387
              || keycode_linux == 0x46 /* ScrollLock. */)
 
388
            continue;
 
389
 
 
390
          keycode_usb = linux_to_usb_map[keycode_linux];
 
391
          if (keycode_usb == 0
 
392
              || keycode_usb >= GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE)
 
393
            {
 
394
              fprintf (stderr, "Unknown keycode 0x%02x\n", keycode_linux);
 
395
              continue;
 
396
            }
 
397
          if (keycode_usb < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE)
 
398
            {
 
399
              layout.keyboard_map[keycode_usb] = get_grub_code (normal, 0);
 
400
              layout.keyboard_map_shift[keycode_usb] = get_grub_code (shift, 1);
 
401
              layout.keyboard_map_l3[keycode_usb]
 
402
                = get_grub_code (normalalt, 0);
 
403
              layout.keyboard_map_shift_l3[keycode_usb]
 
404
                = get_grub_code (shiftalt, 1);
 
405
              ok = 1;
 
406
            }
 
407
        }
 
408
    }
 
409
 
 
410
  if (ok == 0)
 
411
    {
 
412
      fprintf (stderr, "ERROR: no keycodes found. Check output of %s.\n",
 
413
               CKBCOMP);
 
414
      exit (1);
 
415
    }
 
416
 
 
417
  add_special_keys (&layout);
 
418
 
 
419
  write_file (out, &layout);
 
420
}
 
421
 
 
422
int
 
423
main (int argc, char *argv[])
 
424
{
 
425
  int verbosity;
 
426
  char *infile_name = NULL;
 
427
  char *outfile_name = NULL;
 
428
  FILE *in, *out;
 
429
 
 
430
  set_program_name (argv[0]);
 
431
 
 
432
  verbosity = 0;
 
433
 
 
434
  /* Check for options.  */
 
435
  while (1)
 
436
    {
 
437
      int c = getopt_long (argc, argv, "o:i:hVv", options, 0);
 
438
 
 
439
      if (c == -1)
 
440
        break;
 
441
      else
 
442
        switch (c)
 
443
          {
 
444
          case 'h':
 
445
            usage (0);
 
446
            break;
 
447
 
 
448
          case 'i':
 
449
            infile_name = optarg;
 
450
            break;
 
451
 
 
452
          case 'o':
 
453
            outfile_name = optarg;
 
454
            break;
 
455
 
 
456
          case 'V':
 
457
            printf ("%s (%s) %s\n", program_name, PACKAGE_NAME,
 
458
                    PACKAGE_VERSION);
 
459
            return 0;
 
460
 
 
461
          case 'v':
 
462
            verbosity++;
 
463
            break;
 
464
 
 
465
          default:
 
466
            usage (1);
 
467
            break;
 
468
          }
 
469
    }
 
470
 
 
471
  if (infile_name)
 
472
    in = fopen (infile_name, "r");
 
473
  else
 
474
    in = stdin;
 
475
 
 
476
  if (!in)
 
477
    grub_util_error ("Couldn't open input file: %s\n", strerror (errno));
 
478
 
 
479
  if (outfile_name)
 
480
    out = fopen (outfile_name, "wb");
 
481
  else
 
482
    out = stdout;
 
483
 
 
484
  if (!out)
 
485
    {
 
486
      if (in != stdin)
 
487
        fclose (in);
 
488
      grub_util_error ("Couldn't open output file: %s\n", strerror (errno));
 
489
    }
 
490
 
 
491
  write_keymaps (in, out);
 
492
 
 
493
  if (in != stdin)
 
494
    fclose (in);
 
495
 
 
496
  if (out != stdout)
 
497
    fclose (out);
 
498
 
 
499
  return 0;
 
500
}