All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.