diff -Nur orig.vncviewer/vncviewer.dsp vncviewer/vncviewer.dsp
--- orig.vncviewer/vncviewer.dsp	2002-08-04 10:23:30.000000000 +0200
+++ vncviewer/vncviewer.dsp	2005-04-13 18:51:08.000000000 +0200
@@ -321,6 +321,14 @@
 # End Source File
 # Begin Source File
 
+SOURCE=.\LowLevelHook.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LowLevelHook.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\LoginAuthDialog.cpp
 # End Source File
 # Begin Source File
diff -Nur orig.vncviewer/vncviewer.vcproj vncviewer/vncviewer.vcproj
--- orig.vncviewer/vncviewer.vcproj	2002-08-04 10:23:30.000000000 +0200
+++ vncviewer/vncviewer.vcproj	2005-04-13 18:51:08.000000000 +0200
@@ -315,6 +315,12 @@
 			RelativePath=".\Log.h">
 		</File>
 		<File
+			RelativePath=".\LowLevelHook.cpp">
+		</File>
+		<File
+			RelativePath=".\LowLevelHook.h">
+		</File>
+		<File
 			RelativePath=".\MRU.cpp">
 		</File>
 		<File
diff -Nur orig.vncviewer/ClientConnection.cpp vncviewer/ClientConnection.cpp
--- orig.vncviewer/ClientConnection.cpp	2004-11-18 01:12:36.000000000 +0100
+++ vncviewer/ClientConnection.cpp	2005-04-03 22:25:47.000000000 +0200
@@ -57,6 +57,8 @@
 #include "d3des.h"
 }
 
+#include "LowLevelHook.h"
+
 #define INITIALNETBUFSIZE 4096
 #define MAX_ENCODINGS 20
 #define VWR_WND_CLASS_NAME _T("VNCviewer")
@@ -317,6 +319,11 @@
 	
 	SetFormatAndEncodings();
 
+	LowLevelHook::Initialize(m_hwnd1, m_hwnd);
+	CheckMenuItem(
+				GetSystemMenu(m_hwnd1, FALSE), ID_INTERCEPT_SYSKEYS,
+				(LowLevelHook::IsActive() ? MF_CHECKED : 0) | MF_BYCOMMAND);
+
 	// This starts the worker thread.
 	// The rest of the processing continues in run_undetached.
 	start_undetached();
@@ -469,6 +476,7 @@
 				   _T("Ctrl key down"));
 		AppendMenu(hsysmenu, MF_STRING, ID_CONN_ALTDOWN,
 				   _T("Alt key down"));
+		AppendMenu(hsysmenu, MF_STRING, ID_INTERCEPT_SYSKEYS, _T("&Intercept Syskeys"));
 		AppendMenu(hsysmenu, MF_SEPARATOR, NULL, NULL);
 		AppendMenu(hsysmenu, MF_STRING | MF_GRAYED, IDD_FILETRANSFER,
 				   _T("Transf&er files...\tCtrl-Alt-Shift-E"));
