Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37041654
en ru br
Репозитории ALT
S:1.9.0-alt1
5.1: 1.6.0-alt3.M50P.1
4.1: 1.5.0-alt7
4.0: 1.5.0-alt7
3.0: 1.4.1-alt1
www.altlinux.org/Changes

Группа :: Сети/Удалённый доступ
Пакет: rdesktop

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: rdesktop-1.6_auto_raw_keyboard.patch
Скачать


diff -urN rdesktop.orig/l2wscancodes.c rdesktop/l2wscancodes.c
--- rdesktop.orig/l2wscancodes.c	1970-01-01 03:00:00 +0300
+++ rdesktop/l2wscancodes.c	2010-01-24 18:28:00 +0300
@@ -0,0 +1,369 @@
+#include "X11/XKBlib.h"
+#include "X11/keysym.h"
+
+#include "scancodes.h"
+
+void init_l2w_scancode_conv_mx(Display* g_display, int *vks) {
+    int i, j;
+    KeySym *ks;
+    int keysums_per_scancode;
+    const int first_scan_code = 8;
+    ks = XGetKeyboardMapping(g_display, first_scan_code, 256 - first_scan_code, &keysums_per_scancode);
+
+    
+    for (i = 0; i < 255; ++i)
+        vks[i] = 0;
+
+    int scancode;
+    for (scancode = first_scan_code; scancode < 255; ++scancode) {
+        for (j = 0; j < keysums_per_scancode; ++j) {
+            if(vks[scancode]) continue;
+            switch (ks[(scancode - first_scan_code) * keysums_per_scancode + j]) {
+                    //F1 - F12
+                case XK_F1: vks[scancode] = SCANCODE_CHAR_F1;
+                    break;
+
+                case XK_F2: vks[scancode] = SCANCODE_CHAR_F2;
+                    break;
+
+                case XK_F3: vks[scancode] = SCANCODE_CHAR_F3;
+                    break;
+
+                case XK_F4: vks[scancode] = SCANCODE_CHAR_F4;
+                    break;
+
+                case XK_F5: vks[scancode] = SCANCODE_CHAR_F5;
+                    break;
+
+                case XK_F6: vks[scancode] = SCANCODE_CHAR_F6;
+                    break;
+
+                case XK_F7: vks[scancode] = SCANCODE_CHAR_F7;
+                    break;
+
+                case XK_F8: vks[scancode] = SCANCODE_CHAR_F8;
+                    break;
+
+                case XK_F9: vks[scancode] = SCANCODE_CHAR_F9;
+                    break;
+
+                case XK_F10: vks[scancode] = SCANCODE_CHAR_F10;
+                    break;
+
+                case XK_F11: vks[scancode] = SCANCODE_CHAR_F11;
+                    break;
+
+                case XK_F12: vks[scancode] = SCANCODE_CHAR_F12;
+                    break;
+
+                    //1, 2, 3 ... 0
+
+                case XK_1: vks[scancode] = SCANCODE_CHAR_1;
+                    break;
+
+                case XK_2: vks[scancode] = SCANCODE_CHAR_2;
+                    break;
+
+                case XK_3: vks[scancode] = SCANCODE_CHAR_3;
+                    break;
+
+                case XK_4: vks[scancode] = SCANCODE_CHAR_4;
+                    break;
+
+                case XK_5: vks[scancode] = SCANCODE_CHAR_5;
+                    break;
+
+                case XK_6: vks[scancode] = SCANCODE_CHAR_6;
+                    break;
+
+                case XK_7: vks[scancode] = SCANCODE_CHAR_7;
+                    break;
+
+                case XK_8: vks[scancode] = SCANCODE_CHAR_8;
+                    break;
+
+                case XK_9: vks[scancode] = SCANCODE_CHAR_9;
+                    break;
+
+                case XK_0: vks[scancode] = SCANCODE_CHAR_0;
+                    break;
+
+                    // - =
+                case XK_minus: vks[scancode] = SCANCODE_CHAR_MINUS;
+                    break;
+
+                case XK_equal: vks[scancode] = SCANCODE_CHAR_EQUAL;
+                    break;
+
+                    //A - J (10 keys)
+                case XK_A: vks[scancode] = SCANCODE_CHAR_A;
+                    break;
+
+                case XK_B: vks[scancode] = SCANCODE_CHAR_B;
+                    break;
+
+                case XK_C: vks[scancode] = SCANCODE_CHAR_C;
+                    break;
+
+                case XK_D: vks[scancode] = SCANCODE_CHAR_D;
+                    break;
+
+                case XK_E: vks[scancode] = SCANCODE_CHAR_E;
+                    break;
+
+                case XK_F: vks[scancode] = SCANCODE_CHAR_F;
+                    break;
+
+                case XK_G: vks[scancode] = SCANCODE_CHAR_G;
+                    break;
+
+                case XK_H: vks[scancode] = SCANCODE_CHAR_H;
+                    break;
+
+                case XK_I: vks[scancode] = SCANCODE_CHAR_I;
+                    break;
+
+                case XK_J: vks[scancode] = SCANCODE_CHAR_J;
+                    break;
+
+                    //K - T(10 keys)
+                case XK_K: vks[scancode] = SCANCODE_CHAR_K;
+                    break;
+
+                case XK_L: vks[scancode] = SCANCODE_CHAR_L;
+                    break;
+
+                case XK_M: vks[scancode] = SCANCODE_CHAR_M;
+                    break;
+
+                case XK_N: vks[scancode] = SCANCODE_CHAR_N;
+                    break;
+
+                case XK_O: vks[scancode] = SCANCODE_CHAR_O;
+                    break;
+
+                case XK_P: vks[scancode] = SCANCODE_CHAR_P;
+                    break;
+
+                case XK_Q: vks[scancode] = SCANCODE_CHAR_Q;
+                    break;
+
+                case XK_R: vks[scancode] = SCANCODE_CHAR_R;
+                    break;
+
+                case XK_S: vks[scancode] = SCANCODE_CHAR_S;
+                    break;
+
+                case XK_T: vks[scancode] = SCANCODE_CHAR_T;
+                    break;
+
+                    //U - Z (6 keys)
+                case XK_U: vks[scancode] = SCANCODE_CHAR_U;
+                    break;
+
+                case XK_V: vks[scancode] = SCANCODE_CHAR_V;
+                    break;
+
+                case XK_W: vks[scancode] = SCANCODE_CHAR_W;
+                    break;
+
+                case XK_X: vks[scancode] = SCANCODE_CHAR_X;
+                    break;
+
+                case XK_Y: vks[scancode] = SCANCODE_CHAR_Y;
+                    break;
+
+                case XK_Z: vks[scancode] = SCANCODE_CHAR_Z;
+                    break;
+
+                    //[ ] ; ' , . /
+                case XK_bracketleft: vks[scancode] = SCANCODE_CHAR_BRACKETLEFT;
+                    break;
+
+                case XK_bracketright: vks[scancode] = SCANCODE_CHAR_BRACKETRIGHT;
+                    break;
+
+                case XK_apostrophe: vks[scancode] = SCANCODE_CHAR_APOSTROPHE;
+                    break;
+
+                case XK_semicolon: vks[scancode] = SCANCODE_CHAR_SEMICOLON;
+                    break;
+
+                case XK_comma: vks[scancode] = SCANCODE_CHAR_COMMA;
+                    break;
+
+                case XK_period: vks[scancode] = SCANCODE_CHAR_DOT;
+                    break;
+
+                case XK_slash: vks[scancode] = SCANCODE_CHAR_SLASH;
+                    break;
+
+                    //~ backslash
+			case XK_grave : vks[scancode] = SCANCODE_CHAR_GRAVE;
+                    break;
+
+                case XK_backslash: vks[scancode] = SCANCODE_CHAR_BACKSLASH;
+                    break;
+
+
+                    //Esc, Tab, CapsLock, LShift, LCtrl, LWin(LSuper), LAlt
+                case XK_Escape: vks[scancode] = SCANCODE_CHAR_ESC;
+                    break;
+
+                case XK_Tab: vks[scancode] = SCANCODE_CHAR_TAB;
+                    break;
+
+                case XK_Caps_Lock: vks[scancode] = SCANCODE_CHAR_CAPSLOCK;
+                    break;
+
+                case XK_Shift_L: vks[scancode] = SCANCODE_CHAR_LSHIFT;
+                    break;
+
+                case XK_Control_L: vks[scancode] = SCANCODE_CHAR_LCTRL;
+                    break;
+
+                case XK_Alt_L: vks[scancode] = SCANCODE_CHAR_LALT;
+                    break;
+
+                case XK_Super_L: vks[scancode] = SCANCODE_CHAR_LWIN;
+                    break;
+
+                    //BSpace, RShift, RCtrl, RAlt, Apps, Ins, Del, RSuper
+
+                case XK_BackSpace: vks[scancode] = SCANCODE_CHAR_BACKSPACE;
+                    break;
+
+                case XK_Menu: vks[scancode] = SCANCODE_CHAR_APPLICATION;
+                    break;
+
+                case XK_Insert: vks[scancode] = SCANCODE_CHAR_INSERT;
+                    break;
+
+                case XK_Shift_R: vks[scancode] = SCANCODE_CHAR_RSHIFT;
+                    break;
+
+                case XK_Control_R: vks[scancode] = SCANCODE_CHAR_RCTRL;
+                    break;
+
+                case XK_Alt_R: vks[scancode] = SCANCODE_CHAR_RALT;
+                    break;
+
+                case XK_Super_R: vks[scancode] = SCANCODE_CHAR_RWIN;
+                    break;
+
+                case XK_Delete: vks[scancode] = SCANCODE_CHAR_DELETE;
+                    break;
+
+                    //Space, Enter, Up, Down, Right, Left
+                case XK_Left: vks[scancode] = SCANCODE_CHAR_LARROW;
+                    break;
+
+                case XK_Up: vks[scancode] = SCANCODE_CHAR_UPARROW;
+                    break;
+
+                case XK_Right: vks[scancode] = SCANCODE_CHAR_RARROW;
+                    break;
+
+                case XK_Down: vks[scancode] = SCANCODE_CHAR_DNARROW;
+                    break;
+
+                case XK_Return: vks[scancode] = SCANCODE_CHAR_ENTER;
+                    break;
+
+                case XK_space: vks[scancode] = SCANCODE_CHAR_SPACE;
+                    break;
+
+
+
+                //ScrollLock, PrintScreen, PauseBreak, PgUp, PgDn, Home, End
+                case XK_Home: vks[scancode] = SCANCODE_CHAR_HOME;
+                    break;
+
+                case XK_End: vks[scancode] = SCANCODE_CHAR_END;
+                    break;
+
+                case XK_Page_Up: vks[scancode] = SCANCODE_CHAR_PAGEUP;
+                    break;
+
+                case XK_Page_Down: vks[scancode] = SCANCODE_CHAR_PAGEDOWN;
+                    break;
+
+                case XK_Print: vks[scancode] = SCANCODE_CHAR_PRINT;
+                    break;
+
+                case XK_Pause: vks[scancode] = SCANCODE_CHAR_PAUSE;
+                    break;
+
+                case XK_Scroll_Lock: vks[scancode] = SCANCODE_CHAR_SCROLLLOCK;
+                    break;
+
+                    ///////
+                    //Num block
+                    //////
+
+
+                //0, 1, ... 9
+                case XK_KP_1: vks[scancode] = SCANCODE_CHAR_NUMERIC1;
+                    break;
+
+                case XK_KP_2: vks[scancode] = SCANCODE_CHAR_NUMERIC2;
+                    break;
+
+                case XK_KP_3: vks[scancode] = SCANCODE_CHAR_NUMERIC3;
+                    break;
+
+                case XK_KP_4: vks[scancode] = SCANCODE_CHAR_NUMERIC4;
+                    break;
+
+                case XK_KP_5: vks[scancode] = SCANCODE_CHAR_NUMERIC5;
+                    break;
+
+                case XK_KP_6: vks[scancode] = SCANCODE_CHAR_NUMERIC6;
+                    break;
+
+                case XK_KP_7: vks[scancode] = SCANCODE_CHAR_NUMERIC7;
+                    break;
+
+                case XK_KP_8: vks[scancode] = SCANCODE_CHAR_NUMERIC8;
+                    break;
+
+                case XK_KP_9: vks[scancode] = SCANCODE_CHAR_NUMERIC9;
+                    break;
+
+                case XK_KP_0: vks[scancode] = SCANCODE_CHAR_NUMERIC0;
+                    break;
+
+
+                // / * - + .
+                case XK_KP_Divide: vks[scancode] = SCANCODE_CHAR_NUMERICSLASH;
+                    break;
+
+                case XK_KP_Add: vks[scancode] = SCANCODE_CHAR_NUMERICPLUS;
+                    break;
+
+                case XK_KP_Subtract: vks[scancode] = SCANCODE_CHAR_NUMERICMINUS;
+                    break;
+
+                case XK_KP_Multiply: vks[scancode] = SCANCODE_CHAR_NUMERICSTAR;
+                    break;
+
+                case XK_KP_Delete:
+                case XK_KP_Decimal:
+                case XK_KP_Separator:  vks[scancode] = SCANCODE_CHAR_NUMERICDOT;
+                    break;
+
+
+                //Enter, Num Lock
+                case XK_KP_Enter: vks[scancode] = SCANCODE_CHAR_NUMERICENTER;
+                    break;
+
+                case XK_Num_Lock: vks[scancode] = SCANCODE_CHAR_NUMLOCK;
+                    break;
+
+
+
+            }
+        }
+    }
+
+}
diff -urN rdesktop.orig/l2wscancodes.h rdesktop/l2wscancodes.h
--- rdesktop.orig/l2wscancodes.h	1970-01-01 03:00:00 +0300
+++ rdesktop/l2wscancodes.h	2010-01-24 18:28:00 +0300
@@ -0,0 +1,14 @@
+/* 
+ * File:   l2wscancodes.h
+ * Author: alex
+ *
+ * Created on 6 п■п╣п╨п╟п╠я─я▄ 2009 пЁ., 20:59
+ */
+
+#ifndef _L2WSCANCODES_H
+#define	_L2WSCANCODES_H
+
+extern void init_l2w_scancode_conv_mx(Display * g_display, int *vks);
+
+#endif	/* _L2WSCANCODES_H */
+
diff -urN rdesktop.orig/Makefile.in rdesktop/Makefile.in
--- rdesktop.orig/Makefile.in	2009-08-03 19:17:44 +0400
+++ rdesktop/Makefile.in	2010-01-24 18:28:00 +0300
@@ -28,7 +28,7 @@
 SCARDOBJ    = @SCARDOBJ@
 
 RDPOBJ   = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o ssl.o
