/* GDK - The GIMP Drawing Kit
- * Copyright (C) 2002 Hans Breuer
+ * Copyright (C) 2002,2005 Hans Breuer
* Copyright (C) 2003 Tor Lillqvist
*
* This library is free software; you can redistribute it and/or
* Boston, MA 02111-1307, USA.
*/
-#include <config.h>
+#include "config.h"
#include "gdk.h"
#include "gdkprivate-win32.h"
+#include "gdkdisplayprivate.h"
+#include "gdkwin32display.h"
+#include "gdkwin32screen.h"
+#include "gdkwin32window.h"
#define HAVE_MONITOR_INFO
#if defined(_MSC_VER) && (WINVER < 0x500) && (WINVER > 0x0400)
#include <multimon.h>
-#elif (WINVER <= 0x0400)
+#elif defined(_MSC_VER) && (WINVER <= 0x0400)
#undef HAVE_MONITOR_INFO
#endif
-#ifdef HAVE_MONITOR_INFO
-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;
-#endif
-
void
_gdk_windowing_set_default_display (GdkDisplay *display)
{
- g_assert (_gdk_display == display);
+ g_assert (display == NULL || _gdk_display == display);
+}
+
+static gulong
+gdk_win32_display_get_next_serial (GdkDisplay *display)
+{
+ return 0;
}
#ifdef HAVE_MONITOR_INFO
LPRECT rect,
LPARAM data)
{
- MONITORINFOEX monitor_info;
+ /* The struct MONITORINFOEX definition is for some reason different
+ * in the winuser.h bundled with mingw64 from that in MSDN and the
+ * official 32-bit mingw (the MONITORINFO part is in a separate "mi"
+ * member). So to keep this easily compileable with either, repeat
+ * the MSDN definition it here.
+ */
+ typedef struct tagMONITORINFOEXA2 {
+ DWORD cbSize;
+ RECT rcMonitor;
+ RECT rcWork;
+ DWORD dwFlags;
+ CHAR szDevice[CCHDEVICENAME];
+ } MONITORINFOEXA2;
+
+ MONITORINFOEXA2 monitor_info;
+ HDC hDC;
gint *index = (gint *) data;
- GdkRectangle *monitor;
+ GdkWin32Monitor *monitor;
g_assert (*index < _gdk_num_monitors);
monitor = _gdk_monitors + *index;
monitor_info.cbSize = sizeof (MONITORINFOEX);
- (*p_GetMonitorInfoA) (hmonitor, (MONITORINFO *) &monitor_info);
+ GetMonitorInfoA (hmonitor, (MONITORINFO *) &monitor_info);
#ifndef MONITORINFOF_PRIMARY
#define MONITORINFOF_PRIMARY 1
#endif
- if (monitor_info.dwFlags & MONITORINFOF_PRIMARY)
+ monitor->name = g_strdup (monitor_info.szDevice);
+ hDC = CreateDCA ("DISPLAY", monitor_info.szDevice, NULL, NULL);
+ monitor->width_mm = GetDeviceCaps (hDC, HORZSIZE);
+ monitor->height_mm = GetDeviceCaps (hDC, VERTSIZE);
+ DeleteDC (hDC);
+ monitor->rect.x = monitor_info.rcMonitor.left;
+ monitor->rect.y = monitor_info.rcMonitor.top;
+ monitor->rect.width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
+ monitor->rect.height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
+
+ if (monitor_info.dwFlags & MONITORINFOF_PRIMARY &&
+ *index != 0)
{
- /* 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;
+ GdkWin32Monitor temp = *monitor;
+ *monitor = _gdk_monitors[0];
+ _gdk_monitors[0] = temp;
}
(*index)++;
}
#endif /* HAVE_MONITOR_INFO */
-GdkDisplay *
-gdk_display_open (const gchar *display_name)
+void
+_gdk_monitor_init (void)
{
- HMODULE user32;
-
- if (_gdk_display != NULL)
- return NULL; /* single display only */
+#ifdef HAVE_MONITOR_INFO
+ gint i, index;
- _gdk_display = g_object_new (GDK_TYPE_DISPLAY, NULL);
- _gdk_screen = g_object_new (GDK_TYPE_SCREEN, NULL);
+ _gdk_num_monitors = 0;
-#ifdef HAVE_MONITOR_INFO
- user32 = GetModuleHandle ("user32.dll");
- g_assert (user32 != NULL);
+ EnumDisplayMonitors (NULL, NULL, count_monitor, (LPARAM) &_gdk_num_monitors);
- p_EnumDisplayMonitors = (t_EnumDisplayMonitors) GetProcAddress (user32, "EnumDisplayMonitors");
- p_GetMonitorInfoA = (t_GetMonitorInfoA) GetProcAddress (user32, "GetMonitorInfoA");
+ _gdk_monitors = g_renew (GdkWin32Monitor, _gdk_monitors, _gdk_num_monitors);
- if (p_EnumDisplayMonitors != NULL && p_GetMonitorInfoA != NULL)
- {
- gint i, index;
+ index = 0;
+ EnumDisplayMonitors (NULL, NULL, enum_monitor, (LPARAM) &index);
- _gdk_num_monitors = 0;
+ _gdk_offset_x = G_MININT;
+ _gdk_offset_y = G_MININT;
- (*p_EnumDisplayMonitors) (NULL, NULL, count_monitor, (LPARAM) &_gdk_num_monitors);
+ /* Calculate offset */
+ for (i = 0; i < _gdk_num_monitors; i++)
+ {
+ _gdk_offset_x = MAX (_gdk_offset_x, -_gdk_monitors[i].rect.x);
+ _gdk_offset_y = MAX (_gdk_offset_y, -_gdk_monitors[i].rect.y);
+ }
+ GDK_NOTE (MISC, g_print ("Multi-monitor offset: (%d,%d)\n",
+ _gdk_offset_x, _gdk_offset_y));
- _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;
+ /* Translate monitor coords into GDK coordinate space */
+ for (i = 0; i < _gdk_num_monitors; i++)
+ {
+ _gdk_monitors[i].rect.x += _gdk_offset_x;
+ _gdk_monitors[i].rect.y += _gdk_offset_y;
+ GDK_NOTE (MISC, g_print ("Monitor %d: %dx%d@%+d%+d\n",
+ i, _gdk_monitors[i].rect.width,
+ _gdk_monitors[i].rect.height,
+ _gdk_monitors[i].rect.x,
+ _gdk_monitors[i].rect.y));
+ }
+#else
+ HDC hDC;
+
+ _gdk_num_monitors = 1;
+ _gdk_monitors = g_renew (GdkWin32Monitor, _gdk_monitors, 1);
+
+ _gdk_monitors[0].name = g_strdup ("DISPLAY");
+ hDC = GetDC (NULL);
+ _gdk_monitors[0].width_mm = GetDeviceCaps (hDC, HORZSIZE);
+ _gdk_monitors[0].height_mm = GetDeviceCaps (hDC, VERTSIZE);
+ ReleaseDC (NULL, hDC);
+ _gdk_monitors[0].rect.x = 0;
+ _gdk_monitors[0].rect.y = 0;
+ _gdk_monitors[0].rect.width = GetSystemMetrics (SM_CXSCREEN);
+ _gdk_monitors[0].rect.height = GetSystemMetrics (SM_CYSCREEN);
+ _gdk_offset_x = 0;
+ _gdk_offset_y = 0;
+#endif
+}
- /* 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));
+GdkDisplay *
+_gdk_win32_display_open (const gchar *display_name)
+{
+ GDK_NOTE (MISC, g_print ("gdk_display_open: %s\n", (display_name ? display_name : "NULL")));
- /* Translate monitor coords into GDK coordinate space */
- for (i = 0; i < _gdk_num_monitors; i++)
+ if (display_name == NULL ||
+ g_ascii_strcasecmp (display_name,
+ gdk_display_get_name (_gdk_display)) == 0)
+ {
+ if (_gdk_display != NULL)
{
- _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));
+ GDK_NOTE (MISC, g_print ("... return _gdk_display\n"));
+ return _gdk_display;
}
-#endif
}
else
-#endif /* HAVE_MONITOR_INFO */
{
- 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_NOTE (MISC, g_print ("... return NULL\n"));
+ return NULL;
}
+ _gdk_display = g_object_new (GDK_TYPE_WIN32_DISPLAY, NULL);
+ _gdk_screen = g_object_new (GDK_TYPE_WIN32_SCREEN, NULL);
+
+ _gdk_monitor_init ();
_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_windowing_window_init (_gdk_screen);
_gdk_events_init ();
_gdk_input_init (_gdk_display);
_gdk_dnd_init ();
+ /* Precalculate display name */
+ (void) gdk_display_get_name (_gdk_display);
+
g_signal_emit_by_name (gdk_display_manager_get (),
"display_opened", _gdk_display);
+ GDK_NOTE (MISC, g_print ("... _gdk_display now set up\n"));
+
return _gdk_display;
}
-G_CONST_RETURN gchar *
-gdk_display_get_name (GdkDisplay *display)
+struct _GdkWin32Display
+{
+ GdkDisplay display;
+};
+
+struct _GdkWin32DisplayClass
{
- return gdk_get_display_arg_name ();
+ GdkDisplayClass display_class;
+};
+
+G_DEFINE_TYPE (GdkWin32Display, gdk_win32_display, GDK_TYPE_DISPLAY)
+
+static const gchar *
+gdk_win32_display_get_name (GdkDisplay *display)
+{
+ HDESK hdesk = GetThreadDesktop (GetCurrentThreadId ());
+ char dummy;
+ char *desktop_name;
+ HWINSTA hwinsta = GetProcessWindowStation ();
+ char *window_station_name;
+ DWORD n;
+ DWORD session_id;
+ char *display_name;
+ static const char *display_name_cache = NULL;
+ typedef BOOL (WINAPI *PFN_ProcessIdToSessionId) (DWORD, DWORD *);
+ PFN_ProcessIdToSessionId processIdToSessionId;
+
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+ if (display_name_cache != NULL)
+ return display_name_cache;
+
+ n = 0;
+ GetUserObjectInformation (hdesk, UOI_NAME, &dummy, 0, &n);
+ if (n == 0)
+ desktop_name = "Default";
+ else
+ {
+ n++;
+ desktop_name = g_alloca (n + 1);
+ memset (desktop_name, 0, n + 1);
+
+ if (!GetUserObjectInformation (hdesk, UOI_NAME, desktop_name, n, &n))
+ desktop_name = "Default";
+ }
+
+ n = 0;
+ GetUserObjectInformation (hwinsta, UOI_NAME, &dummy, 0, &n);
+ if (n == 0)
+ window_station_name = "WinSta0";
+ else
+ {
+ n++;
+ window_station_name = g_alloca (n + 1);
+ memset (window_station_name, 0, n + 1);
+
+ if (!GetUserObjectInformation (hwinsta, UOI_NAME, window_station_name, n, &n))
+ window_station_name = "WinSta0";
+ }
+
+ processIdToSessionId = (PFN_ProcessIdToSessionId) GetProcAddress (GetModuleHandle ("kernel32.dll"), "ProcessIdToSessionId");
+ if (!processIdToSessionId || !processIdToSessionId (GetCurrentProcessId (), &session_id))
+ session_id = 0;
+
+ display_name = g_strdup_printf ("%ld\\%s\\%s",
+ session_id,
+ window_station_name,
+ desktop_name);
+
+ GDK_NOTE (MISC, g_print ("gdk_win32_display_get_name: %s\n", display_name));
+
+ display_name_cache = display_name;
+
+ return display_name_cache;
}
-gint
-gdk_display_get_n_screens (GdkDisplay *display)
+static gint
+gdk_win32_display_get_n_screens (GdkDisplay *display)
{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
+
return 1;
}
-GdkScreen *
-gdk_display_get_screen (GdkDisplay *display,
- gint screen_num)
+static GdkScreen *
+gdk_win32_display_get_screen (GdkDisplay *display,
+ gint screen_num)
{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+ g_return_val_if_fail (screen_num == 0, NULL);
+
return _gdk_screen;
}
-GdkScreen *
-gdk_display_get_default_screen (GdkDisplay *display)
+static GdkScreen *
+gdk_win32_display_get_default_screen (GdkDisplay *display)
{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
return _gdk_screen;
}
-GdkWindow *
-gdk_display_get_default_group (GdkDisplay *display)
+static GdkWindow *
+gdk_win32_display_get_default_group (GdkDisplay *display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
return NULL;
}
+
+static gboolean
+gdk_win32_display_supports_selection_notification (GdkDisplay *display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+
+ return FALSE;
+}
+
+static gboolean
+gdk_win32_display_request_selection_notification (GdkDisplay *display,
+ GdkAtom selection)
+
+{
+ return FALSE;
+}
+
+static gboolean
+gdk_win32_display_supports_clipboard_persistence (GdkDisplay *display)
+{
+ return FALSE;
+}
+
+static void
+gdk_win32_display_store_clipboard (GdkDisplay *display,
+ GdkWindow *clipboard_window,
+ guint32 time_,
+ const GdkAtom *targets,
+ gint n_targets)
+{
+}
+
+static gboolean
+gdk_win32_display_supports_shapes (GdkDisplay *display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+gdk_win32_display_supports_input_shapes (GdkDisplay *display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+
+ /* Not yet implemented. See comment in
+ * gdk_window_input_shape_combine_mask().
+ */
+
+ return FALSE;
+}
+
+static gboolean
+gdk_win32_display_supports_composite (GdkDisplay *display)
+{
+ return FALSE;
+}
+
+static void
+gdk_win32_display_beep (GdkDisplay *display)
+{
+ g_return_if_fail (display == gdk_display_get_default());
+ if (!MessageBeep (-1))
+ Beep(1000, 50);
+}
+
+static void
+gdk_win32_display_flush (GdkDisplay * display)
+{
+ g_return_if_fail (display == _gdk_display);
+
+ GdiFlush ();
+}
+
+static void
+gdk_win32_display_dispose (GObject *object)
+{
+}
+
+static void
+gdk_win32_display_finalize (GObject *object)
+{
+}
+
+static void
+gdk_win32_display_init(GdkWin32Display *display)
+{
+}
+
+static void
+gdk_win32_display_before_process_all_updates (GdkDisplay *display)
+{
+ /* nothing */
+}
+static void
+gdk_win32_display_after_process_all_updates (GdkDisplay *display)
+{
+ /* nothing */
+}
+static void
+gdk_win32_display_notify_startup_complete (GdkDisplay *display,
+ const gchar *startup_id)
+{
+ /* nothing */
+}
+static void
+gdk_win32_display_event_data_copy (GdkDisplay *display,
+ const GdkEvent *src,
+ GdkEvent *dst)
+{
+ /* nothing */
+}
+static void
+gdk_win32_display_event_data_free (GdkDisplay *display,
+ GdkEvent *event)
+{
+ /* nothing */
+}
+static void
+gdk_win32_display_push_error_trap (GdkDisplay *display)
+{
+ /* nothing */
+}
+static gint
+gdk_win32_display_pop_error_trap (GdkDisplay *display,
+ gboolean ignored)
+{
+ return 0;
+}
+static void
+gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GdkDisplayClass *display_class = GDK_DISPLAY_CLASS (klass);
+
+ object_class->dispose = gdk_win32_display_dispose;
+ object_class->finalize = gdk_win32_display_finalize;
+
+ display_class->window_type = GDK_TYPE_WIN32_WINDOW;
+
+ display_class->get_name = gdk_win32_display_get_name;
+ display_class->get_n_screens = gdk_win32_display_get_n_screens;
+ display_class->get_screen = gdk_win32_display_get_screen;
+ display_class->get_default_screen = gdk_win32_display_get_default_screen;
+ display_class->beep = gdk_win32_display_beep;
+ display_class->sync = _gdk_win32_display_sync;
+ display_class->flush = gdk_win32_display_flush;
+ display_class->has_pending = _gdk_win32_display_has_pending;
+ display_class->queue_events = _gdk_win32_display_queue_events;
+ display_class->get_default_group = gdk_win32_display_get_default_group;
+
+ display_class->supports_selection_notification = gdk_win32_display_supports_selection_notification;
+ display_class->request_selection_notification = gdk_win32_display_request_selection_notification;
+ display_class->supports_clipboard_persistence = gdk_win32_display_supports_clipboard_persistence;
+ display_class->store_clipboard = gdk_win32_display_store_clipboard;
+ display_class->supports_shapes = gdk_win32_display_supports_shapes;
+ display_class->supports_input_shapes = gdk_win32_display_supports_input_shapes;
+ display_class->supports_composite = gdk_win32_display_supports_composite;
+
+ display_class->list_devices = _gdk_win32_display_list_devices;
+ //? display_class->get_app_launch_context = _gdk_win32_display_get_app_launch_context;
+ display_class->get_cursor_for_type = _gdk_win32_display_get_cursor_for_type;
+ display_class->get_cursor_for_name = _gdk_win32_display_get_cursor_for_name;
+ display_class->get_cursor_for_pixbuf = _gdk_win32_display_get_cursor_for_pixbuf;
+ display_class->get_default_cursor_size = _gdk_win32_display_get_default_cursor_size;
+ display_class->get_maximal_cursor_size = _gdk_win32_display_get_maximal_cursor_size;
+ display_class->supports_cursor_alpha = _gdk_win32_display_supports_cursor_alpha;
+ display_class->supports_cursor_color = _gdk_win32_display_supports_cursor_color;
+
+ display_class->before_process_all_updates = gdk_win32_display_before_process_all_updates;
+ display_class->after_process_all_updates = gdk_win32_display_after_process_all_updates;
+ display_class->get_next_serial = gdk_win32_display_get_next_serial;
+ display_class->notify_startup_complete = gdk_win32_display_notify_startup_complete;
+ display_class->event_data_copy = gdk_win32_display_event_data_copy;
+ display_class->event_data_free = gdk_win32_display_event_data_free;
+ display_class->create_window_impl = _gdk_win32_display_create_window_impl;
+
+ display_class->get_keymap = _gdk_win32_display_get_keymap;
+ display_class->push_error_trap = gdk_win32_display_push_error_trap;
+ display_class->pop_error_trap = gdk_win32_display_pop_error_trap;
+ display_class->get_selection_owner = _gdk_win32_display_get_selection_owner;
+ display_class->set_selection_owner = _gdk_win32_display_set_selection_owner;
+ display_class->send_selection_notify = _gdk_win32_display_send_selection_notify;
+ display_class->get_selection_property = _gdk_win32_display_get_selection_property;
+ display_class->convert_selection = _gdk_win32_display_convert_selection;
+ display_class->text_property_to_utf8_list = _gdk_win32_display_text_property_to_utf8_list;
+ display_class->utf8_to_string_target = _gdk_win32_display_utf8_to_string_target;
+}