diff --git a/ChangeLog b/ChangeLog index 1cd046afa1..2272501761 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,94 @@ +2003-08-07 Tor Lillqvist + + * gdk/win32/gdkinput-win32.h + * gdk/win32/gdkinput-win32.c (_gdk_input_configure_event, + _gdk_input_enter_event): Drop the GdkEvent* parameter, it wasn't + used. + + * gdk/win32/gdkevents-win32.c (gdk_event_translate): Adapt caller + accordingly, in fact an uninitialised variable was dereferenced. + + + [Win32] Add support for multiple monitors. + + * gdk/win32/gdkprivate-win32.h + * gdk/win32/gdkglobals-win32.c: New global variables for + multiple-monitor info: _gdk_num_monitors, _gdk_monitors, and + _gdk_offset_x and _gdk_offset_y. + + * gdk/win32/gdkdisplay-win32.c (count_monitor, enum_monitor): New + functions, enumeration functions passed to + EnumDisplayMonitors(). + + (gdk_display_open): If the EnumDisplayMonitors() and + GetMonitorInfo() API is present (on Win98, Win2000 and newer), use + if to find out monitor info. + + Calculate the offset between Win32 coordinates (relative to the + primary monitor's origin (and thus negative on monitors to the + left of or above it), and GDK's + (visible coordinates should be non-negative). + + * gdk/win32/gdkscreen-win32 (gdk_screen_get_n_monitors, + gdk_screen_get_monitor_geometry): Use information collected above. + + (gdk_window_move, gdk_window_move_resize_window_get_geometry): Subtract + _gdk_offset_{x,y} from GDK root window coordinates. + + (gdk_window_get_geometry, gdk_window_get_origin, + gdk_window_get_frame_extents): For top-level windows, add + _gdk_offset_{x,y} to GDK root window coordinates + + Still need to handle multiple monitors in + gdk_window_fullscreen(). Probably should make the window + fullscreen on the monitor where the cursor is? + + * gdk/win32/gdkevents-win32.c: Add _gdk_offset_{x,y} to all GDK + root window coordinates in GdkEvents. + + + [Win32] Fix geometry hint handling. Add support for resize + increment and base size, and aspect ratio geometry hints. The + "gridded geometry" test in testgtk now works beautifully. + + * gdk/win32/gdkwindow-win32.c (gdk_window_set_geometry_hints): + Turns out this function shouldn't actually ever modify the + window's size, just store the hints. (Old code kept for a while + inside #if 0.) + + (gdk_window_set_hints): Remove presumably broken code that handles + the position hints, this function is obsolete anyway. + + * gdk/win32/gdkevents-win32.c: Drop the current_{x,y}_root + variables, not used. + + (adjust_drag): New function, used to implement resize increment + hints. + + (gdk_event_translate): Handle WM_SIZING, implement resize + increment and base size, and aspect ratio geometry hints here. The + WM_GETMINMAXINFO handler takes care of the minimum and maximum + size hints as before. Fix the WM_GETMINMAXINFO handler to take + into account window decorations. No need to modify the + ptMaxPosition and ptMaxTrackSize fields in the MINMAXINFO struct, + the defaults are fine. + + * gdk/win32/gdkprivate-win32.h + * gdk/win32/gdkwindow-win32.c (_gdk_win32_adjust_client_rect, + _gdk_win32_get_adjusted_client_rect): New helper functions. + + + Merge from HEAD: 2003-08-07 Hans Breuer + + * gdk/win32/gdkevents-win32.c : finally use TrackMouseEvent + (only if the new window not known to Gdk) to get proper + leave notification, and get rid of the wrong placed + tooltips, bug #102283 + + (gdk_event_translate) : small code reordering to not get + GDK_MOTION_NOTIFY for still mouse and get back tooltips on + menus, bug #117367 + Thu Aug 7 16:49:29 2003 Owen Taylor * gtk/gtkwidget.c (gtk_widget_set_style_internal): diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 1cd046afa1..2272501761 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,94 @@ +2003-08-07 Tor Lillqvist + + * gdk/win32/gdkinput-win32.h + * gdk/win32/gdkinput-win32.c (_gdk_input_configure_event, + _gdk_input_enter_event): Drop the GdkEvent* parameter, it wasn't + used. + + * gdk/win32/gdkevents-win32.c (gdk_event_translate): Adapt caller + accordingly, in fact an uninitialised variable was dereferenced. + + + [Win32] Add support for multiple monitors. + + * gdk/win32/gdkprivate-win32.h + * gdk/win32/gdkglobals-win32.c: New global variables for + multiple-monitor info: _gdk_num_monitors, _gdk_monitors, and + _gdk_offset_x and _gdk_offset_y. + + * gdk/win32/gdkdisplay-win32.c (count_monitor, enum_monitor): New + functions, enumeration functions passed to + EnumDisplayMonitors(). + + (gdk_display_open): If the EnumDisplayMonitors() and + GetMonitorInfo() API is present (on Win98, Win2000 and newer), use + if to find out monitor info. + + Calculate the offset between Win32 coordinates (relative to the + primary monitor's origin (and thus negative on monitors to the + left of or above it), and GDK's + (visible coordinates should be non-negative). + + * gdk/win32/gdkscreen-win32 (gdk_screen_get_n_monitors, + gdk_screen_get_monitor_geometry): Use information collected above. + + (gdk_window_move, gdk_window_move_resize_window_get_geometry): Subtract + _gdk_offset_{x,y} from GDK root window coordinates. + + (gdk_window_get_geometry, gdk_window_get_origin, + gdk_window_get_frame_extents): For top-level windows, add + _gdk_offset_{x,y} to GDK root window coordinates + + Still need to handle multiple monitors in + gdk_window_fullscreen(). Probably should make the window + fullscreen on the monitor where the cursor is? + + * gdk/win32/gdkevents-win32.c: Add _gdk_offset_{x,y} to all GDK + root window coordinates in GdkEvents. + + + [Win32] Fix geometry hint handling. Add support for resize + increment and base size, and aspect ratio geometry hints. The + "gridded geometry" test in testgtk now works beautifully. + + * gdk/win32/gdkwindow-win32.c (gdk_window_set_geometry_hints): + Turns out this function shouldn't actually ever modify the + window's size, just store the hints. (Old code kept for a while + inside #if 0.) + + (gdk_window_set_hints): Remove presumably broken code that handles + the position hints, this function is obsolete anyway. + + * gdk/win32/gdkevents-win32.c: Drop the current_{x,y}_root + variables, not used. + + (adjust_drag): New function, used to implement resize increment + hints. + + (gdk_event_translate): Handle WM_SIZING, implement resize + increment and base size, and aspect ratio geometry hints here. The + WM_GETMINMAXINFO handler takes care of the minimum and maximum + size hints as before. Fix the WM_GETMINMAXINFO handler to take + into account window decorations. No need to modify the + ptMaxPosition and ptMaxTrackSize fields in the MINMAXINFO struct, + the defaults are fine. + + * gdk/win32/gdkprivate-win32.h + * gdk/win32/gdkwindow-win32.c (_gdk_win32_adjust_client_rect, + _gdk_win32_get_adjusted_client_rect): New helper functions. + + + Merge from HEAD: 2003-08-07 Hans Breuer + + * gdk/win32/gdkevents-win32.c : finally use TrackMouseEvent + (only if the new window not known to Gdk) to get proper + leave notification, and get rid of the wrong placed + tooltips, bug #102283 + + (gdk_event_translate) : small code reordering to not get + GDK_MOTION_NOTIFY for still mouse and get back tooltips on + menus, bug #117367 + Thu Aug 7 16:49:29 2003 Owen Taylor * gtk/gtkwidget.c (gtk_widget_set_style_internal): diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 1cd046afa1..2272501761 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,94 @@ +2003-08-07 Tor Lillqvist + + * gdk/win32/gdkinput-win32.h + * gdk/win32/gdkinput-win32.c (_gdk_input_configure_event, + _gdk_input_enter_event): Drop the GdkEvent* parameter, it wasn't + used. + + * gdk/win32/gdkevents-win32.c (gdk_event_translate): Adapt caller + accordingly, in fact an uninitialised variable was dereferenced. + + + [Win32] Add support for multiple monitors. + + * gdk/win32/gdkprivate-win32.h + * gdk/win32/gdkglobals-win32.c: New global variables for + multiple-monitor info: _gdk_num_monitors, _gdk_monitors, and + _gdk_offset_x and _gdk_offset_y. + + * gdk/win32/gdkdisplay-win32.c (count_monitor, enum_monitor): New + functions, enumeration functions passed to + EnumDisplayMonitors(). + + (gdk_display_open): If the EnumDisplayMonitors() and + GetMonitorInfo() API is present (on Win98, Win2000 and newer), use + if to find out monitor info. + + Calculate the offset between Win32 coordinates (relative to the + primary monitor's origin (and thus negative on monitors to the + left of or above it), and GDK's + (visible coordinates should be non-negative). + + * gdk/win32/gdkscreen-win32 (gdk_screen_get_n_monitors, + gdk_screen_get_monitor_geometry): Use information collected above. + + (gdk_window_move, gdk_window_move_resize_window_get_geometry): Subtract + _gdk_offset_{x,y} from GDK root window coordinates. + + (gdk_window_get_geometry, gdk_window_get_origin, + gdk_window_get_frame_extents): For top-level windows, add + _gdk_offset_{x,y} to GDK root window coordinates + + Still need to handle multiple monitors in + gdk_window_fullscreen(). Probably should make the window + fullscreen on the monitor where the cursor is? + + * gdk/win32/gdkevents-win32.c: Add _gdk_offset_{x,y} to all GDK + root window coordinates in GdkEvents. + + + [Win32] Fix geometry hint handling. Add support for resize + increment and base size, and aspect ratio geometry hints. The + "gridded geometry" test in testgtk now works beautifully. + + * gdk/win32/gdkwindow-win32.c (gdk_window_set_geometry_hints): + Turns out this function shouldn't actually ever modify the + window's size, just store the hints. (Old code kept for a while + inside #if 0.) + + (gdk_window_set_hints): Remove presumably broken code that handles + the position hints, this function is obsolete anyway. + + * gdk/win32/gdkevents-win32.c: Drop the current_{x,y}_root + variables, not used. + + (adjust_drag): New function, used to implement resize increment + hints. + + (gdk_event_translate): Handle WM_SIZING, implement resize + increment and base size, and aspect ratio geometry hints here. The + WM_GETMINMAXINFO handler takes care of the minimum and maximum + size hints as before. Fix the WM_GETMINMAXINFO handler to take + into account window decorations. No need to modify the + ptMaxPosition and ptMaxTrackSize fields in the MINMAXINFO struct, + the defaults are fine. + + * gdk/win32/gdkprivate-win32.h + * gdk/win32/gdkwindow-win32.c (_gdk_win32_adjust_client_rect, + _gdk_win32_get_adjusted_client_rect): New helper functions. + + + Merge from HEAD: 2003-08-07 Hans Breuer + + * gdk/win32/gdkevents-win32.c : finally use TrackMouseEvent + (only if the new window not known to Gdk) to get proper + leave notification, and get rid of the wrong placed + tooltips, bug #102283 + + (gdk_event_translate) : small code reordering to not get + GDK_MOTION_NOTIFY for still mouse and get back tooltips on + menus, bug #117367 + Thu Aug 7 16:49:29 2003 Owen Taylor * gtk/gtkwidget.c (gtk_widget_set_style_internal): diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 1cd046afa1..2272501761 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,94 @@ +2003-08-07 Tor Lillqvist + + * gdk/win32/gdkinput-win32.h + * gdk/win32/gdkinput-win32.c (_gdk_input_configure_event, + _gdk_input_enter_event): Drop the GdkEvent* parameter, it wasn't + used. + + * gdk/win32/gdkevents-win32.c (gdk_event_translate): Adapt caller + accordingly, in fact an uninitialised variable was dereferenced. + + + [Win32] Add support for multiple monitors. + + * gdk/win32/gdkprivate-win32.h + * gdk/win32/gdkglobals-win32.c: New global variables for + multiple-monitor info: _gdk_num_monitors, _gdk_monitors, and + _gdk_offset_x and _gdk_offset_y. + + * gdk/win32/gdkdisplay-win32.c (count_monitor, enum_monitor): New + functions, enumeration functions passed to + EnumDisplayMonitors(). + + (gdk_display_open): If the EnumDisplayMonitors() and + GetMonitorInfo() API is present (on Win98, Win2000 and newer), use + if to find out monitor info. + + Calculate the offset between Win32 coordinates (relative to the + primary monitor's origin (and thus negative on monitors to the + left of or above it), and GDK's + (visible coordinates should be non-negative). + + * gdk/win32/gdkscreen-win32 (gdk_screen_get_n_monitors, + gdk_screen_get_monitor_geometry): Use information collected above. + + (gdk_window_move, gdk_window_move_resize_window_get_geometry): Subtract + _gdk_offset_{x,y} from GDK root window coordinates. + + (gdk_window_get_geometry, gdk_window_get_origin, + gdk_window_get_frame_extents): For top-level windows, add + _gdk_offset_{x,y} to GDK root window coordinates + + Still need to handle multiple monitors in + gdk_window_fullscreen(). Probably should make the window + fullscreen on the monitor where the cursor is? + + * gdk/win32/gdkevents-win32.c: Add _gdk_offset_{x,y} to all GDK + root window coordinates in GdkEvents. + + + [Win32] Fix geometry hint handling. Add support for resize + increment and base size, and aspect ratio geometry hints. The + "gridded geometry" test in testgtk now works beautifully. + + * gdk/win32/gdkwindow-win32.c (gdk_window_set_geometry_hints): + Turns out this function shouldn't actually ever modify the + window's size, just store the hints. (Old code kept for a while + inside #if 0.) + + (gdk_window_set_hints): Remove presumably broken code that handles + the position hints, this function is obsolete anyway. + + * gdk/win32/gdkevents-win32.c: Drop the current_{x,y}_root + variables, not used. + + (adjust_drag): New function, used to implement resize increment + hints. + + (gdk_event_translate): Handle WM_SIZING, implement resize + increment and base size, and aspect ratio geometry hints here. The + WM_GETMINMAXINFO handler takes care of the minimum and maximum + size hints as before. Fix the WM_GETMINMAXINFO handler to take + into account window decorations. No need to modify the + ptMaxPosition and ptMaxTrackSize fields in the MINMAXINFO struct, + the defaults are fine. + + * gdk/win32/gdkprivate-win32.h + * gdk/win32/gdkwindow-win32.c (_gdk_win32_adjust_client_rect, + _gdk_win32_get_adjusted_client_rect): New helper functions. + + + Merge from HEAD: 2003-08-07 Hans Breuer + + * gdk/win32/gdkevents-win32.c : finally use TrackMouseEvent + (only if the new window not known to Gdk) to get proper + leave notification, and get rid of the wrong placed + tooltips, bug #102283 + + (gdk_event_translate) : small code reordering to not get + GDK_MOTION_NOTIFY for still mouse and get back tooltips on + menus, bug #117367 + Thu Aug 7 16:49:29 2003 Owen Taylor * gtk/gtkwidget.c (gtk_widget_set_style_internal): diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 1cd046afa1..2272501761 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,94 @@ +2003-08-07 Tor Lillqvist + + * gdk/win32/gdkinput-win32.h + * gdk/win32/gdkinput-win32.c (_gdk_input_configure_event, + _gdk_input_enter_event): Drop the GdkEvent* parameter, it wasn't + used. + + * gdk/win32/gdkevents-win32.c (gdk_event_translate): Adapt caller + accordingly, in fact an uninitialised variable was dereferenced. + + + [Win32] Add support for multiple monitors. + + * gdk/win32/gdkprivate-win32.h + * gdk/win32/gdkglobals-win32.c: New global variables for + multiple-monitor info: _gdk_num_monitors, _gdk_monitors, and + _gdk_offset_x and _gdk_offset_y. + + * gdk/win32/gdkdisplay-win32.c (count_monitor, enum_monitor): New + functions, enumeration functions passed to + EnumDisplayMonitors(). + + (gdk_display_open): If the EnumDisplayMonitors() and + GetMonitorInfo() API is present (on Win98, Win2000 and newer), use + if to find out monitor info. + + Calculate the offset between Win32 coordinates (relative to the + primary monitor's origin (and thus negative on monitors to the + left of or above it), and GDK's + (visible coordinates should be non-negative). + + * gdk/win32/gdkscreen-win32 (gdk_screen_get_n_monitors, + gdk_screen_get_monitor_geometry): Use information collected above. + + (gdk_window_move, gdk_window_move_resize_window_get_geometry): Subtract + _gdk_offset_{x,y} from GDK root window coordinates. + + (gdk_window_get_geometry, gdk_window_get_origin, + gdk_window_get_frame_extents): For top-level windows, add + _gdk_offset_{x,y} to GDK root window coordinates + + Still need to handle multiple monitors in + gdk_window_fullscreen(). Probably should make the window + fullscreen on the monitor where the cursor is? + + * gdk/win32/gdkevents-win32.c: Add _gdk_offset_{x,y} to all GDK + root window coordinates in GdkEvents. + + + [Win32] Fix geometry hint handling. Add support for resize + increment and base size, and aspect ratio geometry hints. The + "gridded geometry" test in testgtk now works beautifully. + + * gdk/win32/gdkwindow-win32.c (gdk_window_set_geometry_hints): + Turns out this function shouldn't actually ever modify the + window's size, just store the hints. (Old code kept for a while + inside #if 0.) + + (gdk_window_set_hints): Remove presumably broken code that handles + the position hints, this function is obsolete anyway. + + * gdk/win32/gdkevents-win32.c: Drop the current_{x,y}_root + variables, not used. + + (adjust_drag): New function, used to implement resize increment + hints. + + (gdk_event_translate): Handle WM_SIZING, implement resize + increment and base size, and aspect ratio geometry hints here. The + WM_GETMINMAXINFO handler takes care of the minimum and maximum + size hints as before. Fix the WM_GETMINMAXINFO handler to take + into account window decorations. No need to modify the + ptMaxPosition and ptMaxTrackSize fields in the MINMAXINFO struct, + the defaults are fine. + + * gdk/win32/gdkprivate-win32.h + * gdk/win32/gdkwindow-win32.c (_gdk_win32_adjust_client_rect, + _gdk_win32_get_adjusted_client_rect): New helper functions. + + + Merge from HEAD: 2003-08-07 Hans Breuer + + * gdk/win32/gdkevents-win32.c : finally use TrackMouseEvent + (only if the new window not known to Gdk) to get proper + leave notification, and get rid of the wrong placed + tooltips, bug #102283 + + (gdk_event_translate) : small code reordering to not get + GDK_MOTION_NOTIFY for still mouse and get back tooltips on + menus, bug #117367 + Thu Aug 7 16:49:29 2003 Owen Taylor * gtk/gtkwidget.c (gtk_widget_set_style_internal): diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c index 7efce884ea..2439f970a9 100644 --- a/gdk/win32/gdkdisplay-win32.c +++ b/gdk/win32/gdkdisplay-win32.c @@ -1,5 +1,6 @@ /* GDK - The GIMP Drawing Kit * Copyright (C) 2002 Hans Breuer + * Copyright (C) 2003 Tor Lillqvist * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,21 +21,157 @@ #include "gdk.h" #include "gdkprivate-win32.h" +typedef BOOL (WINAPI *t_EnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM); +typedef BOOL (WINAPI *t_GetMonitorInfoA)(HMONITOR, LPMONITORINFO); + +static t_EnumDisplayMonitors p_EnumDisplayMonitors = NULL; +static t_GetMonitorInfoA p_GetMonitorInfoA = NULL; + void _gdk_windowing_set_default_display (GdkDisplay *display) { g_assert (_gdk_display == display); } +static BOOL CALLBACK +count_monitor (HMONITOR hmonitor, + HDC hdc, + LPRECT rect, + LPARAM data) +{ + gint *n = (gint *) data; + + (*n)++; + + return TRUE; +} + +static BOOL CALLBACK +enum_monitor (HMONITOR hmonitor, + HDC hdc, + LPRECT rect, + LPARAM data) +{ + MONITORINFOEX monitor_info; + + gint *index = (gint *) data; + GdkRectangle *monitor; + + g_assert (*index < _gdk_num_monitors); + + monitor = _gdk_monitors + *index; + + monitor_info.cbSize = sizeof (MONITORINFOEX); + (*p_GetMonitorInfoA) (hmonitor, (MONITORINFO *) &monitor_info); + +#ifndef MONITORINFOF_PRIMARY +#define MONITORINFOF_PRIMARY 1 +#endif + + if (monitor_info.dwFlags & MONITORINFOF_PRIMARY) + { + /* For the primary monitor, use SPI_GETWORKAREA */ + RECT rect; + + SystemParametersInfo (SPI_GETWORKAREA, 0, &rect, 0); + monitor->x = rect.left; + monitor->y = rect.top; + monitor->width = rect.right - rect.left; + monitor->height = rect.bottom - rect.top; + + /* Put primary monitor at index 0, just in case somebody needs + * to know which one is the primary. + */ + if (*index != 0) + { + GdkRectangle temp = *monitor; + *monitor = _gdk_monitors[0]; + _gdk_monitors[0] = temp; + } + } + else + { + monitor->x = monitor_info.rcMonitor.left; + monitor->y = monitor_info.rcMonitor.top; + monitor->width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left; + monitor->height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top; + } + + (*index)++; + + return TRUE; +} + GdkDisplay * gdk_display_open (const gchar *display_name) { + HMODULE user32; + if (_gdk_display != NULL) return NULL; /* single display only */ _gdk_display = g_object_new (GDK_TYPE_DISPLAY, NULL); _gdk_screen = g_object_new (GDK_TYPE_SCREEN, NULL); + user32 = GetModuleHandle ("user32.dll"); + g_assert (user32 != NULL); + + p_EnumDisplayMonitors = (t_EnumDisplayMonitors) GetProcAddress (user32, "EnumDisplayMonitors"); + p_GetMonitorInfoA = (t_GetMonitorInfoA) GetProcAddress (user32, "GetMonitorInfoA"); + + CloseHandle (user32); + + if (p_EnumDisplayMonitors != NULL && p_GetMonitorInfoA != NULL) + { + gint i, index; + + _gdk_num_monitors = 0; + + (*p_EnumDisplayMonitors) (NULL, NULL, count_monitor, (LPARAM) &_gdk_num_monitors); + + _gdk_monitors = g_new (GdkRectangle, _gdk_num_monitors); + index = 0; + (*p_EnumDisplayMonitors) (NULL, NULL, enum_monitor, (LPARAM) &index); +#if 1 + _gdk_offset_x = G_MININT; + _gdk_offset_y = G_MININT; + + /* Calculate offset */ + for (i = 0; i < _gdk_num_monitors; i++) + { + _gdk_offset_x = MAX (_gdk_offset_x, -_gdk_monitors[i].x); + _gdk_offset_y = MAX (_gdk_offset_y, -_gdk_monitors[i].y); + } + GDK_NOTE (MISC, g_print ("Multi-monitor offset: (%d,%d)\n", + _gdk_offset_x, _gdk_offset_y)); + + /* Translate monitor coords into GDK coordinate space */ + for (i = 0; i < _gdk_num_monitors; i++) + { + _gdk_monitors[i].x += _gdk_offset_x; + _gdk_monitors[i].y += _gdk_offset_y; + GDK_NOTE (MISC, g_print ("Monitor %d: %dx%d@+%d+%d\n", + i, _gdk_monitors[i].width, + _gdk_monitors[i].height, + _gdk_monitors[i].x, _gdk_monitors[i].y)); + } +#endif + } + else + { + RECT rect; + + _gdk_num_monitors = 1; + _gdk_monitors = g_new (GdkRectangle, 1); + SystemParametersInfo (SPI_GETWORKAREA, 0, &rect, 0); + _gdk_monitors[0].x = rect.left; + _gdk_monitors[0].y = rect.top; + _gdk_monitors[0].width = rect.right - rect.left; + _gdk_monitors[0].height = rect.bottom - rect.top; + _gdk_offset_x = 0; + _gdk_offset_y = 0; + } + _gdk_visual_init (); gdk_screen_set_default_colormap (_gdk_screen, gdk_screen_get_system_colormap (_gdk_screen)); diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 6c3c687ca4..e0ce6b1258 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -31,6 +31,12 @@ * otherwise would make it possible to reliably generate * GDK_LEAVE_NOTIFY events, which would help get rid of those pesky * tooltips sometimes popping up in the wrong place. + * + * Update: a combination of TrackMouseEvent, GetCursorPos and + * GetWindowPos can and is actually used to get rid of those + * pesky tooltips. It should be possible to use this for the + * whole ENTER/LEAVE NOTIFY handling but some platforms may + * not have TrackMouseEvent at all (?) --hb */ #include "config.h" @@ -119,7 +125,6 @@ GPollFD event_poll_fd; static GdkWindow *current_window = NULL; static gint current_x, current_y; -static gdouble current_x_root, current_y_root; #if 0 static UINT gdk_ping_msg; #endif @@ -151,6 +156,46 @@ assign_object (gpointer lhsp, } } +static void +track_mouse_event (DWORD dwFlags, HWND hwnd) +{ + typedef BOOL (WINAPI *PFN_TrackMouseEvent) (LPTRACKMOUSEEVENT); + static PFN_TrackMouseEvent p_TrackMouseEvent = NULL; + static int once = 0; + + if (!once) + { + HMODULE user32; + HINSTANCE commctrl32; + + user32 = GetModuleHandle ("user32.dll"); + if ((p_TrackMouseEvent = (PFN_TrackMouseEvent)GetProcAddress (user32, "TrackMouseEvent")) == NULL) + { + if ((commctrl32 = LoadLibrary ("commctrl32.dll")) != NULL) + p_TrackMouseEvent = (PFN_TrackMouseEvent) + GetProcAddress (commctrl32, "_TrackMouseEvent"); + } + if (p_TrackMouseEvent != NULL) + GDK_NOTE (EVENTS, g_print ("Using TrackMouseEvent to detect leave events\n")); + + once = 1; + } + + if (p_TrackMouseEvent) + { + TRACKMOUSEEVENT tme; + tme.cbSize = sizeof(TRACKMOUSEEVENT); + tme.dwFlags = dwFlags; + tme.hwndTrack = hwnd; + tme.dwHoverTime = HOVER_DEFAULT; /* not used */ + + if (!p_TrackMouseEvent (&tme)) + WIN32_API_FAILED ("TrackMouseEvent"); + else + GDK_NOTE (EVENTS, g_print("TrackMouseEvent (%p, %s)\n", hwnd, dwFlags == TME_CANCEL ? "cancel" : "leave")); + } +} + gulong _gdk_win32_get_next_tick (gulong suggested_tick) { @@ -1156,8 +1201,8 @@ synthesize_enter_or_leave_event (GdkWindow *window, _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset); event->crossing.x = x + xoffset; event->crossing.y = y + yoffset; - event->crossing.x_root = msg->pt.x; - event->crossing.y_root = msg->pt.y; + event->crossing.x_root = msg->pt.x + _gdk_offset_x; + event->crossing.y_root = msg->pt.y + _gdk_offset_y; event->crossing.mode = mode; event->crossing.detail = detail; event->crossing.focus = TRUE; /* FIXME: Set correctly */ @@ -1167,7 +1212,7 @@ synthesize_enter_or_leave_event (GdkWindow *window, if (type == GDK_ENTER_NOTIFY && ((GdkWindowObject *) window)->extension_events != 0) - _gdk_input_enter_event (&event->crossing, window); + _gdk_input_enter_event (window); } static void @@ -1194,6 +1239,11 @@ synthesize_leave_event (GdkWindow *window, else synthesize_enter_or_leave_event (window, msg, GDK_LEAVE_NOTIFY, mode, detail, current_x, current_y); + /* This would only make sense if the WM_MOUSEMOVE messages would come + * before the respective WM_MOUSELEAVE message, which apparently they + * do not. + track_mouse_event (TME_CANCEL, msg->hwnd); + */ } static void @@ -1219,6 +1269,8 @@ synthesize_enter_event (GdkWindow *window, ScreenToClient (GDK_WINDOW_HWND (window), &pt); } synthesize_enter_or_leave_event (window, msg, GDK_ENTER_NOTIFY, mode, detail, pt.x, pt.y); + + track_mouse_event (TME_LEAVE, msg->hwnd); } static void @@ -1604,7 +1656,13 @@ handle_configure_event (MSG *msg, event->configure.x = point.x; event->configure.y = point.y; - + + if (gdk_window_get_parent (window) == _gdk_parent_root) + { + event->configure.x += _gdk_offset_x; + event->configure.y += _gdk_offset_y; + } + append_event (gdk_drawable_get_display (window), event); } } @@ -1769,7 +1827,7 @@ _gdk_win32_hrgn_to_region (HRGN hrgn) RECT *rects; GdkRegion *result; gint nbytes; - gint i; + guint i; if ((nbytes = GetRegionData (hrgn, 0, NULL)) == 0) { @@ -1805,6 +1863,17 @@ _gdk_win32_hrgn_to_region (HRGN hrgn) return result; } +static void +adjust_drag (LONG *drag, + LONG curr, + gint inc) +{ + if (*drag > curr) + *drag = curr + ((*drag + inc/2 - curr) / inc) * inc; + else + *drag = curr - ((curr - *drag + inc/2) / inc) * inc; +} + static gboolean gdk_event_translate (GdkDisplay *display, MSG *msg, @@ -1815,7 +1884,8 @@ gdk_event_translate (GdkDisplay *display, DWORD pidThis; PAINTSTRUCT paintstruct; HDC hdc; - POINT pt; + RECT rect, *drag, orig_drag; + POINT point; MINMAXINFO *mmi; HWND hwnd; HCURSOR hcursor; @@ -1943,9 +2013,9 @@ gdk_event_translate (GdkDisplay *display, * around that. Also, the position is in screen coordinates, not * client coordinates as with the button messages. */ - pt.x = GET_X_LPARAM (msg->lParam); - pt.y = GET_Y_LPARAM (msg->lParam); - if ((hwnd = WindowFromPoint (pt)) == NULL) + point.x = GET_X_LPARAM (msg->lParam); + point.y = GET_Y_LPARAM (msg->lParam); + if ((hwnd = WindowFromPoint (point)) == NULL) goto done; msg->hwnd = hwnd; @@ -1969,7 +2039,7 @@ gdk_event_translate (GdkDisplay *display, if (GDK_WINDOW_DESTROYED (window)) goto done; - ScreenToClient (msg->hwnd, &pt); + ScreenToClient (msg->hwnd, &point); event = gdk_event_new (GDK_SCROLL); event->scroll.window = window; @@ -1977,10 +2047,10 @@ gdk_event_translate (GdkDisplay *display, GDK_SCROLL_UP : GDK_SCROLL_DOWN; event->scroll.time = _gdk_win32_get_next_tick (msg->time); _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) GET_X_LPARAM (msg->lParam); - event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam); + event->scroll.x = (gint16) point.x + xoffset; + event->scroll.y = (gint16) point.y + yoffset; + event->scroll.x_root = (gint16) GET_X_LPARAM (msg->lParam) + _gdk_offset_x; + event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam) + _gdk_offset_y; event->scroll.state = 0; /* No state information with MSH_MOUSEWHEEL */ event->scroll.device = display->core_pointer; @@ -2303,8 +2373,8 @@ gdk_event_translate (GdkDisplay *display, _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset); event->button.x += xoffset; event->button.y += yoffset; - event->button.x_root = current_x_root = msg->pt.x; - event->button.y_root = current_y_root = msg->pt.y; + event->button.x_root = msg->pt.x + _gdk_offset_x; + event->button.y_root = msg->pt.y + _gdk_offset_y; event->button.axes = NULL; event->button.state = build_pointer_event_state (msg); event->button.button = button; @@ -2373,8 +2443,8 @@ gdk_event_translate (GdkDisplay *display, _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset); event->button.x += xoffset; event->button.y += yoffset; - event->button.x_root = current_x_root = msg->pt.x; - event->button.y_root = current_y_root = msg->pt.y; + event->button.x_root = msg->pt.x + _gdk_offset_x; + event->button.y_root = msg->pt.y + _gdk_offset_y; event->button.axes = NULL; event->button.state = build_pointer_event_state (msg); event->button.button = button; @@ -2433,6 +2503,12 @@ gdk_event_translate (GdkDisplay *display, doesnt_want_button_motion)) break; + if (GDK_WINDOW_DESTROYED (window)) + break; + + if (window != orig_window) + translate_mouse_coords (orig_window, window, msg); + /* If we haven't moved, don't create any event. * Windows sends WM_MOUSEMOVE messages after button presses * even if the mouse doesn't move. This disturbs gtk. @@ -2442,22 +2518,16 @@ gdk_event_translate (GdkDisplay *display, GET_Y_LPARAM (msg->lParam) == current_y) break; - if (GDK_WINDOW_DESTROYED (window)) - break; - event = gdk_event_new (GDK_MOTION_NOTIFY); event->motion.window = window; 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) 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; - event->motion.x_root = current_x_root = msg->pt.x; - event->motion.y_root = current_y_root = msg->pt.y; + event->motion.x_root = msg->pt.x + _gdk_offset_x; + event->motion.y_root = msg->pt.y + _gdk_offset_y; event->motion.axes = NULL; event->motion.state = build_pointer_event_state (msg); event->motion.is_hint = FALSE; @@ -2483,6 +2553,32 @@ gdk_event_translate (GdkDisplay *display, break; + case WM_MOUSELEAVE: + { + HWND wndnow; + POINT pt; + + if (!GetCursorPos (&pt)) + WIN32_API_FAILED ("GetCursorPos"); + wndnow = WindowFromPoint (pt); + + if (!gdk_win32_handle_table_lookup ((GdkNativeWindow) wndnow)) + { + /* we are only interested if we don't know the new window */ + GDK_NOTE (EVENTS, g_print ("WM_MOUSELEAVE: %p %d (%d,%d)\n", + msg->hwnd, HIWORD (msg->wParam), pt.x, pt.y)); + synthesize_enter_or_leave_event (current_window, msg, + GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_UNKNOWN, + current_x, current_y); + } + else + { + GDK_NOTE (EVENTS, g_print ("WM_MOUSELEAVE: %p %d (%d,%d) ignored\n", + msg->hwnd, HIWORD (msg->wParam), pt.x, pt.y)); + } + } + return_val = TRUE; + break; case WM_MOUSEWHEEL: GDK_NOTE (EVENTS, g_print ("WM_MOUSEWHEEL: %p %d\n", msg->hwnd, HIWORD (msg->wParam))); @@ -2492,10 +2588,10 @@ gdk_event_translate (GdkDisplay *display, * coordinates as with the button messages. I love the * consistency of Windows. */ - pt.x = GET_X_LPARAM (msg->lParam); - pt.y = GET_Y_LPARAM (msg->lParam); + point.x = GET_X_LPARAM (msg->lParam); + point.y = GET_Y_LPARAM (msg->lParam); - if ((hwnd = WindowFromPoint (pt)) == NULL) + if ((hwnd = WindowFromPoint (point)) == NULL) break; msg->hwnd = hwnd; @@ -2522,7 +2618,7 @@ gdk_event_translate (GdkDisplay *display, if (GDK_WINDOW_DESTROYED (window)) break; - ScreenToClient (msg->hwnd, &pt); + ScreenToClient (msg->hwnd, &point); event = gdk_event_new (GDK_SCROLL); event->scroll.window = window; @@ -2531,10 +2627,10 @@ gdk_event_translate (GdkDisplay *display, event->scroll.window = window; event->scroll.time = _gdk_win32_get_next_tick (msg->time); _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) GET_X_LPARAM (msg->lParam); - event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam); + event->scroll.x = (gint16) point.x + xoffset; + event->scroll.y = (gint16) point.y + yoffset; + event->scroll.x_root = (gint16) GET_X_LPARAM (msg->lParam) + _gdk_offset_x; + event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam) + _gdk_offset_y; event->scroll.state = build_pointer_event_state (msg); event->scroll.device = display->core_pointer; @@ -2808,46 +2904,193 @@ gdk_event_translate (GdkDisplay *display, ((GdkWindowObject *) window)->resize_count -= 1; if (((GdkWindowObject *) window)->extension_events != 0) - _gdk_input_configure_event (&event->configure, window); + _gdk_input_configure_event (window); return_val = TRUE; } break; + case WM_SIZING: + GetWindowRect (GDK_WINDOW_HWND (window), &rect); + GDK_NOTE (EVENTS, g_print ("WM_SIZING: %p %s curr:%s drag:%s\n", + msg->hwnd, + (msg->wParam == WMSZ_BOTTOM ? "BOTTOM" : + (msg->wParam == WMSZ_BOTTOMLEFT ? "BOTTOMLEFT" : + (msg->wParam == WMSZ_LEFT ? "LEFT" : + (msg->wParam == WMSZ_TOPLEFT ? "TOPLEFT" : + (msg->wParam == WMSZ_TOP ? "TOP" : + (msg->wParam == WMSZ_TOPRIGHT ? "TOPRIGHT" : + (msg->wParam == WMSZ_RIGHT ? "RIGHT" : + + (msg->wParam == WMSZ_BOTTOMRIGHT ? "BOTTOMRIGHT" : + "???")))))))), + _gdk_win32_rect_to_string (&rect), + _gdk_win32_rect_to_string ((RECT *) msg->lParam))); + + impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl); + drag = (RECT *) msg->lParam; + orig_drag = *drag; + if (impl->hint_flags & GDK_HINT_RESIZE_INC) + { + if (impl->hint_flags & GDK_HINT_BASE_SIZE) + { + /* Resize in increments relative to the base size */ + rect.left = rect.top = 0; + rect.right = impl->hints.base_width; + rect.bottom = impl->hints.base_height; + _gdk_win32_adjust_client_rect (window, &rect); + point.x = rect.left; + point.y = rect.top; + ClientToScreen (GDK_WINDOW_HWND (window), &point); + rect.left = point.x; + rect.top = point.y; + point.x = rect.right; + point.y = rect.bottom; + ClientToScreen (GDK_WINDOW_HWND (window), &point); + rect.right = point.x; + rect.bottom = point.y; + + GDK_NOTE (EVENTS, g_print ("...also BASE_SIZE, using %s\n", + _gdk_win32_rect_to_string (&rect))); + } + + switch (msg->wParam) + { + case WMSZ_BOTTOM: + if (drag->bottom == rect.bottom) + break; + adjust_drag (&drag->bottom, rect.bottom, impl->hints.height_inc); + + break; + + case WMSZ_BOTTOMLEFT: + if (drag->bottom == rect.bottom && drag->left == rect.left) + break; + adjust_drag (&drag->bottom, rect.bottom, impl->hints.height_inc); + adjust_drag (&drag->left, rect.left, impl->hints.width_inc); + break; + + case WMSZ_LEFT: + if (drag->left == rect.left) + break; + adjust_drag (&drag->left, rect.left, impl->hints.width_inc); + break; + + case WMSZ_TOPLEFT: + if (drag->top == rect.top && drag->left == rect.left) + break; + adjust_drag (&drag->top, rect.top, impl->hints.height_inc); + adjust_drag (&drag->left, rect.left, impl->hints.width_inc); + break; + + case WMSZ_TOP: + if (drag->top == rect.top) + break; + adjust_drag (&drag->top, rect.top, impl->hints.height_inc); + break; + + case WMSZ_TOPRIGHT: + if (drag->top == rect.top && drag->right == rect.right) + break; + adjust_drag (&drag->top, rect.top, impl->hints.height_inc); + adjust_drag (&drag->right, rect.right, impl->hints.width_inc); + break; + + case WMSZ_RIGHT: + if (drag->right == rect.right) + break; + adjust_drag (&drag->right, rect.right, impl->hints.width_inc); + break; + + case WMSZ_BOTTOMRIGHT: + if (drag->bottom == rect.bottom && drag->right == rect.right) + break; + adjust_drag (&drag->bottom, rect.bottom, impl->hints.height_inc); + adjust_drag (&drag->right, rect.right, impl->hints.width_inc); + break; + } + + if (drag->bottom != orig_drag.bottom || drag->left != orig_drag.left || + drag->top != orig_drag.top || drag->right != orig_drag.right) + { + *ret_valp = TRUE; + return_val = TRUE; + GDK_NOTE (EVENTS, g_print ("...handled RESIZE_INC: drag:%s\n", + _gdk_win32_rect_to_string (drag))); + } + } + + /* WM_GETMINMAXINFO handles min_size and max_size hints? */ + + if (impl->hint_flags & GDK_HINT_ASPECT) + { + gdouble drag_aspect = (gdouble) (drag->right - drag->left) / (drag->bottom - drag->top); + + GDK_NOTE (EVENTS, g_print ("... aspect:%g\n", drag_aspect)); + if (drag_aspect < impl->hints.min_aspect || + drag_aspect > impl->hints.max_aspect) + { + *drag = rect; + *ret_valp = TRUE; + return_val = TRUE; + GDK_NOTE (EVENTS, g_print ("...handled ASPECT: drag:%s\n", + _gdk_win32_rect_to_string (drag))); + } + } + break; + case WM_GETMINMAXINFO: GDK_NOTE (EVENTS, g_print ("WM_GETMINMAXINFO: %p\n", msg->hwnd)); + if (GDK_WINDOW_DESTROYED (window)) + break; + impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl); mmi = (MINMAXINFO*) msg->lParam; + GDK_NOTE (EVENTS, g_print ("...mintrack:%dx%d maxtrack:%dx%d " + "maxpos:+%d+%d maxsize:%dx%d\n", + mmi->ptMinTrackSize.x, mmi->ptMinTrackSize.y, + mmi->ptMaxTrackSize.x, mmi->ptMaxTrackSize.y, + mmi->ptMaxPosition.x, mmi->ptMaxPosition.y, + mmi->ptMaxSize.x, mmi->ptMaxSize.y)); + if (impl->hint_flags & GDK_HINT_MIN_SIZE) { - mmi->ptMinTrackSize.x = impl->hints.min_width; - mmi->ptMinTrackSize.y = impl->hints.min_height; + rect.left = rect.top = 0; + rect.right = impl->hints.min_width; + rect.bottom = impl->hints.min_height; + + _gdk_win32_adjust_client_rect (window, &rect); + + mmi->ptMinTrackSize.x = rect.right - rect.left; + mmi->ptMinTrackSize.y = rect.bottom - rect.top; } if (impl->hint_flags & GDK_HINT_MAX_SIZE) { - mmi->ptMaxTrackSize.x = impl->hints.max_width; - mmi->ptMaxTrackSize.y = impl->hints.max_height; + rect.left = rect.top = 0; + rect.right = impl->hints.max_width; + rect.bottom = impl->hints.max_height; - /* kind of WM functionality, limit maximized size to screen */ - mmi->ptMaxPosition.x = 0; - mmi->ptMaxPosition.y = 0; - mmi->ptMaxSize.x = MIN (impl->hints.max_width, gdk_screen_width ()); - mmi->ptMaxSize.y = MIN (impl->hints.max_height, gdk_screen_height ()); - } - else if (impl->hint_flags & GDK_HINT_MIN_SIZE) - { - /* need to initialize */ - mmi->ptMaxSize.x = gdk_screen_width (); - mmi->ptMaxSize.y = gdk_screen_height (); + _gdk_win32_adjust_client_rect (window, &rect); + + mmi->ptMaxTrackSize.x = rect.right - rect.left; + mmi->ptMaxTrackSize.y = rect.bottom - rect.top; } if (impl->hint_flags & (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE)) { /* Don't call DefWindowProc() */ + GDK_NOTE (EVENTS, g_print ("...handled, mintrack:%dx%d maxtrack:%dx%d " + "maxpos:+%d+%d maxsize:%dx%d\n", + mmi->ptMinTrackSize.x, mmi->ptMinTrackSize.y, + mmi->ptMaxTrackSize.x, mmi->ptMaxTrackSize.y, + mmi->ptMaxPosition.x, mmi->ptMaxPosition.y, + mmi->ptMaxSize.x, mmi->ptMaxSize.y)); return_val = TRUE; } + else + GDK_NOTE (EVENTS, g_print ("...let DefWindowProc handle it\n")); break; case WM_MOVE: diff --git a/gdk/win32/gdkglobals-win32.c b/gdk/win32/gdkglobals-win32.c index 4b73f20754..651ac883d7 100644 --- a/gdk/win32/gdkglobals-win32.c +++ b/gdk/win32/gdkglobals-win32.c @@ -32,6 +32,11 @@ GdkDisplay *_gdk_display = NULL; GdkScreen *_gdk_screen = NULL; GdkWindow *_gdk_parent_root = NULL; +gint _gdk_num_monitors; +GdkRectangle *_gdk_monitors; + +gint _gdk_offset_x, _gdk_offset_y; + HWND _gdk_root_window = NULL; HDC _gdk_display_hdc; HINSTANCE _gdk_dll_hinstance; diff --git a/gdk/win32/gdkinput-win32.c b/gdk/win32/gdkinput-win32.c index 88d5a5f566..e7431859c8 100644 --- a/gdk/win32/gdkinput-win32.c +++ b/gdk/win32/gdkinput-win32.c @@ -655,8 +655,7 @@ gdk_input_motion_events (GdkWindow *window, } void -_gdk_input_configure_event (GdkEventConfigure *event, - GdkWindow *window) +_gdk_input_configure_event (GdkWindow *window) { GdkInputWindow *input_window; int root_x, root_y; @@ -672,8 +671,7 @@ _gdk_input_configure_event (GdkEventConfigure *event, } void -_gdk_input_enter_event (GdkEventCrossing *event, - GdkWindow *window) +_gdk_input_enter_event (GdkWindow *window) { GdkInputWindow *input_window; int root_x, root_y; diff --git a/gdk/win32/gdkinput-win32.h b/gdk/win32/gdkinput-win32.h index e2401cf05e..0e79d23a27 100644 --- a/gdk/win32/gdkinput-win32.h +++ b/gdk/win32/gdkinput-win32.h @@ -137,10 +137,8 @@ GdkTimeCoord ** _gdk_device_allocate_history (GdkDevice *device, /* The following functions are provided by each implementation * (just wintab for now) */ -void _gdk_input_configure_event (GdkEventConfigure *event, - GdkWindow *window); -void _gdk_input_enter_event (GdkEventCrossing *event, - GdkWindow *window); +void _gdk_input_configure_event (GdkWindow *window); +void _gdk_input_enter_event (GdkWindow *window); gboolean _gdk_input_other_event (GdkEvent *event, MSG *msg, GdkWindow *window); diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h index 18f48049b8..807f6355f5 100644 --- a/gdk/win32/gdkprivate-win32.h +++ b/gdk/win32/gdkprivate-win32.h @@ -357,6 +357,12 @@ HRGN _gdk_win32_gdkregion_to_hrgn (GdkRegion *region, gint x_origin, gint y_origin); +void _gdk_win32_adjust_client_rect (GdkWindow *window, + RECT *RECT); + +void _gdk_win32_get_adjusted_client_rect (GdkWindow *window, + RECT *RECT); + void _gdk_selection_property_store (GdkWindow *owner, GdkAtom type, gint format, @@ -453,6 +459,16 @@ extern GdkWindow *_gdk_parent_root; extern GdkDisplay *_gdk_display; extern GdkScreen *_gdk_screen; +extern gint _gdk_num_monitors; +extern GdkRectangle *_gdk_monitors; + +/* Offsets to add to Windows coordinates (which are relative to the + * primary monitor's origin, and thus might be negative for monitors + * to the left and/or above the primary monitor) to get GDK + * coordinates, which should be non-negative on the whole screen. + */ +extern gint _gdk_offset_x, _gdk_offset_y; + extern HDC _gdk_display_hdc; extern HINSTANCE _gdk_dll_hinstance; extern HINSTANCE _gdk_app_hmodule; diff --git a/gdk/win32/gdkscreen-win32.c b/gdk/win32/gdkscreen-win32.c index 51850b27ea..cf69307d86 100644 --- a/gdk/win32/gdkscreen-win32.c +++ b/gdk/win32/gdkscreen-win32.c @@ -60,9 +60,9 @@ gdk_screen_set_default_colormap (GdkScreen *screen, gint gdk_screen_get_n_monitors (GdkScreen *screen) { - g_return_val_if_fail (GDK_IS_SCREEN (screen), 1); + g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); - return 1; + return _gdk_num_monitors; } void @@ -70,10 +70,11 @@ gdk_screen_get_monitor_geometry (GdkScreen *screen, gint num_monitor, GdkRectangle *dest) { - dest->x = 0; - dest->y = 0; - dest->width = gdk_screen_width (); - dest->height = gdk_screen_height (); + g_return_if_fail (GDK_IS_SCREEN (screen)); + g_return_if_fail (num_monitor < _gdk_num_monitors); + g_return_if_fail (num_monitor >= 0); + + *dest = _gdk_monitors[num_monitor]; } gint diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index 6006253c7a..87502e4146 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -153,6 +153,25 @@ gdk_window_impl_win32_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +void +_gdk_win32_adjust_client_rect (GdkWindow *window, + RECT *rect) +{ + LONG style, exstyle; + + style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE); + exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE); + API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle)); +} + +void +_gdk_win32_get_adjusted_client_rect (GdkWindow *window, + RECT *rect) +{ + GetClientRect (GDK_WINDOW_HWND (window), rect); + _gdk_win32_adjust_client_rect (window, rect); +} + static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable) { @@ -229,16 +248,11 @@ _gdk_windowing_window_init (void) GdkWindowObject *private; GdkWindowImplWin32 *impl; GdkDrawableImplWin32 *draw_impl; - RECT rect; - guint width; - guint height; + GdkRectangle rect; + gint i; g_assert (_gdk_parent_root == NULL); - SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0); - width = rect.right - rect.left; - height = rect.bottom - rect.top; - _gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL); private = (GdkWindowObject *)_gdk_parent_root; impl = GDK_WINDOW_IMPL_WIN32 (private->impl); @@ -252,8 +266,12 @@ _gdk_windowing_window_init (void) private->window_type = GDK_WINDOW_ROOT; private->depth = gdk_visual_get_system ()->depth; - impl->width = width; - impl->height = height; + rect = _gdk_monitors[0]; + for (i = 1; i < _gdk_num_monitors; i++) + gdk_rectangle_union (&rect, _gdk_monitors+i, &rect); + + impl->width = rect.width; + impl->height = rect.height; _gdk_window_init_position (GDK_WINDOW (private)); @@ -1065,7 +1083,7 @@ gdk_window_move (GdkWindow *window, adjust_for_gravity_hints (impl, &outer_rect, &x, &y); API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL, - x, y, 0, 0, + x - _gdk_offset_x, y - _gdk_offset_y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER)); } } @@ -1154,7 +1172,7 @@ gdk_window_move_resize (GdkWindow *window, adjust_for_gravity_hints (impl, &outer_rect, &x, &y); API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL, - x, y, + x - _gdk_offset_x, y - _gdk_offset_y, outer_rect.right - outer_rect.left, outer_rect.bottom - outer_rect.top, SWP_NOACTIVATE | SWP_NOZORDER)); @@ -1326,12 +1344,7 @@ gdk_window_set_hints (GdkWindow *window, /* Note that this function is obsolete */ GdkWindowImplWin32 *impl; - WINDOWPLACEMENT size_hints; - RECT rect; - DWORD dwStyle; - DWORD dwExStyle; - int diff; - + g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); @@ -1345,9 +1358,6 @@ gdk_window_set_hints (GdkWindow *window, min_width, min_height, max_width, max_height, x, y)); - impl->hint_flags = flags; - size_hints.length = sizeof (size_hints); - if (flags) { GdkGeometry geom; @@ -1358,50 +1368,6 @@ gdk_window_set_hints (GdkWindow *window, geom.max_width = max_width; geom.max_height = max_height; - if (flags & GDK_HINT_POS) - { - if (API_CALL (GetWindowPlacement, (GDK_WINDOW_HWND (window), &size_hints))) - { - GDK_NOTE (MISC, g_print ("...rcNormalPosition:" - " (%ld,%ld)--(%ld,%ld)\n", - size_hints.rcNormalPosition.left, - size_hints.rcNormalPosition.top, - size_hints.rcNormalPosition.right, - size_hints.rcNormalPosition.bottom)); - /* What are the corresponding window coordinates for client - * area coordinates x, y - */ - - /* FIXME: Is the hint client area pos or border? */ - rect.left = x; - rect.top = y; - rect.right = rect.left + 200; /* dummy */ - rect.bottom = rect.top + 200; - dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE); - dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE); - AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle); - size_hints.flags = 0; - size_hints.showCmd = SW_SHOWNA; - - /* Set the normal position hint to that location, with unchanged - * width and height. - */ - diff = size_hints.rcNormalPosition.left - rect.left; - size_hints.rcNormalPosition.left = rect.left; - size_hints.rcNormalPosition.right -= diff; - diff = size_hints.rcNormalPosition.top - rect.top; - size_hints.rcNormalPosition.top = rect.top; - size_hints.rcNormalPosition.bottom -= diff; - GDK_NOTE (MISC, g_print ("...setting: (%ld,%ld)--(%ld,%ld)\n", - size_hints.rcNormalPosition.left, - size_hints.rcNormalPosition.top, - size_hints.rcNormalPosition.right, - size_hints.rcNormalPosition.bottom)); - API_CALL (SetWindowPlacement, (GDK_WINDOW_HWND (window), - &size_hints)); - } - } - if (flags & GDK_HINT_MIN_SIZE) geom_mask |= GDK_HINT_MIN_SIZE; @@ -1418,10 +1384,12 @@ gdk_window_set_geometry_hints (GdkWindow *window, GdkWindowHints geom_mask) { GdkWindowImplWin32 *impl; +#if 0 WINDOWPLACEMENT size_hints; RECT rect; gint new_width = 0, new_height = 0; - +#endif + g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); @@ -1432,7 +1400,6 @@ gdk_window_set_geometry_hints (GdkWindow *window, GDK_WINDOW_HWND (window))); impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl); - size_hints.length = sizeof (size_hints); impl->hint_flags = geom_mask; impl->hints = *geometry; @@ -1445,6 +1412,7 @@ gdk_window_set_geometry_hints (GdkWindow *window, GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n", geometry->min_width, geometry->min_height)); +#if 0 /* Check if the current size of the window is in bounds */ GetClientRect (GDK_WINDOW_HWND (window), &rect); @@ -1464,6 +1432,7 @@ gdk_window_set_geometry_hints (GdkWindow *window, new_width = rect.right; new_height = geometry->min_height; } +#endif } if (geom_mask & GDK_HINT_MAX_SIZE) @@ -1471,6 +1440,7 @@ gdk_window_set_geometry_hints (GdkWindow *window, GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n", geometry->max_width, geometry->max_height)); +#if 0 /* Check if the current size of the window is in bounds */ GetClientRect (GDK_WINDOW_HWND (window), &rect); @@ -1490,20 +1460,23 @@ gdk_window_set_geometry_hints (GdkWindow *window, new_width = rect.right; new_height = geometry->max_height; } +#endif } +#if 0 /* Apply new size constraints */ if (new_width != 0 && new_height != 0) gdk_window_resize (window, new_width, new_height); - - /* I don't know what to do when called with zero base_width and height. */ - if (geom_mask & GDK_HINT_BASE_SIZE - && geometry->base_width > 0 - && geometry->base_height > 0) +#endif + + if (geom_mask & GDK_HINT_BASE_SIZE) { GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n", geometry->base_width, geometry->base_height)); +#if 0 + size_hints.length = sizeof (size_hints); + if (API_CALL (GetWindowPlacement, (GDK_WINDOW_HWND (window), &size_hints))) { GDK_NOTE (MISC, @@ -1523,6 +1496,7 @@ gdk_window_set_geometry_hints (GdkWindow *window, size_hints.rcNormalPosition.bottom)); API_CALL (SetWindowPlacement, (GDK_WINDOW_HWND (window), &size_hints)); } +#endif } if (geom_mask & GDK_HINT_RESIZE_INC) @@ -1806,6 +1780,14 @@ gdk_window_get_geometry (GdkWindow *window, ScreenToClient (GDK_WINDOW_HWND (parent), &pt); rect.right = pt.x; rect.bottom = pt.y; + + if (parent == _gdk_parent_root) + { + rect.left += _gdk_offset_x; + rect.top += _gdk_offset_y; + rect.right += _gdk_offset_x; + rect.bottom += _gdk_offset_y; + } } if (x) @@ -1853,9 +1835,9 @@ gdk_window_get_origin (GdkWindow *window, return_val = 0; if (x) - *x = tx; + *x = tx + _gdk_offset_x; if (y) - *y = ty; + *y = ty + _gdk_offset_y; GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %p: +%d+%d\n", GDK_WINDOW_HWND (window), @@ -1930,8 +1912,8 @@ gdk_window_get_frame_extents (GdkWindow *window, API_CALL (GetWindowRect, (hwnd, &r)); - rect->x = r.left; - rect->y = r.top; + rect->x = r.left + _gdk_offset_x; + rect->y = r.top + _gdk_offset_y; rect->width = r.right - r.left; rect->height = r.bottom - r.top; @@ -2113,8 +2095,6 @@ gdk_window_shape_combine_mask (GdkWindow *window, else { HRGN hrgn; - DWORD dwStyle; - DWORD dwExStyle; RECT rect; /* Convert mask bitmap to region */ @@ -2124,13 +2104,9 @@ gdk_window_shape_combine_mask (GdkWindow *window, GDK_WINDOW_HWND (window), GDK_WINDOW_HWND (mask))); - /* SetWindowRgn wants window (not client) coordinates */ - dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE); - dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE); - GetClientRect (GDK_WINDOW_HWND (window), &rect); - AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle); - OffsetRgn (hrgn, -rect.left, -rect.top); + _gdk_win32_get_adjusted_client_rect (window, &rect); + OffsetRgn (hrgn, -rect.left, -rect.top); OffsetRgn (hrgn, x, y); /* If this is a top-level window, add the title bar to the region */ @@ -2269,7 +2245,7 @@ gdk_window_set_icon (GdkWindow *window, } } - GDK_NOTE (MISC, g_print ("gdk_window_set_icon : %p %dx%d\n", hIcon, w, h)); + GDK_NOTE (MISC, g_print ("gdk_window_set_icon: %p: %p %dx%d\n", GDK_WINDOW_HWND (window), impl->hicon, w, h)); } void @@ -2670,9 +2646,6 @@ gdk_window_fullscreen (GdkWindow *window) g_return_if_fail (GDK_IS_WINDOW (window)); - width = GetSystemMetrics (SM_CXSCREEN); - height = GetSystemMetrics (SM_CYSCREEN); - fi = g_new (FullscreenInfo, 1); if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r))) @@ -2681,6 +2654,9 @@ gdk_window_fullscreen (GdkWindow *window) { GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl); + width = GetSystemMetrics (SM_CXSCREEN); + height = GetSystemMetrics (SM_CYSCREEN); + /* remember for restoring */ fi->hint_flags = impl->hint_flags; impl->hint_flags &= ~GDK_HINT_MAX_SIZE;