-X11OBJ   = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o
+X11OBJ   = l2wscancodes.o rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o
 VNCOBJ   = vnc/rdp2vnc.o vnc/vnc.o vnc/xkeymap.o vnc/x11stubs.o
 
 .PHONY: all
@@ -81,7 +81,7 @@
 proto:
 	cat proto.head > proto.h
 	cproto -DMAKE_PROTO \
-	bitmap.c cache.c channels.c cliprdr.c disk.c mppc.c ewmhints.c	\
+	l2wscancodes.o bitmap.c cache.c channels.c cliprdr.c disk.c mppc.c ewmhints.c	\
 	iso.c licence.c mcs.c orders.c parallel.c printer.c printercache.c \
 	pstcache.c rdesktop.c rdp5.c rdp.c rdpdr.c rdpsnd.c \
 	secure.c serial.c tcp.c xclip.c xkeymap.c xwin.c lspci.c seamless.c \
diff -urN rdesktop.orig/rdesktop.c rdesktop/rdesktop.c
--- rdesktop.orig/rdesktop.c	2009-08-03 19:17:44 +0400
+++ rdesktop/rdesktop.c	2010-01-24 18:28:00 +0300
@@ -91,6 +91,8 @@
 RD_BOOL g_owncolmap = False;
 RD_BOOL g_ownbackstore = True;	/* We can't rely on external BackingStore */
 RD_BOOL g_seamless_rdp = False;
