From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 1 of 3] Fix keymap handling for vnc console
Date: Thu, 08 Jan 2009 14:27:50 -0600 [thread overview]
Message-ID: <496661C6.3010507@codemonkey.ws> (raw)
In-Reply-To: <4947CD50.8040806@oracle.com>
John Haxby wrote:
> Fix keymap handling for international keyboards
>
> Signed-off-by: John Haxby <john.haxby@oracle.com>
>
> curses_keys.h | 2
> keymaps.c | 347
> ++++++++++++++++++++++++++++++++++++----------------------
> sdl_keysym.h | 2
> vnc.c | 87 ++++++++++----
> vnc_keysym.h | 2
> 5 files changed, 286 insertions(+), 154 deletions(-)
>
> diff -up qemu-0.9.1.6042/curses_keys.h.keymap01
> qemu-0.9.1.6042/curses_keys.h
> --- qemu-0.9.1.6042/curses_keys.h.keymap01 2008-10-28
> 00:11:06.000000000 +0000
> +++ qemu-0.9.1.6042/curses_keys.h 2008-12-16 10:47:36.000000000 +0000
> @@ -244,7 +244,7 @@ typedef struct {
> int keysym;
> } name2keysym_t;
>
> -static const name2keysym_t name2keysym[] = {
> +static name2keysym_t name2keysym[] = {
> /* Plain ASCII */
> { "space", 0x020 },
> { "exclam", 0x021 },
> diff -up qemu-0.9.1.6042/keymaps.c.keymap01 qemu-0.9.1.6042/keymaps.c
> --- qemu-0.9.1.6042/keymaps.c.keymap01 2008-10-02
> 19:26:42.000000000 +0100
> +++ qemu-0.9.1.6042/keymaps.c 2008-12-16 10:47:36.000000000 +0000
> @@ -22,58 +22,64 @@
> * THE SOFTWARE.
> */
>
> +static int cmp_keysym(const void *a, const void *b) {
> + return strcmp(((name2keysym_t *) a)->name, ((name2keysym_t *)
> b)->name);
> +}
> +
> +
> static int get_keysym(const char *name)
> {
> - const name2keysym_t *p;
> - for(p = name2keysym; p->name != NULL; p++) {
> - if (!strcmp(p->name, name))
> - return p->keysym;
> + static int n = -1;
> + int l, r, m;
> +
> + if (n < 0) {
> + for (n = 0; name2keysym[n].name; n++);
> + qsort(name2keysym, n, sizeof(name2keysym_t), cmp_keysym);
Doing an in place sort of a literal array is probably not a great
idea. Why does the array need sorting? The indenting is really
screwed up here.
> + }
> + l = 0;
> + r = n-1;
> + while (l <= r) {
> + m = (l + r) / 2;
> + int cmp = strcmp(name2keysym[m].name, name);
Please don't mix variable declarations with code.
> + if (cmp < 0)
> + l = m + 1;
> + else if (cmp > 0)
> + r = m - 1;
> + else
> + return name2keysym[m].keysym;
> + }
This is an open coded binary search? Why not just do a linear search?
Is this really a performance concern?
> + if (name[0] == 'U') {
> + /* unicode symbol key */
> + char *ptr;
> + int k = strtol(name+1, &ptr, 16);
> + return *ptr ? 0 : k;
> }
> - return 0;
> }
>
> -struct key_range {
> - int start;
> - int end;
> - struct key_range *next;
> -};
> +#define MAX_SCANCODE 256
> +#define KEY_LOCALSTATE 0x1
> +#define KEY_KEYPAD 0x2
>
> #define MAX_NORMAL_KEYCODE 512
> #define MAX_EXTRA_COUNT 256
> typedef struct {
> - uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
> - struct {
> - int keysym;
> - uint16_t keycode;
> - } keysym2keycode_extra[MAX_EXTRA_COUNT];
> - int extra_count;
> - struct key_range *keypad_range;
> - struct key_range *numlock_range;
> -} kbd_layout_t;
> + int keysym;
> + int keycode;
> +} keysym2keycode_t;
>
> -static void add_to_key_range(struct key_range **krp, int code) {
> - struct key_range *kr;
> - for (kr = *krp; kr; kr = kr->next) {
> - if (code >= kr->start && code <= kr->end)
> - break;
> - if (code == kr->start - 1) {
> - kr->start--;
> - break;
> - }
> - if (code == kr->end + 1) {
> - kr->end++;
> - break;
> - }
> - }
> - if (kr == NULL) {
> - kr = qemu_mallocz(sizeof(*kr));
> - if (kr) {
> - kr->start = kr->end = code;
> - kr->next = *krp;
> - *krp = kr;
> - }
> - }
> -}
> +typedef struct {
> + int n;
> + keysym2keycode_t k[MAX_SCANCODE];
> +} keysym_map_t;
> +
> +typedef struct {
> + keysym_map_t plain;
> + keysym_map_t shift;
> + keysym_map_t altgr;
> + keysym_map_t shift_altgr;
> + keysym_map_t numlock;
> + uint32_t flags [MAX_SCANCODE];
> +} kbd_layout_t;
>
> static kbd_layout_t *parse_keyboard_layout(const char *language,
> kbd_layout_t * k)
> @@ -81,105 +87,194 @@ static kbd_layout_t *parse_keyboard_layo
> FILE *f;
> char file_name[1024];
> char line[1024];
> - int len;
>
> snprintf(file_name, sizeof(file_name),
> - "%s/keymaps/%s", bios_dir, language);
> + "%s/keymaps/%s", bios_dir, language);
Please don't change existing code formatting.
> if (!k)
> k = qemu_mallocz(sizeof(kbd_layout_t));
> if (!k)
> - return 0;
> + return 0;
Like right here.
> if (!(f = fopen(file_name, "r"))) {
> fprintf(stderr,
> "Could not read keymap file: '%s'\n", file_name);
> return 0;
> }
> - for(;;) {
> - if (fgets(line, 1024, f) == NULL)
> - break;
> - len = strlen(line);
> - if (len > 0 && line[len - 1] == '\n')
> - line[len - 1] = '\0';
> - if (line[0] == '#')
> - continue;
> - if (!strncmp(line, "map ", 4))
> - continue;
> - if (!strncmp(line, "include ", 8)) {
> - parse_keyboard_layout(line + 8, k);
> - } else {
> - char *end_of_keysym = line;
> - while (*end_of_keysym != 0 && *end_of_keysym != ' ')
> - end_of_keysym++;
> - if (*end_of_keysym) {
> - int keysym;
> - *end_of_keysym = 0;
> - keysym = get_keysym(line);
> - if (keysym == 0) {
> - // fprintf(stderr, "Warning: unknown
> keysym %s\n", line);
> - } else {
> - const char *rest = end_of_keysym + 1;
> - char *rest2;
> - int keycode = strtol(rest, &rest2, 0);
> -
> - if (rest && strstr(rest, "numlock")) {
> - add_to_key_range(&k->keypad_range, keycode);
> - add_to_key_range(&k->numlock_range, keysym);
> - //fprintf(stderr, "keypad keysym %04x keycode %d\n",
> keysym, keycode);
> - }
> -
> - /* if(keycode&0x80)
> - keycode=(keycode<<8)^0x80e0; */
> - if (keysym < MAX_NORMAL_KEYCODE) {
> - //fprintf(stderr,"Setting keysym %s (%d) to
> %d\n",line,keysym,keycode);
> - k->keysym2keycode[keysym] = keycode;
> - } else {
> - if (k->extra_count >= MAX_EXTRA_COUNT) {
> - fprintf(stderr,
> - "Warning: Could not assign keysym %s (0x%x)
> because of memory constraints.\n",
> - line, keysym);
> - } else {
> -#if 0
> - fprintf(stderr, "Setting %d: %d,%d\n",
> - k->extra_count, keysym, keycode);
> -#endif
> - k->keysym2keycode_extra[k->extra_count].
> - keysym = keysym;
> - k->keysym2keycode_extra[k->extra_count].
> - keycode = keycode;
> - k->extra_count++;
> - }
> - }
> - }
> - }
> + while (fgets(line, 1024, f)) {
> + char *ptr = strchr(line, '#');
> + char keyname[1024], p1[1024], p2[1024];
> + int keysym, keycode;
> + int shift = 0;
> + int altgr = 0;
> + int addupper = 0;
> + int numlock = 0;
> + int inhibit = 0;
Again, the formatting is off.
> + if (ptr)
> + *ptr-- = '\0';
What happens if the comment character is the first character in the
line You'll under run the buffer.
> + else
> + ptr = &line[strlen(line)-1];
> + while (isspace(*ptr))
> + *ptr-- = '\0';
> + if (!*line)
> + continue;
> + if (strncmp(line, "map ", 4) == 0)
> + continue;
> + if (sscanf(line, "include %s", p1) == 1) {
%s is generally unsafe to use with sscanf unless you use .* too.
Regards,
Anthony Liguori
next prev parent reply other threads:[~2009-01-08 20:28 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-16 15:32 [Qemu-devel] [PATCH 0 of 3] Fix keymap handling for vnc console John Haxby
2008-12-16 15:46 ` [Qemu-devel] [PATCH 1 " John Haxby
2009-01-08 20:27 ` Anthony Liguori [this message]
2009-01-08 20:46 ` John Haxby
2009-01-08 21:06 ` Anthony Liguori
2008-12-16 15:48 ` [Qemu-devel] [PATCH 2 " John Haxby
2008-12-16 15:49 ` [Qemu-devel] [PATCH 3 " John Haxby
2009-01-07 15:12 ` [Qemu-devel] [PATCH 0 " John Haxby
2009-01-08 20:17 ` Anthony Liguori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=496661C6.3010507@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).