This is a patch against Gtk+ 2.2.1 sources that fixes Windows specific problems

Mon May  5 01:34:32 2003	Arnaud Charlet <charlet@gnat.com>

	* gtk+/gdk/win32/gdkwindow-win32.c (gdk_window_move): Revert to
	simple implementation: fixes top level windows going out of screen.
	* gtk+/gdk/win32/gdkevents-win32.c (build_keypress_event): Properly
	differenciate between Control-<key> and Shift-Control-<key>.

Thu Mar 27 18:16:10 2003	Arnaud Charlet <charlet@gnat.com>

	* gtk+/gdk/win32/gdkwindow-win32.c: Bring parent window on top when
	destroying a modal window. Fixes unexpected lost focus.

Fri Mar 14 12:50:58 2003	Arnaud Charlet <charlet@gnat.com>

	* pango/modules/basic/basic-win32.c: Disable undefined macros

Wed Jan 15 14:18:23  2003       Arnaud Charlet <charlet@gnat.com>

	* gtk+/gdk/win32/gdkevents-win32.c: Fix handling of negative coordinates
	* gtk+/gtk/gtkmenuitem.c: Ditto

Mon Nov 25 12:00:14  2002	Arnaud Charlet <charlet@gnat.com>

	* gtk+/gdk/win32/Makefile.am: Remove gdk-win32res.lo dependency,
	since we do not want to use the default Gtk+ icon.

Thu Sep 12 18:03:02 2002        Florent Duguet <duguet@gnat.com>

	* gtk+/gdk/win32/gdkevents-win32.c: Force an update when paint message
	is received, otherwise windows in background are not immediately
	refreshed when moving a modal window on top of them.
	Add handling of WM_NCPAINT message to refresh some areas when a window
	from another application is moved on top of the current app.

Thu Sep 12 18:03:02 2002        Florent Duguet <duguet@gnat.com>

	* gtk+/gtk/gtktextview.c: Improve handling of selections under Windows

#########################################
# Selection problem B430-008
#########################################

--- gtk+/gtk/gtktextview.c.old	2002-11-05 11:11:07 +0100
+++ gtk+/gtk/gtktextview.c	2002-11-05 11:11:25 +0100
@@ -3937,8 +3937,10 @@
 
   text_view = GTK_TEXT_VIEW (widget);
 
+#if 0
   if (event->window != text_view->text_window->bin_window)
     return FALSE;
+#endif
 
   if (event->button == 1)
     {

--- gtk+/gdk/win32/gdkevents-win32.c	2003/03/27 11:08:56	1.2
+++ gtk+/gdk/win32/gdkevents-win32.c	2003/03/27 14:11:31
@@ -2910,6 +2910,12 @@
 	  _gdk_window_process_expose (window, update_region);
 	  gdk_region_destroy (update_region);
 	  return_val = FALSE;
+
+          /* Force a process_updates to refresh visible windows
+           * when receiving a paint message. */
+ 
+          if (!GDK_WINDOW_DESTROYED (window) && gdk_window_is_visible (window))
+            gdk_window_process_updates (window, FALSE);
         }
       DeleteObject (hrgn);
       break;
--- gtk+/gdk/win32/gdkevents-win32.c	2003/04/13 09:25:27	1.3
+++ gtk+/gdk/win32/gdkevents-win32.c	2003/04/13 09:49:57
@@ -2823,6 +2823,31 @@
       *ret_valp = 1;
       break;
 
+    case WM_NCPAINT:
+      if (msg->wParam < 1)
+	break;
+
+      hrgn = CreateRectRgn (0, 0, 0, 0);
+      if (GetUpdateRgn (msg->hwnd, hrgn, FALSE) == ERROR)
+	{
+	  WIN32_GDI_FAILED ("GetUpdateRgn");
+	  break;
+	}
+
+      {
+        GdkRegion *update_region = _gdk_win32_hrgn_to_region (hrgn);
+
+	_gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
+	gdk_region_offset (update_region, xoffset, yoffset);
+
+	_gdk_window_process_expose (window, update_region);
+	gdk_region_destroy (update_region);
+
+	DeleteObject (hrgn);
+	return_val = FALSE;
+      }
+      break;
+
     case WM_PAINT:
       hrgn = CreateRectRgn (0, 0, 0, 0);
       if (GetUpdateRgn (msg->hwnd, hrgn, FALSE) == ERROR)
--- gtk+/gdk/win32/Makefile.am	2002/11/25 10:58:36	1.1
+++ gtk+/gdk/win32/Makefile.am	2002/11/25 10:59:18
@@ -79,4 +79,4 @@
 libgdkinclude_HEADERS =		\
 	gdkwin32.h
 
-libgdk_win32_la_LIBADD = rc/gdk-win32res.lo
+libgdk_win32_la_LIBADD =

--- gdkevents-win32.c.orig	2003-01-21 23:44:47 +0100
+++ gdkevents-win32.c	2003-03-14 12:26:01 +0100
@@ -51,6 +51,8 @@
 #include "gdkinput-win32.h"
 #include "gdkkeysyms.h"
 
+#include <windowsx.h>
+
 #ifdef G_WITH_CYGWIN
 #include <fcntl.h>
 #include <errno.h>
@@ -171,8 +173,8 @@
   msg.lParam = lparam;
   msg.time = _gdk_win32_get_next_tick (0);
   pos = GetMessagePos ();
-  msg.pt.x = LOWORD (pos);
-  msg.pt.y = HIWORD (pos);
+  msg.pt.x = GET_X_LPARAM (pos);
+  msg.pt.y = GET_Y_LPARAM (pos);
 
   event = gdk_event_new (GDK_NOTHING);
   ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
@@ -1220,11 +1222,11 @@
   if (!(GDK_WINDOW_OBJECT (window)->event_mask & GDK_ENTER_NOTIFY_MASK))
     return;
 
-  /* Enter events are at LOWORD (msg->lParam), HIWORD
+  /* Enter events are at GET_X_LPARAM (msg->lParam), GET_Y_LPARAM
    * (msg->lParam) in msg->hwnd */
 
-  pt.x = LOWORD (msg->lParam);
-  pt.y = HIWORD (msg->lParam);
+  pt.x = GET_X_LPARAM (msg->lParam);
+  pt.y = GET_Y_LPARAM (msg->lParam);
   if (msg->hwnd != GDK_WINDOW_HWND (window))
     {
       ClientToScreen (msg->hwnd, &pt);
@@ -1464,11 +1466,12 @@
 {
   POINT pt;
 
-  pt.x = LOWORD (msg->lParam);
-  pt.y = HIWORD (msg->lParam);
+  pt.x = GET_X_LPARAM (msg->lParam);
+  pt.y = GET_Y_LPARAM (msg->lParam);
   ClientToScreen (GDK_WINDOW_HWND (window1), &pt);
   ScreenToClient (GDK_WINDOW_HWND (window2), &pt);
   msg->lParam = MAKELPARAM (pt.x, pt.y);
+
   GDK_NOTE (EVENTS, g_print ("...new coords are (%ld,%ld)\n", pt.x, pt.y));
 }
 
@@ -1971,8 +1974,8 @@
        * around that. Also, the position is in screen coordinates, not
        * client coordinates as with the button messages.
        */
-      pt.x = LOWORD (msg->lParam);
-      pt.y = HIWORD (msg->lParam);
+      pt.x = GET_X_LPARAM (msg->lParam);
+      pt.y = GET_Y_LPARAM (msg->lParam);
       if ((hwnd = WindowFromPoint (pt)) == NULL)
 	goto done;
 
@@ -2010,8 +2013,8 @@
       _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
       event->scroll.x = (gint16) pt.x + xoffset;
       event->scroll.y = (gint16) pt.y + yoffset;
-      event->scroll.x_root = (gint16) LOWORD (msg->lParam);
-      event->scroll.y_root = (gint16) HIWORD (msg->lParam);
+      event->scroll.x_root = (gint16) GET_X_LPARAM (msg->lParam);
+      event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam);
       event->scroll.state = 0;	/* No state information with MSH_MOUSEWHEEL */
       event->scroll.device = display->core_pointer;
       return_val = !GDK_WINDOW_DESTROYED (window);
@@ -2490,7 +2493,7 @@
 		g_print ("WM_%cBUTTONDOWN: %p  (%d,%d)\n",
 			 " LMR"[button],
 			 msg->hwnd,
-			 LOWORD (msg->lParam), HIWORD (msg->lParam)));
+			 GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
 
       if (GDK_WINDOW_OBJECT (window)->extension_events != 0
 	  && _gdk_input_ignore_core)
