handrake

Differences between revisions 14 and 15
Revision 14 as of 2006-03-11 15:50:59
Size: 8919
Editor: CPE001346c06763-CM0014e8220664
Comment:
Revision 15 as of 2006-03-11 15:53:30
Size: 8918
Editor: CPE001346c06763-CM0014e8220664
Comment:
Deletions are marked like this. Additions are marked like this.
Line 87: Line 87:
2. if scancode is more than 0x7f, add 0x100 to it. 2. if scancode is more than 0x7f, add 0x80 to it.

About myself

I am a student in computer engineering at University of Waterloo. I have been using Ubuntu Linux for 2 months now. Right now, I'm living in Etobicoke, it's a part of GTA (around Toronto area), working as co-op (co-op is like an intern program). I'm dying to get a computer sometime next week so that I can participate.

I finally got my computer, fujitsu P7120, and I'm totally satisfied with what I've got. Looks all good to me Smile :)

Known Bugs

There is a bug in gaim 2.0 beta, the one with not being able to send a last character if you are writing in Korean. Currently, you can send messages in Korean without a problem in a message tab, which has been a problem back in gaim 1.5, but in "Set friendly name" menu, the problem seems to still exist.

I think this bug can be fixed with a simple patch, doing the same thing Gaim team has done for a message tab.

-- this bug is fixed in gaim 2.0 beta cvs version.

Translated Documents

I have translated the following documents so far.

http://www.ubuntu.or.kr/wiki.php/KernelHowTo

http://www.ubuntu.or.kr/wiki.php/KernelPatchHowTo

http://www.ubuntu.or.kr/ubuntu/wiki.php/ApacheMySQLPHP

Hacking Linux Keyboard Driver

It is a well-known problem (among Korean users) Linux kernel & X windows do not support Korean/English and Korean/Chinese toggle keys as default. To use them, you have to manually create a keymap for them, which is usually done like the following.

$ setkeycodes 71 123   # Korean/Chinese toggle key
$ setkeycodes 72 122   # Korean/English toggle key

This will tell Linux kernel that those two keys are going to be used as we expect. However, it's not all done yet; because X11 does not have a complete keymap (with keysym and all that) for Korean keyboard, we have to tell X, too, just about the same thing.

$ xmodmap -e "keycode 209 = Hangul"   # Korean/English
$ xmodmap -e "keycode 210 = Hangul_Hanja"   # Korean/Chinese

This is it. This was a quick nice way to get your two keys working in Breezy. However, in Dapper, I heard from a lot of people those two keys don't work any more as they did back in Breezy. So I decided to dig it a little to see what's possibly going wrong and hopefully, how to get it working without setting them if at all possible.

Keyboard Scancode