+RD_BOOL g_raw_keyboard = False;
+RD_BOOL g_ind_raw_converter = False;
 uint32 g_embed_wnd;
 uint32 g_rdp5_performanceflags =
 	RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
@@ -211,6 +213,8 @@
 	fprintf(stderr, "   -0: attach to console\n");
 	fprintf(stderr, "   -4: use RDP version 4\n");
 	fprintf(stderr, "   -5: use RDP version 5 (default)\n");
+	fprintf(stderr, "   -y: use raw keyboard (default no)\n");
+        fprintf(stderr, "   -Y: use raw keyboard with platform-independent raw-converter (default no)\n");
 }
 
 static void
@@ -450,7 +454,7 @@
 #endif
 
 	while ((c = getopt(argc, argv,
-			   VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
+			   VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045Yyh?")) != -1)
 	{
 		switch (c)
 		{
@@ -783,6 +787,11 @@
 			case '5':
 				g_use_rdp5 = True;
 				break;
+                        case 'Y':
+                                g_ind_raw_converter = True;
+			case 'y':
+				g_raw_keyboard = True;
+				break;
 
 			case 'h':
 			case '?':
diff -urN rdesktop.orig/scancodes.h rdesktop/scancodes.h
--- rdesktop.orig/scancodes.h	2009-08-27 12:40:33 +0400
+++ rdesktop/scancodes.h	2010-01-24 18:28:00 +0300
@@ -152,7 +152,7 @@
 #define SCANCODE_KEY_43 0x1c
 #define SCANCODE_CHAR_ENTER SCANCODE_KEY_43
 
-#define SCANCODE_KEY_44 0x2a
+#define SCANCODE_KEY_44 (SCANCODE_EXTENDED | 0x2a)
 #define SCANCODE_CHAR_LSHIFT SCANCODE_KEY_44
 
 /* Only on international keyboard */
@@ -191,7 +191,7 @@
 /* Only on Brazilian and some Far East keyboards */
 #define SCANCODE_KEY_56 0x73
 
-#define SCANCODE_KEY_57 0x36
+#define SCANCODE_KEY_57 (SCANCODE_EXTENDED | 0x36)
 #define SCANCODE_CHAR_RSHIFT SCANCODE_KEY_57
 
 #define SCANCODE_KEY_58 0x1d
@@ -352,10 +352,15 @@
 
 /* Key 124: The Print Screen sequence is complicated, and
    hardcoded in xkeymap.c */
+#define SCANCODE_KEY_124 0xff
+#define SCANCODE_CHAR_PRINT SCANCODE_KEY_124
 
 #define SCANCODE_KEY_125 0x46
 #define SCANCODE_CHAR_SCROLLLOCK SCANCODE_KEY_125
 
+#define SCANCODE_KEY_126 (SCANCODE_EXTENDED | 0x59)
+#define SCANCODE_CHAR_PAUSE SCANCODE_KEY_126
+
 /* Key 126: The Pause and Break sequences is complicated, and
    hardcoded in xkeymap.c */
 
diff -urN rdesktop.orig/xkeymap.c rdesktop/xkeymap.c
--- rdesktop.orig/xkeymap.c	2009-08-03 19:17:44 +0400
+++ rdesktop/xkeymap.c	2010-01-24 18:28:00 +0300
@@ -33,6 +33,7 @@
 #include <string.h>
 #include "rdesktop.h"
 #include "scancodes.h"
+#include "l2wscancodes.h"
 
 #define KEYMAP_SIZE 0xffff+1
 #define KEYMAP_MASK 0xffff
@@ -49,12 +50,15 @@
 extern RD_BOOL g_enable_compose;
 extern RD_BOOL g_use_rdp5;
 extern RD_BOOL g_numlock_sync;
+extern RD_BOOL g_ind_raw_converter;
+extern int scancodes_table[];
 
 static RD_BOOL keymap_loaded;
 static key_translation *keymap[KEYMAP_SIZE];
 static int min_keycode;
 static uint16 remote_modifier_state = 0;
 static uint16 saved_remote_modifier_state = 0;
+static uint32 vkmenu, vkcontrol, vklshift, vkrshift, vknumlock;
 
 static void update_modifier_state(uint8 scancode, RD_BOOL pressed);
 
@@ -943,6 +947,7 @@
 		rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
 
 	reset_winkey(ev_time);
+        vknumlock = get_key_state(state, XK_Num_Lock);
 
 	if (g_numlock_sync)
 		rdp_send_input(ev_time, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(state), 0);
@@ -1028,3 +1033,176 @@
 		rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0);
 	}
 }
+
+typedef unsigned char byte;
+typedef unsigned int  dword;
+
+static byte vkscancode[256] = {
+            /* 00 - 07 */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* 08 - 0f */ 0, SCANCODE_CHAR_ESC, SCANCODE_CHAR_1, SCANCODE_CHAR_2, SCANCODE_CHAR_3, SCANCODE_CHAR_4, SCANCODE_CHAR_5, SCANCODE_CHAR_6,
+            /* 10 - 17 */ SCANCODE_CHAR_7, SCANCODE_CHAR_8, SCANCODE_CHAR_9, SCANCODE_CHAR_0, SCANCODE_CHAR_MINUS, SCANCODE_CHAR_EQUAL, SCANCODE_CHAR_BACKSPACE, SCANCODE_CHAR_TAB,
+            /* 18 - 1f */ SCANCODE_CHAR_Q, SCANCODE_CHAR_W, SCANCODE_CHAR_E, SCANCODE_CHAR_R, SCANCODE_CHAR_T, SCANCODE_CHAR_Y, SCANCODE_CHAR_U, SCANCODE_CHAR_I,
+            /* 20 - 27 */ SCANCODE_CHAR_O, SCANCODE_CHAR_P, SCANCODE_CHAR_BRACKETLEFT, SCANCODE_CHAR_BRACKETRIGHT, SCANCODE_CHAR_ENTER, SCANCODE_CHAR_LCTRL, SCANCODE_CHAR_A, SCANCODE_CHAR_S,
+            /* 28 - 2f */ SCANCODE_CHAR_D, SCANCODE_CHAR_F, SCANCODE_CHAR_G, SCANCODE_CHAR_H, SCANCODE_CHAR_J, SCANCODE_CHAR_K, SCANCODE_CHAR_L, SCANCODE_CHAR_SEMICOLON,
+            /* 30 - 37 */ SCANCODE_CHAR_APOSTROPHE, SCANCODE_CHAR_GRAVE, SCANCODE_CHAR_LSHIFT, SCANCODE_KEY_42, SCANCODE_CHAR_Z, SCANCODE_CHAR_X, SCANCODE_CHAR_C, SCANCODE_CHAR_V,
+            /* 38 - 3f */ SCANCODE_CHAR_B, SCANCODE_CHAR_N, SCANCODE_CHAR_M, SCANCODE_CHAR_COMMA, SCANCODE_CHAR_DOT, SCANCODE_CHAR_SLASH, SCANCODE_CHAR_RSHIFT, SCANCODE_CHAR_NUMERICSTAR,
+            /* 40 - 47 */ SCANCODE_CHAR_LALT, SCANCODE_CHAR_SPACE, SCANCODE_CHAR_CAPSLOCK, SCANCODE_CHAR_F1, SCANCODE_CHAR_F2, SCANCODE_CHAR_F3, SCANCODE_CHAR_F4, SCANCODE_CHAR_F5,
+            /* 48 - 4f */ SCANCODE_CHAR_F6, SCANCODE_CHAR_F7, SCANCODE_CHAR_F8, SCANCODE_CHAR_F9, SCANCODE_CHAR_F10, SCANCODE_CHAR_NUMLOCK, SCANCODE_CHAR_SCROLLLOCK, SCANCODE_CHAR_NUMERIC7,
+            /* 50 - 57 */ SCANCODE_CHAR_NUMERIC8, SCANCODE_CHAR_NUMERIC9, SCANCODE_CHAR_NUMERICMINUS, SCANCODE_CHAR_NUMERIC4, SCANCODE_CHAR_NUMERIC5, SCANCODE_CHAR_NUMERIC6, SCANCODE_CHAR_NUMERICPLUS, SCANCODE_CHAR_NUMERIC1,
+            /* 58 - 5f */ SCANCODE_CHAR_NUMERIC2, SCANCODE_CHAR_NUMERIC3, SCANCODE_CHAR_NUMERIC0, SCANCODE_CHAR_NUMERICDOT, 0, 0, 0, SCANCODE_CHAR_F11,
+            /* 60 - 67 */ SCANCODE_CHAR_F12, SCANCODE_CHAR_HOME, SCANCODE_CHAR_UPARROW, SCANCODE_CHAR_PAGEUP, SCANCODE_CHAR_LARROW, 0, SCANCODE_CHAR_RARROW, SCANCODE_CHAR_END,
+            /* 68 - 6f */ SCANCODE_CHAR_NUMERICENTER, SCANCODE_CHAR_RCTRL, SCANCODE_CHAR_NUMERICSLASH, SCANCODE_CHAR_DELETE, SCANCODE_CHAR_RALT, SCANCODE_CHAR_RCTRL, SCANCODE_CHAR_HOME, SCANCODE_CHAR_UPARROW,
+            /* 70 - 77 */ SCANCODE_CHAR_PAGEUP, SCANCODE_CHAR_LARROW, SCANCODE_CHAR_RARROW, SCANCODE_CHAR_END, SCANCODE_CHAR_DNARROW, SCANCODE_CHAR_PAGEDOWN, SCANCODE_CHAR_INSERT, SCANCODE_CHAR_DELETE,
+            /* 78 - 7f */ 0, 0, 0, 0, 0, 0, 0, 0,
+
+            /* 80 - 87 */ 0, 0, 0, 0, 0, SCANCODE_CHAR_LWIN, 0, SCANCODE_CHAR_APPLICATION,
+            /* 88 - 8f */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* 90 - 97 */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* 98 - 9f */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* a0 - a7 */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* a8 - af */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* b0 - b7 */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* b8 - bf */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* c0 - c7 */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* c8 - cf */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* d0 - d7 */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* d8 - df */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* e0 - e7 */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* e8 - ef */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* f0 - f7 */ 0, 0, 0, 0, 0, 0, 0, 0,
+            /* f8 - ff */ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static inline int vk_handle_special_keys( uint32 keysym, uint32 ev_time, RD_BOOL pressed) {
+
+        RD_BOOL leftkey = 0;
+
+        switch( keysym)        {
+        case SCANCODE_CHAR_NUMLOCK:
+                if( !pressed)
+                        vknumlock = !vknumlock;
+                return 0;
+
+        case SCANCODE_CHAR_ENTER:
+        case SCANCODE_CHAR_NUMERICENTER:
+                if( pressed && vkmenu && vkcontrol) {
+                        /* Ctrl-Alt-Enter: toggle full screen */
+                       xwin_toggle_fullscreen();
+                       return 1;
+                }
+               return 0;
+
+        case SCANCODE_CHAR_PAUSE:
+                if( pressed) {
+                        if( vkcontrol) {
+                                rdp_send_scancode( ev_time, RDP_KEYPRESS, (SCANCODE_EXTENDED | 0x46));
+                                rdp_send_scancode( ev_time, RDP_KEYPRESS, (SCANCODE_EXTENDED | 0xc6));
+                        }
+                        else {
+                                rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
+                                rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x1d, 0);
+                                rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x45, 0);
+                                rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
+                                rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x9d, 0);
+                                rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xc5, 0);
+                        }
+               }
+                else {
+                       /* Release Left Ctrl */
+                        if( vkcontrol)
+                                rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x1d, 0);
+                }
+                return 1;
+
+        case SCANCODE_CHAR_PRINT:
+                if( vkmenu)
+                        rdp_send_input( ev_time, RDP_INPUT_SCANCODE, pressed ? RDP_KEYPRESS : RDP_KEYRELEASE, 0x54, 0);
+                else if( vkcontrol && (vklshift || vklshift))
+                        rdp_send_input( ev_time, RDP_INPUT_SCANCODE, pressed ? RDP_KEYPRESS : RDP_KEYRELEASE, SCANCODE_EXTENDED|0x37, 0);
+                else {
+#if 0
+                        if( pressed) {
+                                rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT, 0);
+                                rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, SCANCODE_EXTENDED|0x37, 0);
+                        }
+                        else {
+                                rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, SCANCODE_EXTENDED|0x37, 0);
+                                rdp_send_input( ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT, 0);
+                        }
+#endif
+                }
+                return 1;
+
+        case SCANCODE_CHAR_LWIN:
+                leftkey = True;
+        case SCANCODE_CHAR_RWIN:
+                if( pressed) {
+                        if( g_use_rdp5) {
+                                rdp_send_scancode(ev_time, RDP_KEYPRESS, keysym);
+                        }
+                        else {
+                                /* RDP4 doesn't support winkey. Fake with Ctrl-Esc */
+                                rdp_send_scancode( ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LCTRL);
+                                rdp_send_scancode( ev_time, RDP_KEYPRESS, SCANCODE_CHAR_ESC);
+                        }
+                }
+                else {
+                        if( g_use_rdp5) {
+                                rdp_send_scancode(ev_time, RDP_KEYRELEASE, keysym);
+                        }
+                        else {
+                                rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_ESC);
+                                rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
+                        }
+                }
+                return 1;
+
+        case SCANCODE_CHAR_INSERT:
+        case SCANCODE_CHAR_DELETE:
+        case SCANCODE_CHAR_LARROW:
+        case SCANCODE_CHAR_HOME:
+        case SCANCODE_CHAR_END:
+        case SCANCODE_CHAR_UPARROW:
+        case SCANCODE_CHAR_DNARROW:
+        case SCANCODE_CHAR_PAGEUP:
+        case SCANCODE_CHAR_PAGEDOWN:
+        case SCANCODE_CHAR_RARROW:
+        case SCANCODE_CHAR_NUMERICSLASH:
+        case SCANCODE_CHAR_APPLICATION:
+               rdp_send_scancode( ev_time, pressed ? RDP_KEYPRESS : RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
+               rdp_send_scancode( ev_time, pressed ? RDP_KEYPRESS : RDP_KEYRELEASE, keysym);
+               return 1;
+        }
+       return 0;
+}
+
+
+void vk_handle_key( XKeyEvent *xkey) {
+
+        uint32 vk, ev_time, pressed = (xkey->type == KeyPress);
+       
+        if (g_ind_raw_converter)
+            vk = scancodes_table[ xkey->keycode];
+        else
+            vk = vkscancode[ xkey->keycode];
+      
+        DEBUG_KBD(( "vk_handle_key( scancode=0x%x) vk = 0x%x\n", xkey->keycode, vk));
+
+        if( !vk)
+                return;
+
+        ev_time = time( 0);
+
+        if( (vk == SCANCODE_CHAR_LCTRL) || (vk == SCANCODE_CHAR_RCTRL))
+                vkcontrol = pressed;
+        else if( (vk == SCANCODE_CHAR_LALT) || (vk == SCANCODE_CHAR_RALT))
+                vkmenu = pressed;
+        else if( vk == SCANCODE_CHAR_LSHIFT)
+                vklshift = pressed;
+        else if( vk == SCANCODE_CHAR_RSHIFT)
+                vkrshift = pressed;
+        else if( vk_handle_special_keys( vk, ev_time, pressed))
+                return;
+
+        rdp_send_input( ev_time, RDP_INPUT_SCANCODE, pressed ? RDP_KEYPRESS : RDP_KEYRELEASE, vk, 0);
+}
diff -urN rdesktop.orig/xwin.c rdesktop/xwin.c
--- rdesktop.orig/xwin.c	2009-08-03 19:17:44 +0400
+++ rdesktop/xwin.c	2010-01-24 18:28:00 +0300
@@ -29,6 +29,11 @@
 #include <strings.h>
 #include "rdesktop.h"
 #include "xproto.h"