@@ -1894,6 +1902,8 @@
 
 ClientConnection::~ClientConnection()
 {
+	LowLevelHook::Release();
+
 	if (m_hwnd1 != 0)
 		DestroyWindow(m_hwnd1);
 
@@ -2071,6 +2081,13 @@
 		case ID_DISCONNECT:
 			SendMessage(hwnd, WM_CLOSE, 0, 0);
 			return 0;
+		case ID_INTERCEPT_SYSKEYS:
+		    LowLevelHook::SetActive(!LowLevelHook::IsActive());
+		    CheckMenuItem(
+				GetSystemMenu(_this->m_hwnd1, FALSE), ID_INTERCEPT_SYSKEYS,
+				(LowLevelHook::IsActive() ? MF_CHECKED : 0) | MF_BYCOMMAND);
+		  return 0;
+
 		case ID_TOOLBAR:
 			if (GetMenuState(GetSystemMenu(_this->m_hwnd1, FALSE),
 				ID_TOOLBAR,MF_BYCOMMAND) == MF_CHECKED) {
@@ -2152,6 +2169,12 @@
 			_this->SendKeyEvent(XK_Alt_L,     false);
 			_this->SendKeyEvent(XK_Control_L, false);
 			return 0;
+		case ID_CONN_WINDOWN:
+			_this->SendKeyEvent(XK_Super_L, true);
+			return 0;
+		case ID_CONN_WINUP:
+			_this->SendKeyEvent(XK_Super_L, false);
+			return 0;
 		case ID_CONN_CTLDOWN:
 			if (GetMenuState(GetSystemMenu(_this->m_hwnd1, FALSE),
 				ID_CONN_CTLDOWN, MF_BYCOMMAND) == MF_CHECKED) {
diff -Nur orig.vncviewer/keysymdef.h vncviewer/keysymdef.h
--- orig.vncviewer/keysymdef.h	2003-10-09 01:50:54.000000000 +0200
+++ vncviewer/keysymdef.h	2005-03-28 22:21:55.000000000 +0200
@@ -138,5 +138,10 @@
 #define XK_Meta_R		0xFFE8
 #define XK_Alt_L		0xFFE9
 #define XK_Alt_R		0xFFEA
+#define XK_Super_L      0xFFEB  /* Left super */
+#define XK_Super_R      0xFFEC  /* Right super */
+#define XK_Hyper_L      0xFFED  /* Left hyper */
+#define XK_Hyper_R      0xFFEE  /* Right hyper */
+
 
 
diff -Nur orig.vncviewer/LowLevelHook.cpp vncviewer/LowLevelHook.cpp
--- orig.vncviewer/LowLevelHook.cpp	1970-01-01 01:00:00.000000000 +0100
+++ vncviewer/LowLevelHook.cpp	2005-04-13 17:30:32.000000000 +0200
@@ -0,0 +1,205 @@
+//  TODO: add Copyright?
+//
+//  The VNC system 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+//  USA.
+//
+// If the source code for the VNC system is not available from the place 
+// whence you received this file, check http://www.uk.research.att.com/vnc or contact
+// the authors on vnc@uk.research.att.com for information on obtaining it.
+
+// This is the source for the low-level keyboard hook, which allows intercepting and sending
+// special keys (such as ALT,CTRL, ALT+TAB, etc) to the VNCServer side.
+// written by Assaf Gordon (Assaf@mazleg.com), 10/9/2003
+// patched by Christian 'Greek0' Aichinger (Greek0@gmx.net) to work with TightVNC, 13/4/2005
+
+#define WINVER 0x0400
+#define _WIN32_WINNT 0x0400
+#include "LowLevelHook.h"
+#include "res/resource.h"
+
+HWND LowLevelHook::g_hwndVNCSysCtrl=NULL;
+HWND LowLevelHook::g_hwndVNCKey=NULL;
+DWORD LowLevelHook::g_VncProcessID=0;
+BOOL  LowLevelHook::g_fHookActive=TRUE;
+HHOOK LowLevelHook::g_HookID=0;
+BOOL  LowLevelHook::g_fGlobalScrollLock=FALSE;
+
+BOOL LowLevelHook::Initialize(HWND hwndSysCtrl, HWND hwndKey)
+{
+	HINSTANCE hInstance = NULL ;
+
+	g_hwndVNCSysCtrl = NULL ;
+	g_hwndVNCKey = NULL ;
+	g_fHookActive = TRUE;
+	g_VncProcessID = 0 ;
+	g_HookID = 0 ;
+	g_fGlobalScrollLock = FALSE ;
+
+	//Store our window's handle
+	g_hwndVNCSysCtrl = hwndSysCtrl;
+	g_hwndVNCKey = hwndKey;
+	if ((g_hwndVNCSysCtrl==NULL) || (g_hwndVNCKey==NULL))
+		return FALSE;
+
+
+	//Get the HInstacne of this window
+	//(required because LowLevel-Keyboard-Hook must be global, 
+	// and need the HMODULE parameter in SetWindowsHookEx)
+	hInstance = (HINSTANCE)GetWindowLong(g_hwndVNCSysCtrl,GWL_HINSTANCE);
+	if (hInstance==NULL)
+		return FALSE;
+
+	//
+	//Store the ProcessID of the VNC window.
+	//this will prevent the keyboard hook procedure to interfere
+	//with keypressed in other processes' windows
+	GetWindowThreadProcessId(g_hwndVNCSysCtrl,&g_VncProcessID);
+
+	//Try to set the hook procedure
+	g_HookID = SetWindowsHookEx(WH_KEYBOARD_LL,VncLowLevelKbHookProc,hInstance,0);
+	if (g_HookID==0) {
+
+		DWORD dw = GetLastError();
+
+		//TODO:
+		//Analyze why the error occured (might be because we're under Win98/95/ME?)
+		return FALSE ;
+	}
+	
+	return TRUE;
+}
+
+BOOL LowLevelHook::Release()
+{
+	if (g_HookID!=0) {
+		return UnhookWindowsHookEx(g_HookID);
+	}
+	return FALSE;
+}
+
+LRESULT CALLBACK LowLevelHook::VncLowLevelKbHookProc(INT nCode, WPARAM wParam, LPARAM lParam)
+{
+	//if set to TRUE, the key-pressed message will NOT be passed on to windows.
+    BOOL fHandled = FALSE;
+
+	BOOL fKeyDown = FALSE;
+
+    if (nCode == HC_ACTION) {
+        KBDLLHOOKSTRUCT *pkbdllhook = (KBDLLHOOKSTRUCT *)lParam;
+
+		DWORD ProcessID ;
+
+ 		//Get the process ID of the Active Window
+		//(The window with the input focus)
+		GetWindowThreadProcessId(GetFocus(),&ProcessID);
+
+		//only if this is "our" process (vncviewer's process)
+		//we should intecept the key-presses
+		if (ProcessID==g_VncProcessID) {
+
+			fKeyDown = ( (wParam==WM_KEYDOWN) || (wParam==WM_SYSKEYDOWN) );
+			switch (pkbdllhook->vkCode)
+			{
+			case VK_LWIN:
+			case VK_RWIN:
+				if (g_fHookActive) {
+					if(fKeyDown)
+						PostMessage(g_hwndVNCSysCtrl,WM_SYSCOMMAND,ID_CONN_WINDOWN,0);
+					else
+						PostMessage(g_hwndVNCSysCtrl,WM_SYSCOMMAND,ID_CONN_WINUP,0);
+					fHandled = TRUE;
+				}
+				break;
+
+				
+				//TAB = If the user presses ALT+TAB, we must block the TAB key (fHandled=TRUE),
+				//Otherwise windows (on the VNCViewer's side) will switch to another application.
+				//But because we block the TAB key, the 'ClientConnection' window won't know to send
+				//a TAB key to the VNCServer. so we simulate a TAB key pressed. 
+				//(The ALT key down was already sent to the VNCServer when the user pressed ALT)
+			case VK_TAB:
+				if (g_fHookActive) {
+					if (pkbdllhook->flags & LLKHF_ALTDOWN) {
+						if(fKeyDown)
+							PostMessage(g_hwndVNCKey,WM_KEYDOWN,VK_TAB,0);
+
+						/* Implementation Note:
+						   Don't send the Key-UP event, it confuses Windows on the server side.
+						   (It makes Windows switch TWO applications at a time). 
+
+						   This way it works OK on servers running Win98, Win2K, WinXP and Linux+IceWM.
+						   Should test it with more servers to make sure it's OK.
+						*/
+						fHandled = TRUE;
+					}
+				}
+				break;
+	#if 0
+				//Left or Right CONTROL keys
+				//	Simulate a "Send CONTROL up/down" from the System Menu
+			case VK_LCONTROL:
+			case VK_RCONTROL:
+				if (g_fHookActive) {
+					PostMessage(g_hwndVNCSysCtrl,WM_SYSCOMMAND,ID_CONN_CTLDOWN,0);
+					fHandled = TRUE;
+				}
+				break;
+
+				//Either Left or Right ALT keys
+				//	Simulate a "Send ALT up/down" from the System Menu
+			case VK_LMENU:
+			case VK_RMENU:
+				if (g_fHookActive) {
+					PostMessage(g_hwndVNCSysCtrl,WM_SYSCOMMAND,ID_CONN_ALTDOWN,0);
+					fHandled = TRUE;
+				}
+				break;
+
+
+				//ESCAPE = ALT+ESC is also a way to switch application, so we block the ESCAPE key,
+				//Otherwise windows (on the VNCViewer's side) will switch to another application.
+				//Transmitting the ALT+ESCAPE combination to a VNCServer running Windows doesn't work
+				//very well, so for now, we'll just block the ALT+ESCAPE combination.
+				//(CTRL+ESC work OK, BTW)
+		case VK_ESCAPE:
+				if (g_fHookActive) {
+					if (pkbdllhook->flags & LLKHF_ALTDOWN) {
+						fHandled = TRUE;
+					}
+				}
+				break;
+
+
+#endif
+			} //switch(pkbdllhook->vkCode)
+
+		} // if (ProcessID == g_VncProcesID)
+
+	} // if (nCode==HT_ACTION)
+
+	//Call the next hook, if we didn't handle this message
+    return (fHandled ? TRUE : CallNextHookEx(g_HookID, nCode, wParam, lParam));
+}
+
+BOOL LowLevelHook::IsActive()
+{
+	return g_fHookActive && (g_HookID!=0);
+}
+
+void LowLevelHook::SetActive(BOOL bActive)
+{
+	g_fHookActive = bActive;
+}
+
diff -Nur orig.vncviewer/LowLevelHook.h vncviewer/LowLevelHook.h
--- orig.vncviewer/LowLevelHook.h	1970-01-01 01:00:00.000000000 +0100
+++ vncviewer/LowLevelHook.h	2005-03-29 01:34:28.000000000 +0200
@@ -0,0 +1,50 @@
+//  TODO: add Copyright?
+//
+//  The VNC system 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+//  USA.
+//
+// If the source code for the VNC system is not available from the place 
+// whence you received this file, check http://www.uk.research.att.com/vnc or contact
+// the authors on vnc@uk.research.att.com for information on obtaining it.
+
+// This is the source for the low-level keyboard hook, which allows intercepting and sending
+// special keys (such as ALT,CTRL, ALT+TAB, etc) to the VNCServer side.
+// written by Assaf Gordon (Assaf@mazleg.com), 10/9/2003
+
+
+#pragma once
+
+#define WINVER 0x0400
+#define _WIN32_WINNT 0x0400
+#include <windows.h>
+
+class LowLevelHook
+{
+public:
+	static BOOL Initialize(HWND hwndSysCtrl, HWND hwndKey);
+	static BOOL Release();
+	static void SetActive(BOOL bActive=TRUE);
+	static BOOL IsActive();
+
+private:
+	static LRESULT CALLBACK VncLowLevelKbHookProc(INT nCode, WPARAM wParam, 
+												  LPARAM lParam);
+	static HWND g_hwndVNCSysCtrl;
+	static HWND g_hwndVNCKey;
+	static DWORD g_VncProcessID;
+	static BOOL  g_fHookActive;
+	static BOOL  g_fGlobalScrollLock;
+	static HHOOK g_HookID;
+};
diff -Nur orig.vncviewer/res/resource.h vncviewer/res/resource.h
--- orig.vncviewer/res/resource.h	2004-03-08 09:07:02.000000000 +0100
+++ vncviewer/res/resource.h	2005-03-29 00:36:19.000000000 +0200
@@ -42,6 +42,9 @@
 #define IDI_FILERELOAD                  241
 #define IDC_SMALLDOT                    244
 #define IDD_CONNECTING_DIALOG           245
+#define ID_INTERCEPT_SYSKEYS            246
+#define ID_CONN_WINDOWN					247
+#define ID_CONN_WINUP					248
 #define IDC_HOSTNAME_EDIT               1000
 #define IDC_DPYNUM_EDIT                 1001
 #define IDC_BELLDEICONIFY               1002

