Messages in this thread Patch in this message | | | From | "Stanislav V. Voronyi" <> | Date | Wed, 16 Dec 1998 14:28:39 +0200 | Subject | [PATCH] bug fix & improvvement for console |
| |
This is patch for console which consist from two logical part: one for selection and another for keyboard. To my mind this patch must be usefull for people who widely use non-ASCII chars (cyrillic, greek, hebrew, etc).
Patch for selection fix bug in inverse_translate which broke selection of 8-bit chars if I use different console mapping on multiconsole (f.e. ISO Latin 1 for one ('\033(B') & User Map on another ('\033(K'). Also I add possibilities to cut/paste in UTF mode. With this patch I can freely cut on normal console and paste to UTF one (if keyboard in VC_UNICODE mode). Also possible cut from normal, paste to normal; ........ UTF, ........... normal; ........ UTF, ........... UTF absolutely free.
Patch for keyboard.c intended to allow use only one keyboard map for both XLATE & UNICODE(UTF-8) mode where all non ASCII symbols described as an Unicode symbols. Translate from Unicode to ASCII in XLATE mode use the same translation tables as in selection & console. This way for translation (Unicode->conv_uni_to_pc->inverse_translate->ASCII) make this translation correct with any combination of used console font/mapping tables without adding special translating table for keyboard.
SY, Stanislav Voronyi.
------------------ Patch here -------------------------------
diff -u --recursive linux-2.1.131.d/drivers/char/console.c linux-2.1.131.n/drivers/char/console.c --- linux-2.1.131.d/drivers/char/console.c Mon Dec 14 02:25:09 1998 +++ linux-2.1.131.n/drivers/char/console.c Wed Dec 16 02:17:52 1998 @@ -1029,7 +1029,7 @@ */ translate = set_translate(charset == 0 ? G0_charset - : G1_charset); + : G1_charset,currcons); disp_ctrl = 0; toggle_meta = 0; break; @@ -1037,7 +1037,7 @@ * Select first alternate font, lets * chars < 32 be displayed as ROM chars. */ - translate = set_translate(IBMPC_MAP); + translate = set_translate(IBMPC_MAP,currcons); 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); + translate = set_translate(IBMPC_MAP,currcons); disp_ctrl = 1; toggle_meta = 1; break; @@ -1328,7 +1328,7 @@ color = s_color; G0_charset = saved_G0; G1_charset = saved_G1; - translate = set_translate(charset ? G1_charset : G0_charset); + translate = set_translate(charset ? G1_charset : G0_charset,currcons); update_attr(currcons); need_wrap = 0; } @@ -1343,7 +1343,7 @@ bottom = video_num_lines; vc_state = ESnormal; ques = 0; - translate = set_translate(LAT1_MAP); + translate = set_translate(LAT1_MAP,currcons); G0_charset = LAT1_MAP; G1_charset = GRAF_MAP; charset = 0; @@ -1426,12 +1426,12 @@ return; case 14: charset = 1; - translate = set_translate(G1_charset); + translate = set_translate(G1_charset,currcons); disp_ctrl = 1; return; case 15: charset = 0; - translate = set_translate(G0_charset); + translate = set_translate(G0_charset,currcons); disp_ctrl = 0; return; case 24: case 26: @@ -1738,7 +1738,7 @@ else if (c == 'K') G0_charset = USER_MAP; if (charset == 0) - translate = set_translate(G0_charset); + translate = set_translate(G0_charset,currcons); vc_state = ESnormal; return; case ESsetG1: @@ -1751,7 +1751,7 @@ else if (c == 'K') G1_charset = USER_MAP; if (charset == 1) - translate = set_translate(G1_charset); + translate = set_translate(G1_charset,currcons); vc_state = ESnormal; return; default: diff -u --recursive linux-2.1.131.d/drivers/char/consolemap.c linux-2.1.131.n/drivers/char/consolemap.c --- linux-2.1.131.d/drivers/char/consolemap.c Mon Dec 14 00:01:05 1998 +++ linux-2.1.131.n/drivers/char/consolemap.c Wed Dec 16 02:17:52 1998 @@ -7,6 +7,8 @@ * aeb, 950210 * * Support for multiple unimaps by Jakub Jelinek <jj@ultra.linux.cz>, July 1998 + * + * Fix bug in inverse translation. Stanislav Voronyi <stas@cnti.uanet.kharkov.ua>, Dec 1998 */ #include <linux/kd.h> @@ -167,7 +169,7 @@ #define MAX_GLYPH 512 /* Max possible glyph value */ -static int inv_translate; +static int inv_translate[MAX_NR_CONSOLES]; struct uni_pagedir { u16 **uni_pgdir[32]; @@ -204,9 +206,9 @@ } } -unsigned short *set_translate(int m) +unsigned short *set_translate(int m,int currcons) { - inv_translate = m; + inv_translate[currcons] = m; return translations[m]; } @@ -220,14 +222,13 @@ unsigned char inverse_translate(struct vc_data *conp, int glyph) { struct uni_pagedir *p; - if (glyph < 0 || glyph >= MAX_GLYPH) return 0; else if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc) || - !p->inverse_translations[inv_translate]) + !p->inverse_translations[inv_translate[conp->vc_num]]) return glyph; else - return p->inverse_translations[inv_translate][glyph]; + return p->inverse_translations[inv_translate[conp->vc_num]][glyph]; } static void update_user_maps(void) diff -u --recursive linux-2.1.131.d/drivers/char/keyboard.c linux-2.1.131.n/drivers/char/keyboard.c --- linux-2.1.131.d/drivers/char/keyboard.c Mon Dec 14 03:10:16 1998 +++ linux-2.1.131.n/drivers/char/keyboard.c Wed Dec 16 02:17:52 1998 @@ -21,6 +21,7 @@ * * 27-05-97: Added support for the Magic SysRq Key (Martin Mares) * 30-07-98: Dead keys redone, aeb@cwi.nl. + * 16-12-98: Add translation Unicode keysyms to ASCII when keyboard in XLATE mode, stas@cnti.uanet.kharkov.ua */ #include <linux/config.h> @@ -41,6 +42,17 @@ #include <linux/kbd_ll.h> #include <linux/sysrq.h> +/* + * Four lines bellow added for support translation unicode + * symbols to ASCII through console unicode table when + * keyboard in XLATE mode, but in keymap U+xxxx symbols + * persent + */ +#include <linux/console_struct.h> +extern int fg_console; +extern struct vc vc_cons[]; +extern conv_uni_to_pc(struct vc_data *conp, long ucs); + #define SIZE(x) (sizeof(x)/sizeof((x)[0])) #ifndef KBD_DEFMODE @@ -301,7 +313,14 @@ } else { /* maybe only if (kbd->kbdmode == VC_UNICODE) ? */ if (!up_flag && !raw_mode) - to_utf8(keysym); + if (kbd->kbdmode == VC_UNICODE) + to_utf8(keysym); + else if (kbd->kbdmode == VC_XLATE) { /* translate unicode to ASCII */ + int c = inverse_translate(vc_cons[fg_console].d, + conv_uni_to_pc(vc_cons[fg_console].d, keysym)); + if (c > 0) + put_queue(c); + } } } else { /* maybe beep? */ diff -u --recursive linux-2.1.131.d/drivers/char/selection.c linux-2.1.131.n/drivers/char/selection.c --- linux-2.1.131.d/drivers/char/selection.c Sun Dec 13 23:23:27 1998 +++ linux-2.1.131.n/drivers/char/selection.c Wed Dec 16 02:17:52 1998 @@ -9,6 +9,8 @@ * 'int sel_loadlut(const unsigned long arg)' * * Now that /dev/vcs exists, most of this can disappear again. + * + * Add paste in UTF-8 if keyboard in UNICODE mode, Stanislav Voronyi <stas@cnti.uanet.kharkov.ua>, Dec 1998 */ #include <linux/module.h> @@ -23,6 +25,7 @@ #include <linux/vt_kern.h> #include <linux/consolemap.h> #include <linux/console_struct.h> +#include <linux/kbd_kern.h> #include <linux/selection.h> #ifndef MIN @@ -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 unsigned char * sel_buffer = NULL; /* clear_selection, highlight and highlight_pointer can be called from interrupt (via scrollback/front) */ @@ -119,7 +122,7 @@ 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; + unsigned char *bp, *obp; int i, ps, pe; unsigned int currcons = fg_console; @@ -295,9 +298,45 @@ int paste_selection(struct tty_struct *tty) { struct vt_struct *vt = (struct vt_struct *) tty->driver_data; - int pasted = 0, count; + int pasted = 0, count, utf_mode = 0; struct wait_queue wait = { current, NULL }; - + unsigned char *new_buffer = NULL; + int i, j, new_buffer_lth = 0; + ushort unicode; + + if (kbd_table[vt->vc_num].kbdmode == VC_UNICODE){ + for (i=0;i < sel_buffer_lth;i++) + if ((sel_buffer[i]&0x80) == 0) + new_buffer_lth++; + else if (vc_cons[vt->vc_num].d->vc_translate[sel_buffer[i]] < 0x800) + new_buffer_lth+=2; + else + new_buffer_lth+=3; + if( new_buffer_lth == sel_buffer_lth) + goto no_utf; + utf_mode = 1; + new_buffer = kmalloc(new_buffer_lth, GFP_KERNEL); + if (!new_buffer) { + printk(KERN_WARNING "selection: kmalloc() failed\n"); + return -ENOMEM; + } + for (i=0,j=0;i < sel_buffer_lth;i++,j++) { + if ((sel_buffer[i]&0x80) == 0) + new_buffer[j]=sel_buffer[i]; + else { + unicode = vc_cons[vt->vc_num].d->vc_translate[sel_buffer[i]]; + if (unicode < 0x800) { /* 110XXXXX 10XXXXXX */ + new_buffer[j++] = (0xc0 | (unicode >> 6)); + new_buffer[j] = (0x80 | (unicode & 0x3f)); + } else { /* 1110XXXX 10XXXXXX 10XXXXXX */ + new_buffer[j++] = (0xe0 | (unicode >> 12)); + new_buffer[j++] = (0x80 | ((unicode >> 6) & 0x3f)); + new_buffer[j] = (0x80 | (unicode & 0x3f)); + } + } + } + } +no_utf: poke_blanked_console(); add_wait_queue(&vt->paste_wait, &wait); while (sel_buffer && sel_buffer_lth > pasted) { @@ -306,11 +345,13 @@ schedule(); continue; } - count = sel_buffer_lth - pasted; + count = utf_mode?new_buffer_lth:sel_buffer_lth - pasted; count = MIN(count, tty->ldisc.receive_room(tty)); - tty->ldisc.receive_buf(tty, sel_buffer + pasted, 0, count); + tty->ldisc.receive_buf(tty, utf_mode?new_buffer:sel_buffer + pasted, 0, count); pasted += count; } + if (new_buffer) + kfree(new_buffer); remove_wait_queue(&vt->paste_wait, &wait); current->state = TASK_RUNNING; return 0; diff -u --recursive linux-2.1.131.d/include/linux/consolemap.h linux-2.1.131.n/include/linux/consolemap.h --- linux-2.1.131.d/include/linux/consolemap.h Mon Dec 14 03:02:40 1998 +++ linux-2.1.131.n/include/linux/consolemap.h Mon Dec 14 02:32:06 1998 @@ -11,5 +11,5 @@ struct vc_data; extern unsigned char inverse_translate(struct vc_data *conp, int glyph); -extern unsigned short *set_translate(int m); +extern unsigned short *set_translate(int m,int currcons); extern int conv_uni_to_pc(struct vc_data *conp, long ucs); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |