diff -up fltk-1.3.x-r8501/src/Fl_win32.cxx.dead-win32 fltk-1.3.x-r8501/src/Fl_win32.cxx
--- fltk-1.3.x-r8501/src/Fl_win32.cxx.dead-win32	2011-03-11 13:42:59.298646109 +0100
+++ fltk-1.3.x-r8501/src/Fl_win32.cxx	2011-03-11 16:02:49.452346270 +0100
@@ -777,6 +777,27 @@ static int ms2fltk(int vk, int extended)
   return extended ? extendedlut[vk] : vklut[vk];
 }
 
+static xchar msdead2fltk(xchar in)
+{
+  switch (in) {
+  case 0x0060:      // GRAVE ACCENT
+    return 0x0300;  // COMBINING GRAVE ACCENT
+  case 0x00b4:      // ACUTE ACCENT
+    return 0x0301;  // COMBINING ACUTE ACCENT
+  case 0x005e:      // CIRCUMFLEX ACCENT
+    return 0x0302;  // COMBINING CIRCUMFLEX ACCENT
+  case 0x007e:      // TILDE
+    return 0x0303;  // COMBINING TILDE
+  case 0x00a8:      // DIAERESIS
+    return 0x0308;  // COMBINING DIAERESIS
+  // FIXME: Windows dead key behaviour isn't documented and I don't have
+  //        any more keyboards to test with...
+  }
+
+  // hope that Windows gave us something proper to begin with
+  return in;
+}
+
 #if USE_COLORMAP
 extern HPALETTE fl_select_palette(void); // in fl_color_win32.cxx
 #endif
@@ -838,6 +859,8 @@ static LRESULT CALLBACK WndProc(HWND hWn
   //fl_msg.pt = ???
   //fl_msg.lPrivate = ???
 
+  MSG fl_orig_msg = fl_msg;
+
   Fl_Window *window = fl_find(hWnd);
 
   if (window) switch (uMsg) {
@@ -1019,6 +1040,7 @@ static LRESULT CALLBACK WndProc(HWND hWn
     if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK;
     Fl::e_state = state;
     static char buffer[1024];
+    static char compose_buffer[1024];
     if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
 
       xchar u = (xchar) wParam;
@@ -1026,7 +1048,67 @@ static LRESULT CALLBACK WndProc(HWND hWn
       Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
       buffer[Fl::e_length] = 0;
 
+      if (Fl::e_compose_state == FL_COMPOSE_INTERMEDIATE) {
+        // if you enter an invalid compose sequence Windows will spit
+        // out the entire thing in back-to-back messages
+        while (PeekMessageW(&fl_msg, hWnd, WM_CHAR, WM_SYSDEADCHAR, PM_REMOVE)) {
+          uMsg = fl_msg.message;
+          wParam = fl_msg.wParam;
+          lParam = fl_msg.lParam;
+
+          u = (xchar) wParam;
+          Fl::e_length += fl_utf8fromwc(&buffer[Fl::e_length], 1024-Fl::e_length, &u, 1);
+          buffer[Fl::e_length] = 0;
+
+          // update the compose symbol so that it will end up pointing at
+          // the last symbol in the sequence
+          u = msdead2fltk(u);
+          int length = fl_utf8fromwc(compose_buffer, 1024, &u, 1);
+          compose_buffer[length] = '\0';
 
+          Fl::e_compose_symbol = compose_buffer;
+          Fl::e_compose_state = FL_COMPOSE_FINAL;
+        }
+
+        if (Fl::e_compose_state != FL_COMPOSE_FINAL) {
+          MSG extra_msg;
+
+          // Windows doesn't expose the raw symbol (AFAIK), so we have to
+          // get a bit creative. Resend the last message to TranslateMessage()
+          // without all the inital dead characters, and we should get the
+          // raw symbol.
+          TranslateMessage(&fl_orig_msg);
+
+          if (PeekMessageW(&extra_msg, hWnd, WM_CHAR, WM_SYSDEADCHAR, PM_REMOVE)) {
+            u = (xchar) extra_msg.wParam;
+            int length = fl_utf8fromwc(compose_buffer, 1024, &u, 1);
+            compose_buffer[length] = '\0';
+
+            Fl::e_compose_symbol = compose_buffer;
+            Fl::e_compose_state = FL_COMPOSE_FINAL;
+          } else {
+            // something went wrong, just provide the composed symbol
+            Fl::e_compose_symbol = buffer;
+            Fl::e_compose_state = FL_COMPOSE_FINAL;
+          }
+        }
+      } else {
+        Fl::e_compose_state = FL_COMPOSE_NONE;
+      }
+    } else if (uMsg == WM_DEADCHAR || uMsg == WM_SYSDEADCHAR) {
+      xchar u = (xchar) wParam;
+      int length;
+
+      u = msdead2fltk(u);
+
+      length = fl_utf8fromwc(compose_buffer, 1024, &u, 1);
+      compose_buffer[length] = '\0';
+
+      Fl::e_compose_state = FL_COMPOSE_INTERMEDIATE;
+      Fl::e_compose_symbol = compose_buffer;
+
+      buffer[0] = '\0';
+      Fl::e_length = 0;
     } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) {
       if (state & FL_NUM_LOCK) {
         // Convert to regular keypress...
@@ -1077,19 +1159,8 @@ static LRESULT CALLBACK WndProc(HWND hWn
 	}
       }
     } else if ((lParam & (1<<31))==0) {
-#ifdef FLTK_PREVIEW_DEAD_KEYS
-      if ((lParam & (1<<24))==0) { // clear if dead key (always?)
-        xchar u = (xchar) wParam;
-        Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
-        buffer[Fl::e_length] = 0;
-      } else { // set if "extended key" (never printable?)
-        buffer[0] = 0;
-        Fl::e_length = 0;
-      }
-#else
       buffer[0] = 0;
       Fl::e_length = 0;
-#endif
     }
     Fl::e_text = buffer;
     if (lParam & (1<<31)) { // key up events.
