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:
Peter Åstrand 2002-07-18 18:28:12 +00:00
parent 4c90d366e2
commit 2dd151bd20
67 changed files with 1616 additions and 719 deletions

1
configure vendored
View File

@ -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
View 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)

View File

@ -1,3 +1,3 @@
# Arabic (101)
include common
map 401 ar
map 0x401

View File

@ -1,3 +1,3 @@
# Belarusian
include common
map be 423
map 0xbe

View File

@ -1,3 +1,3 @@
# Bulgarian
include common
map 402 bg
map 0x402

View File

@ -1,3 +1,3 @@
# Portuguese (Brazilian ABNT)
include common
map 416 br
map 0x416

View File

@ -1,3 +1,3 @@
# Canadian French (Legacy)
include common
map c0c cf
map 0xc0c

View File

@ -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
View 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()

View File

@ -1,3 +1,3 @@
# Czech
include common
map 405 cs
map 0x405

View File

@ -1,3 +1,3 @@
# Danish
include common
map 406 da
map 0x406

View File

@ -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

View File

@ -1,3 +1,3 @@
# United States-Dvorak
include common
map 10409 dv
map 0x10409

View File

@ -1,3 +1,3 @@
# Greek
include common
map 408 el
map 0x408

View File

@ -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

View File

@ -1,3 +1,3 @@
# Spanish
include common
map 40a es
map 0x40a

View File

@ -1,3 +1,3 @@
# Estonian
include common
map 425 et
map 0x425

View File

@ -1,3 +1,3 @@
# Finnish
include common
map 40b fi
map 0x40b

View File

@ -1,3 +1,3 @@
# Faeroese
include common
map 438 fo
map 0x438

View File

@ -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

View File

@ -1,3 +1,3 @@
# Irish
include common
map 1809 ga
map 0x1809

View File

@ -1,3 +1,3 @@
# Gaelic
include common
map 11809 gd
map 0x11809

View File

@ -1,3 +1,3 @@
# Hebrew
include common
map 40d he
map 0x40d

View File

@ -1,3 +1,3 @@
# Hindi Traditional
include common
map 10439 hi
map 0x10439

View File

@ -1,3 +1,3 @@
# Croatian
include common
map 41a hr
map 0x41a

View File

@ -1,3 +1,3 @@
# Hungarian
include common
map 40e hu
map 0x40e

View File

@ -1,3 +1,3 @@
# Icelandic
include common
map 40f is
map 0x40f

View File

@ -1,3 +1,3 @@
# Italian
include common
map 410 it
map 0x410

View File

@ -1,3 +1,3 @@
# Japanese
include common
map 411 ja
map 0x411

View File

@ -1,3 +1,3 @@
# Georgian
include common
map 437 ka
map 0x437

View File

@ -1,3 +1,3 @@
# Kazakh
include common
map 43f kk
map 0x43f

View File

@ -1,3 +1,3 @@
# Korean(Hangul)
include common
map 412 ko
map 0x412

View File

@ -1,3 +1,3 @@
# Latin American
include common
map 80a la
map 0x80a

View File

@ -1,3 +1,3 @@
# Lithuanian
include common
map 10427
map 0x10427

View File

@ -1,3 +1,3 @@
# Latvian
include common
map 426 lv
map 0x426

View File

@ -1,3 +1,3 @@
# Macedonian (FYROM)
include common
map 42f mk
map 0x42f

24
keymaps/modifiers Normal file
View 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

View File

@ -1,3 +1,3 @@
# Marathi
include common
map 44e mr
map 0x44e

View File

@ -1,3 +1,3 @@
# Dutch
include common
map 413 nl
map 0x413

View File

@ -1,3 +1,3 @@
# Norwegian
include common
map 414 no
map 0x414

View File

@ -1,3 +1,3 @@
# Polish (Programmers)
include common
map 415 pl
map 0x415

View File

@ -1,3 +1,3 @@
# Portuguese
include common
map 816 pt
map 0x816

View File

@ -1,3 +1,3 @@
# Romanian
include common
map 418 ro
map 0x418

View File

@ -1,3 +1,3 @@
# Russian
include common
map 419 ru
map 0x419

View File

@ -1,3 +1,3 @@
# Swiss French
include common
map 100c sf
map 0x100c

View File

@ -1,3 +1,3 @@
# Swiss German
include common
map 807 sg
map 0x807

View File

@ -1,3 +1,3 @@
# Slovak
include common
map 41b sk
map 0x41b

View File

@ -1,3 +1,3 @@
# Slovenian
include common
map 424 sl
map 0x424

View File

@ -1,3 +1,3 @@
# Albanian
include common
map 41c sq
map 0x41c

View File

@ -1,3 +1,3 @@
# Serbian (Latin)
include common
map 81a sr
map 0x81a

View File

@ -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

View File

@ -1,3 +1,3 @@
# Tamil
include common
map 449 ta
map 0x449

View File

@ -1,3 +1,3 @@
# Thai Kedmanee
include common
map 41e th
map 0x41e

View File

@ -1,3 +1,3 @@
# Turkish F
include common
map 1041f tr
map 0x1041f

View File

@ -1,3 +1,3 @@
# Tatar
include common
map 444 tt
map 0x444

View File

@ -1,3 +1,3 @@
# Ukrainian
include common
map 422 uk
map 0x422

View File

@ -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

View File

@ -1,3 +1,3 @@
# Uzbek Cyrillic
include common
map 843 uz
map 0x843

View File

@ -1,3 +1,3 @@
# Vietnamese
include common
map 42a vi
map 0x42a

View File

@ -1,3 +1,3 @@
# Chinese (Traditional) - US Keyboard
include common
map 404 zh
map 0x404

10
proto.h
View File

@ -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);

View File

@ -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;

View File

@ -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
View 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)

View File

@ -98,3 +98,10 @@ typedef struct _DATABLOB
}
DATABLOB;
typedef struct _key_translation
{
uint8 scancode;
uint16 modifiers;
}
key_translation;

438
xkeymap.c
View File

@ -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;
continue;
}
while (keyname != NULL);
}
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);
}
}

548
xwin.c
View File

@ -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)
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;
scancode =
xkeymap_translate_key(keysym,
}
}
else
{
/* Plain old XLookupString */
DEBUG_KBD
("No input context, using XLookupString\n");
XLookupString((XKeyEvent *) & xevent,
str, sizeof(str),
&keysym, NULL);
}
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,
&flags);
keycode);
ensure_remote_modifiers(ev_time, tr);
if (scancode == 0)
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,7 +718,8 @@ 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,
xcursor =
XCreatePixmapCursor(display, (Pixmap) cursorglyph,
(Pixmap) maskglyph, &fg, &bg, x, y);
ui_destroy_glyph(maskglyph);
@ -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)
{