diff options
author | Tor Lillqvist <tml@iki.fi> | 2003-08-07 22:17:18 +0000 |
---|---|---|
committer | Tor Lillqvist <tml@src.gnome.org> | 2003-08-07 22:17:18 +0000 |
commit | 5155f3ca66d6fe94428a9885e2e6f118b14ea518 (patch) | |
tree | b341fb56a0489e0f3bbf22ed0ab91f87dda2e34c /gdk | |
parent | 9bfaab6e77de4016690a6d930986220f8f7937a4 (diff) | |
download | gdk-pixbuf-5155f3ca66d6fe94428a9885e2e6f118b14ea518.tar.gz |
gdk/win32/gdkinput-win32.h Drop the GdkEvent* parameter, it wasn't used.
2003-08-07 Tor Lillqvist <tml@iki.fi>
* 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 ptMaxSize 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.
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/win32/gdkdisplay-win32.c | 137 | ||||
-rw-r--r-- | gdk/win32/gdkevents-win32.c | 256 | ||||
-rw-r--r-- | gdk/win32/gdkglobals-win32.c | 5 | ||||
-rw-r--r-- | gdk/win32/gdkinput-win32.c | 6 | ||||
-rw-r--r-- | gdk/win32/gdkinput-win32.h | 6 | ||||
-rw-r--r-- | gdk/win32/gdkprivate-win32.h | 16 | ||||
-rw-r--r-- | gdk/win32/gdkscreen-win32.c | 13 | ||||
-rw-r--r-- | gdk/win32/gdkwindow-win32.c | 150 |
8 files changed, 442 insertions, 147 deletions
diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c index 7efce884e..2439f970a 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 d574b9eb7..5e7f887bc 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -125,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 @@ -1204,8 +1203,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 */ @@ -1215,7 +1214,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 @@ -1659,7 +1658,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); } } @@ -1824,7 +1829,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) { @@ -1860,6 +1865,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, @@ -1870,7 +1886,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; @@ -1998,9 +2015,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; @@ -2024,7 +2041,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; @@ -2032,10 +2049,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; @@ -2358,8 +2375,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; @@ -2428,8 +2445,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; @@ -2511,8 +2528,8 @@ gdk_event_translate (GdkDisplay *display, _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; @@ -2573,10 +2590,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; @@ -2603,7 +2620,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; @@ -2612,10 +2629,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; @@ -2889,46 +2906,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; - - /* 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 (); + rect.left = rect.top = 0; + rect.right = impl->hints.max_width; + rect.bottom = impl->hints.max_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 4b73f2075..651ac883d 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 88d5a5f56..e7431859c 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 e2401cf05..0e79d23a2 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 18f48049b..807f6355f 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 51850b27e..cf69307d8 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 7ae560556..04f2c8ccb 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -151,6 +151,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) { @@ -227,16 +246,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); @@ -250,8 +264,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)); @@ -1063,7 +1081,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)); } } @@ -1152,7 +1170,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)); @@ -1324,12 +1342,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)); @@ -1343,9 +1356,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; @@ -1356,50 +1366,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; @@ -1416,10 +1382,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)); @@ -1430,7 +1398,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; @@ -1443,6 +1410,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); @@ -1462,6 +1430,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) @@ -1469,6 +1438,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); @@ -1488,20 +1458,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, @@ -1521,6 +1494,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) @@ -1804,6 +1778,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) @@ -1851,9 +1833,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), @@ -1928,8 +1910,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; @@ -2111,8 +2093,6 @@ gdk_window_shape_combine_mask (GdkWindow *window, else { HRGN hrgn; - DWORD dwStyle; - DWORD dwExStyle; RECT rect; /* Convert mask bitmap to region */ @@ -2122,13 +2102,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 */ @@ -2267,7 +2243,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 @@ -2668,9 +2644,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))) @@ -2679,6 +2652,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; |