+#include "X11/XKBlib.h"
+#include "X11/keysym.h"
+
+#include "scancodes.h"
+#include "l2wscancodes.h"
 
 extern int g_width;
 extern int g_height;
@@ -39,11 +44,14 @@
 extern RD_BOOL g_fullscreen;
 extern RD_BOOL g_grab_keyboard;
 extern RD_BOOL g_hide_decorations;
+extern RD_BOOL g_ind_raw_converter;
+int scancodes_table[256];
 extern char g_title[];
 /* Color depth of the RDP session.
    As of RDP 5.1, it may be 8, 15, 16 or 24. */
 extern int g_server_depth;
 extern int g_win_button_size;
+extern RD_BOOL g_raw_keyboard;
 
 Display *g_display;
 Time g_last_gesturetime;
@@ -136,6 +144,8 @@
     so its endianess doesn't matter)
  */
 static RD_BOOL g_no_translate_image = False;
+static RD_BOOL g_modeswitch_down = False;
+
 
 /* endianness */
 static RD_BOOL g_host_be;
@@ -1846,6 +1856,10 @@
 	if (!select_visual(screen_num))
 		return False;
 
+        if (g_ind_raw_converter){
+            init_l2w_scancode_conv_mx(g_display, scancodes_table);
+        }
+
 	if (g_no_translate_image)
 	{
 		DEBUG(("Performance optimization possible: avoiding image translation (colour depth conversion).\n"));
@@ -2267,6 +2281,8 @@
 	}
 }
 