@@ -2530,8 +2533,8 @@
       event->button.time = _gdk_win32_get_next_tick (msg->time);
       if (window != orig_window)
 	translate_mouse_coords (orig_window, window, msg);
-      event->button.x = current_x = (gint16) LOWORD (msg->lParam);
-      event->button.y = current_y = (gint16) HIWORD (msg->lParam);
+      event->button.x = current_x = (gint16) GET_X_LPARAM (msg->lParam);
+      event->button.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam);
       _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
       event->button.x += xoffset;  /* XXX translate current_x, y too? */
       event->button.y += yoffset;
@@ -2559,7 +2562,7 @@
 		g_print ("WM_%cBUTTONUP: %p  (%d,%d)\n",
 			 " LMR"[button],
 			 msg->hwnd,
-			 LOWORD (msg->lParam), HIWORD (msg->lParam)));
+			 GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
 
       ASSIGN_WINDOW (find_window_for_pointer_event (window, msg));
 
@@ -2588,8 +2591,8 @@
 	  if (window != orig_window)
 	    translate_mouse_coords (orig_window, window, msg);
 	  _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
-	  event->button.x = (gint16) LOWORD (msg->lParam) + xoffset;
-	  event->button.y = (gint16) HIWORD (msg->lParam) + yoffset;
+	  event->button.x = (gint16) GET_X_LPARAM (msg->lParam) + xoffset;
+	  event->button.y = (gint16) GET_Y_LPARAM (msg->lParam) + yoffset;
 	  event->button.x_root = current_x_root = msg->pt.x;
 	  event->button.y_root = current_y_root = msg->pt.y;
 	  event->button.axes = NULL;
@@ -2610,7 +2613,7 @@
       GDK_NOTE (EVENTS,
 		g_print ("WM_MOUSEMOVE: %p  %#x (%d,%d)\n",
 			 msg->hwnd, msg->wParam,
-			 LOWORD (msg->lParam), HIWORD (msg->lParam)));
+			 GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
 
       ASSIGN_WINDOW (find_window_for_pointer_event (window, msg));
 
@@ -2619,8 +2622,8 @@
        * even if the mouse doesn't move. This disturbs gtk.
        */
       if (window == current_window
-	  && LOWORD (msg->lParam) == current_x
-	  && HIWORD (msg->lParam) == current_y)
+	  && GET_X_LPARAM (msg->lParam) == current_x
+	  && GET_Y_LPARAM (msg->lParam) == current_y)
 	break;
 
       /* HB: only process mouse move messages if we own the active window. */
@@ -2650,8 +2653,8 @@
       event->motion.time = _gdk_win32_get_next_tick (msg->time);
       if (window != orig_window)
 	translate_mouse_coords (orig_window, window, msg);
-      event->motion.x = current_x = (gint16) LOWORD (msg->lParam);
-      event->motion.y = current_y = (gint16) HIWORD (msg->lParam);
+      event->motion.x = current_x = (gint16) GET_X_LPARAM (msg->lParam);
+      event->motion.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam);
       _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
       event->motion.x += xoffset;
       event->motion.y += yoffset;
@@ -2669,7 +2672,7 @@
       GDK_NOTE (EVENTS,
 		g_print ("WM_NCMOUSEMOVE: %p  x,y: %d %d\n",
 			 msg->hwnd,
-			 LOWORD (msg->lParam), HIWORD (msg->lParam)));
+			 GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
       if (current_window != NULL
 	  && (GDK_WINDOW_OBJECT (current_window)->event_mask & GDK_LEAVE_NOTIFY_MASK))
 	{
@@ -2702,7 +2705,7 @@
 
     case WM_MOUSEWHEEL:
       GDK_NOTE (EVENTS, g_print ("WM_MOUSEWHEEL: %p %d\n",
-				 msg->hwnd, HIWORD (msg->wParam)));
+				 msg->hwnd, GET_Y_LPARAM (msg->wParam)));
 
       event->scroll.type = GDK_SCROLL;
 
@@ -2711,8 +2714,8 @@
        * coordinates as with the button messages. I love the
        * consistency of Windows.
        */
