1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2002,2005 Hans Breuer
3 * Copyright (C) 2003 Tor Lillqvist
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
23 #include "gdkprivate-win32.h"
25 #define HAVE_MONITOR_INFO
27 #if defined(_MSC_VER) && (WINVER < 0x500) && (WINVER > 0x0400)
29 #elif defined(_MSC_VER) && (WINVER <= 0x0400)
30 #undef HAVE_MONITOR_INFO
34 _gdk_windowing_set_default_display (GdkDisplay *display)
36 g_assert (display == NULL || _gdk_display == display);
40 _gdk_windowing_window_get_next_serial (GdkDisplay *display)
45 #ifdef HAVE_MONITOR_INFO
47 count_monitor (HMONITOR hmonitor,
52 gint *n = (gint *) data;
60 enum_monitor (HMONITOR hmonitor,
65 /* The struct MONITORINFOEX definition is for some reason different
66 * in the winuser.h bundled with mingw64 from that in MSDN and the
67 * official 32-bit mingw (the MONITORINFO part is in a separate "mi"
68 * member). So to keep this easily compileable with either, repeat
69 * the MSDN definition it here.
71 typedef struct tagMONITORINFOEXA2 {
76 CHAR szDevice[CCHDEVICENAME];
79 MONITORINFOEXA2 monitor_info;
82 gint *index = (gint *) data;
83 GdkWin32Monitor *monitor;
85 g_assert (*index < _gdk_num_monitors);
87 monitor = _gdk_monitors + *index;
89 monitor_info.cbSize = sizeof (MONITORINFOEX);
90 GetMonitorInfoA (hmonitor, (MONITORINFO *) &monitor_info);
92 #ifndef MONITORINFOF_PRIMARY
93 #define MONITORINFOF_PRIMARY 1
96 monitor->name = g_strdup (monitor_info.szDevice);
97 hDC = CreateDCA ("DISPLAY", monitor_info.szDevice, NULL, NULL);
98 monitor->width_mm = GetDeviceCaps (hDC, HORZSIZE);
99 monitor->height_mm = GetDeviceCaps (hDC, VERTSIZE);
101 monitor->rect.x = monitor_info.rcMonitor.left;
102 monitor->rect.y = monitor_info.rcMonitor.top;
103 monitor->rect.width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
104 monitor->rect.height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
106 if (monitor_info.dwFlags & MONITORINFOF_PRIMARY &&
109 /* Put primary monitor at index 0, just in case somebody needs
110 * to know which one is the primary.
112 GdkWin32Monitor temp = *monitor;
113 *monitor = _gdk_monitors[0];
114 _gdk_monitors[0] = temp;
121 #endif /* HAVE_MONITOR_INFO */
124 _gdk_monitor_init (void)
126 #ifdef HAVE_MONITOR_INFO
129 _gdk_num_monitors = 0;
131 EnumDisplayMonitors (NULL, NULL, count_monitor, (LPARAM) &_gdk_num_monitors);
133 _gdk_monitors = g_renew (GdkWin32Monitor, _gdk_monitors, _gdk_num_monitors);
136 EnumDisplayMonitors (NULL, NULL, enum_monitor, (LPARAM) &index);
138 _gdk_offset_x = G_MININT;
139 _gdk_offset_y = G_MININT;
141 /* Calculate offset */
142 for (i = 0; i < _gdk_num_monitors; i++)
144 _gdk_offset_x = MAX (_gdk_offset_x, -_gdk_monitors[i].rect.x);
145 _gdk_offset_y = MAX (_gdk_offset_y, -_gdk_monitors[i].rect.y);
147 GDK_NOTE (MISC, g_print ("Multi-monitor offset: (%d,%d)\n",
148 _gdk_offset_x, _gdk_offset_y));
150 /* Translate monitor coords into GDK coordinate space */
151 for (i = 0; i < _gdk_num_monitors; i++)
153 _gdk_monitors[i].rect.x += _gdk_offset_x;
154 _gdk_monitors[i].rect.y += _gdk_offset_y;
155 GDK_NOTE (MISC, g_print ("Monitor %d: %dx%d@%+d%+d\n",
156 i, _gdk_monitors[i].rect.width,
157 _gdk_monitors[i].rect.height,
158 _gdk_monitors[i].rect.x,
159 _gdk_monitors[i].rect.y));
164 _gdk_num_monitors = 1;
165 _gdk_monitors = g_renew (GdkWin32Monitor, _gdk_monitors, 1);
167 _gdk_monitors[0].name = g_strdup ("DISPLAY");
169 _gdk_monitors[0].width_mm = GetDeviceCaps (hDC, HORZSIZE);
170 _gdk_monitors[0].height_mm = GetDeviceCaps (hDC, VERTSIZE);
171 ReleaseDC (NULL, hDC);
172 _gdk_monitors[0].rect.x = 0;
173 _gdk_monitors[0].rect.y = 0;
174 _gdk_monitors[0].rect.width = GetSystemMetrics (SM_CXSCREEN);
175 _gdk_monitors[0].rect.height = GetSystemMetrics (SM_CYSCREEN);
182 gdk_display_open (const gchar *display_name)
184 GDK_NOTE (MISC, g_print ("gdk_display_open: %s\n", (display_name ? display_name : "NULL")));
186 if (display_name == NULL ||
187 g_ascii_strcasecmp (display_name,
188 gdk_display_get_name (_gdk_display)) == 0)
190 if (_gdk_display != NULL)
192 GDK_NOTE (MISC, g_print ("... return _gdk_display\n"));
198 GDK_NOTE (MISC, g_print ("... return NULL\n"));
202 _gdk_display = g_object_new (GDK_TYPE_DISPLAY, NULL);
203 _gdk_screen = g_object_new (GDK_TYPE_SCREEN, NULL);
205 _gdk_monitor_init ();
207 gdk_screen_set_default_colormap (_gdk_screen,
208 gdk_screen_get_system_colormap (_gdk_screen));
209 _gdk_windowing_window_init (_gdk_screen);
210 _gdk_windowing_image_init ();
212 _gdk_input_init (_gdk_display);
215 /* Precalculate display name */
216 (void) gdk_display_get_name (_gdk_display);
218 g_signal_emit_by_name (gdk_display_manager_get (),
219 "display_opened", _gdk_display);
221 GDK_NOTE (MISC, g_print ("... _gdk_display now set up\n"));
226 G_CONST_RETURN gchar *
227 gdk_display_get_name (GdkDisplay *display)
229 HDESK hdesk = GetThreadDesktop (GetCurrentThreadId ());
232 HWINSTA hwinsta = GetProcessWindowStation ();
233 char *window_station_name;
237 static const char *display_name_cache = NULL;
238 typedef BOOL (WINAPI *PFN_ProcessIdToSessionId) (DWORD, DWORD *);
239 PFN_ProcessIdToSessionId processIdToSessionId;
241 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
243 if (display_name_cache != NULL)
244 return display_name_cache;
247 GetUserObjectInformation (hdesk, UOI_NAME, &dummy, 0, &n);
249 desktop_name = "Default";
253 desktop_name = g_alloca (n + 1);
254 memset (desktop_name, 0, n + 1);
256 if (!GetUserObjectInformation (hdesk, UOI_NAME, desktop_name, n, &n))
257 desktop_name = "Default";
261 GetUserObjectInformation (hwinsta, UOI_NAME, &dummy, 0, &n);
263 window_station_name = "WinSta0";
267 window_station_name = g_alloca (n + 1);
268 memset (window_station_name, 0, n + 1);
270 if (!GetUserObjectInformation (hwinsta, UOI_NAME, window_station_name, n, &n))
271 window_station_name = "WinSta0";
274 processIdToSessionId = (PFN_ProcessIdToSessionId) GetProcAddress (GetModuleHandle ("kernel32.dll"), "ProcessIdToSessionId");
275 if (!processIdToSessionId || !processIdToSessionId (GetCurrentProcessId (), &session_id))
278 display_name = g_strdup_printf ("%ld\\%s\\%s",
283 GDK_NOTE (MISC, g_print ("gdk_display_get_name: %s\n", display_name));
285 display_name_cache = display_name;
287 return display_name_cache;
291 gdk_display_get_n_screens (GdkDisplay *display)
293 g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
299 gdk_display_get_screen (GdkDisplay *display,
302 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
303 g_return_val_if_fail (screen_num == 0, NULL);
309 gdk_display_get_default_screen (GdkDisplay *display)
311 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
317 gdk_display_get_default_group (GdkDisplay *display)
319 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
321 g_warning ("gdk_display_get_default_group not yet implemented");
327 gdk_display_supports_selection_notification (GdkDisplay *display)
329 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
335 gdk_display_request_selection_notification (GdkDisplay *display,
343 gdk_display_supports_clipboard_persistence (GdkDisplay *display)
349 gdk_display_store_clipboard (GdkDisplay *display,
350 GdkWindow *clipboard_window,
352 const GdkAtom *targets,
358 gdk_display_supports_shapes (GdkDisplay *display)
360 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
366 gdk_display_supports_input_shapes (GdkDisplay *display)
368 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
370 /* Not yet implemented. See comment in
371 * gdk_window_input_shape_combine_mask().
378 gdk_display_supports_composite (GdkDisplay *display)