qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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

  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).