46688
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
index 0c6251a..dbde67e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
@@ -1174,6 +1174,7 @@
 	public static final int WM_CTLCOLORSCROLLBAR = 0x137;
 	public static final int WM_CTLCOLORSTATIC = 0x138;
 	public static final int WM_CUT = 0x300;
+	public static final int WM_DEADCHAR = 0x103;
 	public static final int WM_DESTROY = 0x2;
 	public static final int WM_DRAWITEM = 0x2b;
 	public static final int WM_ENDSESSION = 0x16;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java
index c3c7a1e..29bb277 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java
@@ -51,8 +51,6 @@
 	Object layoutData;
 	Accessible accessible;
 	int drawCount, foreground, background;
-	
-	static final short [] ACCENTS = new short [] {'~', '`', '\'', '^', '"'};
 
 /**
  * Prevents uninitialized instances from being created outside the package.
@@ -2539,7 +2537,7 @@
 	Decorations shell = menuShell ();
 	if (shell.isVisible () && shell.isEnabled ()) {
 		display.lastAscii = msg.wParam;
-		display.lastNull = false;
+		display.lastNull = display.lastDead = false;
 		Event event = new Event ();
 		event.detail = SWT.TRAVERSE_MNEMONIC;
 		if (setKeyState (event, SWT.Traverse, msg.wParam, msg.lParam)) {
@@ -2660,7 +2658,7 @@
 	display.lastKey = lastKey;
 	display.lastAscii = lastAscii;
 	display.lastVirtual = lastVirtual;
-	display.lastNull = false;
+	display.lastNull = display.lastDead = false;
 	if (!setKeyState (event, SWT.Traverse, msg.wParam, msg.lParam)) return false;
 	Shell shell = getShell ();
 	Control control = this;
@@ -3205,7 +3203,7 @@
 	Display display = this.display;
 	display.lastKey = 0;
 	display.lastAscii = wParam;
-	display.lastVirtual = display.lastNull = false;
+	display.lastVirtual = display.lastNull = display.lastDead = false;
 	if (!sendKeyEvent (SWT.KeyDown, OS.WM_IME_CHAR, wParam, lParam)) {
 		return LRESULT.ZERO;
 	}
@@ -3290,8 +3288,8 @@
 	
 	/* Clear last key and last ascii because a new key has been typed */
 	display.lastAscii = display.lastKey = 0;
-	display.lastVirtual = display.lastNull = false;
-
+	display.lastVirtual = display.lastNull = display.lastDead = false;
+	
 	/*
 	* Do not report a lead byte as a key pressed.
 	*/
@@ -3313,44 +3311,34 @@
 	* Bug in Windows 95 and NT.  When the user types an accent key such
 	* as ^ to get an accented character on a German keyboard, the accent
 	* key should be ignored and the next key that the user types is the
-	* accented key.  On Windows 95 and NT, a call to ToAscii (), clears the
-	* accented state such that the next WM_CHAR loses the accent.  The fix
-	* is to detect the accent key stroke (called a dead key) by testing the
-	* high bit of the value returned by MapVirtualKey ().  A further problem
-	* is that the high bit on Windows NT is bit 32 while the high bit on
-	* Windows 95 is bit 16.  They should both be bit 32.
+	* accented key.  The fix is to detect the accent key stroke (called
+	* a dead key) by testing the high bit of the value returned by
+	* MapVirtualKey().  A further problem is that the high bit on
+	* Windows NT is bit 32 while the high bit on Windows 95 is bit 16.
+	* They should both be bit 32.
+	*
+	* When the user types an accent key that does not correspond to a
+	* virtual key, MapVirtualKey() won't set the high bit to indicate
+	* a dead key.  This happens when an accent key, such as '^' is the
+	* result of a modifier such as Shift key and MapVirtualKey() always
+	* returns the unshifted key.  The fix is to peek for a WM_DEADCHAR
+	* and avoid issuing the event. 
 	* 