-      pt.x = LOWORD (msg->lParam);
-      pt.y = HIWORD (msg->lParam);
+      pt.x = GET_X_LPARAM (msg->lParam);
+      pt.y = GET_Y_LPARAM (msg->lParam);
       if ((hwnd = WindowFromPoint (pt)) == NULL)
 	break;
 
@@ -2750,8 +2753,8 @@
       _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
       event->scroll.x = (gint16) pt.x + xoffset;
       event->scroll.y = (gint16) pt.y + yoffset;
-      event->scroll.x_root = (gint16) LOWORD (msg->lParam);
-      event->scroll.y_root = (gint16) HIWORD (msg->lParam);
+      event->scroll.x_root = (gint16) GET_X_LPARAM (msg->lParam);
+      event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam);
       event->scroll.state = build_pointer_event_state (msg);
       event->scroll.device = display->core_pointer;
       return_val = !GDK_WINDOW_DESTROYED (window);
@@ -3105,7 +3108,7 @@
     case WM_MOVE:
       GDK_NOTE (EVENTS, g_print ("WM_MOVE: %p  (%d,%d)\n",
 				 msg->hwnd,
-				 LOWORD (msg->lParam), HIWORD (msg->lParam)));
+				 GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
 
       if (!(private->event_mask & GDK_STRUCTURE_MASK))
 	break;
@@ -3116,8 +3119,8 @@
 	{
 	  event->configure.type = GDK_CONFIGURE;
 	  event->configure.window = window;
-	  event->configure.x = LOWORD (msg->lParam);
-	  event->configure.y = HIWORD (msg->lParam);
+	  event->configure.x = GET_X_LPARAM (msg->lParam);
+	  event->configure.y = GET_Y_LPARAM (msg->lParam);
 	  GetClientRect (msg->hwnd, &rect);
 	  event->configure.width = rect.right;
 	  event->configure.height = rect.bottom;
--- pango/modules/basic/basic-win32.c.old	2003-03-14 11:36:44 +0100
+++ pango/modules/basic/basic-win32.c	2003-03-14 11:37:20 +0100
@@ -303,7 +303,6 @@
     {
 #define CASE(n) case LANG_##n: return #n
       CASE (NEUTRAL);
-      CASE (INVARIANT);
       CASE (AFRIKAANS);
       CASE (ALBANIAN);
       CASE (ARABIC);
@@ -319,7 +318,6 @@
       CASE (CROATIAN);
       CASE (CZECH);
       CASE (DANISH);
-      CASE (DIVEHI);
       CASE (DUTCH);
       CASE (ENGLISH);
       CASE (ESTONIAN);
@@ -327,7 +325,6 @@
       CASE (FARSI);
       CASE (FINNISH);
       CASE (FRENCH);
-      CASE (GALICIAN);
       CASE (GEORGIAN);
       CASE (GERMAN);
       CASE (GREEK);
@@ -344,7 +341,6 @@
       CASE (KAZAK);
       CASE (KONKANI);
       CASE (KOREAN);
-      CASE (KYRGYZ);
       CASE (LATVIAN);
       CASE (LITHUANIAN);
       CASE (MACEDONIAN);
@@ -352,7 +348,6 @@
       CASE (MALAYALAM);
       CASE (MANIPURI);
       CASE (MARATHI);
-      CASE (MONGOLIAN);
       CASE (NEPALI);
       CASE (NORWEGIAN);
       CASE (ORIYA);
@@ -368,7 +363,6 @@
       CASE (SPANISH);
       CASE (SWAHILI);
       CASE (SWEDISH);
-      CASE (SYRIAC);
       CASE (TAMIL);
       CASE (TATAR);
       CASE (TELUGU);
--- gtk+/gtk/gtkmenuitem.c.orig	2003-01-29 21:20:03 +0100
+++ gtk+/gtk/gtkmenuitem.c	2003-03-14 12:32:06 +0100
@@ -923,7 +923,7 @@
   GtkWidget *parent_menu_item;
   GdkScreen *screen;
   gint twidth, theight;
-  gint tx, ty;
+  gint tx, ty, otx, oty;
   GtkTextDirection direction;
   GdkRectangle monitor;
   gint monitor_num;
@@ -946,14 +946,14 @@
     monitor_num = 0;
   gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
 
-  if (!gdk_window_get_origin (widget->window, &tx, &ty))
+  if (!gdk_window_get_origin (widget->window, &otx, &oty))
     {
       g_warning ("Menu not on screen");
       return;
     }
 
-  tx += widget->allocation.x;
-  ty += widget->allocation.y;
+  tx = otx + widget->allocation.x;
+  ty = oty + widget->allocation.y;
 
   switch (menu_item->submenu_placement)
     {
@@ -1013,14 +1013,14 @@
       ty += widget->allocation.height / 4;
 
       /* If the height of the menu doesn't fit we move it upward. */
-      ty = CLAMP (ty, monitor.y, MAX (monitor.y, monitor.y + monitor.height - theight));
+      ty = oty < 0 ? ty : CLAMP (ty, monitor.y, MAX (monitor.y, monitor.y + monitor.height - theight));
       break;
     }
 
   /* If we have negative, tx, here it is because we can't get
    * the menu all the way on screen. Favor the left portion.
    */
-  *x = CLAMP (tx, monitor.x, MAX (monitor.x, monitor.x + monitor.width - twidth));
+  *x = otx < 0 ? tx : CLAMP (tx, monitor.x, MAX (monitor.x, monitor.x + monitor.width - twidth));
   *y = ty;
 }
 
--- gtk+/gdk/win32/gdkwindow-win32.c	2003/03/27 14:43:01	1.1
+++ gtk+/gdk/win32/gdkwindow-win32.c	2003/04/13 09:22:48
@@ -742,6 +742,15 @@
   GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy %p\n",
 			   GDK_WINDOW_HWND (window)));
 
