From: James S. <jsi...@ac...> - 2000-03-08 16:48:23
|
Here is a old unicode support patch I have. "Look its a text editor, not its a OS, no it Emacs" James Simmons ____/| fbdev/gfx developer \ o.O| http://www.linux-fbdev.org =(_)= http://linuxgfx.sourceforge.net U This fixes the input side of the Unicode console: mouse selection and keyboard mappings. diff -u -r v2.2.0-pre9/linux/drivers/char/console.c linux/drivers/char/console. c --- v2.2.0-pre9/linux/drivers/char/console.c Fri Jan 22 20:44:08 1999 +++ linux/drivers/char/console.c Fri Jan 22 23:51:37 1999 @@ -1027,7 +1027,7 @@ * control chars if defined, don't set * bit 8 on output. */ - translate = set_translate(charset == 0 + set_translate(vc_cons[currcons].d, charset == 0 ? G0_charset - : G1_charset,currcons); + : G1_charset); disp_ctrl = 0; @@ -1037,7 +1037,7 @@ * Select first alternate font, lets * chars < 32 be displayed as ROM chars. */ - translate = set_translate(IBMPC_MAP,currcons); + set_translate(vc_cons[currcons].d, IBMPC_MAP); disp_ctrl = 1; toggle_meta = 0; break; @@ -1045,7 +1045,7 @@ * Select second alternate font, toggle * high bit before displaying as ROM char. */ - translate = set_translate(IBMPC_MAP,currcons); + set_translate(vc_cons[currcons].d, IBMPC_MAP); disp_ctrl = 1; toggle_meta = 1; break; @@ -1330,7 +1330,7 @@ color = s_color; G0_charset = saved_G0; G1_charset = saved_G1; - translate = set_translate(charset ? G1_charset : G0_charset,currc ons); + set_translate(vc_cons[currcons].d, charset ? G1_charset : G0_charset); update_attr(currcons); need_wrap = 0; } @@ -1345,7 +1345,7 @@ bottom = video_num_lines; vc_state = ESnormal; ques = 0; - translate = set_translate(LAT1_MAP,currcons); + set_translate(vc_cons[currcons].d, LAT1_MAP); G0_charset = LAT1_MAP; G1_charset = GRAF_MAP; charset = 0; @@ -1428,12 +1428,12 @@ return; case 14: charset = 1; - translate = set_translate(G1_charset,currcons); + set_translate(vc_cons[currcons].d, G1_charset); disp_ctrl = 1; return; case 15: charset = 0; - translate = set_translate(G0_charset,currcons); + set_translate(vc_cons[currcons].d, G0_charset); disp_ctrl = 0; return; case 24: case 26: @@ -1740,7 +1740,7 @@ else if (c == 'K') G0_charset = USER_MAP; if (charset == 0) - translate = set_translate(G0_charset,currcons); + set_translate(vc_cons[currcons].d, G0_charset); vc_state = ESnormal; return; case ESsetG1: @@ -1753,7 +1753,7 @@ else if (c == 'K') G1_charset = USER_MAP; if (charset == 1) - translate = set_translate(G1_charset,currcons); + set_translate(vc_cons[currcons].d, G1_charset); vc_state = ESnormal; return; default: @@ -1778,8 +1778,10 @@ unsigned long draw_from = 0, draw_to = 0; struct vt_struct *vt = (struct vt_struct *)tty->driver_data; u16 himask, charmask; + unsigned short *translation; currcons = vt->vc_num; + translation = get_acm(translate); if (!vc_cons_allocated(currcons)) { /* could this happen? */ static int error = 0; @@ -1848,7 +1850,7 @@ utf_count = 0; } } else { /* no utf */ - tc = translate[toggle_meta ? (c|0x80) : c]; + tc = translation[toggle_meta ? (c|0x80) : c]; } /* If the original code was a control character we diff -u -r v2.2.0-pre9/linux/drivers/char/consolemap.c linux/drivers/char/conso lemap.c --- v2.2.0-pre9/linux/drivers/char/consolemap.c Wed Jan 20 21:17:04 1999 +++ linux/drivers/char/consolemap.c Fri Jan 22 23:44:43 1999 @@ -9,6 +9,29 @@ * Support for multiple unimaps by Jakub Jelinek <jj...@ul...>, July 199 8 * * Fix bug in inverse translation. Stanislav Voronyi <st...@cn...arkov. ua>, Dec 1998 + * + * Adapted for selection in Unicode by <ed...@ra...>, January 1999 + * + */ + +/* + * There are two kinds of mapping: + * + * Application-Charset Map (ACM) maps from 8-bit character to 16-bit Unicode. + * Data structures: translations[4][256], inverse_translations[4] + * Functions: clear_inverse_translations, set_inverse_translations, + * set_translate, get_acm, inverse_translate, con_[gs]et_trans_* + * + * Screen Font Map (SFM) maps from 16-bit Unicode to font position. + * Data structures: struct uni_pagedir + * Functions: clear_inverse_map, set_inverse_map, + * inverse_convert, *_unimap, conv_uni_to_pc + * + * An inverse SFM is calculated when it is required by inverse_convert, + * but an inverse ACM is calculated from sys_setup and whenever the ACM + * changes. This is because inverse_translate may get called from inside + * an interrupt in keyboard.c. + * */ #include <linux/kd.h> @@ -129,6 +152,7 @@ }, /* User mapping -- default to codes for direct font mapping */ { + /* UNI_DIRECT_BASE, ... */ 0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007, 0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f, 0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017, @@ -167,84 +191,180 @@ /* The standard kernel character-to-font mappings are not invertible -- this is just a best effort. */ -#define MAX_GLYPH 512 /* Max possible glyph value */ +static unsigned char ***inverse_translations[4] = { NULL, NULL, NULL, NULL }; -static int inv_translate[MAX_NR_CONSOLES]; +#define MAX_GLYPH 512 /* Max possible glyph value */ struct uni_pagedir { u16 **uni_pgdir[32]; unsigned long refcount; unsigned long sum; - unsigned char *inverse_translations[4]; + u16 *inverse_map; int readonly; }; -static struct uni_pagedir *dflt; +static struct uni_pagedir *dflt = NULL; -static void set_inverse_transl(struct vc_data *conp, struct uni_pagedir *p, in t i) +static void clear_inverse_translations(int m) { - int j, glyph; - unsigned short *t = translations[i]; - unsigned char *q; - - if (!p) return; - q = p->inverse_translations[i]; + unsigned char ***q = inverse_translations[m]; + unsigned char **p1; + int i, j; - if (!q) { - q = p->inverse_translations[i] = (unsigned char *) - kmalloc(MAX_GLYPH, GFP_KERNEL); - if (!q) return; + if (!q) return; + + for (i = 0; i < 32; i++) { + if ((p1 = q[i]) != NULL) { + for (j = 0; j < 32; j++) + if (p1[j]) + kfree(p1[j]); + kfree(p1); + } } - memset(q, 0, MAX_GLYPH); + kfree(q); + inverse_translations[m] = NULL; +} - for (j = 0; j < E_TABSZ; j++) { - glyph = conv_uni_to_pc(conp, t[j]); - if (glyph >= 0 && glyph < MAX_GLYPH && q[glyph] < 32) { - /* prefer '-' above SHY etc. */ - q[glyph] = j; +static void set_inverse_translations(int m) +{ + int i, c, n; + unsigned char ***q, **p1, *p2; + u16 *t = translations[m]; + u16 unicode; + + clear_inverse_translations(m); + q = inverse_translations[m] = (unsigned char ***) + kmalloc(32*sizeof(unsigned char **), GFP_KERNEL); + if (!q) return; + for (i = 0; i < 32; i++) + q[i] = NULL; + + /* The ACM may not be 1-1. In inverting it we prefer + lower characters over higher ones, + while excluding control characters (0..31, 127), + except that we force '\r' to be translated correctly. + */ + for (c = E_TABSZ-1; c >= 0; c--) { + if (c < 32) { + if (c == '\r') + unicode = c; + else + continue; + } + else { + if (c == 127) + continue; + else + unicode = t[c]; + } + if (!(p1 = q[n = unicode >> 11])) { + p1 = q[n] = kmalloc(32*sizeof(unsigned char *), GFP_KER NEL); + if (!p1) { + clear_inverse_translations(m); + return; + } + for (i = 0; i < 32; i++) + p1[i] = NULL; + } + if (!(p2 = p1[n = (unicode >> 6) & 0x1f])) { + p2 = p1[n] = kmalloc(64*sizeof(unsigned char), GFP_KERN EL); + if (!p2) { + clear_inverse_translations(m); + return; + } + memset(p2, 0, 64*sizeof(unsigned char)); } + p2[unicode & 0x3f] = c; + } +} + +static void clear_inverse_map(struct uni_pagedir *p) +{ + if (p->inverse_map) { + kfree(p->inverse_map); + p->inverse_map = NULL; + } +} + +static void set_inverse_map(struct uni_pagedir *p) +{ + int i, j, k; + u16 *q; + u16 **p1, *p2; + int ucs; + + q = p->inverse_map; + if (!q) { + q = p->inverse_map = (u16 *) + kmalloc(MAX_GLYPH*sizeof(u16), GFP_KERNEL); + if (!q) return; } + memset(q, 0xff, MAX_GLYPH*sizeof(u16)); + + /* The SFM is often not 1-1. In inverting it we prefer + lower characters over higher ones, + while excluding control characters (0..31, 127..159). + This has the desirable side effect that ' ' overrides + any other character mapped to the same glyph. + One might think about preferring Unicode characters that are + in the current ACM over ones that are not, but this couldn't + be implemented cleanly: we don't know what ACM will be used + with this SFM. + */ + for (i = 31; i >= 0; i--) + if ((p1 = p->uni_pgdir[i])) + for (j = 31; j >= 0; j--) + if ((p2 = p1[j])) + for (k = 63; k >= 0; k--) + if (p2[k] < MAX_GLYPH) { + ucs = (i << 11) | (j << 6) | k; + if (ucs < 160 && (ucs >= 127 || ucs < 32)) + continue; + q[p2[k]] = ucs; + } } -unsigned short *set_translate(int m,int currcons) +void set_translate(struct vc_data *conp, int m) +{ + conp->vc_translate = m; +} + +unsigned short *get_acm(int m) { - inv_translate[currcons] = m; return translations[m]; } -/* - * Inverse translation is impossible for several reasons: - * 1. The font<->character maps are not 1-1. - * 2. The text may have been written while a different translation map - * was active, or using Unicode. - * Still, it is now possible to a certain extent to cut and paste non-ASCII. - */ -unsigned char inverse_translate(struct vc_data *conp, int glyph) +unsigned char inverse_translate(int m, int ucs) { - struct uni_pagedir *p; - if (glyph < 0 || glyph >= MAX_GLYPH) + unsigned char ***q, **p1, *p2, c; + + if (ucs > 0xffff) return 0; - else if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc) || - !p->inverse_translations[inv_translate[conp->vc_num]]) - return glyph; + + if ((q = inverse_translations[m]) && + (p1 = q[ucs >> 11]) && + (p2 = p1[(ucs >> 6) & 0x1f]) && + (c = p2[ucs &0x3f])) + return c; else - return p->inverse_translations[inv_translate[conp->vc_num]][gly ph]; + return 0; } -static void update_user_maps(void) +u16 inverse_convert(struct vc_data *conp, int glyph) { - int i; - struct uni_pagedir *p, *q = NULL; - - for (i = 0; i < MAX_NR_CONSOLES; i++) { - if (!vc_cons_allocated(i)) - continue; - p = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc; - if (p && p != q) { - set_inverse_transl(vc_cons[i].d, p, USER_MAP); - q = p; - } + struct uni_pagedir *p; + + if (glyph < 0 || glyph >= MAX_GLYPH) + return 0xffff; + if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc)) + /* This shouldn't happen! */ + return UNI_DIRECT_BASE | glyph; + if (!p->inverse_map) { + set_inverse_map(p); + if (!p->inverse_map) + return 0xffff; } + return p->inverse_map[glyph]; } /* @@ -270,7 +390,7 @@ p[i] = UNI_DIRECT_BASE | uc; } - update_user_maps(); + set_inverse_translations(USER_MAP); return 0; } @@ -307,7 +427,7 @@ p[i] = us; } - update_user_maps(); + set_inverse_translations(USER_MAP); return 0; } @@ -355,11 +475,7 @@ } p->uni_pgdir[i] = NULL; } - for (i = 0; i < 4; i++) - if (p->inverse_translations[i]) { - kfree(p->inverse_translations[i]); - p->inverse_translations[i] = NULL; - } + clear_inverse_map(p); } void con_free_unimap(int con) @@ -455,7 +571,7 @@ if (p) p->refcount++; return -ENOMEM; } - memset(q, 0, sizeof(*q)); + memset(q, 0, sizeof(*q)); /* makes the pointers NULL, one hopes */ q->refcount=1; *conp->vc_uni_pagedir_loc = (unsigned long)q; } else { @@ -518,9 +634,8 @@ if (con_unify_unimap(conp, p)) return err; - for (i = 0; i <= 3; i++) - set_inverse_transl(conp, p, i); /* Update all inverse translati ons */ - + clear_inverse_map(p); + return err; } @@ -570,8 +685,7 @@ return err; } - for (i = 0; i <= 3; i++) - set_inverse_transl(conp, p, i); /* Update all inverse translati ons */ + clear_inverse_map(p); dflt = p; return err; } @@ -679,4 +793,6 @@ for (i = 0; i < MAX_NR_CONSOLES; i++) if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc) con_set_default_unimap(i); + for (i = 0; i < 4; i++) + set_inverse_translations(i); } diff -u -r v2.2.0-pre9/linux/drivers/char/keyboard.c linux/drivers/char/keyboar d.c --- v2.2.0-pre9/linux/drivers/char/keyboard.c Wed Jan 20 21:17:31 1999 +++ linux/drivers/char/keyboard.c Fri Jan 22 23:28:41 1999 @@ -41,6 +41,9 @@ #include <linux/kbd_ll.h> #include <linux/sysrq.h> +#include <linux/console_struct.h> +#include <linux/consolemap.h> + #define SIZE(x) (sizeof(x)/sizeof((x)[0])) #ifndef KBD_DEFMODE @@ -137,7 +140,7 @@ const int max_vals[] = { 255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1, NR_DEAD - 1, 255, 3, NR_SHIFT - 1, - 255, NR_ASCII - 1, NR_LOCK - 1, 255, + 255, NR_ASCII - 1, 2*NR_LOCK - 1, 255, NR_LOCK - 1, 255 }; @@ -155,12 +158,38 @@ #endif /* - * Many other routines do put_queue, but I think either - * they produce ASCII, or they produce some user-assigned - * string, and in both cases we might assume that it is - * in utf-8 already. + * A note on character conversion: + * + * A keymap maps keycodes to keysyms, which, at present, are 16-bit + * values. If a keysym is < 0xf000 then it specifies a 16-bit Unicode + * character to be queued. If a keysym is >= 0xf000, then 0xf000 is + * subtracted to give a pair of octets, extracted by KTYP and KVAL. + * The KTYP is used as an index into key_handler[] to give a function + * which handles the KVAL. The "normal" key_handler is do_self, which + * treats the KVAL as an 8-bit character to be queued. + * + * When a 16-bit Unicode character is queued it is converted to UTF-8 + * if the keyboard is in Unicode mode; otherwise it is converted to an + * 8-bit character using the current ACM (see consolemap.c). An 8-bit + * character is assumed to be in the character set defined by the + * current ACM, so it is queued unchanged if the keyboard is in 8-bit + * mode; otherwise it is converted using the inverse ACM. + * + * The handling of diacritics uses 8-bit characters, which are + * converted using the inverse ACM, when in Unicode mode. The strings + * bound to function keys are not converted, so they may already + * contain UTF-8. Codes entered using do_ascii() treated as 16-bit and + * converted to UTF-8 in Unicode mode; otherwise they are treated as + * 8-bit and queued unchanged. + * + * Since KTYP is not used in the case of Unicode keysyms, it is not + * possible to use KT_LETTER to implement CapsLock. Either use 8-bit + * keysyms with an appropriate ACM or use the work-around proposed in + * do_lock(). + * */ -void to_utf8(ushort c) { + +static void to_utf8(ushort c) { if (c < 0x80) put_queue(c); /* 0******* */ else if (c < 0x800) { @@ -175,6 +204,29 @@ but we need only 16 bits here */ } +static void put_unicode(u16 uc) +{ + if (kbd->kbdmode == VC_UNICODE) + to_utf8(uc); + else if ((uc & ~0x9f) == 0 || uc == 127) + /* Don't translate control chars */ + put_queue(uc); + else { + unsigned char c; + c = inverse_translate(vc_cons[fg_console].d->vc_translate, uc); + if (c) put_queue(c); + } +} + +static void put_8bit(u8 c) +{ + if (kbd->kbdmode != VC_UNICODE || + c < 32 || c == 127) /* Don't translate control chars */ + put_queue(c); + else + to_utf8(get_acm(vc_cons[fg_console].d->vc_translate)[c]); +} + /* * Translation of escaped scancodes to keycodes. * This is now user-settable (for machines were it makes sense). @@ -304,9 +356,8 @@ if (type != KT_SLOCK) kbd->slockstate = 0; } else { - /* maybe only if (kbd->kbdmode == VC_UNICODE) ? */ if (!up_flag && !raw_mode) - to_utf8(keysym); + put_unicode(keysym); } } else { /* maybe beep? */ @@ -358,7 +409,7 @@ static void enter(void) { if (diacr) { - put_queue(diacr); + put_8bit(diacr); diacr = 0; } put_queue(13); @@ -545,7 +596,7 @@ return; } - put_queue(value); + put_8bit(value); } #define A_GRAVE '`' @@ -600,7 +651,7 @@ if (ch == ' ' || ch == d) return d; - put_queue(d); + put_8bit(d); return ch; } @@ -674,7 +725,7 @@ return; } - put_queue(pad_chars[value]); + put_8bit(pad_chars[value]); if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF)) put_queue(10); } @@ -790,7 +841,22 @@ { if (up_flag || rep) return; - chg_vc_kbd_lock(kbd, value); + + if (value >= NR_LOCK) { + /* Change the lock state and + set the CapsLock LED to the new state */ + unsigned char mask; + + mask = 1 << (value -= NR_LOCK); + if ((kbd->lockstate ^= mask) & mask) + set_vc_kbd_led(kbd, VC_CAPSLOCK); + else + clr_vc_kbd_led(kbd, VC_CAPSLOCK); + } + else { + /* Just change the lock state */ + chg_vc_kbd_lock(kbd, value); + } } static void do_slock(unsigned char value, char up_flag) diff -u -r v2.2.0-pre9/linux/drivers/char/selection.c linux/drivers/char/select ion.c --- v2.2.0-pre9/linux/drivers/char/selection.c Thu Sep 17 17:35:03 1998 +++ linux/drivers/char/selection.c Fri Jan 22 23:28:41 1999 @@ -9,6 +9,8 @@ * 'int sel_loadlut(const unsigned long arg)' * * Now that /dev/vcs exists, most of this can disappear again. + * + * Adapted for selection in Unicode by <ed...@ra...>, January 1999 */ #include <linux/module.h> @@ -24,6 +26,7 @@ #include <linux/consolemap.h> #include <linux/console_struct.h> #include <linux/selection.h> +#include <linux/kbd_kern.h> #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -40,7 +43,7 @@ static volatile int sel_start = -1; /* cleared by clear_selection */ static int sel_end; static int sel_buffer_lth = 0; -static char *sel_buffer = NULL; +static u16 *sel_buffer = NULL; /* clear_selection, highlight and highlight_pointer can be called from interrupt (via scrollback/front) */ @@ -57,10 +60,11 @@ complement_pos(sel_cons, where); } -static unsigned char +static u16 sel_pos(int n) { - return inverse_translate(vc_cons[sel_cons].d, screen_glyph(sel_cons, n) ); + return inverse_convert(vc_cons[sel_cons].d, + screen_glyph(sel_cons, n)); } /* remove the current selection highlight, if any, @@ -89,8 +93,9 @@ 0xFF7FFFFF /* latin-1 accented letters, not division sign */ }; -static inline int inword(const unsigned char c) { - return ( inwordLut[c>>5] >> (c & 0x1F) ) & 1; +static inline int inword(const u16 c) { + /* Everything over 0xff is considered alphabetic! */ + return c >= 0x100 || ( inwordLut[c>>5] >> (c & 0x1F) ) & 1; } /* set inwordLut contents. Invoked by ioctl(). */ @@ -119,7 +124,8 @@ int set_selection(const unsigned long arg, struct tty_struct *tty, int user) { int sel_mode, new_sel_start, new_sel_end, spc; - char *bp, *obp; + u16 *bp, *obp; + u16 ucs; int i, ps, pe; unsigned int currcons = fg_console; @@ -259,7 +265,7 @@ sel_end = new_sel_end; /* Allocate a new buffer before freeing the old one ... */ - bp = kmalloc((sel_end-sel_start)/2+1, GFP_KERNEL); + bp = kmalloc(((sel_end-sel_start)/2+1)*sizeof(u16), GFP_KERNEL); if (!bp) { printk(KERN_WARNING "selection: kmalloc() failed\n"); clear_selection(); @@ -271,8 +277,9 @@ obp = bp; for (i = sel_start; i <= sel_end; i += 2) { - *bp = sel_pos(i); - if (!isspace(*bp++)) + ucs = sel_pos(i); + *bp++ = ucs; + if (!isspace(ucs)) obp = bp; if (! ((i + 2) % video_size_row)) { /* strip trailing blanks from line and add newline, @@ -294,25 +301,80 @@ */ int paste_selection(struct tty_struct *tty) { + int utf; + unsigned char *paste_buffer, *bp, *p; struct vt_struct *vt = (struct vt_struct *) tty->driver_data; - int pasted = 0, count; + int count; struct wait_queue wait = { current, NULL }; + if (!sel_buffer || !sel_buffer_lth) return 0; + + /* Paste UTF-8 iff the keyboard is in UTF-8 mode */ + utf = (kbd_table[fg_console].kbdmode == VC_UNICODE); + + /* Make a paste buffer containing an appropriate translation + of the selection buffer */ + paste_buffer = kmalloc(utf ? sel_buffer_lth*3 : sel_buffer_lth, GFP_KER NEL); + if (!paste_buffer) { + printk(KERN_WARNING "selection: kmalloc() failed\n"); + return -ENOMEM; + } + + bp = paste_buffer; + if (utf) { + /* convert to UTF-8 */ + int i, ucs; + + for (i = 0; i < sel_buffer_lth; i++) { + ucs = sel_buffer[i]; + /* The following code should at some point + be merged with to_utf8() in keyboard.c */ + if (!(ucs & ~0x7f)) /* 0?????? */ + *bp++ = ucs; + else if (!(ucs & ~0x7ff)) { /* 110????? 10?????? */ + *bp++ = 0xc0 | (ucs >> 6); + *bp++ = 0x80 | (ucs & 0x3f); + } + else { /* 1110???? 10?????? 10?????? */ + *bp++ = 0xe0 | (ucs >> 12); + *bp++ = 0x80 | ((ucs >> 6) & 0x3f); + *bp++ = 0x80 | (ucs & 0x3f); + } + /* UTF-8 is defined for words of up to 31 bits, + but we need only 16 bits here */ + } + } + else { + /* convert to 8-bit */ + int inv_translate = vc_cons[fg_console].d->vc_translate; + int i; + unsigned char c; + + for (i = 0; i < sel_buffer_lth; i++) { + c = inverse_translate(inv_translate, sel_buffer[i]); + if (c) *bp++ = c; + } + } + poke_blanked_console(); add_wait_queue(&vt->paste_wait, &wait); - while (sel_buffer && sel_buffer_lth > pasted) { + p = paste_buffer; + while (bp > p) { current->state = TASK_INTERRUPTIBLE; if (test_bit(TTY_THROTTLED, &tty->flags)) { schedule(); continue; } - count = sel_buffer_lth - pasted; + count = bp - p; count = MIN(count, tty->ldisc.receive_room(tty)); - tty->ldisc.receive_buf(tty, sel_buffer + pasted, 0, count); - pasted += count; + tty->ldisc.receive_buf(tty, p, 0, count); + p += count; } remove_wait_queue(&vt->paste_wait, &wait); current->state = TASK_RUNNING; + + kfree(paste_buffer); + return 0; } diff -u -r v2.2.0-pre9/linux/drivers/char/vt.c linux/drivers/char/vt.c --- v2.2.0-pre9/linux/drivers/char/vt.c Wed Jan 20 21:17:42 1999 +++ linux/drivers/char/vt.c Fri Jan 22 23:28:41 1999 @@ -159,11 +159,9 @@ switch (cmd) { case KDGKBENT: key_map = key_maps[s]; - if (key_map) { + if (key_map) val = U(key_map[i]); - if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES) - val = K_HOLE; - } else + else val = (i ? K_HOLE : K_NOSUCHMAP); return __put_user(val, &user_kbe->kb_value); case KDSKBENT: @@ -182,12 +180,9 @@ break; } - if (KTYP(v) < NR_TYPES) { - if (KVAL(v) > max_vals[KTYP(v)]) - return -EINVAL; - } else - if (kbd->kbdmode != VC_UNICODE) - return -EINVAL; + if ((v & 0xf000) == 0 && + (KTYP(v) >= NR_TYPES || KVAL(v) > max_vals[KTYP(v)])) + return -EINVAL; /* ++Geert: non-PC keyboards may generate keycode zero */ #if !defined(__mc68000__) && !defined(__powerpc__) diff -u -r v2.2.0-pre9/linux/include/linux/console_struct.h linux/include/linux /console_struct.h --- v2.2.0-pre9/linux/include/linux/console_struct.h Thu Sep 17 17:35:04 199 8 +++ linux/include/linux/console_struct.h Fri Jan 22 23:28:41 1999 @@ -70,7 +70,7 @@ int vc_utf_char; unsigned int vc_tab_stop[5]; /* Tab stops. 160 columns. */ unsigned char vc_palette[16*3]; /* Colour palette for VGA+ */ - unsigned short * vc_translate; + int vc_translate; /* Current ACM */ unsigned char vc_G0_charset; unsigned char vc_G1_charset; unsigned char vc_saved_G0; diff -u -r v2.2.0-pre9/linux/include/linux/consolemap.h linux/include/linux/con solemap.h --- v2.2.0-pre9/linux/include/linux/consolemap.h Wed Jan 20 21:17:09 199 9 +++ linux/include/linux/consolemap.h Fri Jan 22 23:30:16 1999 @@ -10,6 +10,8 @@ struct vc_data; -extern unsigned char inverse_translate(struct vc_data *conp, int glyph); -extern unsigned short *set_translate(int m,int currcons); +extern unsigned short *get_acm(int m); +extern unsigned char inverse_translate(int m, int ucs); +extern u16 inverse_convert(struct vc_data *conp, int glyph); +extern void set_translate(struct vc_data *conp, int m); extern int conv_uni_to_pc(struct vc_data *conp, long ucs); |