diff --git a/configure b/configure index 3bbb9f3..2b57160 100755 --- a/configure +++ b/configure @@ -49,6 +49,7 @@ case $arg in echo "Build configuration:" echo " --with-openssl use system OpenSSL libraries for crypto" echo " --with-debug enable debugging output" + echo " --with-debug-kbd enable debugging of keyboard handling" echo rm -f Makeconf exit 1 diff --git a/keymaps/README b/keymaps/README new file mode 100644 index 0000000..eaa0845 --- /dev/null +++ b/keymaps/README @@ -0,0 +1,67 @@ +Keymap-files +============ +The keymaps are line based. There are three different types of lines: + +1) include-lines +Syntax: +include + + +2) map-lines +Syntax: +map + +Map-lines specifies how the remote RDP server should interpret the +sent scancodes. + + +3) Translation-lines +Syntax: + [flags..] + +The scancode can be found in scancodes.h. Note: The scancode value for +extended keys can be calculated by OR:ing with 0x80. Example: The +Delete key have the scancode sequence 0xe0, 0x52. You can get the +scancode value to put into the map file by running: + +python -c "print hex(0x80 | 0x52)" + +If flags are "altgr", "shift", "numlock", the scancode sent for this +keysym will be prefix with AltGr, Shift or Numlock. + +If flags include "addupper", an translation for this keysyms uppercase +name will as well, in addition to the non-uppercase name. Example: + +x 2d addupper + +...will add an translation for "X" automatically, just like if you +would specify: + +X 2d shift + + +Suggested X11 keysym mapping on PCs +=================================== +Unfortunately, there is no standard for which keysyms a given key +should generate. If you have a PC-keyboard with Windows keys, I suggest this mapping: + +Keyboard keys: +CtrlLeft WinLeft AltLeft Space AltGr WinRight Menu CtrlRight + +...should generate keysyms: +Control_L Hyper_L Alt_L space Mode_switch Hyper_R Menu Control_R + +Additionally: +Shift-Alt should produce Meta_L +Shift-AltGr should produce Multi_Key. + +Use a modifier-map like this: + +shift Shift_L (0x32), Shift_R (0x3e) +lock Caps_Lock (0x25) +control Control_L (0x42), Control_R (0x6d) +mod1 Alt_L (0x40) +mod2 Num_Lock (0x4d) +mod3 Mode_switch (0x71) +mod4 Hyper_L (0x73), Hyper_R (0x74) +mod5 Scroll_Lock (0x4e) diff --git a/keymaps/ar b/keymaps/ar index 6b8d75e..215c97a 100644 --- a/keymaps/ar +++ b/keymaps/ar @@ -1,3 +1,3 @@ # Arabic (101) include common -map 401 ar +map 0x401 diff --git a/keymaps/be b/keymaps/be index bef1bcc..f30771f 100644 --- a/keymaps/be +++ b/keymaps/be @@ -1,3 +1,3 @@ # Belarusian include common -map be 423 +map 0xbe diff --git a/keymaps/bg b/keymaps/bg index 05cd819..7b05d2a 100644 --- a/keymaps/bg +++ b/keymaps/bg @@ -1,3 +1,3 @@ # Bulgarian include common -map 402 bg +map 0x402 diff --git a/keymaps/br b/keymaps/br index 9baf6c1..0e987f3 100644 --- a/keymaps/br +++ b/keymaps/br @@ -1,3 +1,3 @@ # Portuguese (Brazilian ABNT) include common -map 416 br +map 0x416 diff --git a/keymaps/cf b/keymaps/cf index 61714bd..78d388b 100644 --- a/keymaps/cf +++ b/keymaps/cf @@ -1,3 +1,3 @@ # Canadian French (Legacy) include common -map c0c cf +map 0xc0c diff --git a/keymaps/common b/keymaps/common index 1c5273f..ff9c894 100644 --- a/keymaps/common +++ b/keymaps/common @@ -1,52 +1,139 @@ -01 Escape -0e BackSpace -0f Tab ISO_Left_Tab -1c Return -1d Control_L -2a Shift_L -36 Shift_R -37 KP_Multiply -38 Alt_L -39 space -3a Caps_Lock -3b F1 -3c F2 -3d F3 -3e F4 -3f F5 -40 F6 -41 F7 -42 F8 -43 F9 -44 F10 -45 Num_Lock -46 Scroll_Lock -47 KP_Home KP_7 -48 KP_Up KP_8 -49 KP_Prior KP_9 -4a KP_Subtract -4b KP_Left KP_4 -4c KP_Begin KP_5 -4d KP_Right KP_6 -4e KP_Add -4f KP_End KP_1 -50 KP_Down KP_2 -51 KP_Next KP_3 -52 KP_Insert KP_0 -53 KP_Delete KP_Decimal -54 Print -57 F11 -58 F12 -9c KP_Enter -9d Control_R -b8 Alt_R -c7 Home -c8 Up -c9 Prior -cb Left -cd Right -cf End -d0 Down -d1 Next -d2 Insert -d3 Delete +include modifiers + +# +# Top row +# +1 0x2 +2 0x3 +3 0x4 +4 0x5 +5 0x6 +6 0x7 +7 0x8 +8 0x9 +9 0xa +0 0xb +BackSpace 0xe + +# +# QWERTY first row +# +Tab 0xf +q 0x10 addupper +w 0x11 addupper +e 0x12 addupper +r 0x13 addupper +t 0x14 addupper +y 0x15 addupper +u 0x16 addupper +i 0x17 addupper +o 0x18 addupper +p 0x19 addupper + +# +# QWERTY second row +# +a 0x1e addupper +s 0x1f addupper +d 0x20 addupper +f 0x21 addupper +g 0x22 addupper +h 0x23 addupper +j 0x24 addupper +k 0x25 addupper +l 0x26 addupper +Return 0x1c + +# +# QWERTY third row +# +z 0x2c addupper +x 0x2d addupper +c 0x2e addupper +v 0x2f addupper +b 0x30 addupper +n 0x31 addupper +m 0x32 addupper + +space 0x39 + +# +# Esc and Function keys +# +Escape 0x1 +F1 0x3b +F2 0x3c +F3 0x3d +F4 0x3e +F5 0x3f +F6 0x40 +F7 0x41 +F8 0x42 +F9 0x43 +F10 0x44 +F11 0x57 +F12 0x58 + +# Printscreen, Scrollock and Pause +# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37), +# but (0xe0, 0x37) seems to work. +Print 0xb7 +Scroll_Lock 0x46 +# Pause requires five scancodes. TBD. + +# +# Insert - PgDown +# +Insert 0xd2 +Delete 0xd3 +Home 0xc7 +End 0xcf +Page_Up 0xc9 +Page_Down 0xd1 + +# +# Arrow keys +# +Left 0xcb +Up 0xc8 +Down 0xd0 +Right 0xcd + +# +# Numpad +# +KP_Divide 0xb5 +KP_Multiply 0x37 +KP_Subtract 0x4a +KP_Add 0x4e +KP_Enter 0x9c +KP_Decimal 0x33 + +KP_0 0x52 numlock +KP_Insert 0x52 + +KP_1 0x4f numlock +KP_End 0x4f + +KP_2 0x50 numlock +KP_Down 0x50 + +KP_3 0x51 numlock +KP_Page_Down 0x51 + +KP_4 0x4b numlock +KP_Left 0x4b + +KP_5 0x4c numlock + +KP_6 0x4d numlock +KP_Right 0x4d + +KP_7 0x47 numlock +KP_Home 0x47 + +KP_8 0x48 numlock +KP_Up 0x48 + +KP_9 0x49 numlock +KP_Page_Up 0x49 diff --git a/keymaps/convert-map b/keymaps/convert-map new file mode 100755 index 0000000..889b703 --- /dev/null +++ b/keymaps/convert-map @@ -0,0 +1,63 @@ +#!/usr/bin/env python2 +# -*-Python-*- +# +# +# Copyright (C) 2001 Peter Åstrand +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import sys + +def main(): + f = open(sys.argv[1]) + while 1: + line = f.readline() + if not line: break + + if line.startswith("#") or line.startswith("include"): + print line, + continue + + fields = line.split() + + if line.startswith("map"): + print "map 0x%s" % fields[1] + continue + + scancode = fields[0] + for pos in range(1, len(fields)): + keysym = fields[pos] + + if pos == 1: + modifiers = "" + elif pos == 2: + modifiers = "shift" + elif pos == 3: + modifiers = "altgr" + elif pos == 4: + modifiers = "shift altgr" + else: + raise("Invalid line: %s" % line) + + print "%s 0x%s %s" % (keysym, scancode, modifiers) + + + +if __name__ == "__main__": + if len(sys.argv) < 2: + print "Convert old-style keymaps to new style" + print "Usage: %s " % sys.argv[0] + sys.exit(1) + else: + main() diff --git a/keymaps/cs b/keymaps/cs index 299e2af..fa72954 100644 --- a/keymaps/cs +++ b/keymaps/cs @@ -1,3 +1,3 @@ # Czech include common -map 405 cs +map 0x405 diff --git a/keymaps/da b/keymaps/da index 2d43978..63fac84 100644 --- a/keymaps/da +++ b/keymaps/da @@ -1,3 +1,3 @@ # Danish include common -map 406 da +map 0x406 diff --git a/keymaps/de b/keymaps/de index c09e3ba..974d821 100644 --- a/keymaps/de +++ b/keymaps/de @@ -1,51 +1,109 @@ # German include common -map 407 de -02 1 exclam -03 2 quotedbl twosuperior -04 3 section threesuperior -05 4 dollar -06 5 percent -07 6 ampersand -08 7 slash braceleft -09 8 parenleft bracketleft -0a 9 parenright bracketright -0b 0 equal braceright -0c ssharp question backslash -0d apostrophe -10 q Q at -11 w W -12 e E -13 r R -14 t T -15 z Z -16 u U -17 i I -18 o O -19 p P -1a udiaeresis Udiaeresis -1b plus asterisk asciitilde -1e a A -1f s S -20 d D -21 f F -22 g G -23 h H -24 j J -25 k K -26 l L -27 odiaeresis Odiaeresis -28 adiaeresis Adiaeresis -29 asciicircum degree -2b numbersign acute -2c y Y -2d x X -2e c C -2f v V -30 b B -31 n N -32 m M mu -33 comma semicolon -34 period colon -35 minus underscore -56 less greater bar +map 0x407 +1 0x02 +exclam 0x02 shift +2 0x03 +quotedbl 0x03 shift +twosuperior 0x03 altgr +3 0x04 +section 0x04 shift +threesuperior 0x04 altgr +4 0x05 +dollar 0x05 shift +5 0x06 +percent 0x06 shift +6 0x07 +ampersand 0x07 shift +7 0x08 +slash 0x08 shift +braceleft 0x08 altgr +8 0x09 +parenleft 0x09 shift +bracketleft 0x09 altgr +9 0x0a +parenright 0x0a shift +bracketright 0x0a altgr +0 0x0b +equal 0x0b shift +braceright 0x0b altgr +ssharp 0x0c +question 0x0c shift +backslash 0x0c altgr +apostrophe 0x0d +q 0x10 +Q 0x10 shift +at 0x10 altgr +w 0x11 +W 0x11 shift +e 0x12 +E 0x12 shift +r 0x13 +R 0x13 shift +t 0x14 +T 0x14 shift +z 0x15 +Z 0x15 shift +u 0x16 +U 0x16 shift +i 0x17 +I 0x17 shift +o 0x18 +O 0x18 shift +p 0x19 +P 0x19 shift +udiaeresis 0x1a +Udiaeresis 0x1a shift +plus 0x1b +asterisk 0x1b shift +asciitilde 0x1b altgr +a 0x1e +A 0x1e shift +s 0x1f +S 0x1f shift +d 0x20 +D 0x20 shift +f 0x21 +F 0x21 shift +g 0x22 +G 0x22 shift +h 0x23 +H 0x23 shift +j 0x24 +J 0x24 shift +k 0x25 +K 0x25 shift +l 0x26 +L 0x26 shift +odiaeresis 0x27 +Odiaeresis 0x27 shift +adiaeresis 0x28 +Adiaeresis 0x28 shift +asciicircum 0x29 +degree 0x29 shift +numbersign 0x2b +acute 0x2b shift +y 0x2c +Y 0x2c shift +x 0x2d +X 0x2d shift +c 0x2e +C 0x2e shift +v 0x2f +V 0x2f shift +b 0x30 +B 0x30 shift +n 0x31 +N 0x31 shift +m 0x32 +M 0x32 shift +mu 0x32 altgr +comma 0x33 +semicolon 0x33 shift +period 0x34 +colon 0x34 shift +minus 0x35 +underscore 0x35 shift +less 0x56 +greater 0x56 shift +bar 0x56 altgr diff --git a/keymaps/dv b/keymaps/dv index 6489369..1a874a2 100644 --- a/keymaps/dv +++ b/keymaps/dv @@ -1,3 +1,3 @@ # United States-Dvorak include common -map 10409 dv +map 0x10409 diff --git a/keymaps/el b/keymaps/el index 2f7adf7..0189791 100644 --- a/keymaps/el +++ b/keymaps/el @@ -1,3 +1,3 @@ # Greek include common -map 408 el +map 0x408 diff --git a/keymaps/en b/keymaps/en index b0fa3c7..f4f536e 100644 --- a/keymaps/en +++ b/keymaps/en @@ -1,8 +1,13 @@ # English include us -map 809 en -03 2 quotedbl -04 3 sterling -28 apostrophe at -2b numbersign asciitilde -56 backslash bar +map 0x809 +2 0x03 +quotedbl 0x03 shift +3 0x04 +sterling 0x04 shift +apostrophe 0x28 +at 0x28 shift +numbersign 0x2b +asciitilde 0x2b shift +backslash 0x56 +bar 0x56 shift diff --git a/keymaps/es b/keymaps/es index 1ada5fd..e7e4a05 100644 --- a/keymaps/es +++ b/keymaps/es @@ -1,3 +1,3 @@ # Spanish include common -map 40a es +map 0x40a diff --git a/keymaps/et b/keymaps/et index d941048..4f6ec9e 100644 --- a/keymaps/et +++ b/keymaps/et @@ -1,3 +1,3 @@ # Estonian include common -map 425 et +map 0x425 diff --git a/keymaps/fi b/keymaps/fi index 477e8f6..5c0eca1 100644 --- a/keymaps/fi +++ b/keymaps/fi @@ -1,3 +1,3 @@ # Finnish include common -map 40b fi +map 0x40b diff --git a/keymaps/fo b/keymaps/fo index f857520..2e742d8 100644 --- a/keymaps/fo +++ b/keymaps/fo @@ -1,3 +1,3 @@ # Faeroese include common -map 438 fo +map 0x438 diff --git a/keymaps/fr b/keymaps/fr index e0eb5ae..33e69dc 100644 --- a/keymaps/fr +++ b/keymaps/fr @@ -1,50 +1,109 @@ # French include common -map 40c fr -02 ampersand 1 -03 eacute 2 asciitilde -04 quotedbl 3 numbersign -05 apostrophe 4 braceleft -06 parenleft 5 bracketleft -07 minus 6 bar -08 egrave 7 grave -09 underscore 8 backslash -0a ccedilla 9 asciicircum -0b agrave 0 at -0c parenright degree bracketright -0d equal plus braceright -10 a A -11 z Z -12 e E -13 r R -14 t T -15 y Y -16 u U -17 i I -18 o O -19 p P -1a diaeresis -1b dollar sterling currency -1e q Q -1f s S ssharp -20 d D -21 f F -22 g G -23 h H -24 j J -25 k K -26 l L -27 m M -28 ugrave percent -29 asterisk mu -2c w W -2d x X -2e c C -2f v V -30 b B -31 n N -32 comma question -33 semicolon period -34 colon slash -35 exclam section -56 less greater +map 0x40c +ampersand 0x02 +1 0x02 shift +eacute 0x03 +2 0x03 shift +asciitilde 0x03 altgr +quotedbl 0x04 +3 0x04 shift +numbersign 0x04 altgr +apostrophe 0x05 +4 0x05 shift +braceleft 0x05 altgr +parenleft 0x06 +5 0x06 shift +bracketleft 0x06 altgr +minus 0x07 +6 0x07 shift +bar 0x07 altgr +egrave 0x08 +7 0x08 shift +grave 0x08 altgr +underscore 0x09 +8 0x09 shift +backslash 0x09 altgr +ccedilla 0x0a +9 0x0a shift +asciicircum 0x0a altgr +agrave 0x0b +0 0x0b shift +at 0x0b altgr +parenright 0x0c +degree 0x0c shift +bracketright 0x0c altgr +equal 0x0d +plus 0x0d shift +braceright 0x0d altgr +a 0x10 +A 0x10 shift +z 0x11 +Z 0x11 shift +e 0x12 +E 0x12 shift +r 0x13 +R 0x13 shift +t 0x14 +T 0x14 shift +y 0x15 +Y 0x15 shift +u 0x16 +U 0x16 shift +i 0x17 +I 0x17 shift +o 0x18 +O 0x18 shift +p 0x19 +P 0x19 shift +diaeresis 0x1a +dollar 0x1b +sterling 0x1b shift +currency 0x1b altgr +q 0x1e +Q 0x1e shift +s 0x1f +S 0x1f shift +ssharp 0x1f altgr +d 0x20 +D 0x20 shift +f 0x21 +F 0x21 shift +g 0x22 +G 0x22 shift +h 0x23 +H 0x23 shift +j 0x24 +J 0x24 shift +k 0x25 +K 0x25 shift +l 0x26 +L 0x26 shift +m 0x27 +M 0x27 shift +ugrave 0x28 +percent 0x28 shift +asterisk 0x29 +mu 0x29 shift +w 0x2c +W 0x2c shift +x 0x2d +X 0x2d shift +c 0x2e +C 0x2e shift +v 0x2f +V 0x2f shift +b 0x30 +B 0x30 shift +n 0x31 +N 0x31 shift +comma 0x32 +question 0x32 shift +semicolon 0x33 +period 0x33 shift +colon 0x34 +slash 0x34 shift +exclam 0x35 +section 0x35 shift +less 0x56 +greater 0x56 shift diff --git a/keymaps/ga b/keymaps/ga index 2a5639a..1b70999 100644 --- a/keymaps/ga +++ b/keymaps/ga @@ -1,3 +1,3 @@ # Irish include common -map 1809 ga +map 0x1809 diff --git a/keymaps/gd b/keymaps/gd index 4b0ccbc..1e70fe1 100644 --- a/keymaps/gd +++ b/keymaps/gd @@ -1,3 +1,3 @@ # Gaelic include common -map 11809 gd +map 0x11809 diff --git a/keymaps/he b/keymaps/he index 7c2bbf3..cc91679 100644 --- a/keymaps/he +++ b/keymaps/he @@ -1,3 +1,3 @@ # Hebrew include common -map 40d he +map 0x40d diff --git a/keymaps/hi b/keymaps/hi index cd3cef4..304fce6 100644 --- a/keymaps/hi +++ b/keymaps/hi @@ -1,3 +1,3 @@ # Hindi Traditional include common -map 10439 hi +map 0x10439 diff --git a/keymaps/hr b/keymaps/hr index 72a86af..2ea9353 100644 --- a/keymaps/hr +++ b/keymaps/hr @@ -1,3 +1,3 @@ # Croatian include common -map 41a hr +map 0x41a diff --git a/keymaps/hu b/keymaps/hu index 4026089..e1adda7 100644 --- a/keymaps/hu +++ b/keymaps/hu @@ -1,3 +1,3 @@ # Hungarian include common -map 40e hu +map 0x40e diff --git a/keymaps/is b/keymaps/is index a299f68..6cdf7be 100644 --- a/keymaps/is +++ b/keymaps/is @@ -1,3 +1,3 @@ # Icelandic include common -map 40f is +map 0x40f diff --git a/keymaps/it b/keymaps/it index d8a8988..1a6371c 100644 --- a/keymaps/it +++ b/keymaps/it @@ -1,3 +1,3 @@ # Italian include common -map 410 it +map 0x410 diff --git a/keymaps/ja b/keymaps/ja index 255cddf..4a882c3 100644 --- a/keymaps/ja +++ b/keymaps/ja @@ -1,3 +1,3 @@ # Japanese include common -map 411 ja +map 0x411 diff --git a/keymaps/ka b/keymaps/ka index 2829d74..fabc67c 100644 --- a/keymaps/ka +++ b/keymaps/ka @@ -1,3 +1,3 @@ # Georgian include common -map 437 ka +map 0x437 diff --git a/keymaps/kk b/keymaps/kk index 6c31a69..d2979ef 100644 --- a/keymaps/kk +++ b/keymaps/kk @@ -1,3 +1,3 @@ # Kazakh include common -map 43f kk +map 0x43f diff --git a/keymaps/ko b/keymaps/ko index d72bbe9..cb8830a 100644 --- a/keymaps/ko +++ b/keymaps/ko @@ -1,3 +1,3 @@ # Korean(Hangul) include common -map 412 ko +map 0x412 diff --git a/keymaps/la b/keymaps/la index 846bdb0..d9001e0 100644 --- a/keymaps/la +++ b/keymaps/la @@ -1,3 +1,3 @@ # Latin American include common -map 80a la +map 0x80a diff --git a/keymaps/lt b/keymaps/lt index 7266f25..acaa7f4 100644 --- a/keymaps/lt +++ b/keymaps/lt @@ -1,3 +1,3 @@ # Lithuanian include common -map 10427 +map 0x10427 diff --git a/keymaps/lv b/keymaps/lv index ff14547..9fcace0 100644 --- a/keymaps/lv +++ b/keymaps/lv @@ -1,3 +1,3 @@ # Latvian include common -map 426 lv +map 0x426 diff --git a/keymaps/mk b/keymaps/mk index f48ca8b..855961a 100644 --- a/keymaps/mk +++ b/keymaps/mk @@ -1,3 +1,3 @@ # Macedonian (FYROM) include common -map 42f mk +map 0x42f diff --git a/keymaps/modifiers b/keymaps/modifiers new file mode 100644 index 0000000..19f04d2 --- /dev/null +++ b/keymaps/modifiers @@ -0,0 +1,24 @@ +Shift_R 36 +Shift_L 2a + +Alt_R 0xb8 +Mode_switch 0xb8 +Alt_L 0x38 + +Control_R 0x9d +Control_L 0x1d + +Num_Lock 0x45 + +# Translate Meta, Super and Hyper to Windows key +# For some reason, these are broken, it seems. +Meta_L 0xdb +Super_L 0xdb +Hyper_L 0xdb +Meta_R 0xdc +Super_R 0xdc +Hyper_R 0xdc + +# Translate Menu to the Windows Application key. +# This one does not work either. +Menu 0xdd diff --git a/keymaps/mr b/keymaps/mr index c800e00..d25f172 100644 --- a/keymaps/mr +++ b/keymaps/mr @@ -1,3 +1,3 @@ # Marathi include common -map 44e mr +map 0x44e diff --git a/keymaps/nl b/keymaps/nl index 808ac08..85520c9 100644 --- a/keymaps/nl +++ b/keymaps/nl @@ -1,3 +1,3 @@ # Dutch include common -map 413 nl +map 0x413 diff --git a/keymaps/no b/keymaps/no index e790de3..56631e3 100644 --- a/keymaps/no +++ b/keymaps/no @@ -1,3 +1,3 @@ # Norwegian include common -map 414 no +map 0x414 diff --git a/keymaps/pl b/keymaps/pl index adfd805..269e741 100644 --- a/keymaps/pl +++ b/keymaps/pl @@ -1,3 +1,3 @@ # Polish (Programmers) include common -map 415 pl +map 0x415 diff --git a/keymaps/pt b/keymaps/pt index 21d2003..345e8fd 100644 --- a/keymaps/pt +++ b/keymaps/pt @@ -1,3 +1,3 @@ # Portuguese include common -map 816 pt +map 0x816 diff --git a/keymaps/ro b/keymaps/ro index 8b994e9..8dfcc9a 100644 --- a/keymaps/ro +++ b/keymaps/ro @@ -1,3 +1,3 @@ # Romanian include common -map 418 ro +map 0x418 diff --git a/keymaps/ru b/keymaps/ru index 527279c..ffa7692 100644 --- a/keymaps/ru +++ b/keymaps/ru @@ -1,3 +1,3 @@ # Russian include common -map 419 ru +map 0x419 diff --git a/keymaps/sf b/keymaps/sf index 1a8c206..71ebda8 100644 --- a/keymaps/sf +++ b/keymaps/sf @@ -1,3 +1,3 @@ # Swiss French include common -map 100c sf +map 0x100c diff --git a/keymaps/sg b/keymaps/sg index 00d4121..d25b73e 100644 --- a/keymaps/sg +++ b/keymaps/sg @@ -1,3 +1,3 @@ # Swiss German include common -map 807 sg +map 0x807 diff --git a/keymaps/sk b/keymaps/sk index 1156934..3116b80 100644 --- a/keymaps/sk +++ b/keymaps/sk @@ -1,3 +1,3 @@ # Slovak include common -map 41b sk +map 0x41b diff --git a/keymaps/sl b/keymaps/sl index f9b3eea..47176cd 100644 --- a/keymaps/sl +++ b/keymaps/sl @@ -1,3 +1,3 @@ # Slovenian include common -map 424 sl +map 0x424 diff --git a/keymaps/sq b/keymaps/sq index 3e0e1eb..86ebaa4 100644 --- a/keymaps/sq +++ b/keymaps/sq @@ -1,3 +1,3 @@ # Albanian include common -map 41c sq +map 0x41c diff --git a/keymaps/sr b/keymaps/sr index 37a2d95..c2c7736 100644 --- a/keymaps/sr +++ b/keymaps/sr @@ -1,3 +1,3 @@ # Serbian (Latin) include common -map 81a sr +map 0x81a diff --git a/keymaps/sv b/keymaps/sv index d3ce92d..9cfe9eb 100644 --- a/keymaps/sv +++ b/keymaps/sv @@ -1,3 +1,78 @@ -# Swedish +map 0x0000041d include common -map 41d sv + +# +# Top row +# +section 0x29 +onehalf 0x29 shift + +# 1 +exclam 0x2 shift + +# 2 +quotedbl 0x3 shift +at 0x3 altgr + +# 3 +numbersign 0x4 shift +sterling 0x4 altgr +# 4 +currency 0x5 shift +dollar 0x5 altgr +# 5 +percent 0x6 shift +# 6 +ampersand 0x7 shift +# 7 +slash 0x8 shift +braceleft 0x8 altgr +# 8 +parenleft 0x9 shift +bracketleft 0x9 altgr +# 9 +parenright 0xa shift +bracketright 0xa altgr +# 0 +equal 0xb shift +braceright 0xb altgr + +plus 0xc +question 0xc shift +backslash 0xc altgr + +dead_acute 0xd +dead_grave 0xd shift + +# +# QWERTY first row +# +EuroSign 0x12 altgr +aring 0x1a +Aring 0x1a shift +dead_diaeresis 0x1b +dead_circumflex 0x1b shift +dead_tilde 0x1b altgr + +# +# QWERTY second row +# +odiaeresis 0x27 +Odiaeresis 0x27 shift +adiaeresis 0x28 +Adiaeresis 0x28 shift +apostrophe 0x2b +asterisk 0x2b shift + +# +# QWERTY third row +# +less 0x56 +greater 0x56 shift +bar 0x56 altgr +comma 0x33 +semicolon 0x33 shift +period 0x34 +colon 0x34 shift +minus 0x35 +underscore 0x35 shift diff --git a/keymaps/ta b/keymaps/ta index 6693b2e..bcbfb97 100644 --- a/keymaps/ta +++ b/keymaps/ta @@ -1,3 +1,3 @@ # Tamil include common -map 449 ta +map 0x449 diff --git a/keymaps/th b/keymaps/th index de1b136..c572af0 100644 --- a/keymaps/th +++ b/keymaps/th @@ -1,3 +1,3 @@ # Thai Kedmanee include common -map 41e th +map 0x41e diff --git a/keymaps/tr b/keymaps/tr index dc02929..1d2c77a 100644 --- a/keymaps/tr +++ b/keymaps/tr @@ -1,3 +1,3 @@ # Turkish F include common -map 1041f tr +map 0x1041f diff --git a/keymaps/tt b/keymaps/tt index 296b1f5..6f110ed 100644 --- a/keymaps/tt +++ b/keymaps/tt @@ -1,3 +1,3 @@ # Tatar include common -map 444 tt +map 0x444 diff --git a/keymaps/uk b/keymaps/uk index dccaba9..e977adb 100644 --- a/keymaps/uk +++ b/keymaps/uk @@ -1,3 +1,3 @@ # Ukrainian include common -map 422 uk +map 0x422 diff --git a/keymaps/us b/keymaps/us index 9297b98..d5953de 100644 --- a/keymaps/us +++ b/keymaps/us @@ -1,50 +1,34 @@ -# US +map 0x00000808 include common -map 409 us -02 1 exclam -03 2 at -04 3 numbersign -05 4 dollar -06 5 percent -07 6 asciicircum -08 7 ampersand -09 8 asterisk -0a 9 parenleft -0b 0 parenright -0c minus underscore -0d equal plus -10 q Q -11 w W -12 e E -13 r R -14 t T -15 y Y -16 u U -17 i I -18 o O -19 p P -1a bracketleft braceleft -1b bracketright braceright -1e a A -1f s S -20 d D -21 f F -22 g G -23 h H -24 j J -25 k K -26 l L -27 semicolon colon -28 apostrophe quotedbl -29 grave asciitilde -2b backslash bar -2c z Z -2d x X -2e c C -2f v V -30 b B -31 n N -32 m M -33 comma less -34 period greater -35 slash question +grave 0x29 +asciitilde 0x29 shift +exclam 0x02 shift +at 0x03 shift +numbersign 0x04 shift +dollar 0x05 shift +percent 0x06 shift +asciicircum 0x07 shift +ampersand 0x08 shift +asterisk 0x09 shift +parenleft 0x0a shift +parenright 0x0b shift +minus 0x0c +underscore 0x0c shift +equal 0x0d +plus 0x0d shift +bracketleft 0x1a +braceleft 0x1a shift +bracketright 0x1b +braceright 0x1b shift +backslash 0x2b +bar 0x2b shift +semicolon 0x27 +colon 0x27 shift +apostrophe 0x28 +quotedbl 0x28 shift +comma 0x33 +less 0x33 shift +period 0x34 +greater 0x34 shift +slash 0x35 +question 0x35 shift diff --git a/keymaps/uz b/keymaps/uz index 8a0b80b..43d2c22 100644 --- a/keymaps/uz +++ b/keymaps/uz @@ -1,3 +1,3 @@ # Uzbek Cyrillic include common -map 843 uz +map 0x843 diff --git a/keymaps/vi b/keymaps/vi index 7abc656..85acecd 100644 --- a/keymaps/vi +++ b/keymaps/vi @@ -1,3 +1,3 @@ # Vietnamese include common -map 42a vi +map 0x42a diff --git a/keymaps/zh b/keymaps/zh index 2fe3c94..8cefb12 100644 --- a/keymaps/zh +++ b/keymaps/zh @@ -1,3 +1,3 @@ # Chinese (Traditional) - US Keyboard include common -map 404 zh +map 0x404 diff --git a/proto.h b/proto.h index 7fbefe7..1958b3b 100644 --- a/proto.h +++ b/proto.h @@ -70,10 +70,14 @@ STREAM tcp_recv(int length); BOOL tcp_connect(char *server); void tcp_disconnect(void); /* xkeymap.c */ -void xkeymap_init(void); -uint8 xkeymap_translate_key(unsigned int keysym, unsigned int keycode, - uint16 * flags); +void xkeymap_init1(void); +void xkeymap_init2(void); +key_translation xkeymap_translate_key(KeySym keysym, unsigned int keycode); uint16 xkeymap_translate_button(unsigned int button); +char *get_ksname(KeySym keysym); +BOOL inhibit_key(KeySym keysym); +void ensure_remote_modifiers(uint32 ev_time, key_translation tr); +void rdp_send_scancode(uint32 time, uint16 flags, uint16 scancode); /* xwin.c */ BOOL ui_create_window(char *title); void ui_destroy_window(void); diff --git a/rdesktop.c b/rdesktop.c index 6a903e4..e651bd8 100644 --- a/rdesktop.c +++ b/rdesktop.c @@ -32,7 +32,7 @@ char username[16]; char hostname[16]; char keymapname[16]; -int keylayout; +int keylayout = 0x409; /* Defaults to US keyboard layout */ int width; int height; int tcp_port_rdp = TCP_PORT_RDP; @@ -55,7 +55,7 @@ usage(char *program) printf(" -c: working directory\n"); printf(" -p: password (autologon)\n"); printf(" -n: client hostname\n"); - printf(" -k: keyboard layout\n"); + printf(" -k: keyboard layout on terminal server (us,sv,gr etc.)\n"); printf(" -g: desktop geometry (WxH)\n"); printf(" -f: full-screen mode\n"); printf(" -b: force bitmap updates\n"); @@ -222,6 +222,8 @@ main(int argc, char *argv[]) strcpy(title, "rdesktop - "); strncat(title, server, sizeof(title) - sizeof("rdesktop - ")); + xkeymap_init1(); + if (!rdp_connect(server, flags, domain, password, shell, directory)) return 1; diff --git a/rdesktop.h b/rdesktop.h index bfda5c8..e4bd2a8 100644 --- a/rdesktop.h +++ b/rdesktop.h @@ -21,6 +21,7 @@ #include #include #include +#include #define VERSION "1.1.0" @@ -30,6 +31,12 @@ #define DEBUG(args) #endif +#if defined(WITH_DEBUG_KBD) +#define DEBUG_KBD(args...) fprintf(stderr, args); +#else +#define DEBUG_KBD(args...) +#endif + #define STRNCPY(dst,src,n) { strncpy(dst,src,n-1); dst[n-1] = 0; } #include "constants.h" diff --git a/scancodes.h b/scancodes.h new file mode 100644 index 0000000..cd286b9 --- /dev/null +++ b/scancodes.h @@ -0,0 +1,378 @@ + +/* Two defines for every scancode: + One called SCANCODE_KEY_, where is the key location number. + One called SCANCODE_CHAR_, where is the + unshifted character on a US 101/102 keyboard. See the Microsoft + document "Keyboard Scan Code Specification" for more information. + + Up keys normally have scancode values +0x80. + + 0x0: Avoid + 0x1- 0x59: Normal + 0x60, 0x61: Avoid, since the up key would be 0xe1, 0xe1 + 0x61 - 0x79: Normal + 0xfa - : keyboard drivers interpret these as responses from the 8042 chip + + We use bit 7 to indicate 0xe0 prefix instead of two-byte sequence (0xe0, something). Eq., + 0xe 0x38 is defined as (0x80 | 0x38) +*/ + +/* FIXME: + Special keys like Numeric / are very complicated and emits many scancodes. +*/ + +#define SCANCODE_EXTENDED 0x80 + +#define SCANCODE_KEY_1 0x29 +#define SCANCODE_CHAR_GRAVE 0x29 + +#define SCANCODE_KEY_2 0x2 +#define SCANCODE_CHAR_1 SCANCODE_KEY_2 + +#define SCANCODE_KEY_3 0x3 +#define SCANCODE_CHAR_2 SCANCODE_KEY_3 + +#define SCANCODE_KEY_4 0x4 +#define SCANCODE_CHAR_3 SCANCODE_KEY_4 + +#define SCANCODE_KEY_5 0x5 +#define SCANCODE_CHAR_4 SCANCODE_KEY_5 + +#define SCANCODE_KEY_6 0x6 +#define SCANCODE_CHAR_5 SCANCODE_KEY_6 + +#define SCANCODE_KEY_7 0x7 +#define SCANCODE_CHAR_6 SCANCODE_KEY_7 + +#define SCANCODE_KEY_8 0x8 +#define SCANCODE_CHAR_7 SCANCODE_KEY_8 + +#define SCANCODE_KEY_9 0x9 +#define SCANCODE_CHAR_8 SCANCODE_KEY_9 + +#define SCANCODE_KEY_10 0xa +#define SCANCODE_CHAR_9 SCANCODE_KEY_10 + +#define SCANCODE_KEY_11 0xb +#define SCANCODE_CHAR_0 SCANCODE_KEY_11 + +#define SCANCODE_KEY_12 0xc +#define SCANCODE_CHAR_MINUS SCANCODE_KEY_12 + +#define SCANCODE_KEY_13 0xd +#define SCANCODE_CHAR_EQUAL SCANCODE_KEY_13 + +/* Key 14 does not exist */ + +#define SCANCODE_KEY_15 0xe +#define SCANCODE_CHAR_BACKSPACE SCANCODE_KEY_15 + +#define SCANCODE_KEY_16 0xf +#define SCANCODE_CHAR_TAB SCANCODE_KEY_16 + +#define SCANCODE_KEY_17 0x10 +#define SCANCODE_CHAR_Q SCANCODE_KEY_17 + +#define SCANCODE_KEY_18 0x11 +#define SCANCODE_CHAR_W SCANCODE_KEY_18 + +#define SCANCODE_KEY_19 0x12 +#define SCANCODE_CHAR_E SCANCODE_KEY_19 + +#define SCANCODE_KEY_20 0x13 +#define SCANCODE_CHAR_R SCANCODE_KEY_20 + +#define SCANCODE_KEY_21 0x14 +#define SCANCODE_CHAR_T SCANCODE_KEY_21 + +#define SCANCODE_KEY_22 0x15 +#define SCANCODE_CHAR_Y SCANCODE_KEY_22 + +#define SCANCODE_KEY_23 0x16 +#define SCANCODE_CHAR_U SCANCODE_KEY_23 + +#define SCANCODE_KEY_24 0x17 +#define SCANCODE_CHAR_I SCANCODE_KEY_24 + +#define SCANCODE_KEY_25 0x18 +#define SCANCODE_CHAR_O SCANCODE_KEY_25 + +#define SCANCODE_KEY_26 0x19 +#define SCANCODE_CHAR_P SCANCODE_KEY_26 + +#define SCANCODE_KEY_27 0x1a +#define SCANCODE_CHAR_BRACKETLEFT SCANCODE_KEY_27 + +#define SCANCODE_KEY_28 0x1b +#define SCANCODE_CHAR_BRACKETRIGHT SCANCODE_KEY_28 + +/* Only on US keyboard */ +#define SCANCODE_KEY_29 0x2b +#define SCANCODE_CHAR_BACKSPACE SCANCODE_KEY_291 + +#define SCANCODE_KEY_30 0x3a +#define SCANCODE_CHAR_CAPSLOCK SCANCODE_KEY_30 + +#define SCANCODE_KEY_31 0x1e +#define SCANCODE_CHAR_A SCANCODE_KEY_31 + +#define SCANCODE_KEY_32 0x1f +#define SCANCODE_CHAR_S SCANCODE_KEY_32 + +#define SCANCODE_KEY_33 0x20 +#define SCANCODE_CHAR_D SCANCODE_KEY_33 + +#define SCANCODE_KEY_34 0x21 +#define SCANCODE_CHAR_F SCANCODE_KEY_34 + +#define SCANCODE_KEY_35 0x22 +#define SCANCODE_CHAR_G SCANCODE_KEY_35 + +#define SCANCODE_KEY_36 0x23 +#define SCANCODE_CHAR_H SCANCODE_KEY_36 + +#define SCANCODE_KEY_37 0x24 +#define SCANCODE_CHAR_J SCANCODE_KEY_37 + +#define SCANCODE_KEY_38 0x25 +#define SCANCODE_CHAR_K SCANCODE_KEY_38 + +#define SCANCODE_KEY_39 0x26 +#define SCANCODE_CHAR_L SCANCODE_KEY_39 + +#define SCANCODE_KEY_40 0x27 +#define SCANCODE_CHAR_SEMICOLON SCANCODE_KEY_40 + +#define SCANCODE_KEY_41 0x28 +#define SCANCODE_CHAR_APOSTROPHE SCANCODE_KEY_41 + +/* Only on international keyboard */ +#define SCANCODE_KEY_42 0x2b + +#define SCANCODE_KEY_43 0x1c +#define SCANCODE_CHAR_ENTER SCANCODE_KEY_43 + +#define SCANCODE_KEY_44 0x2a +#define SCANCODE_CHAR_LSHIFT SCANCODE_KEY_44 + +/* Only on international keyboard */ +#define SCANCODE_KEY_45 0x56 + +#define SCANCODE_KEY_46 0x2c +#define SCANCODE_CHAR_Z SCANCODE_KEY_46 + +#define SCANCODE_KEY_47 0x2d +#define SCANCODE_CHAR_X SCANCODE_KEY_47 + +#define SCANCODE_KEY_48 0x2e +#define SCANCODE_CHAR_C SCANCODE_KEY_48 + +#define SCANCODE_KEY_49 0x2f +#define SCANCODE_CHAR_V SCANCODE_KEY_49 + +#define SCANCODE_KEY_50 0x30 +#define SCANCODE_CHAR_B SCANCODE_KEY_50 + +#define SCANCODE_KEY_51 0x31 +#define SCANCODE_CHAR_N SCANCODE_KEY_51 + +#define SCANCODE_KEY_52 0x32 +#define SCANCODE_CHAR_M SCANCODE_KEY_52 + +#define SCANCODE_KEY_53 0x33 +#define SCANCODE_CHAR_COMMA SCANCODE_KEY_53 + +#define SCANCODE_KEY_54 0x34 +#define SCANCODE_CHAR_DOT SCANCODE_KEY_54 + +#define SCANCODE_KEY_55 0x35 +#define SCANCODE_CHAR_SLASH SCANCODE_KEY_55 + +/* Only on Brazilian and some Far East keyboards */ +#define SCANCODE_KEY_56 0x73 + +#define SCANCODE_KEY_57 0x36 +#define SCANCODE_CHAR_RSHIFT SCANCODE_KEY_57 + +#define SCANCODE_KEY_58 0x1d +#define SCANCODE_CHAR_LCTRL SCANCODE_KEY_58 + +/* Key 59 does not exist */ + +#define SCANCODE_KEY_60 0x38 +#define SCANCODE_CHAR_LALT SCANCODE_KEY_60 + +#define SCANCODE_KEY_61 0x39 +#define SCANCODE_CHAR_SPACE SCANCODE_KEY_61 + +#define SCANCODE_KEY_62 (SCANCODE_EXTENDED | 0x38) +#define SCANCODE_CHAR_RALT SCANCODE_KEY_62 + +/* Key 63 does not exist */ + +#define SCANCODE_KEY_64 (SCANCODE_EXTENDED | 0x1d) +#define SCANCODE_CHAR_RCTRL SCANCODE_KEY_64 + +/* Key 65 - 74 does not exist */ + +#define SCANCODE_KEY_75 (SCANCODE_EXTENDED | 0x52) +#define SCANCODE_CHAR_INSERT SCANCODE_KEY_75 + +#define SCANCODE_KEY_76 (SCANCODE_EXTENDED | 0x53) +#define SCANCODE_CHAR_DELETE SCANCODE_KEY_76 + +/* Key 77 - 78 does not exist */ + +#define SCANCODE_KEY_79 (SCANCODE_EXTENDED | 0x4b) +#define SCANCODE_CHAR_LARROW SCANCODE_KEY_79 + +#define SCANCODE_KEY_80 (SCANCODE_EXTENDED | 0x47) +#define SCANCODE_CHAR_HOME SCANCODE_KEY_80 + +#define SCANCODE_KEY_81 (SCANCODE_EXTENDED | 0x4f) +#define SCANCODE_CHAR_END SCANCODE_KEY_81 + +/* Key 82 does not exist */ + +#define SCANCODE_KEY_83 (SCANCODE_EXTENDED | 0x48) +#define SCANCODE_CHAR_UPARROW SCANCODE_KEY_82 + +#define SCANCODE_KEY_84 (SCANCODE_EXTENDED | 0x50) +#define SCANCODE_CHAR_DNARROW SCANCODE_KEY_84 + +#define SCANCODE_KEY_85 (SCANCODE_EXTENDED | 0x49) +#define SCANCODE_CHAR_PAGEUP SCANCODE_KEY_85 + +#define SCANCODE_KEY_86 (SCANCODE_EXTENDED | 0x51) +#define SCANCODE_CHAR_PAGEDOWN SCANCODE_KEY_86 + +/* Key 87 - 88 does not exist */ + +#define SCANCODE_KEY_89 (SCANCODE_EXTENDED | 0x4d) +#define SCANCODE_CHAR_RARROW SCANCODE_KEY_89 + +#define SCANCODE_KEY_90 0x45 +#define SCANCODE_CHAR_NUMLOCK SCANCODE_KEY_90 + +#define SCANCODE_KEY_91 0x47 +#define SCANCODE_CHAR_NUMERIC7 SCANCODE_KEY_91 + +#define SCANCODE_KEY_92 0x4b +#define SCANCODE_CHAR_NUMERIC4 SCANCODE_KEY_92 + +#define SCANCODE_KEY_93 0x4f +#define SCANCODE_CHAR_NUMERIC1 SCANCODE_KEY_93 + +/* Key 94 does not exist */ + +#define SCANCODE_KEY_95 (SCANCODE_EXTENDED | 0x35) +#define SCANCODE_CHAR_NUMERICSLASH SCANCODE_KEY_95 + +#define SCANCODE_KEY_96 0x48 +#define SCANCODE_CHAR_NUMERIC8 SCANCODE_KEY_96 + +#define SCANCODE_KEY_97 0x4c +#define SCANCODE_CHAR_NUMERIC5 SCANCODE_KEY_97 + +#define SCANCODE_KEY_98 0x50 +#define SCANCODE_CHAR_NUMERIC2 SCANCODE_KEY_98 + +#define SCANCODE_KEY_99 0x52 +#define SCANCODE_CHAR_NUMERIC0 SCANCODE_KEY_99 + +#define SCANCODE_KEY_100 0x37 +#define SCANCODE_CHAR_NUMERICSTAR SCANCODE_KEY_100 + +#define SCANCODE_KEY_101 0x49 +#define SCANCODE_CHAR_NUMERIC9 SCANCODE_KEY_101 + +#define SCANCODE_KEY_102 0x4d +#define SCANCODE_CHAR_NUMERIC6 SCANCODE_KEY_102 + +#define SCANCODE_KEY_103 0x51 +#define SCANCODE_CHAR_NUMERIC3 SCANCODE_KEY_103 + +#define SCANCODE_KEY_104 0x53 +#define SCANCODE_CHAR_NUMERICDOT SCANCODE_KEY_104 + +#define SCANCODE_KEY_105 0x4a +#define SCANCODE_CHAR_NUMERICMINUS SCANCODE_KEY_105 + +#define SCANCODE_KEY_106 0x4e +#define SCANCODE_CHAR_NUMERICPLUS SCANCODE_KEY_106 + +/* Only on Brazilian and some Far East keyboards */ +#define SCANCODE_KEY_107 0x + +#define SCANCODE_KEY_108 (SCANCODE_EXTENDED | 0x1c) +#define SCANCODE_CHAR_NUMERICENTER SCANCODE_KEY_108 + +/* Key 109 does not exist */ + +#define SCANCODE_KEY_110 0x1 +#define SCANCODE_CHAR_ESC SCANCODE_KEY_109 + +/* Key 111 does not exist */ + +#define SCANCODE_KEY_112 0x3b +#define SCANCODE_CHAR_F1 SCANCODE_KEY_112 + +#define SCANCODE_KEY_113 0x3c +#define SCANCODE_CHAR_F2 SCANCODE_KEY_113 + +#define SCANCODE_KEY_114 0x3d +#define SCANCODE_CHAR_F3 SCANCODE_KEY_114 + +#define SCANCODE_KEY_115 0x3e +#define SCANCODE_CHAR_F4 SCANCODE_KEY_115 + +#define SCANCODE_KEY_116 0x3f +#define SCANCODE_CHAR_F5 SCANCODE_KEY_116 + +#define SCANCODE_KEY_117 0x40 +#define SCANCODE_CHAR_F6 SCANCODE_KEY_117 + +#define SCANCODE_KEY_118 0x41 +#define SCANCODE_CHAR_F7 SCANCODE_KEY_118 + +#define SCANCODE_KEY_119 0x42 +#define SCANCODE_CHAR_F8 SCANCODE_KEY_119 + +#define SCANCODE_KEY_120 0x43 +#define SCANCODE_CHAR_F9 SCANCODE_KEY_120 + +#define SCANCODE_KEY_121 0x44 +#define SCANCODE_CHAR_F10 SCANCODE_KEY_121 + +#define SCANCODE_KEY_122 0x57 +#define SCANCODE_CHAR_F11 SCANCODE_KEY_122 + +#define SCANCODE_KEY_123 0x58 +#define SCANCODE_CHAR_F12 SCANCODE_KEY_123 + +/* FIXME */ +#define SCANCODE_KEY_124 0x0 +#define SCANCODE_CHAR_PRINTSCREEN SCANCODE_KEY_124 + +#define SCANCODE_KEY_125 0x46 +#define SCANCODE_CHAR_SCROLLLOCK SCANCODE_KEY_125 + +/* FIXME */ +#define SCANCODE_KEY_126 0x0 +#define SCANCODE_CHAR_PAUSE SCANCODE_KEY_125 + +/* + The keys below does not have any key location number +*/ + +#define SCANCODE_CHAR_LWIN (SCANCODE_EXTENDED | 0x5b) + +#define SCANCODE_CHAR_RWIN (SCANCODE_EXTENDED | 0x5c) + +#define SCANCODE_CHAR_APPLICATION (SCANCODE_EXTENDED | 0x5d) + +#define SCANCODE_CHAR_ACPIPOWER (SCANCODE_EXTENDED | 0x5e) + +#define SCANCODE_CHAR_ACPISLEEP (SCANCODE_EXTENDED | 0x5f) + +#define SCANCODE_CHAR_ACPIWAKE (SCANCODE_EXTENDED | 0x63) diff --git a/types.h b/types.h index 67bce3f..a3cd408 100644 --- a/types.h +++ b/types.h @@ -98,3 +98,10 @@ typedef struct _DATABLOB } DATABLOB; + +typedef struct _key_translation +{ + uint8 scancode; + uint16 modifiers; +} +key_translation; diff --git a/xkeymap.c b/xkeymap.c index 774a7ab..f5818b7 100644 --- a/xkeymap.c +++ b/xkeymap.c @@ -23,27 +23,58 @@ #include #include #include +#include #include #include "rdesktop.h" +#include "scancodes.h" #define KEYMAP_SIZE 4096 #define KEYMAP_MASK (KEYMAP_SIZE - 1) +#define KEYMAP_MAX_LINE_LENGTH 80 extern Display *display; extern char keymapname[16]; extern int keylayout; -static uint8 keymap[KEYMAP_SIZE]; +static key_translation keymap[KEYMAP_SIZE]; static unsigned int min_keycode; +static uint16 remote_modifier_state = 0; + +static void +add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname) +{ + KeySym keysym; + + keysym = XStringToKeysym(keyname); + if (keysym == NoSymbol) + { + error("Bad keysym %s in keymap %s\n", keyname, mapname); + return; + } + + DEBUG_KBD("Adding translation, keysym=0x%x, scancode=0x%x, " + "modifiers=0x%x\n", (unsigned int) keysym, scancode, + modifiers); + + keymap[keysym & KEYMAP_MASK].scancode = scancode; + keymap[keysym & KEYMAP_MASK].modifiers = modifiers; + + return; +} + static BOOL xkeymap_read(char *mapname) { FILE *fp; - char line[PATH_MAX], path[PATH_MAX]; + char line[KEYMAP_MAX_LINE_LENGTH], path[PATH_MAX]; + unsigned int line_num = 0; + unsigned int line_length = 0; char *keyname, *p; - KeySym keysym; - unsigned char keycode; + char *line_rest; + uint8 scancode; + uint16 modifiers; + strcpy(path, KEYMAP_PATH); strncat(path, mapname, sizeof(path) - sizeof(KEYMAP_PATH)); @@ -55,45 +86,93 @@ xkeymap_read(char *mapname) return False; } + /* FIXME: More tolerant on white space */ while (fgets(line, sizeof(line), fp) != NULL) { + line_num++; + + /* Replace the \n with \0 */ p = strchr(line, '\n'); if (p != NULL) *p = 0; - keycode = strtol(line, &keyname, 16); - if ((keycode != 0) && (*keyname == ' ')) + line_length = strlen(line); + + /* Completely empty line */ + if (strspn(line, " \t\n\r\f\v") == line_length) { - do - { - keyname++; - p = strchr(keyname, ' '); - if (p != NULL) - *p = 0; - - keysym = XStringToKeysym(keyname); - if (keysym == NoSymbol) - error("Bad keysym %s in keymap %s\n", - keyname, mapname); - - keymap[keysym & KEYMAP_MASK] = keycode; - keyname = p; - - } - while (keyname != NULL); + continue; } - else if (strncmp(line, "include ", 8) == 0) + + /* Include */ + if (strncmp(line, "include ", 8) == 0) { if (!xkeymap_read(line + 8)) return False; + continue; } - else if (strncmp(line, "map ", 4) == 0) + + /* map */ + if (strncmp(line, "map ", 4) == 0) { keylayout = strtol(line + 4, NULL, 16); + DEBUG_KBD("Keylayout 0x%x\n", keylayout); + continue; } - else if (line[0] != '#') + + /* Comment */ + if (line[0] == '#') { - error("Malformed line in keymap %s\n", mapname); + continue; + } + + /* Normal line */ + keyname = line; + p = strchr(line, ' '); + if (p == NULL) + { + error("Bad line %d in keymap %s\n", line_num, + mapname); + continue; + } + else + { + *p = 0; + } + + /* scancode */ + p++; + scancode = strtol(p, &line_rest, 16); + + /* flags */ + /* FIXME: Should allow case-insensitive flag names. + Fix by using lex+yacc... */ + modifiers = 0; + if (strstr(line_rest, "altgr")) + { + MASK_ADD_BITS(modifiers, MapAltGrMask); + } + + if (strstr(line_rest, "shift")) + { + MASK_ADD_BITS(modifiers, MapLeftShiftMask); + } + + if (strstr(line_rest, "numlock")) + { + MASK_ADD_BITS(modifiers, MapNumLockMask); + } + + add_to_keymap(keyname, scancode, modifiers, mapname); + + if (strstr(line_rest, "addupper")) + { + /* Automatically add uppercase key, with same modifiers + plus shift */ + for (p = keyname; *p; p++) + *p = toupper(*p); + MASK_ADD_BITS(modifiers, MapLeftShiftMask); + add_to_keymap(keyname, scancode, modifiers, mapname); } } @@ -101,82 +180,66 @@ xkeymap_read(char *mapname) return True; } -void -xkeymap_init(void) -{ - unsigned int max_keycode; - XDisplayKeycodes(display, &min_keycode, &max_keycode); +/* Before connecting and creating UI */ +void +xkeymap_init1(void) +{ + int i; + + /* Zeroing keymap */ + for (i = 0; i < KEYMAP_SIZE; i++) + { + keymap[i].scancode = 0; + keymap[i].modifiers = 0; + } if (strcmp(keymapname, "none")) + { xkeymap_read(keymapname); + } + } -uint8 -xkeymap_translate_key(unsigned int keysym, unsigned int keycode, - uint16 * flags) +/* After connecting and creating UI */ +void +xkeymap_init2(void) { - uint8 scancode; + unsigned int max_keycode; + XDisplayKeycodes(display, &min_keycode, &max_keycode); +} - scancode = keymap[keysym & KEYMAP_MASK]; - if (scancode != 0) + +key_translation +xkeymap_translate_key(KeySym keysym, unsigned int keycode) +{ + key_translation tr = { 0, 0 }; + + tr = keymap[keysym & KEYMAP_MASK]; + + if (tr.scancode != 0) { - if (scancode & 0x80) - *flags |= KBD_FLAG_EXT; - - return (scancode & 0x7f); + DEBUG_KBD + ("Found key translation, scancode=0x%x, modifiers=0x%x\n", + tr.scancode, tr.modifiers); + return tr; } + printf("No translation for (keysym 0x%lx, %s)\n", keysym, + get_ksname(keysym)); + /* not in keymap, try to interpret the raw scancode */ - if ((keycode >= min_keycode) && (keycode <= 0x60)) - return (uint8) (keycode - min_keycode); - - *flags |= KBD_FLAG_EXT; - - switch (keycode) { - case 0x61: /* home */ - return 0x47; - case 0x62: /* up arrow */ - return 0x48; - case 0x63: /* page up */ - return 0x49; - case 0x64: /* left arrow */ - return 0x4b; - case 0x66: /* right arrow */ - return 0x4d; - case 0x67: /* end */ - return 0x4f; - case 0x68: /* down arrow */ - return 0x50; - case 0x69: /* page down */ - return 0x51; - case 0x6a: /* insert */ - return 0x52; - case 0x6b: /* delete */ - return 0x53; - case 0x6c: /* keypad enter */ - return 0x1c; - case 0x6d: /* right ctrl */ - return 0x1d; - case 0x6f: /* ctrl - print screen */ - return 0x37; - case 0x70: /* keypad '/' */ - return 0x35; - case 0x71: /* right alt */ - return 0x38; - case 0x72: /* ctrl break */ - return 0x46; - case 0x73: /* left window key */ - return 0x5b; - case 0x74: /* right window key */ - return 0x5c; - case 0x75: /* menu key */ - return 0x5d; + tr.scancode = keycode - min_keycode; + printf("Sending guessed scancode 0x%x\n", tr.scancode); + } + else + { + printf("No good guess for keycode 0x%x found\n", keycode); } - return 0; + return tr; } uint16 @@ -190,11 +253,204 @@ xkeymap_translate_button(unsigned int button) return MOUSE_FLAG_BUTTON3; case Button3: /* right */ return MOUSE_FLAG_BUTTON2; - case Button4: /* wheel up */ - return MOUSE_FLAG_BUTTON4; - case Button5: /* wheel down */ - return MOUSE_FLAG_BUTTON5; } return 0; } + +char * +get_ksname(KeySym keysym) +{ + char *ksname = NULL; + + if (keysym == NoSymbol) + ksname = "NoSymbol"; + else if (!(ksname = XKeysymToString(keysym))) + ksname = "(no name)"; + + return ksname; +} + +BOOL +inhibit_key(KeySym keysym) +{ + switch (keysym) + { + case XK_Caps_Lock: + return True; + break; + case XK_Multi_key: + return True; + break; + default: + break; + } + return False; +} + +void +ensure_remote_modifiers(uint32 ev_time, key_translation tr) +{ + /* If this key is a modifier, do nothing */ + switch (tr.scancode) + { + case SCANCODE_CHAR_LSHIFT: + case SCANCODE_CHAR_RSHIFT: + case SCANCODE_CHAR_LCTRL: + case SCANCODE_CHAR_RCTRL: + case SCANCODE_CHAR_LALT: + case SCANCODE_CHAR_RALT: + case SCANCODE_CHAR_LWIN: + case SCANCODE_CHAR_RWIN: + case SCANCODE_CHAR_NUMLOCK: + return; + default: + break; + } + + /* Shift */ + if (MASK_HAS_BITS(tr.modifiers, MapShiftMask) + != MASK_HAS_BITS(remote_modifier_state, MapShiftMask)) + { + /* The remote modifier state is not correct */ + if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)) + { + /* Needs this modifier. Send down. */ + rdp_send_scancode(ev_time, RDP_KEYPRESS, + SCANCODE_CHAR_LSHIFT); + } + else + { + /* Should not use this modifier. Send up. */ + rdp_send_scancode(ev_time, RDP_KEYRELEASE, + SCANCODE_CHAR_LSHIFT); + } + } + + /* AltGr */ + if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask) + != MASK_HAS_BITS(remote_modifier_state, MapAltGrMask)) + { + /* The remote modifier state is not correct */ + if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask)) + { + /* Needs this modifier. Send down. */ + rdp_send_scancode(ev_time, RDP_KEYPRESS, + SCANCODE_CHAR_RALT); + } + else + { + /* Should not use this modifier. Send up. */ + rdp_send_scancode(ev_time, RDP_KEYRELEASE, + SCANCODE_CHAR_RALT); + } + } + + /* NumLock */ + if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask) + != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask)) + { + /* The remote modifier state is not correct */ + DEBUG_KBD("Remote NumLock state is incorrect. Toggling\n"); + if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)) + { + /* Needs this modifier. Toggle */ + rdp_send_scancode(ev_time, RDP_KEYPRESS, + SCANCODE_CHAR_NUMLOCK); + rdp_send_scancode(ev_time, RDP_KEYRELEASE, + SCANCODE_CHAR_NUMLOCK); + } + else + { + /* Should not use this modifier. Toggle */ + rdp_send_scancode(ev_time, RDP_KEYPRESS, + SCANCODE_CHAR_NUMLOCK); + rdp_send_scancode(ev_time, RDP_KEYRELEASE, + SCANCODE_CHAR_NUMLOCK); + } + } + +} + + +static void +update_modifier_state(uint16 modifiers, BOOL pressed) +{ + + DEBUG_KBD("Before updating modifier_state:0x%x, pressed=0x%x\n", + remote_modifier_state, pressed); + switch (modifiers) + { + case SCANCODE_CHAR_LSHIFT: + MASK_CHANGE_BIT(remote_modifier_state, + MapLeftShiftMask, pressed); + break; + case SCANCODE_CHAR_RSHIFT: + MASK_CHANGE_BIT(remote_modifier_state, + MapRightShiftMask, pressed); + break; + case SCANCODE_CHAR_LCTRL: + MASK_CHANGE_BIT(remote_modifier_state, + MapLeftCtrlMask, pressed); + break; + case SCANCODE_CHAR_RCTRL: + MASK_CHANGE_BIT(remote_modifier_state, + MapRightCtrlMask, pressed); + break; + case SCANCODE_CHAR_LALT: + MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, + pressed); + break; + case SCANCODE_CHAR_RALT: + MASK_CHANGE_BIT(remote_modifier_state, + MapRightAltMask, pressed); + break; + case SCANCODE_CHAR_LWIN: + MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, + pressed); + break; + case SCANCODE_CHAR_RWIN: + MASK_CHANGE_BIT(remote_modifier_state, + MapRightWinMask, pressed); + break; + case SCANCODE_CHAR_NUMLOCK: + /* KeyReleases for NumLocks are sent immediately. Toggle the + modifier state only on Keypress */ + if (pressed) + { + BOOL newNumLockState; + newNumLockState = + (MASK_HAS_BITS + (remote_modifier_state, + MapNumLockMask) == False); + MASK_CHANGE_BIT(remote_modifier_state, + MapNumLockMask, + newNumLockState); + } + break; + } + DEBUG_KBD("After updating modifier_state:0x%x\n", + remote_modifier_state); + +} + +/* Send keyboard input */ +void +rdp_send_scancode(uint32 time, uint16 flags, uint16 scancode) +{ + update_modifier_state(scancode, !(flags & RDP_KEYRELEASE)); + + if (scancode & SCANCODE_EXTENDED) + { + DEBUG_KBD("Sending extended scancode=0x%x, flags=0x%x\n", + scancode & ~SCANCODE_EXTENDED, flags); + rdp_send_input(time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT, + scancode & ~SCANCODE_EXTENDED, 0); + } + else + { + DEBUG_KBD("Sending scancode=0x%x, flags=0x%x\n", scancode, + flags); + rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0); + } +} diff --git a/xwin.c b/xwin.c index 247e99c..e5b30bc 100644 --- a/xwin.c +++ b/xwin.c @@ -20,20 +20,18 @@ #include #include -#include #include #include +#define XK_MISCELLANY +#include #include "rdesktop.h" -extern char keymapname[16]; -extern int keylayout; extern int width; extern int height; extern BOOL sendmotion; extern BOOL fullscreen; -Display *display; -XkbDescPtr xkb; +Display *display = NULL; static int x_socket; static Window wnd; static GC gc; @@ -49,23 +47,6 @@ static BOOL xserver_be; static BOOL ownbackstore; static Pixmap backstore; -/* needed to keep track of the modifiers */ -static unsigned int numlock_modifier_mask = 0; -static unsigned int key_down_state = 0; - - -#define DShift1Mask (1<<0) -#define DLockMask (1<<1) -#define DControl1Mask (1<<2) -#define DMod1Mask (1<<3) -#define DMod2Mask (1<<4) -#define DMod3Mask (1<<5) -#define DMod4Mask (1<<6) -#define DMod5Mask (1<<7) -#define DShift2Mask (1<<8) -#define DControl2Mask (1<<9) -#define DNumLockMask (1<<10) - #define FILL_RECTANGLE(x,y,cx,cy)\ { \ XFillRectangle(display, wnd, gc, x, y, cx, cy); \ @@ -78,6 +59,8 @@ static BOOL owncolmap; static Colormap xcolmap; static uint32 white; static uint32 *colmap; +static XIM IM = NULL; +static XIC IC = NULL; #define TRANSLATE(col) ( owncolmap ? col : translate_colour(colmap[col]) ) #define SET_FOREGROUND(col) XSetForeground(display, gc, TRANSLATE(col)); @@ -105,11 +88,6 @@ static int rop2_map[] = { #define SET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); } #define RESET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); } -void xwin_get_numlock_mask(); -void xwin_mod_update(uint32 state, uint32 ev_time); -void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode); -void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode); - static void translate8(uint8 * data, uint8 * out, uint8 * end) { @@ -204,6 +182,61 @@ translate_colour(uint32 colour) return colour; } +static unsigned long +init_inputmethod(void) +{ + unsigned long filtered_events; + + IM = XOpenIM(display, NULL, NULL, NULL); + if (IM == NULL) + { + error("Failed to open input method\n"); + } + + if (IM != NULL) + { + /* Must be done after XCreateWindow */ + IC = XCreateIC(IM, XNInputStyle, + (XIMPreeditNothing | XIMStatusNothing), + XNClientWindow, wnd, XNFocusWindow, wnd, NULL); + + if (IC == NULL) + { + error("Failed to create input context\n"); + XCloseIM(IM); + IM = NULL; + } + } + + /* For correct Multi_key/Compose processing, I guess. + It seems to work alright anyway, though. */ + if (IC != NULL) + { + if (XGetICValues(IC, XNFilterEvents, &filtered_events, NULL) + != NULL) + { + error("Failed to obtain XNFilterEvents value from IC\n"); + filtered_events = 0; + } + } + return filtered_events; +} + +static void +close_inputmethod(void) +{ + if (IC != NULL) + { + XDestroyIC(IC); + if (IM != NULL) + { + XCloseIM(IM); + IM = NULL; + } + } +} + + BOOL ui_create_window(char *title) { @@ -215,41 +248,9 @@ ui_create_window(char *title) Screen *screen; uint16 test; int i; + unsigned long filtered_events; - int xkb_minor, xkb_major; - int xkb_event, xkb_error, xkb_reason; - - /* compare compiletime libs with runtime libs. */ - xkb_major = XkbMajorVersion; - xkb_minor = XkbMinorVersion; - if (XkbLibraryVersion(&xkb_major, &xkb_minor) == False) - { - error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n"); - return False; - } - - - display = - XkbOpenDisplay(NULL, &xkb_event, &xkb_error, &xkb_major, - &xkb_minor, &xkb_reason); - switch (xkb_reason) - { - case XkbOD_BadLibraryVersion: - error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n"); - break; - case XkbOD_ConnectionRefused: - error("XkbOD_ConnectionRefused\n"); - break; - case XkbOD_BadServerVersion: - error("XkbOD_BadServerVersion\n"); - break; - case XkbOD_NonXkbServer: - error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n"); - break; - case XkbOD_Success: - DEBUG("XkbOD_Success: Connection established with display\n"); - break; - } + display = XOpenDisplay(NULL); if (display == NULL) { @@ -340,18 +341,21 @@ ui_create_window(char *title) XFree(sizehints); } - xkeymap_init(); + xkeymap_init2(); - input_mask = KeyPressMask | KeyReleaseMask | - ButtonPressMask | ButtonReleaseMask | - EnterWindowMask | LeaveWindowMask; + input_mask = + KeyPressMask | KeyReleaseMask | ButtonPressMask | + ButtonReleaseMask | EnterWindowMask | LeaveWindowMask; if (sendmotion) input_mask |= PointerMotionMask; if (ownbackstore) input_mask |= ExposureMask; - XSelectInput(display, wnd, input_mask); + filtered_events = init_inputmethod(); + + XSelectInput(display, wnd, input_mask | filtered_events); + gc = XCreateGC(display, wnd, 0, NULL); if (ownbackstore) @@ -359,86 +363,19 @@ ui_create_window(char *title) XMapWindow(display, wnd); - /* TODO: error texts... make them friendly. */ - xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd); - if ((int) xkb == BadAlloc || xkb == NULL) - { - error("XkbGetKeyboard failed.\n"); - exit(0); - } - - /* TODO: error texts... make them friendly. */ - if (XkbSelectEvents - (display, xkb->device_spec, XkbAllEventsMask, - XkbAllEventsMask) == False) - { - error("XkbSelectEvents failed.\n"); - exit(0); - } - - xwin_get_numlock_mask(); - return True; } -void -xwin_get_numlock_mask() -{ - KeyCode numlockcode; - KeyCode *keycode; - XModifierKeymap *modmap; - int i, j; - - /* Find out if numlock is already defined as a modifier key, and if so where */ - numlockcode = XKeysymToKeycode(display, 0xFF7F); /* XF_Num_Lock = 0xFF7F */ - if (numlockcode) - { - modmap = XGetModifierMapping(display); - if (modmap) - { - keycode = modmap->modifiermap; - for (i = 0; i < 8; i++) - for (j = modmap->max_keypermod; j--;) - { - if (*keycode == numlockcode) - { - numlock_modifier_mask = - (1 << i); - i = 8; - break; - } - keycode++; - } - if (!numlock_modifier_mask) - { - modmap->modifiermap[7 * - modmap->max_keypermod] = - numlockcode; - if (XSetModifierMapping(display, modmap) == - MappingSuccess) - numlock_modifier_mask = (1 << 7); - else - printf("XSetModifierMapping failed!\n"); - } - XFreeModifiermap(modmap); - } - } - - if (!numlock_modifier_mask) - printf("WARNING: Failed to get a numlock modifier mapping.\n"); - -} - void ui_destroy_window() { - if (xkb != NULL) - XkbFreeKeyboard(xkb, XkbAllControlsMask, True); - if (ownbackstore) XFreePixmap(display, backstore); XFreeGC(display, gc); + + close_inputmethod(); + XDestroyWindow(display, wnd); XCloseDisplay(display); display = NULL; @@ -450,48 +387,105 @@ xwin_process_events() XEvent xevent; KeySym keysym; - uint8 scancode; uint16 button, flags; uint32 ev_time; - uint32 tmpmods; + key_translation tr; + char *ksname = NULL; + char str[256]; + Status status; + + /* Refresh keyboard mapping if it has changed. This is important for + Xvnc, since it allocates keycodes dynamically */ + if (XCheckTypedEvent(display, MappingNotify, &xevent)) + { + if (xevent.xmapping.request == MappingKeyboard + || xevent.xmapping.request == MappingModifier) + XRefreshKeyboardMapping(&xevent.xmapping); + } while (XCheckMaskEvent(display, ~0, &xevent)) { + if (XFilterEvent(&xevent, None) == True) + { + DEBUG_KBD("Filtering event\n"); + continue; + } + ev_time = time(NULL); flags = 0; switch (xevent.type) { - case KeyRelease: - flags = KBD_FLAG_DOWN | KBD_FLAG_UP; - /* fall through */ case KeyPress: - if (XkbTranslateKeyCode - (xkb, xevent.xkey.keycode, - xevent.xkey.state, &tmpmods, - &keysym) == False) - break; - scancode = - xkeymap_translate_key(keysym, - xevent.xkey. - keycode, - &flags); + if (IC != NULL) + /* Multi_key compatible version */ + { + XmbLookupString(IC, + (XKeyPressedEvent *) & + xevent, str, + sizeof(str), &keysym, + &status); + if (! + ((status == XLookupKeySym) + || (status == XLookupBoth))) + { + error("XmbLookupString failed with status 0x%x\n", status); + break; + } + } + else + { + /* Plain old XLookupString */ + DEBUG_KBD + ("No input context, using XLookupString\n"); + XLookupString((XKeyEvent *) & xevent, + str, sizeof(str), + &keysym, NULL); + } - if (scancode == 0) + ksname = get_ksname(keysym); + DEBUG_KBD + ("\nKeyPress for (keysym 0x%lx, %s)\n", + keysym, ksname); + + if (inhibit_key(keysym)) + { + DEBUG_KBD("Inhibiting key\n"); + break; + } + + tr = xkeymap_translate_key(keysym, + xevent.xkey. + keycode); + ensure_remote_modifiers(ev_time, tr); + + if (tr.scancode == 0) break; - /* keep track of the modifiers -- needed for stickykeys... */ - if (xevent.type == KeyPress) - xwin_mod_press(xevent.xkey.state, - ev_time, scancode); + rdp_send_scancode(ev_time, RDP_KEYPRESS, + tr.scancode); + break; + case KeyRelease: + XLookupString((XKeyEvent *) & xevent, str, + sizeof(str), &keysym, NULL); - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, - flags, scancode, 0); + ksname = get_ksname(keysym); + DEBUG_KBD + ("\nKeyRelease for (keysym 0x%lx, %s)\n", + keysym, ksname); - if (xevent.type == KeyRelease) - xwin_mod_release(xevent.xkey.state, - ev_time, scancode); + if (inhibit_key(keysym)) + break; + tr = xkeymap_translate_key(keysym, + xevent.xkey. + keycode); + + if (tr.scancode == 0) + break; + + rdp_send_scancode(ev_time, RDP_KEYRELEASE, + tr.scancode); break; case ButtonPress: @@ -522,9 +516,6 @@ xwin_process_events() XGrabKeyboard(display, wnd, True, GrabModeAsync, GrabModeAsync, CurrentTime); - - xwin_mod_update(xevent.xcrossing.state, - ev_time); break; case LeaveNotify: @@ -542,178 +533,6 @@ xwin_process_events() } } -void -xwin_mod_update(uint32 state, uint32 ev_time) -{ - xwin_mod_press(state, ev_time, 0); - xwin_mod_release(state, ev_time, 0); -} - -void -xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode) -{ - switch (scancode) - { - case 0x2a: - key_down_state &= ~DShift1Mask; - break; - case 0x36: - key_down_state &= ~DShift2Mask; - break; - case 0x1d: - key_down_state &= ~DControl1Mask; - break; - case 0x9d: - key_down_state &= ~DControl2Mask; - break; - case 0x38: - key_down_state &= ~DMod1Mask; - break; - case 0xb8: - key_down_state &= ~DMod2Mask; - break; - } - - if (!(numlock_modifier_mask & state) - && (key_down_state & DNumLockMask)) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0); - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, - KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0); - key_down_state &= ~DNumLockMask; - } - - if (!(LockMask & state) && (key_down_state & DLockMask)) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0); - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, - KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0); - key_down_state &= ~DLockMask; - - } - - - if (!(ShiftMask & state) && (key_down_state & DShift1Mask)) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a, - 0); - key_down_state &= ~DShift1Mask; - - } - - if (!(ControlMask & state) && (key_down_state & DControl1Mask)) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d, - 0); - key_down_state &= ~DControl1Mask; - - } - - if (!(Mod1Mask & state) && (key_down_state & DMod1Mask)) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38, - 0); - key_down_state &= ~DMod1Mask; - - } - - if (!(Mod2Mask & state) && (key_down_state & DMod2Mask)) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8, - 0); - key_down_state &= ~DMod2Mask; - } -} - - -void -xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode) -{ - - switch (scancode) - { - case 0x2a: - key_down_state |= DShift1Mask; - break; - case 0x36: - key_down_state |= DShift2Mask; - break; - case 0x1d: - key_down_state |= DControl1Mask; - break; - case 0x9d: - key_down_state |= DControl2Mask; - break; - case 0x3a: - key_down_state ^= DLockMask; - break; - case 0x45: - key_down_state ^= DNumLockMask; - break; - case 0x38: - key_down_state |= DMod1Mask; - break; - case 0xb8: - key_down_state |= DMod2Mask; - break; - } - - if ((numlock_modifier_mask && state) - && !(key_down_state & DNumLockMask)) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0); - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, - KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0); - key_down_state |= DNumLockMask; - } - - if ((LockMask & state) && !(key_down_state & DLockMask)) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0); - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, - KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0); - key_down_state |= DLockMask; - - } - - - if ((ShiftMask & state) - && !((key_down_state & DShift1Mask) - || (key_down_state & DShift2Mask))) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, - 0x2a, 0); - key_down_state |= DShift1Mask; - - } - - if ((ControlMask & state) - && !((key_down_state & DControl1Mask) - || (key_down_state & DControl2Mask))) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, - 0x1d, 0); - key_down_state |= DControl1Mask; - - } - - if ((Mod1Mask & state) && !(key_down_state & DMod1Mask)) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, - 0x38, 0); - key_down_state |= DMod1Mask; - - } - - if ((Mod2Mask & state) && !(key_down_state & DMod2Mask)) - { - rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, - 0xb8, 0); - key_down_state |= DMod2Mask; - - } -} - void ui_select(int rdp_socket) { @@ -764,8 +583,8 @@ ui_create_bitmap(int width, int height, uint8 * data) tdata = (owncolmap ? data : translate_image(width, height, data)); bitmap = XCreatePixmap(display, wnd, width, height, depth); - image = XCreateImage(display, visual, depth, ZPixmap, - 0, tdata, width, height, 8, 0); + image = XCreateImage(display, visual, depth, ZPixmap, 0, tdata, width, + height, 8, 0); XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height); @@ -776,15 +595,15 @@ ui_create_bitmap(int width, int height, uint8 * data) } void -ui_paint_bitmap(int x, int y, int cx, int cy, - int width, int height, uint8 * data) +ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, + uint8 * data) { XImage *image; uint8 *tdata; tdata = (owncolmap ? data : translate_image(width, height, data)); - image = XCreateImage(display, visual, depth, ZPixmap, - 0, tdata, width, height, 8, 0); + image = XCreateImage(display, visual, depth, ZPixmap, 0, tdata, width, + height, 8, 0); if (ownbackstore) { @@ -820,8 +639,8 @@ ui_create_glyph(int width, int height, uint8 * data) bitmap = XCreatePixmap(display, wnd, width, height, 1); gc = XCreateGC(display, bitmap, 0, NULL); - image = XCreateImage(display, visual, 1, ZPixmap, 0, - data, width, height, 8, scanline); + image = XCreateImage(display, visual, 1, ZPixmap, 0, data, width, + height, 8, scanline); image->byte_order = MSBFirst; image->bitmap_bit_order = MSBFirst; XInitImage(image); @@ -840,8 +659,8 @@ ui_destroy_glyph(HGLYPH glyph) } HCURSOR -ui_create_cursor(unsigned int x, unsigned int y, int width, - int height, uint8 * andmask, uint8 * xormask) +ui_create_cursor(unsigned int x, unsigned int y, int width, int height, + uint8 * andmask, uint8 * xormask) { HGLYPH maskglyph, cursorglyph; XColor bg, fg; @@ -899,8 +718,9 @@ ui_create_cursor(unsigned int x, unsigned int y, int width, cursorglyph = ui_create_glyph(width, height, cursor); maskglyph = ui_create_glyph(width, height, mask); - xcursor = XCreatePixmapCursor(display, (Pixmap) cursorglyph, - (Pixmap) maskglyph, &fg, &bg, x, y); + xcursor = + XCreatePixmapCursor(display, (Pixmap) cursorglyph, + (Pixmap) maskglyph, &fg, &bg, x, y); ui_destroy_glyph(maskglyph); ui_destroy_glyph(cursorglyph); @@ -1084,8 +904,8 @@ ui_screenblt(uint8 opcode, SET_FUNCTION(opcode); XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y); if (ownbackstore) - XCopyArea(display, backstore, backstore, gc, srcx, srcy, - cx, cy, x, y); + XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, + cy, x, y); RESET_FUNCTION(opcode); } @@ -1115,16 +935,16 @@ ui_triblt(uint8 opcode, { case 0x69: /* PDSxxn */ ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy); - ui_patblt(ROP2_NXOR, x, y, cx, cy, - brush, bgcolour, fgcolour); + ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, + fgcolour); break; case 0xb8: /* PSDPxax */ - ui_patblt(ROP2_XOR, x, y, cx, cy, - brush, bgcolour, fgcolour); + ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, + fgcolour); ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy); - ui_patblt(ROP2_XOR, x, y, cx, cy, - brush, bgcolour, fgcolour); + ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, + fgcolour); break; case 0xc0: /* PSa */ @@ -1164,14 +984,15 @@ ui_rect( void ui_draw_glyph(int mixmode, /* dest */ int x, int y, int cx, int cy, - /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour, - int fgcolour) + /* src */ HGLYPH glyph, int srcx, int srcy, + int bgcolour, int fgcolour) { SET_FOREGROUND(fgcolour); SET_BACKGROUND(bgcolour); - XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT) - ? FillStippled : FillOpaqueStippled); + XSetFillStyle(display, gc, + (mixmode == + MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled); XSetStipple(display, gc, (Pixmap) glyph); XSetTSOrigin(display, gc, x, y); @@ -1214,8 +1035,8 @@ ui_draw_glyph(int mixmode, void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y, - int clipx, int clipy, int clipcx, int clipcy, int boxx, - int boxy, int boxcx, int boxcy, int bgcolour, + int clipx, int clipy, int clipcx, int clipcy, + int boxx, int boxy, int boxcx, int boxcy, int bgcolour, int fgcolour, uint8 * text, uint8 length) { FONTGLYPH *glyph; @@ -1312,8 +1133,8 @@ ui_desktop_save(uint32 offset, int x, int y, int cx, int cy) } offset *= bpp / 8; - cache_put_desktop(offset, cx, cy, image->bytes_per_line, - bpp / 8, (uint8 *) image->data); + cache_put_desktop(offset, cx, cy, image->bytes_per_line, bpp / 8, + (uint8 *) image->data); XDestroyImage(image); } @@ -1329,9 +1150,8 @@ ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy) if (data == NULL) return; - image = XCreateImage(display, visual, depth, ZPixmap, - 0, data, cx, cy, BitmapPad(display), - cx * bpp / 8); + image = XCreateImage(display, visual, depth, ZPixmap, 0, data, cx, cy, + BitmapPad(display), cx * bpp / 8); if (ownbackstore) {