+  if (private->modal_hint)
+    {
+      HWND parent = (HWND) GetWindowLong
+	(GDK_WINDOW_HWND (window), GWL_HWNDPARENT);
+
+      if ((long)parent > 1 && !BringWindowToTop (parent))
+	WIN32_API_FAILED ("BringWindowToTop");
+    }
+
   if (private->extension_events != 0)
     _gdk_input_window_destroy (window);
 
--- gtk+/gdk/win32/gdkwindow-win32.c	2003/05/04 21:27:07	1.2
+++ gtk+/gdk/win32/gdkwindow-win32.c	2003/05/04 21:28:25
@@ -986,6 +986,7 @@
 				       impl->width, impl->height);
       else
 	{
+#if 0
 	  /* SetWindowPos uses non-client coordinates, we have client
 	   * coordinates. Thus offset them.
 	   */
@@ -998,6 +999,12 @@
 	                     x + rect.left, y + rect.top, 0, 0,
 	                     SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER))
 	    WIN32_API_FAILED ("SetWindowPos");
+#else
+	  if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL,
+			     x, y, impl->width, impl->height,
+			     SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER))
+	    WIN32_API_FAILED ("SetWindowPos");
+#endif
 	}
     }
 }
--- gtk+/gdk/win32/gdkevents-win32.c	2003/05/05 10:28:49	1.5
+++ gtk+/gdk/win32/gdkevents-win32.c	2003/05/05 10:44:46
@@ -883,6 +883,8 @@
   event->key.group = 0;		/* ??? */
   event->key.keyval = GDK_VoidSymbol;
   
+  build_key_event_state (event);
+
   if (msg->message == WM_IME_COMPOSITION)
     {
       himc = ImmGetContext (msg->hwnd);
@@ -906,7 +908,12 @@
 	      /* For ASCII control chars, the keyval should be the
 	       * corresponding ASCII character.
 	       */
-	      event->key.keyval = msg->wParam + '@';
+
+	      if ((event->key.state & GDK_SHIFT_MASK) == 0)
+		event->key.keyval = gdk_keyval_to_lower (msg->wParam + '@');
+	      else
+		event->key.keyval = msg->wParam + '@';
+
 	      /* This is needed in case of Alt+nnn or Alt+0nnn (on the numpad)
 	       * where nnn<32
 	       */
@@ -940,8 +947,6 @@
 				    wbuf, G_N_ELEMENTS (wbuf));
     }
 
-  build_key_event_state (event);
-
   /* Build UTF-8 string */
   if (ucount > 0)
     {