To hack keyboard driver (which is located in kernel source under drivers/input/keyboard/atkbd.c AT keyboard driver looks like it's always built-in to the kernel) I needed to have some background information to understand what's really going on behind the scene. Without a solid knowledge of how keyboard works (at least how scancodes are translated from set 2 to set 1 and all that) keyboard driver looks like a mess of unsolved mathematical problems.

http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html

this is where you can get all the gory details needed to understand how keyboard driver works. Just read section 10 first then 8 and 9 since all other sections talk about special keyboards and mouse we are not really interested in. Now let's look at the source code.

 /* drivers/input/keyboard/atkbd.c */

static unsigned char atkbd_set2_keycode[512] = {

#ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES

/* XXX: need a more general approach */

#include "hpps2atkbd.h" /* include the keyboard scancodes */

#else
          0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
          0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
          0, 46, 45, 32, 18,  5,  4, 95,  0, 57, 47, 33, 20, 19,  6,183,
          0, 49, 48, 35, 34, 21,  7,184,  0,  0, 50, 36, 22,  8,  9,185,
          0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
          0, 89, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0, 85,
          0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0,
         82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,

          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
        173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
        159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
        157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
        226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
        110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,

          0,  0,  0, 65, 99,
#endif
};

this is the set 2 keymap; all default keys are registered here. However, you can see that there is no 122 or 123 which are Korean/English and Korean/Chinese keys respectively defined in kernel under include/linux/input.h

From the above keymap, first 0x7f(=127) keys (0, 67 ... 70, 99) are the ones that have their position as their scancode. For example, 67 is located in 0x01, which is F9 (see the very bottom in section 10 of the website far above). 82 is located 0x70, and that's keypad 0. The bottom half from 0x80 to 0xff is the keymap for escape scancodes that start with e0 xx (2 bytes). So what are the scancodes for Korean/English and Korean/Chinese keys? 0xf2 and 0xf1. There seems to be no room for them because first half is 0x00-0x7f and the other half is 0x80-0xff. Well, but actually there is. If you scrutinize every line of the source code (atkbd.c), you will find that

drivers/input/keyboard/atkbd.c  line : 346-347

       if (atkbd->set != 3)
               code = (code & 0x7f) | ((code & 0x80) << 1);

something like this. Basically what it does is,1. if scancode is in range 0x00~0x7f, leave it as it is. 2. if scancode is more than 0x7f, add 0x80 to it.

You may have noticed that even in the original source code, there are 65 and 99 that are out of 0x7f or 0xff. They (F7 and SysRq keys) have 0x83 and 0x84 which are also out of range and 0x80 added to them.

So all I need to do is to include those two keys appropriately in keymap. They are going to be : 0xf2 + 0x80 = 0x172 // Korean/English 0xf1 + 0x80 = 0x171 // Korean/Chinese

However, I need to delete all the exceptions about those two keys that already exist in the source code (looks like they tried to implement but stopped trying while doing it)

So the patch would look like the following.

--- a/drivers/input/keyboard/atkbd.c    2006-01-02 22:21:10.000000000 -0500
+++ b/drivers/input/keyboard/atkbd.c    2006-03-08 15:13:16.000000000 -0500
@@ -98,7 +98,14 @@ static unsigned char atkbd_set2_keycode[
         0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
       110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,

-         0,  0,  0, 65, 99,
+         0,  0,  0, 65, 99,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,123,122,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 #endif
 };

@@ -149,8 +156,6 @@ static unsigned char atkbd_unxlate_table
 #define ATKBD_RET_EMUL0                0xe0
 #define ATKBD_RET_EMUL1                0xe1
 #define ATKBD_RET_RELEASE      0xf0
-#define ATKBD_RET_HANGUEL      0xf1
-#define ATKBD_RET_HANJA                0xf2
 #define ATKBD_RET_ERR          0xff

 #define ATKBD_KEY_UNKNOWN        0
@@ -303,7 +308,6 @@ static irqreturn_t atkbd_interrupt(struc

               if (atkbd->emul ||
                   !(code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 ||
-                     code == ATKBD_RET_HANGUEL || code == ATKBD_RET_HANJA ||
                    (code == ATKBD_RET_ERR && !atkbd->err_xl) ||
                    (code == ATKBD_RET_BAT && !atkbd->bat_xl))) {
                       atkbd->release = code >> 7;
@@ -332,12 +336,6 @@ static irqreturn_t atkbd_interrupt(struc
               case ATKBD_RET_RELEASE:
                       atkbd->release = 1;
                       goto out;
-               case ATKBD_RET_HANGUEL:
-                       atkbd_report_key(atkbd->dev, regs, KEY_HANGUEL, 3);
-                       goto out;
-               case ATKBD_RET_HANJA:
-                       atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3);
-                       goto out;
               case ATKBD_RET_ERR:
                       printk(KERN_DEBUG "atkbd.c: Keyboard on %s
reports too many keys pressed.\n", serio->phys);
                       goto out;


CategoryHomepage

handrake (last edited 2008-08-06 16:26:29 by localhost)