Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:olh:xen-buildrequires
grub2
grub.tastaturbelegung.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File grub.tastaturbelegung.patch of Package grub2
From: Olaf Hering <olaf@aepfle.de> Date: Wed, 13 Dec 2017 08:14:44 +0000 Subject: tastaturbelegung --- grub-core/term/efi/console.c | 156 +++++- grub-core/term/i386/pc/console.c | 210 ++++++++- 2 files changed, 352 insertions(+), 14 deletions(-) --- a/grub-core/term/efi/console.c +++ b/grub-core/term/efi/console.c @@ -195,49 +195,201 @@ grub_console_putchar (struct grub_term_output *term, } const unsigned efi_codes[] = { 0, GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_RIGHT, GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_END, GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_F1, GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, GRUB_TERM_KEY_F10, GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12, GRUB_TERM_ESC }; +static const int tastatur_deutsch[] = { + /* Reihe 1, ohne Shift */ + ['`'] = '^', + ['1'] = '1', + ['2'] = '2', + ['3'] = '3', + ['4'] = '4', + ['5'] = '5', + ['6'] = '6', + ['7'] = '7', + ['8'] = '8', + ['9'] = '9', + ['0'] = '0', + ['-'] = 'ß', + ['='] = '´', + + /* Reihe 2, ohne Shift */ + ['q'] = 'q', + ['w'] = 'w', + ['e'] = 'e', + ['r'] = 'r', + ['t'] = 't', + ['y'] = 'z', + ['u'] = 'u', + ['i'] = 'i', + ['o'] = 'o', + ['p'] = 'p', + ['['] = 'ü', + [']'] = '+', + + /* Reihe 3, ohne Shift */ + ['a'] = 'a', + ['s'] = 's', + ['d'] = 'd', + ['f'] = 'f', + ['g'] = 'g', + ['h'] = 'h', + ['j'] = 'j', + ['k'] = 'k', + ['l'] = 'l', + [';'] = 'ö', + ['\''] = 'ä', + ['\\'] = '#', + + /* Reihe 4, ohne Shift */ +/* ['\\'] = '<', */ + ['z'] = 'y', + ['x'] = 'x', + ['c'] = 'c', + ['v'] = 'v', + ['b'] = 'b', + ['n'] = 'n', + ['m'] = 'm', + [','] = ',', + ['.'] = '.', + ['/'] = '-', + + /* Reihe 1, mit Shift */ + ['~'] = '\0', + ['!'] = '!', + ['@'] = '"', + ['#'] = '§', + ['$'] = '$', + ['%'] = '%', + ['^'] = '&', + ['&'] = '/', + ['*'] = '(', + ['('] = ')', + [')'] = '=', + ['_'] = '?', + ['+'] = '`', + + /* Reihe 2, mit Shift */ + ['Q'] = 'Q', + ['W'] = 'W', + ['E'] = 'E', + ['R'] = 'R', + ['T'] = 'T', + ['Y'] = 'Z', + ['U'] = 'U', + ['I'] = 'I', + ['O'] = 'O', + ['P'] = 'P', + ['{'] = 'Ü', + ['}'] = '*', + + + /* Reihe 3, mit Shift */ + ['A'] = 'A', + ['S'] = 'S', + ['D'] = 'D', + ['F'] = 'F', + ['G'] = 'G', + ['H'] = 'H', + ['J'] = 'J', + ['K'] = 'K', + ['L'] = 'L', + [':'] = 'Ö', + ['"'] = 'ä', + ['|'] = '#', + + /* Reihe 4, mit Shift */ +/* ['|'] = '>',*/ + ['Z'] = 'Y', + ['X'] = 'X', + ['C'] = 'C', + ['V'] = 'V', + ['B'] = 'B', + ['N'] = 'N', + ['M'] = 'M', + ['<'] = ';', + ['>'] = ':', + ['?'] = '_', + +}; + +static struct belegung { + const char *hinweis; + const char *name; + const int *map; +} belegung[] = { + { + .hinweis = "Tastaturbelegung ist jetzt", + .name = "deutsch", + .map = tastatur_deutsch, + }, + { + .name = "none", + .map = NULL, + }, +}; +static int *tastatur_belegung; + +static int deutsch(grub_efi_char16_t unicode_char) +{ + int i, ret; + if (!tastatur_belegung) { + for (i = 0; belegung[i].map; i++) + { + if (grub_strcmp("deutsch", belegung[i].name) == 0) + { + grub_printf("%s %s\n", belegung[i].hinweis ? : "", belegung[i].name); + tastatur_belegung = belegung[i].map; + } + } + } + ret = i = unicode_char; + if (tastatur_belegung && tastatur_belegung[i]) + ret = tastatur_belegung[i]; + return ret; +} + static int grub_efi_translate_key (grub_efi_input_key_t key) { if (key.scan_code == 0) { /* Some firmware implementations use VT100-style codes against the spec. This is especially likely if driven by serial. */ if (key.unicode_char < 0x20 && key.unicode_char != 0 && key.unicode_char != '\t' && key.unicode_char != '\b' && key.unicode_char != '\n' && key.unicode_char != '\r') return GRUB_TERM_CTRL | (key.unicode_char - 1 + 'a'); else - return key.unicode_char; + return deutsch(key.unicode_char); } /* Some devices send enter with scan_code 0x0d (F3) and unicode_char 0x0d. */ else if (key.scan_code == '\r' && key.unicode_char == '\r') return key.unicode_char; else if (key.scan_code < ARRAY_SIZE (efi_codes)) return efi_codes[key.scan_code]; if ((key.unicode_char >= 0x20 && key.unicode_char <= 0x7f) || key.unicode_char == '\t' || key.unicode_char == '\b' || key.unicode_char == '\n' || key.unicode_char == '\r') - return key.unicode_char; + return deutsch(key.unicode_char); return GRUB_TERM_NO_KEY; } static int grub_console_getkey_con (struct grub_term_input *term __attribute__ ((unused))) { grub_efi_simple_input_interface_t *i; grub_efi_input_key_t key; grub_efi_status_t status; i = grub_efi_system_table->con_in; --- a/grub-core/term/i386/pc/console.c +++ b/grub-core/term/i386/pc/console.c @@ -11,24 +11,25 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GRUB. If not, see <http://www.gnu.org/licenses/>. */ #include <grub/machine/memory.h> #include <grub/machine/console.h> #include <grub/term.h> #include <grub/types.h> +#include <grub/command.h> #include <grub/machine/int.h> static grub_uint8_t grub_console_cur_color = 0x7; static void int10_9 (grub_uint8_t ch, grub_uint16_t n) { struct grub_bios_int_registers regs; regs.eax = ch | 0x0900; regs.ebx = grub_console_cur_color & 0xff; regs.ecx = n; @@ -114,31 +115,24 @@ grub_console_putchar_real (grub_uint8_t c) /* check the column with the width */ if (pos.x >= 79) { grub_console_putchar_real (0x0d); grub_console_putchar_real (0x0a); } else grub_console_gotoxy (NULL, (struct grub_term_coordinate) { pos.x + 1, pos.y }); } -static void -grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), - const struct grub_unicode_glyph *c) -{ - grub_console_putchar_real (c->base); -} - /* * BIOS call "INT 10H Function 09h" to write character and attribute * Call with %ah = 0x09 * %al = (character) * %bh = (page number) * %bl = (attribute) * %cx = (number of times) */ static void grub_console_cls (struct grub_term_output *term) { /* move the cursor to the beginning */ @@ -191,60 +185,219 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), * If key waiting to be input: * %ah = keyboard scan code * %al = ASCII character * Zero flag = clear * else * Zero flag = set * BIOS call "INT 16H Function 00H" to read character from keyboard * Call with %ah = 0x0 * Return: %ah = keyboard scan code * %al = ASCII character */ +static const int tastatur_deutsch[] = { + /* Reihe 1, ohne Shift */ + ['`'] = '^', + ['1'] = '1', + ['2'] = '2', + ['3'] = '3', + ['4'] = '4', + ['5'] = '5', + ['6'] = '6', + ['7'] = '7', + ['8'] = '8', + ['9'] = '9', + ['0'] = '0', + ['-'] = 'ß', + ['='] = '´', + + /* Reihe 2, ohne Shift */ + ['q'] = 'q', + ['w'] = 'w', + ['e'] = 'e', + ['r'] = 'r', + ['t'] = 't', + ['y'] = 'z', + ['u'] = 'u', + ['i'] = 'i', + ['o'] = 'o', + ['p'] = 'p', + ['['] = 'ü', + [']'] = '+', + + /* Reihe 3, ohne Shift */ + ['a'] = 'a', + ['s'] = 's', + ['d'] = 'd', + ['f'] = 'f', + ['g'] = 'g', + ['h'] = 'h', + ['j'] = 'j', + ['k'] = 'k', + ['l'] = 'l', + [';'] = 'ö', + ['\''] = 'ä', + ['\\'] = '#', + + /* Reihe 4, ohne Shift */ +/* ['\\'] = '<', */ + ['z'] = 'y', + ['x'] = 'x', + ['c'] = 'c', + ['v'] = 'v', + ['b'] = 'b', + ['n'] = 'n', + ['m'] = 'm', + [','] = ',', + ['.'] = '.', + ['/'] = '-', + + /* Reihe 1, mit Shift */ + ['~'] = '\0', + ['!'] = '!', + ['@'] = '"', + ['#'] = '§', + ['$'] = '$', + ['%'] = '%', + ['^'] = '&', + ['&'] = '/', + ['*'] = '(', + ['('] = ')', + [')'] = '=', + ['_'] = '?', + ['+'] = '`', + + /* Reihe 2, mit Shift */ + ['Q'] = 'Q', + ['W'] = 'W', + ['E'] = 'E', + ['R'] = 'R', + ['T'] = 'T', + ['Y'] = 'Z', + ['U'] = 'U', + ['I'] = 'I', + ['O'] = 'O', + ['P'] = 'P', + ['{'] = 'Ü', + ['}'] = '*', + + + /* Reihe 3, mit Shift */ + ['A'] = 'A', + ['S'] = 'S', + ['D'] = 'D', + ['F'] = 'F', + ['G'] = 'G', + ['H'] = 'H', + ['J'] = 'J', + ['K'] = 'K', + ['L'] = 'L', + [':'] = 'Ö', + ['"'] = 'ä', + ['|'] = '#', + + /* Reihe 4, mit Shift */ +/* ['|'] = '>',*/ + ['Z'] = 'Y', + ['X'] = 'X', + ['C'] = 'C', + ['V'] = 'V', + ['B'] = 'B', + ['N'] = 'N', + ['M'] = 'M', + ['<'] = ';', + ['>'] = ':', + ['?'] = '_', + +}; + +static struct belegung { + const char *hinweis; + const char *name; + const int *map; +} belegung[] = { + { + .hinweis = "Tastaturbelegung ist jetzt", + .name = "deutsch", + .map = tastatur_deutsch, + }, + { + .name = "none", + .map = NULL, + }, +}; +static int *tastatur_belegung; static int grub_console_getkey (struct grub_term_input *term __attribute__ ((unused))) { const grub_uint16_t bypass_table[] = { 0x0100 | GRUB_TERM_ESC, 0x0f00 | GRUB_TERM_TAB, 0x0e00 | GRUB_TERM_BACKSPACE, 0x1c00 | '\r', 0x1c00 | '\n' }; struct grub_bios_int_registers regs; unsigned i; + int ret, orig; + static int prev; /* * Due to a bug in apple's bootcamp implementation, INT 16/AH = 0 would * cause the machine to hang at the second keystroke. However, we can * work around this problem by ensuring the presence of keystroke with * INT 16/AH = 1 before calling INT 16/AH = 0. */ regs.eax = 0x0100; regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; grub_bios_interrupt (0x16, ®s); if (regs.flags & GRUB_CPU_INT_FLAGS_ZERO) - return GRUB_TERM_NO_KEY; + { + ret = GRUB_TERM_NO_KEY; + goto out; + } regs.eax = 0x0000; regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; grub_bios_interrupt (0x16, ®s); if (!(regs.eax & 0xff)) - return ((regs.eax >> 8) & 0xff) | GRUB_TERM_EXTENDED; +{ +orig = + ret = ((regs.eax >> 8) & 0xff) | GRUB_TERM_EXTENDED; + goto out; + } if ((regs.eax & 0xff) >= ' ') - return regs.eax & 0xff; +{ +orig = + ret = regs.eax & 0xff; + i = ret; + if (tastatur_belegung && tastatur_belegung[i]) + ret = tastatur_belegung[i]; + goto out; + } for (i = 0; i < ARRAY_SIZE (bypass_table); i++) if (bypass_table[i] == (regs.eax & 0xffff)) - return regs.eax & 0xff; +{ +orig = + ret = regs.eax & 0xff; + goto out; + } - return (regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL); +orig = + ret = (regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL); +out: + if (0 && ret != prev) { + grub_printf("\n %04x %04x > %08x > %04x\n ", regs.eax, regs.flags, orig, ret); + prev = ret; + } + return ret; } static int grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused))) { const struct grub_machine_bios_data_area *bios_data_area = (struct grub_machine_bios_data_area *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR); /* conveniently GRUB keystatus is modelled after BIOS one. */ return bios_data_area->keyboard_flag_lower & ~0x80; } static struct grub_term_coordinate @@ -264,24 +417,55 @@ grub_console_setcolorstate (struct grub_term_output *term break; case GRUB_TERM_COLOR_NORMAL: grub_console_cur_color = grub_term_normal_color & 0x7f; break; case GRUB_TERM_COLOR_HIGHLIGHT: grub_console_cur_color = grub_term_highlight_color & 0x7f; break; default: break; } } +static grub_err_t +grub_cmd_tastatur_belegung (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "layout name required"); + + for (i = 0; belegung[i].map; i++) + { + if (grub_strcmp(argv[0], belegung[i].name) == 0) + { + grub_printf("%s %s\n", belegung[i].hinweis ? : "", belegung[i].name); + tastatur_belegung = belegung[i].map; + return GRUB_ERR_NONE; + } + } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "layout %s not found.", argv[0]); +} + +static grub_command_t cmd; +static void +grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c) +{ + if (!cmd) + cmd = grub_register_command ("tastatur_belegung", grub_cmd_tastatur_belegung, + 0, N_("Set a keyboard layout.")); + grub_console_putchar_real (c->base); +} + static struct grub_term_input grub_console_term_input = { .name = "console", .getkey = grub_console_getkey, .getkeystatus = grub_console_getkeystatus }; static struct grub_term_output grub_console_term_output = { .name = "console", .putchar = grub_console_putchar, .getwh = grub_console_getwh, @@ -295,15 +479,17 @@ static struct grub_term_output grub_console_term_output = }; void grub_console_init (void) { grub_term_register_output ("console", &grub_console_term_output); grub_term_register_input ("console", &grub_console_term_input); } void grub_console_fini (void) { + if (cmd) + grub_unregister_command (cmd); grub_term_unregister_input (&grub_console_term_input); grub_term_unregister_output (&grub_console_term_output); }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor