编写:Ove K鍁en <ovek@winehq.com>
(提取自 wine/documentation/keyboard)
现在 Wine 需要知道你的键盘布局(layout)。这个要求来自一些应用程序的需求,它们需要获得正确的键盘扫描码,原因是它们直接读取这些扫描码,而不是接受从 X 服务器返回的字符。这意味着 Wine 现在需要有一个从 X 键到这些程序所需要的扫描码的映射。
在启动的时候,Wine 尝试着识别活跃的 X 布局,方法是查看它是否匹配任何定义的表。如果是,所有的事情都正常。如果不是,你需要定义它。
要想定义它,打开文件 windows/x11drv/keyboard.c 并查看现存的表。复制它做为一个备份,特别是在你不是使用 CVS 的时候。
你实际上需要做的是找出每个键需要生成的那个扫描码。在 main_key_scan 表中查看,它看起来如下:
static const int main_key_scan[MAIN_LEN] = { /* 这是我的 (102-键) 键盘布局,如果不匹配你的键盘是很遗憾的 */ 0x29,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B, 0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x2B, 0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35, 0x56 /* 第 102 个键(实际上在 l-shift 的右边) */ }; static const char main_key_US_phantom[MAIN_LEN][4] = { "`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+", "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}", "aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|", "zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?", "<>" /* 幽灵键 */ }; |
接着,把印在按键上的字符赋予每个扫描码。这为 US 101 键键盘(的次序)做的。它可以在 keyboard.c 的顶部找到。它还显示了如果没有第 102 键,你可以跳过它。
但是,对于多数国际化的 102 键键盘,我们使它易于你的使用。这些键盘的扫描码布局已经非常匹配在 main_key_scan 中的物理键盘布局了,所以你要做的所有事情就是完成在你主键盘上生成字符的所有的键(除了空格键之外),并把它们组织到一个适当的表中。只有第 102 个键是个例外,它通常在最后一行的第一个字符的左边(通常是 Z),它必须放到在最后一行之后的单独一行中。
例如,我的挪威(Norwegian)键盘看起来如下
? ! " # ? % & / ( ) = ? ` Back- | 1 2@ 3?4$ 5 6 7{ 8[ 9] 0} + \?space Tab Q W E R T Y U I O P ? ^ ▇ Enter Caps A S D F G H J K L ? ? * Lock ' Sh- > Z X C V B N M ; : _ Shift ift < , . - Ctrl Alt Spacebar AltGr Ctrl |
注意第 102 个键,它是 <> 键,在 Z 的左边。在主字符右侧的那个字符是由 AltGr 键生成的字符。
定义这个键盘如下:
static const char main_key_NO[MAIN_LEN][4] = { "|?,"1!","2\"@","3#?,"4?","5%","6&","7/{","8([","9)]","0=}","+?","\\?, "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","迮","╚~", "aA","sS","dD","fF","gG","hH","jJ","kK","lL","","嫫","'*", "zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_", "<>" }; |
除了 " 和 \ 需要用反斜杠引用起来,和第 102 个键在单独的一行之外,它是非常直接的。
你写完了一个这样的表之后,你需要把它添加到 main_key_tab[] 布局索引表中。这看起来如下:
static struct { WORD lang, ansi_codepage, oem_codepage; const char (*key)[MAIN_LEN][4]; } main_key_tab[]={ ... ... {MAKELANGID(LANG_NORWEGIAN,SUBLANG_DEFAULT), 1252, 865, &main_key_NO}, ... |
在你增加了这个表之后,重新编译 Wine 并测试它的工作。如果检测你的表失败,尝试运行
wine --debugmsg +key,+keyboard >& key.log |
并查看结果的 key.log 文件来找到关于你的布局的错误消息。
注意 LANG_* 和 SUBLANG_* 定义在 include/winnls.h 中,你可能需要用它找出给你的语言分配的编号,并在调试消息输出中找到它。这个编号是(SUBLANG * 0x400 + LANG),所以,例如 LANG_NORWEGIAN (0x14) 和 SUBLANG_DEFAULT (0x1) 的组合将是 (十六进制的) 14 + 1*400 = 414,因为我是挪威人,我将在调试消息输出中查找 0414 以便找出为什么不能检测到我的键盘。
一旦它工作了,请提交到 Wine 计划。如果你使用 CVS,你需要在你的主 Wine 目录中做
cvs -z3 diff -u windows/x11drv/keyboard.c > layout.diff |
,接着把 layout.diff 提交到 <wine-patches@winehq.com> 并加上关于它是什么的一个简要的说明。
如果你不使用 CVS,你需要做
diff -u the_backup_file_you_made windows/x11drv/keyboard.c > layout.diff |
并按上面解说的那样提交。
如果你做的正确,它将被包括到下一次 Wine 发行中,而所有使用扫描码的有问题的应用程序(尤其是远程控制应用程序)和游戏将荣幸的使用你键盘布局,并且你将不再得到这些闹心的 fixme 消息了。
祝你好运。