+extern void vk_handle_key( XKeyEvent *xkey);
+
 
 /* Process events in Xlib queue
    Returns 0 after user quit, 1 otherwise */
@@ -2291,6 +2307,12 @@
 			continue;
 		}
 
+		if( g_raw_keyboard && ((xevent.type == KeyPress) || (xevent.type == KeyRelease))) {
+                    g_last_gesturetime = xevent.xkey.time;
+			vk_handle_key( (XKeyEvent*)&xevent);
+			continue;
+		}
+
 		switch (xevent.type)
 		{
 			case VisibilityNotify:
@@ -2338,6 +2360,11 @@
 						      str, sizeof(str), &keysym, NULL);
 				}
 
+
+				// Mode_switch during XGrabKeyboard fix: Ungrab Keyboard during Mode_switch
+				if ( keysym == XK_Mode_switch ) g_modeswitch_down = True;
+				if ( g_focused && g_modeswitch_down ) XUngrabKeyboard(g_display, CurrentTime);
+
 				DEBUG_KBD(("KeyPress for keysym (0x%lx, %s)\n", keysym,
 					   get_ksname(keysym)));
 
@@ -2354,6 +2381,11 @@
 				XLookupString((XKeyEvent *) & xevent, str,
 					      sizeof(str), &keysym, NULL);
 
+
+				// Mode_switch during XGrabKeyboard fix: Regrab Keyboard after Mode_switch
+				if ( keysym == XK_Mode_switch ) g_modeswitch_down = False;
+				if ( g_focused && !g_modeswitch_down ) XGrabKeyboard(g_display, g_wnd, True, GrabModeAsync, GrabModeAsync, CurrentTime);
+
 				DEBUG_KBD(("\nKeyRelease for keysym (0x%lx, %s)\n", keysym,
 					   get_ksname(keysym)));
 
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin