lkml.org 
[lkml]   [2004]   [May]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    SubjectRe: [patch - please comment] Support for UTF dead keys in 2.6
    Date
    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    On Saturday 29 May 2004 16:34, Vojtech Pavlik wrote:
    > Hi!
    >
    > Several languages (polish, czech, slovak, ...) use dead keys (keys that
    > don't do anything per se, but put an accent on the next letter). And now
    > almost everyone is switching to unicode. And Linux kernel doesn't
    > support unicode for dead keys. This means trouble.
    >
    > The patch (ported from original 2.4 version by Radovan Garabik) below
    > fixes the problem. Is anyone opposed to it? If not, I'll merge it into
    > my tree and send to Linus.
    >
    > It needs a patch to loadkeys to do something. It should be 100% binary
    > and source backward compatible.
    >
    > ChangeSet@1.1610, 2004-05-03 12:38:37+02:00, vojtech@suse.cz
    > input: Make accent tables able to generate unicode characters. This
    > is needed for UTF8 console with multi-keystroke characters.
    >
    >
    > drivers/acorn/char/defkeymap-l7200.c | 2 -
    > drivers/char/defkeymap.c_shipped | 2 -
    > drivers/char/keyboard.c | 34 ++++++++++++-----
    > drivers/char/qtronixmap.c_shipped | 2 -
    > drivers/char/vt_ioctl.c | 46 ++++++++++++++++++++++--
    > drivers/s390/char/defkeymap.c | 2 -
    > drivers/s390/char/keyboard.c | 67 ++++++++++++++++++++++++++++-------
    > drivers/s390/char/keyboard.h | 2 -
    > drivers/tc/lk201-map.c_shipped | 2 -
    > include/linux/kbd_diacr.h | 2 -
    > include/linux/kd.h | 14 +++++++
    > 11 files changed, 143 insertions(+), 32 deletions(-)
    >
    >
    > diff -Nru a/drivers/acorn/char/defkeymap-l7200.c b/drivers/acorn/char/defkeymap-l7200.c
    > --- a/drivers/acorn/char/defkeymap-l7200.c Mon May 3 12:39:59 2004
    > +++ b/drivers/acorn/char/defkeymap-l7200.c Mon May 3 12:39:59 2004
    > @@ -346,7 +346,7 @@
    > 0,
    > };
    >
    > -struct kbdiacr accent_table[MAX_DIACR] = {
    > +struct kbdiacruc accent_table[MAX_DIACR] = {
    > {'`', 'A', '\300'}, {'`', 'a', '\340'},
    > {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
    > {'^', 'A', '\302'}, {'^', 'a', '\342'},
    > diff -Nru a/drivers/char/defkeymap.c_shipped b/drivers/char/defkeymap.c_shipped
    > --- a/drivers/char/defkeymap.c_shipped Mon May 3 12:39:59 2004
    > +++ b/drivers/char/defkeymap.c_shipped Mon May 3 12:39:59 2004
    > @@ -222,7 +222,7 @@
    > 0,
    > };
    >
    > -struct kbdiacr accent_table[MAX_DIACR] = {
    > +struct kbdiacruc accent_table[MAX_DIACR] = {
    > {'`', 'A', '\300'}, {'`', 'a', '\340'},
    > {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
    > {'^', 'A', '\302'}, {'^', 'a', '\342'},
    > diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
    > --- a/drivers/char/keyboard.c Mon May 3 12:39:59 2004
    > +++ b/drivers/char/keyboard.c Mon May 3 12:39:59 2004
    > @@ -331,7 +331,7 @@
    > * in utf-8 already. UTF-8 is defined for words of up to 31 bits,
    > * but we need only 16 bits here
    > */
    > -void to_utf8(struct vc_data *vc, ushort c)
    > +void to_utf8(struct vc_data *vc, unsigned int c)
    > {
    > if (c < 0x80)
    > /* 0******* */
    > @@ -387,13 +387,12 @@
    > }
    >
    > /*
    > - * We have a combining character DIACR here, followed by the character CH.
    > - * If the combination occurs in the table, return the corresponding value.
    > - * Otherwise, if CH is a space or equals DIACR, return DIACR.
    > - * Otherwise, conclude that DIACR was not combining after all,
    > - * queue it and return CH.
    > + * We have a combining character DIACR here, followed by the character CH. If
    > + * the combination occurs in the table, return the corresponding UCS2 value.
    > + * Otherwise, if CH is a space or equals DIACR, return DIACR. Otherwise,
    > + * conclude that DIACR was not combining after all, queue it and return CH.
    > */
    > -unsigned char handle_diacr(struct vc_data *vc, unsigned char ch)
    > +unsigned int handle_diacr(struct vc_data *vc, unsigned char ch)
    > {
    > int d = diacr;
    > int i;
    > @@ -616,11 +615,26 @@
    >
    > static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
    > {
    > + unsigned int v;
    > +
    > +
    > if (up_flag)
    > return; /* no action, if this is a key release */
    >
    > - if (diacr)
    > - value = handle_diacr(vc, value);
    > + if (diacr) {
    > + v = handle_diacr(vc, value);
    > +
    > + if (kbd->kbdmode == VC_UNICODE) {
    > + to_utf8(vc, v & 0xFFFF);
    > + return;
    > + }
    > +
    > + /*
    > + * this makes at least latin-1 compose chars work
    > + * even when using unicode keymap in non-unicode mode
    > + */
    > + value = v & 0xFF;
    > + }
    >
    > if (dead_key_next) {
    > dead_key_next = 0;
    > @@ -639,7 +653,7 @@
    > {
    > if (up_flag)
    > return;
    > - diacr = (diacr ? handle_diacr(vc, value) : value);
    > + diacr = (diacr ? handle_diacr(vc, value) & 0xff : value);
    > }
    >
    > /*
    > diff -Nru a/drivers/char/qtronixmap.c_shipped b/drivers/char/qtronixmap.c_shipped
    > --- a/drivers/char/qtronixmap.c_shipped Mon May 3 12:39:59 2004
    > +++ b/drivers/char/qtronixmap.c_shipped Mon May 3 12:39:59 2004
    > @@ -225,7 +225,7 @@
    > 0,
    > };
    >
    > -struct kbdiacr accent_table[MAX_DIACR] = {
    > +struct kbdiacruc accent_table[MAX_DIACR] = {
    > {'`', 'A', '?'}, {'`', 'a', '?'},
    > {'\'', 'A', 'Á'}, {'\'', 'a', 'á'},
    > {'^', 'A', 'Â'}, {'^', 'a', 'â'},
    > diff -Nru a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
    > --- a/drivers/char/vt_ioctl.c Mon May 3 12:39:59 2004
    > +++ b/drivers/char/vt_ioctl.c Mon May 3 12:39:59 2004
    > @@ -584,10 +584,28 @@
    > case KDGKBDIACR:
    > {
    > struct kbdiacrs *a = (struct kbdiacrs *)arg;
    > + struct kbdiacr diacr;
    > + int i;
    >
    > if (put_user(accent_table_size, &a->kb_cnt))
    > return -EFAULT;
    > - if (copy_to_user(a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr)))
    > + for (i = 0; i < accent_table_size; i++) {
    > + diacr.diacr = accent_table[i].diacr;
    > + diacr.base = accent_table[i].base;
    > + diacr.result = accent_table[i].result> 0xff ? 0 : accent_table[i].base;
    > + if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr)))
    > + return -EFAULT;
    > + }
    > + return 0;
    > + }
    > +
    > + case KDGKBDIACRUC:
    > + {
    > + struct kbdiacrsuc *a = (struct kbdiacrsuc *)arg;
    > +
    > + if (put_user(accent_table_size, &a->kb_cnt))
    > + return -EFAULT;
    > + if (copy_to_user(a->kbdiacruc, accent_table, accent_table_size*sizeof(struct kbdiacruc)))
    > return -EFAULT;
    > return 0;
    > }
    > @@ -595,6 +613,30 @@
    > case KDSKBDIACR:
    > {
    > struct kbdiacrs *a = (struct kbdiacrs *)arg;
    > + struct kbdiacr diacr;
    > + unsigned int ct;
    > + int i;
    > +
    > + if (!perm)
    > + return -EPERM;
    > + if (get_user(ct,&a->kb_cnt))
    > + return -EFAULT;
    > + if (ct >= MAX_DIACR)
    > + return -EINVAL;
    > + accent_table_size = ct;
    > + for (i = 0; i < ct; i++) {
    > + if (copy_from_user(&diacr, a->kbdiacr, sizeof(struct kbdiacr)))
    > + return -EFAULT;
    > + accent_table[i].diacr = diacr.diacr;
    > + accent_table[i].base = diacr.base;
    > + accent_table[i].result = diacr.result;
    > + }
    > + return 0;
    > + }
    > +
    > + case KDSKBDIACRUC:
    > + {
    > + struct kbdiacrsuc *a = (struct kbdiacrsuc *)arg;
    > unsigned int ct;
    >
    > if (!perm)
    > @@ -604,7 +646,7 @@
    > if (ct >= MAX_DIACR)
    > return -EINVAL;
    > accent_table_size = ct;
    > - if (copy_from_user(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr)))
    > + if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc)))
    > return -EFAULT;
    > return 0;
    > }
    > diff -Nru a/drivers/s390/char/defkeymap.c b/drivers/s390/char/defkeymap.c
    > --- a/drivers/s390/char/defkeymap.c Mon May 3 12:39:59 2004
    > +++ b/drivers/s390/char/defkeymap.c Mon May 3 12:39:59 2004
    > @@ -148,7 +148,7 @@
    > 0,
    > };
    >
    > -struct kbdiacr accent_table[MAX_DIACR] = {
    > +struct kbdiacruc accent_table[MAX_DIACR] = {
    > {'^', 'c', '\003'}, {'^', 'd', '\004'},
    > {'^', 'z', '\032'}, {'^', '\012', '\000'},
    > };
    > diff -Nru a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
    > --- a/drivers/s390/char/keyboard.c Mon May 3 12:39:59 2004
    > +++ b/drivers/s390/char/keyboard.c Mon May 3 12:39:59 2004
    > @@ -87,11 +87,11 @@
    > goto out_func;
    > memset(kbd->fn_handler, 0, sizeof(fn_handler_fn *) * NR_FN_HANDLER);
    > kbd->accent_table =
    > - kmalloc(sizeof(struct kbdiacr)*MAX_DIACR, GFP_KERNEL);
    > + kmalloc(sizeof(struct kbdiacruc)*MAX_DIACR, GFP_KERNEL);
    > if (!kbd->accent_table)
    > goto out_fn_handler;
    > memcpy(kbd->accent_table, accent_table,
    > - sizeof(struct kbdiacr)*MAX_DIACR);
    > + sizeof(struct kbdiacruc)*MAX_DIACR);
    > kbd->accent_table_size = accent_table_size;
    > return kbd;
    >
    > @@ -464,7 +464,6 @@
    > kbd_ioctl(struct kbd_data *kbd, struct file *file,
    > unsigned int cmd, unsigned long arg)
    > {
    > - struct kbdiacrs *a;
    > int ct, perm;
    >
    > /*
    > @@ -482,28 +481,70 @@
    > case KDSKBSENT:
    > return do_kdgkb_ioctl(kbd, (struct kbsentry *)arg, cmd, perm);
    > case KDGKBDIACR:
    > - a = (struct kbdiacrs *) arg;
    > + {
    > + struct kbdiacrs *a = (struct kbdiacrs *)arg;
    > + struct kbdiacr diacr;
    > + int i;
    >
    > - if (put_user(kbd->accent_table_size, &a->kb_cnt))
    > + if (put_user(accent_table_size, &a->kb_cnt))
    > return -EFAULT;
    > - ct = kbd->accent_table_size;
    > - if (copy_to_user(a->kbdiacr, kbd->accent_table,
    > - ct * sizeof(struct kbdiacr)))
    > + for (i = 0; i < accent_table_size; i++) {
    > + diacr.diacr = accent_table[i].diacr;
    > + diacr.base = accent_table[i].base;
    > + diacr.result = accent_table[i].base > 0xff ? 0 : accent_table[i].base;
    > + if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr)))
    > + return -EFAULT;
    > + }
    > + return 0;
    > + }
    > + case KDGKBDIACRUC:
    > + {
    > + struct kbdiacrsuc *a = (struct kbdiacrsuc *)arg;
    > +
    > + if (put_user(accent_table_size, &a->kb_cnt))
    > + return -EFAULT;
    > + if (copy_to_user(a->kbdiacruc, accent_table, accent_table_size*sizeof(struct kbdiacruc)))
    > return -EFAULT;
    > return 0;
    > + }
    > case KDSKBDIACR:
    > - a = (struct kbdiacrs *) arg;
    > + {
    > + struct kbdiacrs *a = (struct kbdiacrs *)arg;
    > + struct kbdiacr diacr;
    > + int i;
    > +
    > if (!perm)
    > return -EPERM;
    > - if (get_user(ct, &a->kb_cnt))
    > + if (get_user(ct,&a->kb_cnt))
    > return -EFAULT;
    > if (ct >= MAX_DIACR)
    > return -EINVAL;
    > - kbd->accent_table_size = ct;
    > - if (copy_from_user(kbd->accent_table, a->kbdiacr,
    > - ct * sizeof(struct kbdiacr)))
    > + accent_table_size = ct;
    > + for (i = 0; i < ct; i++) {
    > + if (copy_from_user(&diacr, a->kbdiacr, sizeof(struct kbdiacr)))
    > + return -EFAULT;
    > + accent_table[i].diacr = diacr.diacr;
    > + accent_table[i].base = diacr.base;
    > + accent_table[i].result = diacr.result;
    > + }
    > + return 0;
    > + }
    > + case KDSKBDIACRUC:
    > + {
    > + struct kbdiacrsuc *a = (struct kbdiacrsuc *)arg;
    > + unsigned int ct;
    > +
    > + if (!perm)
    > + return -EPERM;
    > + if (get_user(ct,&a->kb_cnt))
    > + return -EFAULT;
    > + if (ct >= MAX_DIACR)
    > + return -EINVAL;
    > + accent_table_size = ct;
    > + if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc)))
    > return -EFAULT;
    > return 0;
    > + }
    > default:
    > return -ENOIOCTLCMD;
    > }
    > diff -Nru a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h
    > --- a/drivers/s390/char/keyboard.h Mon May 3 12:39:59 2004
    > +++ b/drivers/s390/char/keyboard.h Mon May 3 12:39:59 2004
    > @@ -25,7 +25,7 @@
    > unsigned short **key_maps;
    > char **func_table;
    > fn_handler_fn **fn_handler;
    > - struct kbdiacr *accent_table;
    > + struct kbdiacruc *accent_table;
    > unsigned int accent_table_size;
    > unsigned char diacr;
    > unsigned short sysrq;
    > diff -Nru a/drivers/tc/lk201-map.c_shipped b/drivers/tc/lk201-map.c_shipped
    > --- a/drivers/tc/lk201-map.c_shipped Mon May 3 12:39:59 2004
    > +++ b/drivers/tc/lk201-map.c_shipped Mon May 3 12:39:59 2004
    > @@ -225,7 +225,7 @@
    > 0,
    > };
    >
    > -struct kbdiacr accent_table[MAX_DIACR] = {
    > +struct kbdiacruc accent_table[MAX_DIACR] = {
    > {'`', 'A', '?'}, {'`', 'a', '?'},
    > {'\'', 'A', 'Á'}, {'\'', 'a', 'á'},
    > {'^', 'A', 'Â'}, {'^', 'a', 'â'},
    > diff -Nru a/include/linux/kbd_diacr.h b/include/linux/kbd_diacr.h
    > --- a/include/linux/kbd_diacr.h Mon May 3 12:39:59 2004
    > +++ b/include/linux/kbd_diacr.h Mon May 3 12:39:59 2004
    > @@ -2,7 +2,7 @@
    > #define _DIACR_H
    > #include <linux/kd.h>
    >
    > -extern struct kbdiacr accent_table[];
    > +extern struct kbdiacruc accent_table[];
    > extern unsigned int accent_table_size;
    >
    > #endif /* _DIACR_H */
    > diff -Nru a/include/linux/kd.h b/include/linux/kd.h
    > --- a/include/linux/kd.h Mon May 3 12:39:59 2004
    > +++ b/include/linux/kd.h Mon May 3 12:39:59 2004
    > @@ -121,12 +121,26 @@
    > unsigned int kb_cnt; /* number of entries in following array */
    > struct kbdiacr kbdiacr[256]; /* MAX_DIACR from keyboard.h */
    > };
    > +
    > #define KDGKBDIACR 0x4B4A /* read kernel accent table */
    > #define KDSKBDIACR 0x4B4B /* write kernel accent table */
    >
    > +struct kbdiacruc {
    > + unsigned char diacr, base;
    > + unsigned int result; /* UCS */
    > +};
    > +struct kbdiacrsuc {
    > + unsigned int kb_cnt; /* number of entries in following array */
    > + struct kbdiacruc kbdiacruc[256]; /* MAX_DIACR from keyboard.h */
    > +};
    > +
    > +#define KDGKBDIACRUC 0x4BFA /* read kernel accent table - UCS */
    > +#define KDSKBDIACRUC 0x4BFB /* write kernel accent table - UCS */
    > +
    > struct kbkeycode {
    > unsigned int scancode, keycode;
    > };
    > +
    > #define KDGETKEYCODE 0x4B4C /* read kernel keycode table entry */
    > #define KDSETKEYCODE 0x4B4D /* write kernel keycode table entry */
    >
    >



    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.4 (GNU/Linux)

    iD8DBQFAuswqU56oYWuOrkARArshAKCjB3NJwj9qPirGqNP5dznxtJVtqQCffxIC
    YoD8bLnLs/mB0QLO+LFJwVI=
    =dLeI
    -----END PGP SIGNATURE-----
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:03    [W:0.050 / U:32.804 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site