Author: jim
Date: 2006-01-18 08:58:57 -0700 (Wed, 18 Jan 2006)
New Revision: 1357

Added:
   trunk/linux/linux-2.6.15.1-utf8_input-1.patch
Modified:
   trunk/
Log:
 [EMAIL PROTECTED]:  jim | 2006-01-17 22:09:39 -0800
 Added: linux-2.6.15.1-utf8_input-1.patch



Property changes on: trunk
___________________________________________________________________
Name: svk:merge
   - cc2644d5-6cf8-0310-b111-c40428001e49:/patches:1695
   + cc2644d5-6cf8-0310-b111-c40428001e49:/patches:1698

Added: trunk/linux/linux-2.6.15.1-utf8_input-1.patch
===================================================================
--- trunk/linux/linux-2.6.15.1-utf8_input-1.patch       2006-01-18 15:57:42 UTC 
(rev 1356)
+++ trunk/linux/linux-2.6.15.1-utf8_input-1.patch       2006-01-18 15:58:57 UTC 
(rev 1357)
@@ -0,0 +1,335 @@
+Submitted by: Alexander E. Patrakov
+Date: 2005-10-18
+Initial Package Version: 2.6.15
+Upstream Status: Rejected: they say it modifies the meaning of an existing 
ioctl
+Origin: http://chris.heathens.co.nz/linux/downloads/patches-2.6.4-cdh1.tar.gz
+       Porting to linux-2.6.12.5 by Alexander E. Patrakov
+       Porting to linux-2.6.15
+Description: This patch fixes dead keys and copy/paste of non-ASCII characters
+            in UTF-8 mode on Linux console.
+            See more details about the original patch at:
+            http://chris.heathens.co.nz/linux/utf8.html 
+
+diff -Naur linux-2.6.15.1.orig/drivers/char/consolemap.c 
linux-2.6.15.1/drivers/char/consolemap.c
+--- linux-2.6.15.1.orig/drivers/char/consolemap.c      2006-01-15 
06:16:02.000000000 +0000
++++ linux-2.6.15.1/drivers/char/consolemap.c   2006-01-18 06:00:08.000000000 
+0000
+@@ -178,6 +178,7 @@
+       unsigned long   refcount;
+       unsigned long   sum;
+       unsigned char   *inverse_translations[4];
++      u16             *inverse_trans_unicode;
+       int             readonly;
+ };
+ 
+@@ -208,6 +209,41 @@
+       }
+ }
+ 
++static void set_inverse_trans_unicode(struct vc_data *conp, 
++                                    struct uni_pagedir *p)
++{
++      int i, j, k, glyph;
++      u16 **p1, *p2;
++      u16 *q;
++      
++      if (!p) return;
++      q = p->inverse_trans_unicode;
++      if (!q) {
++              q = p->inverse_trans_unicode =
++                      kmalloc(MAX_GLYPH * sizeof(u16), GFP_KERNEL);
++              if (!q)
++                      return;
++      }
++      memset(q, 0, MAX_GLYPH * sizeof(u16));
++
++      for (i = 0; i < 32; i++) {
++              p1 = p->uni_pgdir[i];
++              if (!p1)
++                      continue;
++              for (j = 0; j < 32; j++) {
++                      p2 = p1[j];
++                      if (!p2)
++                              continue;
++                      for (k = 0; k < 64; k++) {
++                              glyph = p2[k];
++                              if (glyph >= 0 && glyph < MAX_GLYPH 
++                                             && q[glyph] < 32)
++                                      q[glyph] = (i << 11) + (j << 6) + k;
++                      }
++              }
++      }
++}
++
+ unsigned short *set_translate(int m, struct vc_data *vc)
+ {
+       inv_translate[vc->vc_num] = m;
+@@ -218,19 +254,29 @@
+  * 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.
++ *    was active.
+  * 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)
++u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode)
+ {
+       struct uni_pagedir *p;
++      int m;
+       if (glyph < 0 || glyph >= MAX_GLYPH)
+               return 0;
+-      else if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc) ||
+-               !p->inverse_translations[inv_translate[conp->vc_num]])
++      else if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc))
+               return glyph;
+-      else
+-              return 
p->inverse_translations[inv_translate[conp->vc_num]][glyph];
++      else if (use_unicode) {
++              if (!p->inverse_trans_unicode)
++                      return glyph;
++              else
++                      return p->inverse_trans_unicode[glyph];
++      } else {
++              m = inv_translate[conp->vc_num];
++              if (!p->inverse_translations[m])
++                      return glyph;
++              else
++                      return p->inverse_translations[m][glyph];
++      }
+ }
+ 
+ static void update_user_maps(void)
+@@ -244,6 +290,7 @@
+               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);
++                      set_inverse_trans_unicode(vc_cons[i].d, p);
+                       q = p;
+               }
+       }
+@@ -354,6 +401,10 @@
+               kfree(p->inverse_translations[i]);
+               p->inverse_translations[i] = NULL;
+       }
++      if (p->inverse_trans_unicode) {
++              kfree(p->inverse_trans_unicode);
++              p->inverse_trans_unicode = NULL;
++      }
+ }
+ 
+ void con_free_unimap(struct vc_data *vc)
+@@ -512,6 +563,7 @@
+ 
+       for (i = 0; i <= 3; i++)
+               set_inverse_transl(vc, p, i); /* Update all inverse 
translations */
++      set_inverse_trans_unicode(vc, p);
+   
+       return err;
+ }
+@@ -562,6 +614,7 @@
+ 
+       for (i = 0; i <= 3; i++)
+               set_inverse_transl(vc, p, i);   /* Update all inverse 
translations */
++      set_inverse_trans_unicode(vc, p);
+       dflt = p;
+       return err;
+ }
+@@ -618,6 +671,19 @@
+               p->readonly = rdonly;
+ }
+ 
++/* may be called during an interrupt */
++u32 conv_8bit_to_uni(unsigned char c)
++{
++      /* 
++       * Always use USER_MAP. This function is used by the keyboard,
++       * which shouldn't be affected by G0/G1 switching, etc.
++       * If the user map still contains default values, i.e. the 
++       * direct-to-font mapping, then assume user is using Latin1.
++       */
++      unsigned short uni = translations[USER_MAP][c];
++      return uni == (0xf000 | c) ? c : uni;
++}
++
+ int
+ conv_uni_to_pc(struct vc_data *conp, long ucs) 
+ {
+diff -Naur linux-2.6.15.1.orig/drivers/char/keyboard.c 
linux-2.6.15.1/drivers/char/keyboard.c
+--- linux-2.6.15.1.orig/drivers/char/keyboard.c        2006-01-15 
06:16:02.000000000 +0000
++++ linux-2.6.15.1/drivers/char/keyboard.c     2006-01-18 05:58:11.000000000 
+0000
+@@ -34,6 +34,7 @@
+ #include <linux/init.h>
+ #include <linux/slab.h>
+ 
++#include <linux/consolemap.h>
+ #include <linux/kbd_kern.h>
+ #include <linux/kbd_diacr.h>
+ #include <linux/vt_kern.h>
+@@ -349,6 +350,15 @@
+       }
+ }
+ 
++static void put_8bit(struct vc_data *vc, u8 c)
++{
++      if (kbd->kbdmode != VC_UNICODE || c < 32 || c == 127) 
++              /* Don't translate control chars */
++              put_queue(vc, c);
++      else
++              to_utf8(vc, conv_8bit_to_uni(c));
++}
++
+ /*
+  * Called after returning from RAW mode or when changing consoles - recompute
+  * shift_down[] and shift_state from key_down[] maybe called when keymap is
+@@ -409,7 +419,7 @@
+       if (ch == ' ' || ch == d)
+               return d;
+ 
+-      put_queue(vc, d);
++      put_8bit(vc, d);
+       return ch;
+ }
+ 
+@@ -419,7 +429,7 @@
+ static void fn_enter(struct vc_data *vc, struct pt_regs *regs)
+ {
+       if (diacr) {
+-              put_queue(vc, diacr);
++              put_8bit(vc, diacr);
+               diacr = 0;
+       }
+       put_queue(vc, 13);
+@@ -628,7 +638,7 @@
+               diacr = value;
+               return;
+       }
+-      put_queue(vc, value);
++      put_8bit(vc, value);
+ }
+ 
+ /*
+diff -Naur linux-2.6.15.1.orig/drivers/char/selection.c 
linux-2.6.15.1/drivers/char/selection.c
+--- linux-2.6.15.1.orig/drivers/char/selection.c       2006-01-15 
06:16:02.000000000 +0000
++++ linux-2.6.15.1/drivers/char/selection.c    2006-01-18 05:58:12.000000000 
+0000
+@@ -20,6 +20,7 @@
+ 
+ #include <asm/uaccess.h>
+ 
++#include <linux/kbd_kern.h>
+ #include <linux/vt_kern.h>
+ #include <linux/consolemap.h>
+ #include <linux/selection.h>
+@@ -34,6 +35,7 @@
+ /* Variables for selection control. */
+ /* Use a dynamic buffer, instead of static (Dec 1994) */
+ struct vc_data *sel_cons;             /* must not be disallocated */
++static int use_unicode;
+ static volatile int sel_start = -1;   /* cleared by clear_selection */
+ static int sel_end;
+ static int sel_buffer_lth;
+@@ -54,10 +56,8 @@
+       complement_pos(sel_cons, where);
+ }
+ 
+-static unsigned char
+-sel_pos(int n)
+-{
+-      return inverse_translate(sel_cons, screen_glyph(sel_cons, n));
++static u16 sel_pos(int n) {
++    return inverse_translate(sel_cons, screen_glyph(sel_cons, n), 
use_unicode);
+ }
+ 
+ /* remove the current selection highlight, if any,
+@@ -86,8 +86,8 @@
+   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) {
++    return c > 0xff || ((inwordLut[c >> 5] >> (c & 0x1F)) & 1);
+ }
+ 
+ /* set inwordLut contents. Invoked by ioctl(). */
+@@ -108,13 +108,35 @@
+       return (v > u) ? u : v;
+ }
+ 
++/* stores the char in UTF8 and returns the number of bytes used (1-3) */
++int store_utf8(u16 c, char *p)  {
++      if (c < 0x80) {
++              /* 0******* */
++              p[0] = c;
++              return 1;
++      } else if (c < 0x800) {
++              /* 110***** 10****** */
++              p[0] = 0xc0 | (c >> 6);
++              p[1] = 0x80 | (c & 0x3f);
++              return 2;
++      } else {
++              /* 1110**** 10****** 10****** */
++              p[0] = 0xe0 | (c >> 12);
++              p[1] = 0x80 | ((c >> 6) & 0x3f);
++              p[2] = 0x80 | (c & 0x3f);
++              return 3;
++      }
++}
++
+ /* set the current selection. Invoked by ioctl() or by kernel code. */
+ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct 
*tty)
+ {
+       struct vc_data *vc = vc_cons[fg_console].d;
+       int sel_mode, new_sel_start, new_sel_end, spc;
+       char *bp, *obp;
+-      int i, ps, pe;
++        int i, ps, pe, multiplier;
++        u16 c;
++        struct kbd_struct *kbd = kbd_table + fg_console;
+ 
+       poke_blanked_console();
+ 
+@@ -158,6 +180,7 @@
+               clear_selection();
+               sel_cons = vc_cons[fg_console].d;
+       }
++      use_unicode = kbd && kbd->kbdmode == VC_UNICODE;
+ 
+       switch (sel_mode)
+       {
+@@ -240,7 +263,8 @@
+       sel_end = new_sel_end;
+ 
+       /* Allocate a new buffer before freeing the old one ... */
+-      bp = kmalloc((sel_end-sel_start)/2+1, GFP_KERNEL);
++      multiplier = use_unicode ? 3 : 1;  /* chars can take up to 3 bytes */
++      bp = kmalloc((sel_end-sel_start)/2*multiplier+1, GFP_KERNEL);
+       if (!bp) {
+               printk(KERN_WARNING "selection: kmalloc() failed\n");
+               clear_selection();
+@@ -251,8 +275,12 @@
+ 
+       obp = bp;
+       for (i = sel_start; i <= sel_end; i += 2) {
+-              *bp = sel_pos(i);
+-              if (!isspace(*bp++))
++              c = sel_pos(i);
++              if (use_unicode)
++                      bp += store_utf8(c, bp);
++              else
++                      *bp++ = c;
++              if (!isspace(c))
+                       obp = bp;
+               if (! ((i + 2) % vc->vc_size_row)) {
+                       /* strip trailing blanks from line and add newline,
+diff -Naur linux-2.6.15.1.orig/include/linux/consolemap.h 
linux-2.6.15.1/include/linux/consolemap.h
+--- linux-2.6.15.1.orig/include/linux/consolemap.h     2006-01-15 
06:16:02.000000000 +0000
++++ linux-2.6.15.1/include/linux/consolemap.h  2006-01-18 05:58:12.000000000 
+0000
+@@ -10,6 +10,7 @@
+ 
+ struct vc_data;
+ 
+-extern unsigned char inverse_translate(struct vc_data *conp, int glyph);
++extern u16 inverse_translate(struct vc_data *conp, int glyph, int 
use_unicode);
+ extern unsigned short *set_translate(int m, struct vc_data *vc);
+ extern int conv_uni_to_pc(struct vc_data *conp, long ucs);
++extern u32 conv_8bit_to_uni(unsigned char c);

-- 
http://linuxfromscratch.org/mailman/listinfo/patches
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to