-	* NOTE: This code is used to avoid a call to ToAscii ().
+	* NOTE: On Windows 95 and NT, a call to ToAscii(), clears the
+	* accented state such that the next WM_CHAR loses the accent.
+	* This makes is critical that the accent key is detected.
 	*/
 	if (OS.IsWinNT) {
 		if ((mapKey & 0x80000000) != 0) return null;
 	} else {
 		if ((mapKey & 0x8000) != 0) return null;
 	}
-	
-	/*
-	* Bug in Windows.  When the accent key is generated on an international
-	* keyboard using Ctrl+Alt or the special key, MapVirtualKey () does not
-	* have the high bit set indicating that this is an accent key stroke.
-	* The fix is to iterate through all known accent, mapping them back to
-	* their corresponding virtual key and key state.  If the virtual key
-	* and key state match the current key, then this is an accent that has
-	* been generated using an international keyboard and calling ToAscii ()
-	* will clear the accent state.
-	* 
-	* NOTE: This code is used to avoid a call to ToAscii ().
-	*/
-	if (!OS.IsWinCE) {
-		if (OS.GetKeyState (OS.VK_CONTROL) < 0 && OS.GetKeyState (OS.VK_MENU) < 0) {
-			for (int i=0; i<ACCENTS.length; i++) {
-				int value = OS.VkKeyScan (ACCENTS [i]);
-				if ((value & 0xFF) == wParam && (value & 0x600) == 0x600) {
-					display.lastVirtual = mapKey == 0;
-					display.lastKey = display.lastVirtual ? wParam : mapKey;
-					return null;
-				}
-			}
-		}
+	MSG msg = new MSG ();
+	if (OS.PeekMessage (msg, handle, OS.WM_DEADCHAR, OS.WM_DEADCHAR, OS.PM_NOREMOVE)) {
+		display.lastDead = true;
+		display.lastVirtual = mapKey == 0;
+		display.lastKey = display.lastVirtual ? wParam : mapKey;
+		return null;
 	}
 	
 	/*
@@ -3485,7 +3473,7 @@
 	if (OS.IsWinCE) {
 		if (OS.VK_APP1 <= wParam && wParam <= OS.VK_APP6) {
 			display.lastKey = display.lastAscii = 0;
-			display.lastVirtual = display.lastNull = false;
+			display.lastVirtual = display.lastNull = display.lastDead = false;
 			Event event = new Event ();
 			event.detail = wParam - OS.VK_APP1 + 1;
 			/* Check the bit 30 to get the key state */
@@ -3502,7 +3490,7 @@
 	*/
 	if (!hooks (SWT.KeyUp) && !display.filters (SWT.KeyUp)) {
 		display.lastKey = display.lastAscii = 0;
-		display.lastVirtual = display.lastNull = false;
+		display.lastVirtual = display.lastNull = display.lastDead = false;
 		return null;
 	}
 	
@@ -3519,46 +3507,19 @@
 	* Bug in Windows 95 and NT.  When the user types an accent key such
 	* as ^ to get an accented character on a German keyboard, the accent
 	* key should be ignored and the next key that the user types is the
-	* accented key.  On Windows 95 and NT, a call to ToAscii (), clears the
-	* accented state such that the next WM_CHAR loses the accent.  The fix
-	* is to detect the accent key stroke (called a dead key) by testing the
-	* high bit of the value returned by MapVirtualKey ().  A further problem
-	* is that the high bit on Windows NT is bit 32 while the high bit on
-	* Windows 95 is bit 16.  They should both be bit 32.
-	* 
-	* NOTE: This code is used to avoid a call to ToAscii ().
-	* 
+	* accented key. The fix is to detect the accent key stroke (called
+	* a dead key) by testing the high bit of the value returned by
+	* MapVirtualKey ().  A further problem is that the high bit on
+	* Windows NT is bit 32 while the high bit on Windows 95 is bit 16.
+	* They should both be bit 32.
 	*/
 	if (OS.IsWinNT) {
 		if ((mapKey & 0x80000000) != 0) return null;
 	} else {
 		if ((mapKey & 0x8000) != 0) return null;
 	}
-	
-	/*
-	* Bug in Windows.  When the accent key is generated on an international
-	* keyboard using Ctrl+Alt or the special key, MapVirtualKey () does not
-	* have the high bit set indicating that this is an accent key stroke.
-	* The fix is to iterate through all known accent, mapping them back to
-	* their corresponding virtual key and key state.  If the virtual key
-	* and key state match the current key, then this is an accent that has
-	* been generated using an international keyboard.
-	* 
-	* NOTE: This code is used to avoid a call to ToAscii ().
-	*/
-	if (!OS.IsWinCE) {
-		if (OS.GetKeyState (OS.VK_CONTROL) < 0 && OS.GetKeyState (OS.VK_MENU) < 0) {
-			for (int i=0; i<ACCENTS.length; i++) {
-				int value = OS.VkKeyScan (ACCENTS [i]);
-				if ((value & 0xFF) == wParam && (value & 0x600) == 0x600) {
-					display.lastKey = display.lastAscii = 0;
-					display.lastVirtual = display.lastNull = false;
-					return null;
-				}
-			}
-		}
-	}
-	
+	if (display.lastDead) return null;
+
 	/*
 	* NOTE: On Windows 98, keypad keys are virtual despite the
 	* fact that a WM_CHAR is issued.  On Windows 2000 and XP,
@@ -3579,7 +3540,7 @@
 		if (wParam == OS.VK_CANCEL) display.lastVirtual = true;
 		if (display.lastKey == 0) {
 			display.lastAscii = 0;
-			display.lastNull = false;
+			display.lastNull = display.lastDead = false;
 			return null;
 		}
 	}
@@ -3589,7 +3550,7 @@
 	}
 	// widget could be disposed at this point
 	display.lastKey = display.lastAscii = 0;
-	display.lastVirtual = display.lastNull = false;
+	display.lastVirtual = display.lastNull = display.lastDead = false;
 	return result;
 }
 
@@ -4318,7 +4279,7 @@
 	
 	/* Clear last key and last ascii because a new key has been typed */
 	display.lastAscii = display.lastKey = 0;
-	display.lastVirtual = display.lastNull = false;
+	display.lastVirtual = display.lastNull = display.lastDead = false;
 
 	/* If are going to get a WM_SYSCHAR, ignore this message. */
 	/*
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
index f4e5329..5ea3457 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
@@ -136,8 +136,8 @@
 	Runnable [] timerList;
 	
 	/* Keyboard and Mouse State */
-	boolean lastVirtual, lastNull;
 	int lastKey, lastAscii, lastMouse;
+	boolean lastVirtual, lastNull, lastDead;
 	byte [] keyboard = new byte [256];
 	boolean accelKeyHit, mnemonicKeyHit;
 	boolean lockActiveWindow;
@@ -673,7 +673,7 @@
 		if (control != null) {
 			if (translateAccelerator (msg, control) || translateMnemonic (msg, control) || translateTraversal (msg, control)) {	
 				lastAscii = lastKey = 0;
-				lastVirtual = lastNull = false;
+				lastVirtual = lastNull = lastDead = false;
 				return true;
 			}
 		}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java
index a792ea9..cdaa575 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java
@@ -1853,7 +1853,7 @@
 	Display display = this.display;
 	display.lastKey = 0;
 	display.lastAscii = wParam;
-	display.lastVirtual = display.lastNull = false;
+	display.lastVirtual = display.lastNull = display.lastDead = false;
 	if (!sendKeyEvent (SWT.KeyDown, OS.WM_IME_CHAR, wParam, lParam)) {
 		return LRESULT.ZERO;
 	}