added de, fr, and gb key layouts
This commit is contained in:
parent
3c3fb960dc
commit
d3e361d09b
@ -2,7 +2,7 @@
|
|||||||
XRDPOBJ = xrdp.o xrdp_process.o xrdp_listen.o \
|
XRDPOBJ = xrdp.o xrdp_process.o xrdp_listen.o \
|
||||||
xrdp_bitmap.o xrdp_wm.o xrdp_painter.o \
|
xrdp_bitmap.o xrdp_wm.o xrdp_painter.o \
|
||||||
xrdp_region.o xrdp_cache.o xrdp_font.o funcs.o \
|
xrdp_region.o xrdp_cache.o xrdp_font.o funcs.o \
|
||||||
xrdp_login_wnd.o xrdp_interface.o \
|
xrdp_login_wnd.o xrdp_interface.o lang.o \
|
||||||
list.o file.o os_calls.o thread_calls.o
|
list.o file.o os_calls.o thread_calls.o
|
||||||
|
|
||||||
DESTDIR = /usr/local/xrdp
|
DESTDIR = /usr/local/xrdp
|
||||||
|
Binary file not shown.
198
xrdp/funcs.c
198
xrdp/funcs.c
@ -143,204 +143,6 @@ check_bounds(struct xrdp_bitmap* b, int* x, int* y, int* cx, int* cy)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* scan codes
|
|
||||||
1 0x01 esc
|
|
||||||
2 0x02 1 or !
|
|
||||||
3 0x03 2 or @
|
|
||||||
4 0x04 3 or #
|
|
||||||
5 0x05 4 or $
|
|
||||||
6 0x06 5 or %
|
|
||||||
7 0x07 6 or ^
|
|
||||||
8 0x08 7 or &
|
|
||||||
9 0x09 8 or *
|
|
||||||
10 0x0a 9 or (
|
|
||||||
11 0x0b 0 or )
|
|
||||||
12 0x0c - or _
|
|
||||||
13 0x0d = or +
|
|
||||||
14 0x0e backspace
|
|
||||||
15 0x0f tab
|
|
||||||
16 0x10 q or Q
|
|
||||||
17 0x11 w or W
|
|
||||||
18 0x12 e or E
|
|
||||||
19 0x13 r or R
|
|
||||||
20 0x14 t or T
|
|
||||||
21 0x15 y or Y
|
|
||||||
22 0x16 u or U
|
|
||||||
23 0x17 i or I
|
|
||||||
24 0x18 o or O
|
|
||||||
25 0x19 p or P
|
|
||||||
26 0x1a [ or {
|
|
||||||
27 0x1b ] or }
|
|
||||||
28 0x1c enter, keypad is ext
|
|
||||||
29 0x1d left or right ctrl, ext flag is right
|
|
||||||
30 0x1e a or A
|
|
||||||
31 0x1f s or S
|
|
||||||
32 0x20 d or D
|
|
||||||
33 0x21 f or F
|
|
||||||
34 0x22 g or G
|
|
||||||
35 0x23 h or H
|
|
||||||
36 0x24 j or J
|
|
||||||
37 0x25 k or K
|
|
||||||
38 0x26 l or L
|
|
||||||
39 0x27 ; or :
|
|
||||||
40 0x28 ' or "
|
|
||||||
41 0x29 ` or ~
|
|
||||||
42 0x2a left shift
|
|
||||||
43 0x2b \
|
|
||||||
44 0x2c z or Z
|
|
||||||
45 0x2d x or X
|
|
||||||
46 0x2e c or C
|
|
||||||
47 0x2f v or V
|
|
||||||
48 0x30 b or B
|
|
||||||
49 0x31 n or N
|
|
||||||
50 0x32 m or M
|
|
||||||
51 0x33 , or <
|
|
||||||
52 0x34 . or >
|
|
||||||
53 0x35 / can be / on keypad, ext flag is keypad
|
|
||||||
54 0x36 right shift
|
|
||||||
55 0x37 * on keypad or print screen if ext
|
|
||||||
56 0x38 left or right alt, ext flag is right
|
|
||||||
57 0x39 space
|
|
||||||
58 0x3a caps lock
|
|
||||||
59 0x3b F1
|
|
||||||
60 0x3c F2
|
|
||||||
61 0x3d F3
|
|
||||||
62 0x3e F4
|
|
||||||
63 0x3f F5
|
|
||||||
64 0x40 F6
|
|
||||||
65 0x41 F7
|
|
||||||
66 0x42 F8
|
|
||||||
67 0x43 F9
|
|
||||||
68 0x44 F10
|
|
||||||
69 0x45 num lock
|
|
||||||
70 0x46 scroll lock
|
|
||||||
71 0x47 7 or home on keypad, ext flag is not keypad
|
|
||||||
72 0x48 8 or arrow up on keypad, ext flag is not keypad
|
|
||||||
73 0x49 9 or page up
|
|
||||||
74 0x4a -(minus) on keypad
|
|
||||||
75 0x4b 4 or arrow left on keypad, ext flag is not keypad
|
|
||||||
76 0x4c middle(5 key) of keypad
|
|
||||||
77 0x4d 6 or arrow right, can be on keypad, ext flag in not keypad
|
|
||||||
78 0x4e + on keypad
|
|
||||||
79 0x4f 1 or end
|
|
||||||
80 0x50 2 or arrow down, can be on keypad, ext flag in not keypad
|
|
||||||
81 0x51 3 or page down
|
|
||||||
82 0x52 0 or insert on keypad, ext flag is not keypad
|
|
||||||
83 0x53 . or delete on keypad, ext flag is not keypad
|
|
||||||
84 0x54
|
|
||||||
85 0x55
|
|
||||||
86 0x56
|
|
||||||
87 0x57 F11
|
|
||||||
88 0x58 F12
|
|
||||||
89 0x59
|
|
||||||
90 0x5a
|
|
||||||
91 0x5b left win key ext always on
|
|
||||||
92 0x5c right win key ext always on
|
|
||||||
93 0x5d menu key ext always on
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* non shift chars */
|
|
||||||
static char chars1[] =
|
|
||||||
{'\0', '\0', '1', '2', '3', '4', '5', '6',
|
|
||||||
'7', '8', '9', '0', '-', '=', '\0', '\0',
|
|
||||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
|
||||||
'o', 'p', '[', ']', '\0', '\0', 'a', 's',
|
|
||||||
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
|
|
||||||
'\'', '`', '\0', '\\', 'z', 'x', 'c', 'v',
|
|
||||||
'b', 'n', 'm', ',', '.', '/', '\0', '*',
|
|
||||||
'\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '7',
|
|
||||||
'8', '9', '-', '4', '5', '6', '+', '1',
|
|
||||||
'2', '3', '0', '.', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'};
|
|
||||||
/* shift chars */
|
|
||||||
static char chars2[] =
|
|
||||||
{'\0', '\0', '!', '@', '#', '$', '%', '^',
|
|
||||||
'&', '*', '(', ')', '_', '+', '\0', '\0',
|
|
||||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
|
|
||||||
'O', 'P', '{', '}', '\0', '\0', 'A', 'S',
|
|
||||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
|
|
||||||
'"', '~', '\0', '|', 'Z', 'X', 'C', 'V',
|
|
||||||
'B', 'N', 'M', '<', '>', '?', '\0', '*',
|
|
||||||
'\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '7',
|
|
||||||
'8', '9', '-', '4', '5', '6', '+', '1',
|
|
||||||
'2', '3', '0', '.', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
|
||||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'};
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
char APP_CC
|
|
||||||
get_char_from_scan_code(int device_flags, int scan_code, int* keys,
|
|
||||||
int caps_lock, int num_lock, int scroll_lock)
|
|
||||||
{
|
|
||||||
char rv;
|
|
||||||
int shift;
|
|
||||||
int ext;
|
|
||||||
|
|
||||||
shift = keys[42] || keys[54];
|
|
||||||
ext = device_flags & 0x0100;
|
|
||||||
rv = 0;
|
|
||||||
if (scan_code >= 128)
|
|
||||||
{
|
|
||||||
scan_code = scan_code % 128;
|
|
||||||
num_lock = 0;
|
|
||||||
}
|
|
||||||
if (!num_lock)
|
|
||||||
{
|
|
||||||
switch (scan_code)
|
|
||||||
{
|
|
||||||
case 71: /* 7 */
|
|
||||||
case 72: /* 8 */
|
|
||||||
case 73: /* 9 */
|
|
||||||
case 75: /* 4 */
|
|
||||||
case 76: /* 5 */
|
|
||||||
case 77: /* 6 */
|
|
||||||
case 79: /* 1 */
|
|
||||||
case 80: /* 2 */
|
|
||||||
case 81: /* 3 */
|
|
||||||
case 82: /* 0 */
|
|
||||||
case 83: /* . */
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ext)
|
|
||||||
{
|
|
||||||
if (scan_code == 53)
|
|
||||||
{
|
|
||||||
rv = '/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (shift)
|
|
||||||
{
|
|
||||||
rv = chars2[scan_code];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rv = chars1[scan_code];
|
|
||||||
}
|
|
||||||
if (rv >= 'a' && rv <= 'z' && caps_lock)
|
|
||||||
{
|
|
||||||
rv = rv - ('a' - 'A');
|
|
||||||
}
|
|
||||||
else if (rv >= 'A' && rv <= 'Z' && caps_lock)
|
|
||||||
{
|
|
||||||
rv = rv + ('a' - 'A');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* add a ch at index position in text, index starts at 0 */
|
/* add a ch at index position in text, index starts at 0 */
|
||||||
/* if index = -1 add it to the end */
|
/* if index = -1 add it to the end */
|
||||||
|
393
xrdp/lang.c
Normal file
393
xrdp/lang.c
Normal file
@ -0,0 +1,393 @@
|
|||||||
|
/*
|
||||||
|
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; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
xrdp: A Remote Desktop Protocol server.
|
||||||
|
Copyright (C) Jay Sorg 2006
|
||||||
|
|
||||||
|
keylayout
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xrdp.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* us english */
|
||||||
|
|
||||||
|
/* non shift chars */
|
||||||
|
char en_us_noshift[] =
|
||||||
|
{
|
||||||
|
0, 0, '1', '2', '3', '4', '5', '6',
|
||||||
|
'7', '8', '9', '0', '-', '=', 0, 0,
|
||||||
|
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
||||||
|
'o', 'p', '[', ']', 0, 0, 'a', 's',
|
||||||
|
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
|
||||||
|
'\'', '`', 0, '\\', 'z', 'x', 'c', 'v',
|
||||||
|
'b', 'n', 'm', ',', '.', '/', 0, '*',
|
||||||
|
0, ' ', 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, '7',
|
||||||
|
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* shift chars */
|
||||||
|
char en_us_shift[] =
|
||||||
|
{
|
||||||
|
0, 0, '!', '@', '#', '$', '%', '^',
|
||||||
|
'&', '*', '(', ')', '_', '+', 0, 0,
|
||||||
|
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
|
||||||
|
'O', 'P', '{', '}', 0, 0, 'A', 'S',
|
||||||
|
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
|
||||||
|
'"', '~', 0, '|', 'Z', 'X', 'C', 'V',
|
||||||
|
'B', 'N', 'M', '<', '>', '?', 0, '*',
|
||||||
|
0, ' ', 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, '7',
|
||||||
|
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* right alt chars */
|
||||||
|
char en_us_altgr[] =
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* uk english */
|
||||||
|
|
||||||
|
/* non shift chars */
|
||||||
|
char en_uk_noshift[] =
|
||||||
|
{
|
||||||
|
0, 0, '1', '2', '3', '4', '5', '6',
|
||||||
|
'7', '8', '9', '0', '-', '=', 0, 0,
|
||||||
|
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
||||||
|
'o', 'p', '[', ']', 0, 0, 'a', 's',
|
||||||
|
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
|
||||||
|
'\'', '`', 0, '#', 'z', 'x', 'c', 'v',
|
||||||
|
'b', 'n', 'm', ',', '.', '/', 0, '*',
|
||||||
|
0, ' ', 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, '7',
|
||||||
|
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* shift chars */
|
||||||
|
char en_uk_shift[] =
|
||||||
|
{
|
||||||
|
0, 0, '!', '"', 0xa3, '$', '%', '^',
|
||||||
|
'&', '*', '(', ')', '_', '+', 0, 0,
|
||||||
|
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
|
||||||
|
'O', 'P', '{', '}', 0, 0, 'A', 'S',
|
||||||
|
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
|
||||||
|
'@', 0xac, 0, '~', 'Z', 'X', 'C', 'V',
|
||||||
|
'B', 'N', 'M', '<', '>', '?', 0, '*',
|
||||||
|
0, ' ', 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, '7',
|
||||||
|
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0, 0, 0xa6, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* right alt chars */
|
||||||
|
char en_uk_altgr[] =
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0x80, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0xe9, 0, 0, 0, 0xfa, 0xed,
|
||||||
|
0xf3, 0, 0, 0, 0, 0, 0xe1, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0xa6, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0xa6, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* german */
|
||||||
|
|
||||||
|
/* non shift chars */
|
||||||
|
char de_noshift[] =
|
||||||
|
{
|
||||||
|
0, 0, '1', '2', '3', '4', '5', '6',
|
||||||
|
'7', '8', '9', '0', 0xdf, 0xb4, 0, 0,
|
||||||
|
'q', 'w', 'e', 'r', 't', 'z', 'u', 'i',
|
||||||
|
'o', 'p', 0xfc, '+', 0, 0, 'a', 's',
|
||||||
|
'd', 'f', 'g', 'h', 'j', 'k', 'l', 0xf6,
|
||||||
|
0xe4, '^', 0, '#', 'y', 'x', 'c', 'v',
|
||||||
|
'b', 'n', 'm', ',', '.', '-', 0, '*',
|
||||||
|
0, ' ', 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, '7',
|
||||||
|
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* shift chars */
|
||||||
|
char de_shift[] =
|
||||||
|
{
|
||||||
|
0, 0, '!', '"', 0xa7, '$', '%', '&',
|
||||||
|
'/', '(', ')', '=', '?', '`', 0, 0,
|
||||||
|
'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I',
|
||||||
|
'O', 'P', 0xdc, '*', 0, 0, 'A', 'S',
|
||||||
|
'D', 'F', 'G', 'H', 'J', 'K', 'L', 0xd6,
|
||||||
|
0xc4, 0xb0, 0, '\'', 'Y', 'X', 'C', 'V',
|
||||||
|
'B', 'N', 'M', ';', ':', '_', 0, '*',
|
||||||
|
0, ' ', 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, '7',
|
||||||
|
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* right alt chars */
|
||||||
|
char de_altgr[] =
|
||||||
|
{
|
||||||
|
0, 0, 0, 0xb2, 0xb3, 0, 0, 0,
|
||||||
|
'{', '[', ']', '}', '\\', 0, 0, 0,
|
||||||
|
'@', 0, 0x80, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, '~', 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0xb5, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* french */
|
||||||
|
|
||||||
|
/* non shift chars */
|
||||||
|
char fr_noshift[] =
|
||||||
|
{
|
||||||
|
0, 0, '&', 0xe9, '"', '\'', '(', '-',
|
||||||
|
0xe8, '_', 0xe7, 0xe0, ')', '=', 0, 0,
|
||||||
|
'a', 'z', 'e', 'r', 't', 'y', 'u', 'i',
|
||||||
|
'o', 'p', '^', '$', 0, 0, 'q', 's',
|
||||||
|
'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm',
|
||||||
|
0xf9, 0xb2, 0, '*', 'w', 'x', 'c', 'v',
|
||||||
|
'b', 'n', ',', ';', ':', '!', 0, '*',
|
||||||
|
0, ' ', 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, '7',
|
||||||
|
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* shift chars */
|
||||||
|
char fr_shift[] =
|
||||||
|
{
|
||||||
|
0, 0, '1', '2', '3', '4', '5', '6',
|
||||||
|
'7', '8', '9', '0', 0xb0, '+', 0, 0,
|
||||||
|
'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I',
|
||||||
|
'O', 'P', 0xa8, 0xa3, 0, 0, 'Q', 'S',
|
||||||
|
'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M',
|
||||||
|
'%', '~', 0, 0xb5, 'W', 'X', 'C', 'V',
|
||||||
|
'B', 'N', '?', '.', '/', 0xa7, 0, '*',
|
||||||
|
0, ' ', 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, '7',
|
||||||
|
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* right alt chars */
|
||||||
|
char fr_altgr[] =
|
||||||
|
{
|
||||||
|
0, 0, 0, '~', '#', '{', '[', '|',
|
||||||
|
'`', '\\', '^', '@', ']', '}', 0, 0,
|
||||||
|
0, 0, 0x80, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0xa4, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
char APP_CC
|
||||||
|
get_char_from_scan_code(int device_flags, int scan_code, int* keys,
|
||||||
|
int caps_lock, int num_lock, int scroll_lock,
|
||||||
|
int keylayout)
|
||||||
|
{
|
||||||
|
char rv;
|
||||||
|
char* keys_noshift;
|
||||||
|
char* keys_shift;
|
||||||
|
char* keys_altgr;
|
||||||
|
int shift;
|
||||||
|
int altgr;
|
||||||
|
int ext;
|
||||||
|
|
||||||
|
if (keylayout == 0x40c) /* france */
|
||||||
|
{
|
||||||
|
keys_noshift = fr_noshift;
|
||||||
|
keys_shift = fr_shift;
|
||||||
|
keys_altgr = fr_altgr;
|
||||||
|
}
|
||||||
|
else if (keylayout == 0x809) /* en-uk or en-gb */
|
||||||
|
{
|
||||||
|
keys_noshift = en_uk_noshift;
|
||||||
|
keys_shift = en_uk_shift;
|
||||||
|
keys_altgr = en_uk_altgr;
|
||||||
|
}
|
||||||
|
else if (keylayout == 0x407) /* german */
|
||||||
|
{
|
||||||
|
keys_noshift = de_noshift;
|
||||||
|
keys_shift = de_shift;
|
||||||
|
keys_altgr = de_altgr;
|
||||||
|
}
|
||||||
|
/* italy
|
||||||
|
else if (keylayout == 0x410)
|
||||||
|
{
|
||||||
|
} */
|
||||||
|
else /* english us 0x409 */
|
||||||
|
{
|
||||||
|
keys_noshift = en_us_noshift;
|
||||||
|
keys_shift = en_us_shift;
|
||||||
|
keys_altgr = en_us_altgr;
|
||||||
|
}
|
||||||
|
/*g_writeln("%d %d %x", scan_code, device_flags, keylayout);*/
|
||||||
|
shift = keys[42] || keys[54];
|
||||||
|
altgr = keys[56]; /* right alt */
|
||||||
|
ext = device_flags & 0x0100;
|
||||||
|
rv = 0;
|
||||||
|
if (scan_code >= 128)
|
||||||
|
{
|
||||||
|
scan_code = scan_code % 128;
|
||||||
|
num_lock = 0;
|
||||||
|
}
|
||||||
|
if (!num_lock)
|
||||||
|
{
|
||||||
|
switch (scan_code)
|
||||||
|
{
|
||||||
|
case 71: /* 7 */
|
||||||
|
case 72: /* 8 */
|
||||||
|
case 73: /* 9 */
|
||||||
|
case 75: /* 4 */
|
||||||
|
case 76: /* 5 */
|
||||||
|
case 77: /* 6 */
|
||||||
|
case 79: /* 1 */
|
||||||
|
case 80: /* 2 */
|
||||||
|
case 81: /* 3 */
|
||||||
|
case 82: /* 0 */
|
||||||
|
case 83: /* . */
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ext)
|
||||||
|
{
|
||||||
|
if (scan_code == 53)
|
||||||
|
{
|
||||||
|
rv = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (shift)
|
||||||
|
{
|
||||||
|
rv = keys_shift[scan_code];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (altgr)
|
||||||
|
{
|
||||||
|
rv = keys_altgr[scan_code];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rv = keys_noshift[scan_code];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rv >= 'a' && rv <= 'z' && caps_lock)
|
||||||
|
{
|
||||||
|
rv = rv - ('a' - 'A');
|
||||||
|
}
|
||||||
|
else if (rv >= 'A' && rv <= 'Z' && caps_lock)
|
||||||
|
{
|
||||||
|
rv = rv + ('a' - 'A');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
@ -9,116 +9,116 @@ come once at the end.
|
|||||||
Rdesktop does not do this as of yet. It always sends down and up
|
Rdesktop does not do this as of yet. It always sends down and up
|
||||||
for each repeat.
|
for each repeat.
|
||||||
|
|
||||||
key rdp code down flags up flags
|
key rdp code down flags up flags
|
||||||
esc 01 0000 8000
|
esc 0x01 1 0000 8000
|
||||||
1 02 0000 8000
|
1 0x02 2 0000 8000
|
||||||
2 03 0000 8000
|
2 0x03 3 0000 8000
|
||||||
3 04 0000 8000
|
3 0x04 4 0000 8000
|
||||||
4 05 0000 8000
|
4 0x05 5 0000 8000
|
||||||
5 06 0000 8000
|
5 0x06 6 0000 8000
|
||||||
6 07 0000 8000
|
6 0x07 7 0000 8000
|
||||||
7 08 0000 8000
|
7 0x08 8 0000 8000
|
||||||
8 09 0000 8000
|
8 0x09 9 0000 8000
|
||||||
9 0a 0000 8000
|
9 0x0a 10 0000 8000
|
||||||
0 0b 0000 8000
|
0 0x0b 11 0000 8000
|
||||||
- 0c 0000 8000
|
- 0x0c 12 0000 8000
|
||||||
= 0d 0000 8000
|
= 0x0d 13 0000 8000
|
||||||
backspace 0e 0000 8000
|
backspace 0x0e 14 0000 8000
|
||||||
tab 0f 0000 8000
|
tab 0x0f 15 0000 8000
|
||||||
q 10 0000 8000
|
q 0x10 16 0000 8000
|
||||||
w 11 0000 8000
|
w 0x11 17 0000 8000
|
||||||
e 12 0000 8000
|
e 0x12 18 0000 8000
|
||||||
r 13 0000 8000
|
r 0x13 19 0000 8000
|
||||||
t 14 0000 8000
|
t 0x14 20 0000 8000
|
||||||
y 15 0000 8000
|
y 0x15 21 0000 8000
|
||||||
u 16 0000 8000
|
u 0x16 22 0000 8000
|
||||||
i 17 0000 8000
|
i 0x17 23 0000 8000
|
||||||
o 18 0000 8000
|
o 0x18 24 0000 8000
|
||||||
p 19 0000 8000
|
p 0x19 25 0000 8000
|
||||||
[ 1a 0000 8000
|
[ 0x1a 26 0000 8000
|
||||||
] 1b 0000 8000
|
] 0x1b 27 0000 8000
|
||||||
enter 1c 0000 8000
|
enter 0x1c 28 0000 8000
|
||||||
left ctrl 1d 0000/4000 c000
|
left ctrl 0x1d 29 0000/4000 c000
|
||||||
right ctrl 1d 0100/4100 c100
|
right ctrl 0x1d 29 0100/4100 c100
|
||||||
a 1e 0000 8000
|
a 0x1e 30 0000 8000
|
||||||
s 1f 0000 8000
|
s 0x1f 31 0000 8000
|
||||||
d 20 0000 8000
|
d 0x20 32 0000 8000
|
||||||
f 21 0000 8000
|
f 0x21 33 0000 8000
|
||||||
g 22 0000 8000
|
g 0x22 34 0000 8000
|
||||||
h 23 0000 8000
|
h 0x23 35 0000 8000
|
||||||
j 24 0000 8000
|
j 0x24 36 0000 8000
|
||||||
k 25 0000 8000
|
k 0x25 37 0000 8000
|
||||||
l 26 0000 8000
|
l 0x26 38 0000 8000
|
||||||
; 27 0000 8000
|
; 0x27 39 0000 8000
|
||||||
' 28 0000 8000
|
' 0x28 40 0000 8000
|
||||||
` 29 0000 8000
|
` 0x29 41 0000 8000
|
||||||
left shift 2a 0000/4000 c000
|
left shift 0x2a 42 0000/4000 c000
|
||||||
\ 2b 0000 8000
|
\ 0x2b 43 0000 8000
|
||||||
z 2c 0000 8000
|
z 0x2c 44 0000 8000
|
||||||
x 2d 0000 8000
|
x 0x2d 45 0000 8000
|
||||||
c 2e 0000 8000
|
c 0x2e 46 0000 8000
|
||||||
v 2f 0000 8000
|
v 0x2f 47 0000 8000
|
||||||
b 30 0000 8000
|
b 0x30 48 0000 8000
|
||||||
n 31 0000 8000
|
n 0x31 49 0000 8000
|
||||||
m 32 0000 8000
|
m 0x32 50 0000 8000
|
||||||
, 33 0000 8000
|
, 0x33 51 0000 8000
|
||||||
. 34 0000 8000
|
. 0x34 52 0000 8000
|
||||||
/ 35 0000 8000
|
/ 0x35 53 0000 8000
|
||||||
right shift 36 0000/4000 c000
|
right shift 0x36 54 0000/4000 c000
|
||||||
*(keypad) 37 0000 8000
|
*(keypad) 0x37 55 0000 8000
|
||||||
print scrn 37 0100 8100
|
print scrn 0x37 55 0100 8100
|
||||||
left alt 38 0000/4000 c000
|
left alt 0x38 56 0000/4000 c000
|
||||||
right alt 38 0100/4100 c100
|
right alt 0x38 56 0100/4100 c100
|
||||||
space 39 0000 8000
|
space 0x39 57 0000 8000
|
||||||
caps lock 3a 0000/4000 c000
|
caps lock 0x3a 58 0000/4000 c000
|
||||||
f1 3b 0000 8000
|
f1 0x3b 59 0000 8000
|
||||||
f2 3c 0000 8000
|
f2 0x3c 60 0000 8000
|
||||||
f3 3d 0000 8000
|
f3 0x3d 61 0000 8000
|
||||||
f4 3e 0000 8000
|
f4 0x3e 62 0000 8000
|
||||||
f5 3f 0000 8000
|
f5 0x3f 63 0000 8000
|
||||||
f6 40 0000 8000
|
f6 0x40 64 0000 8000
|
||||||
f7 41 0000 8000
|
f7 0x41 65 0000 8000
|
||||||
f8 42 0000 8000
|
f8 0x42 66 0000 8000
|
||||||
f9 43 0000 8000
|
f9 0x43 67 0000 8000
|
||||||
f10 44 0000 8000
|
f10 0x44 68 0000 8000
|
||||||
num lock 45 0000/4000 c000
|
num lock 0x45 69 0000/4000 c000
|
||||||
scroll lock 46 0000/4000 c000
|
scroll lock 0x46 70 0000/4000 c000
|
||||||
7(keypad) 47 0000 8000
|
7(keypad) 0x47 71 0000 8000
|
||||||
home 47 0100 8100
|
home 0x47 71 0100 8100
|
||||||
8(keypad) 48 0000 8000
|
8(keypad) 0x48 72 0000 8000
|
||||||
up arrow 48 0100 8100
|
up arrow 0x48 72 0100 8100
|
||||||
9(kaypad) 49 0000 8000
|
9(kaypad) 0x49 73 0000 8000
|
||||||
pg up 49 0100 8100
|
pg up 0x49 73 0100 8100
|
||||||
-(keypad) 4a 0000 8000
|
-(keypad) 0x4a 74 0000 8000
|
||||||
4(keypad) 4b 0000 8000
|
4(keypad) 0x4b 75 0000 8000
|
||||||
left arrow 4b 0100 8100
|
left arrow 0x4b 75 0100 8100
|
||||||
5(keypad) 4c 0000 8000
|
5(keypad) 0x4c 76 0000 8000
|
||||||
6(keypad) 4d 0000 8000
|
6(keypad) 0x4d 77 0000 8000
|
||||||
right arrow 4d 0100 8100
|
right arrow 0x4d 77 0100 8100
|
||||||
+(keypad) 4e 0000 8000
|
+(keypad) 0x4e 78 0000 8000
|
||||||
1(keypad) 4f 0000 8000
|
1(keypad) 0x4f 79 0000 8000
|
||||||
end 4f 0100 8100
|
end 0x4f 79 0100 8100
|
||||||
2(keypad) 50 0000 8000
|
2(keypad) 0x50 80 0000 8000
|
||||||
down arrow 50 0100 8100
|
down arrow 0x50 80 0100 8100
|
||||||
3(keypad) 51 0000 8000
|
3(keypad) 0x51 81 0000 8000
|
||||||
pg down 51 0100 8100
|
pg down 0x51 81 0100 8100
|
||||||
o(keypad) 52 0000 8000
|
o(keypad) 0x52 82 0000 8000
|
||||||
insert 52 0100 8100
|
insert 0x52 82 0100 8100
|
||||||
.(keypad) 53 0000 8000
|
.(keypad) 0x53 83 0000 8000
|
||||||
delete 53 0100 8100
|
delete 0x53 83 0100 8100
|
||||||
? 54
|
? 0x54 84
|
||||||
? 55
|
? 0x55 85
|
||||||
? 56
|
? 0x56 86
|
||||||
f11 57 0000 8000
|
f11 0x57 87 0000 8000
|
||||||
f12 58 0000 8000
|
f12 0x58 88 0000 8000
|
||||||
? 59
|
? 0x59 89
|
||||||
? 5a
|
? 0x5a 90
|
||||||
left win 5b 0100 8100
|
left win 0x5b 91 0100 8100
|
||||||
right win 5c 0100 8100
|
right win 0x5c 92 0100 8100
|
||||||
menu key 5d 0100 8100
|
menu key 0x5d 93 0100 8100
|
||||||
|
|
||||||
pause break 1d 0200 8200
|
pause break 0x1d 29 0200 8200
|
||||||
45 0000 8000
|
0x45 69 0000 8000
|
||||||
This is a special key that sends 2 down and 2 up like this
|
This is a special key that sends 2 down and 2 up like this
|
||||||
down 001d 0200
|
down 001d 0200
|
||||||
down 0045 0000
|
down 0045 0000
|
||||||
|
@ -280,9 +280,6 @@ rect_contained_by(struct xrdp_rect* in1, int left, int top,
|
|||||||
int right, int bottom);
|
int right, int bottom);
|
||||||
int APP_CC
|
int APP_CC
|
||||||
check_bounds(struct xrdp_bitmap* b, int* x, int* y, int* cx, int* cy);
|
check_bounds(struct xrdp_bitmap* b, int* x, int* y, int* cx, int* cy);
|
||||||
char APP_CC
|
|
||||||
get_char_from_scan_code(int device_flags, int scan_code, int* keys,
|
|
||||||
int caps_lock, int num_lock, int scroll_lock);
|
|
||||||
int APP_CC
|
int APP_CC
|
||||||
add_char_at(char* text, char ch, int index);
|
add_char_at(char* text, char ch, int index);
|
||||||
int APP_CC
|
int APP_CC
|
||||||
@ -290,6 +287,12 @@ remove_char_at(char* text, int index);
|
|||||||
int APP_CC
|
int APP_CC
|
||||||
set_string(char** in_str, char* in);
|
set_string(char** in_str, char* in);
|
||||||
|
|
||||||
|
/* in lang.c */
|
||||||
|
char APP_CC
|
||||||
|
get_char_from_scan_code(int device_flags, int scan_code, int* keys,
|
||||||
|
int caps_lock, int num_lock, int scroll_lock,
|
||||||
|
int keylayout);
|
||||||
|
|
||||||
/* xrdp_login_wnd.c */
|
/* xrdp_login_wnd.c */
|
||||||
int APP_CC
|
int APP_CC
|
||||||
xrdp_wm_setup_mod1(struct xrdp_wm* self,
|
xrdp_wm_setup_mod1(struct xrdp_wm* self,
|
||||||
|
@ -1383,7 +1383,8 @@ xrdp_bitmap_def_proc(struct xrdp_bitmap* self, int msg,
|
|||||||
c = get_char_from_scan_code(param2, scan_code, self->wm->keys,
|
c = get_char_from_scan_code(param2, scan_code, self->wm->keys,
|
||||||
self->wm->caps_lock,
|
self->wm->caps_lock,
|
||||||
self->wm->num_lock,
|
self->wm->num_lock,
|
||||||
self->wm->scroll_lock);
|
self->wm->scroll_lock,
|
||||||
|
self->wm->session->client_info->keylayout);
|
||||||
if (c != 0)
|
if (c != 0)
|
||||||
{
|
{
|
||||||
add_char_at(self->caption1, c, self->edit_pos);
|
add_char_at(self->caption1, c, self->edit_pos);
|
||||||
|
@ -78,11 +78,11 @@ xrdp_font_create(struct xrdp_wm* wm)
|
|||||||
self = (struct xrdp_font*)g_malloc(sizeof(struct xrdp_font), 1);
|
self = (struct xrdp_font*)g_malloc(sizeof(struct xrdp_font), 1);
|
||||||
self->wm = wm;
|
self->wm = wm;
|
||||||
make_stream(s);
|
make_stream(s);
|
||||||
init_stream(s, 8192);
|
init_stream(s, 8192 * 2);
|
||||||
fd = g_file_open("Tahoma-10.fv1");
|
fd = g_file_open("Tahoma-10.fv1");
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
b = g_file_read(fd, s->data, 8192);
|
b = g_file_read(fd, s->data, 8192 * 2);
|
||||||
g_file_close(fd);
|
g_file_close(fd);
|
||||||
if (b > 0)
|
if (b > 0)
|
||||||
{
|
{
|
||||||
|
@ -1169,7 +1169,8 @@ xrdp_wm_key(struct xrdp_wm* self, int device_flags, int scan_code)
|
|||||||
c = get_char_from_scan_code(device_flags, scan_code, self->keys,
|
c = get_char_from_scan_code(device_flags, scan_code, self->keys,
|
||||||
self->caps_lock,
|
self->caps_lock,
|
||||||
self->num_lock,
|
self->num_lock,
|
||||||
self->scroll_lock);
|
self->scroll_lock,
|
||||||
|
self->session->client_info->keylayout);
|
||||||
/*g_printf("%x\n", c);*/
|
/*g_printf("%x\n", c);*/
|
||||||
if (c != 0)
|
if (c != 0)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user