forked from AuroraMiddleware/gtk
5155f3ca66
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.
215 lines
5.6 KiB
C
215 lines
5.6 KiB
C
/* 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
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#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));
|
|
_gdk_windowing_window_init ();
|
|
_gdk_windowing_image_init ();
|
|
_gdk_events_init ();
|
|
_gdk_input_init (_gdk_display);
|
|
_gdk_dnd_init ();
|
|
|
|
g_signal_emit_by_name (gdk_display_manager_get (),
|
|
"display_opened", _gdk_display);
|
|
|
|
return _gdk_display;
|
|
}
|
|
|
|
G_CONST_RETURN gchar *
|
|
gdk_display_get_name (GdkDisplay *display)
|
|
{
|
|
return gdk_get_display_arg_name ();
|
|
}
|
|
|
|
gint
|
|
gdk_display_get_n_screens (GdkDisplay *display)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
GdkScreen *
|
|
gdk_display_get_screen (GdkDisplay *display,
|
|
gint screen_num)
|
|
{
|
|
return _gdk_screen;
|
|
}
|
|
|
|
GdkScreen *
|
|
gdk_display_get_default_screen (GdkDisplay *display)
|
|
{
|
|
return _gdk_screen;
|
|
}
|
|
|