Merged new keysym-based keyboard handling (from alt. CVS repos)
git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@65 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
4c90d366e2
commit
2dd151bd20
1
configure
vendored
1
configure
vendored
@ -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
|
||||
|
67
keymaps/README
Normal file
67
keymaps/README
Normal file
@ -0,0 +1,67 @@
|
||||
Keymap-files
|
||||
============
|
||||
The keymaps are line based. There are three different types of lines:
|
||||
|
||||
1) include-lines
|
||||
Syntax:
|
||||
include <another-map-file>
|
||||
|
||||
|
||||
2) map-lines
|
||||
Syntax:
|
||||
map <hex-number>
|
||||
|
||||
Map-lines specifies how the remote RDP server should interpret the
|
||||
sent scancodes.
|
||||
|
||||
|
||||
3) Translation-lines
|
||||
Syntax:
|
||||
<keysym-name> <scancode> [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)
|
@ -1,3 +1,3 @@
|
||||
# Arabic (101)
|
||||
include common
|
||||
map 401 ar
|
||||
map 0x401
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Belarusian
|
||||
include common
|
||||
map be 423
|
||||
map 0xbe
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Bulgarian
|
||||
include common
|
||||
map 402 bg
|
||||
map 0x402
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Portuguese (Brazilian ABNT)
|
||||
include common
|
||||
map 416 br
|
||||
map 0x416
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Canadian French (Legacy)
|
||||
include common
|
||||
map c0c cf
|
||||
map 0xc0c
|
||||
|
191
keymaps/common
191
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
|
||||
|
63
keymaps/convert-map
Executable file
63
keymaps/convert-map
Executable file
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python2
|
||||
# -*-Python-*-
|
||||
#
|
||||
#
|
||||
# Copyright (C) 2001 Peter Åstrand <peter@cendio.se>
|
||||
#
|
||||
# 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 <old-style-keymap>" % sys.argv[0]
|
||||
sys.exit(1)
|
||||
else:
|
||||
main()
|
@ -1,3 +1,3 @@
|
||||
# Czech
|
||||
include common
|
||||
map 405 cs
|
||||
map 0x405
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Danish
|
||||
include common
|
||||
map 406 da
|
||||
map 0x406
|
||||
|
156
keymaps/de
156
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
|
||||
|
@ -1,3 +1,3 @@
|
||||
# United States-Dvorak
|
||||
include common
|
||||
map 10409 dv
|
||||
map 0x10409
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Greek
|
||||
include common
|
||||
map 408 el
|
||||
map 0x408
|
||||
|
17
keymaps/en
17
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
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Spanish
|
||||
include common
|
||||
map 40a es
|
||||
map 0x40a
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Estonian
|
||||
include common
|
||||
map 425 et
|
||||
map 0x425
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Finnish
|
||||
include common
|
||||
map 40b fi
|
||||
map 0x40b
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Faeroese
|
||||
include common
|
||||
map 438 fo
|
||||
map 0x438
|
||||
|
155
keymaps/fr
155
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
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Irish
|
||||
include common
|
||||
map 1809 ga
|
||||
map 0x1809
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Gaelic
|
||||
include common
|
||||
map 11809 gd
|
||||
map 0x11809
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Hebrew
|
||||
include common
|
||||
map 40d he
|
||||
map 0x40d
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Hindi Traditional
|
||||
include common
|
||||
map 10439 hi
|
||||
map 0x10439
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Croatian
|
||||
include common
|
||||
map 41a hr
|
||||
map 0x41a
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Hungarian
|
||||
include common
|
||||
map 40e hu
|
||||
map 0x40e
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Icelandic
|
||||
include common
|
||||
map 40f is
|
||||
map 0x40f
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Italian
|
||||
include common
|
||||
map 410 it
|
||||
map 0x410
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Japanese
|
||||
include common
|
||||
map 411 ja
|
||||
map 0x411
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Georgian
|
||||
include common
|
||||
map 437 ka
|
||||
map 0x437
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Kazakh
|
||||
include common
|
||||
map 43f kk
|
||||
map 0x43f
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Korean(Hangul)
|
||||
include common
|
||||
map 412 ko
|
||||
map 0x412
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Latin American
|
||||
include common
|
||||
map 80a la
|
||||
map 0x80a
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Lithuanian
|
||||
include common
|
||||
map 10427
|
||||
map 0x10427
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Latvian
|
||||
include common
|
||||
map 426 lv
|
||||
map 0x426
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Macedonian (FYROM)
|
||||
include common
|
||||
map 42f mk
|
||||
map 0x42f
|
||||
|
24
keymaps/modifiers
Normal file
24
keymaps/modifiers
Normal file
@ -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
|
@ -1,3 +1,3 @@
|
||||
# Marathi
|
||||
include common
|
||||
map 44e mr
|
||||
map 0x44e
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Dutch
|
||||
include common
|
||||
map 413 nl
|
||||
map 0x413
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Norwegian
|
||||
include common
|
||||
map 414 no
|
||||
map 0x414
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Polish (Programmers)
|
||||
include common
|
||||
map 415 pl
|
||||
map 0x415
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Portuguese
|
||||
include common
|
||||
map 816 pt
|
||||
map 0x816
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Romanian
|
||||
include common
|
||||
map 418 ro
|
||||
map 0x418
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Russian
|
||||
include common
|
||||
map 419 ru
|
||||
map 0x419
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Swiss French
|
||||
include common
|
||||
map 100c sf
|
||||
map 0x100c
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Swiss German
|
||||
include common
|
||||
map 807 sg
|
||||
map 0x807
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Slovak
|
||||
include common
|
||||
map 41b sk
|
||||
map 0x41b
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Slovenian
|
||||
include common
|
||||
map 424 sl
|
||||
map 0x424
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Albanian
|
||||
include common
|
||||
map 41c sq
|
||||
map 0x41c
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Serbian (Latin)
|
||||
include common
|
||||
map 81a sr
|
||||
map 0x81a
|
||||
|
79
keymaps/sv
79
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
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Tamil
|
||||
include common
|
||||
map 449 ta
|
||||
map 0x449
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Thai Kedmanee
|
||||
include common
|
||||
map 41e th
|
||||
map 0x41e
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Turkish F
|
||||
include common
|
||||
map 1041f tr
|
||||
map 0x1041f
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Tatar
|
||||
include common
|
||||
map 444 tt
|
||||
map 0x444
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Ukrainian
|
||||
include common
|
||||
map 422 uk
|
||||
map 0x422
|
||||
|
82
keymaps/us
82
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
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Uzbek Cyrillic
|
||||
include common
|
||||
map 843 uz
|
||||
map 0x843
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Vietnamese
|
||||
include common
|
||||
map 42a vi
|
||||
map 0x42a
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Chinese (Traditional) - US Keyboard
|
||||
include common
|
||||
map 404 zh
|
||||
map 0x404
|
||||
|
10
proto.h
10
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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#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"
|
||||
|
378
scancodes.h
Normal file
378
scancodes.h
Normal file
@ -0,0 +1,378 @@
|
||||
|
||||
/* Two defines for every scancode:
|
||||
One called SCANCODE_KEY_<num>, where <num> is the key location number.
|
||||
One called SCANCODE_CHAR_<char-on-us-kbd>, where <char-on-us-kbd> 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)
|
7
types.h
7
types.h
@ -98,3 +98,10 @@ typedef struct _DATABLOB
|
||||
|
||||
}
|
||||
DATABLOB;
|
||||
|
||||
typedef struct _key_translation
|
||||
{
|
||||
uint8 scancode;
|
||||
uint16 modifiers;
|
||||
}
|
||||
key_translation;
|
||||
|
438
xkeymap.c
438
xkeymap.c
@ -23,27 +23,58 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
554
xwin.c
554
xwin.c
@ -20,20 +20,18 @@
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#define XK_MISCELLANY
|
||||
#include <X11/keysymdef.h>
|
||||
#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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user