]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkdisplay-win32.c
gdk/win32/gdkinput-win32.h Drop the GdkEvent* parameter, it wasn't used.
[~andy/gtk] / gdk / win32 / gdkdisplay-win32.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 2002 Hans Breuer
3  * Copyright (C) 2003 Tor Lillqvist
4  *
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.
9  *
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.
14  *
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.
19  */
20
21 #include "gdk.h"
22 #include "gdkprivate-win32.h"
23
24 typedef BOOL (WINAPI *t_EnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
25 typedef BOOL (WINAPI *t_GetMonitorInfoA)(HMONITOR, LPMONITORINFO);
26
27 static t_EnumDisplayMonitors p_EnumDisplayMonitors = NULL;
28 static t_GetMonitorInfoA p_GetMonitorInfoA = NULL;
29
30 void
31 _gdk_windowing_set_default_display (GdkDisplay *display)
32 {
33   g_assert (_gdk_display == display);
34 }
35
36 static BOOL CALLBACK
37 count_monitor (HMONITOR hmonitor,
38                HDC      hdc,
39                LPRECT   rect,
40                LPARAM   data)
41 {
42   gint *n = (gint *) data;
43
44   (*n)++;
45
46   return TRUE;
47 }
48
49 static BOOL CALLBACK
50 enum_monitor (HMONITOR hmonitor,
51               HDC      hdc,
52               LPRECT   rect,
53               LPARAM   data)
54 {
55   MONITORINFOEX monitor_info;
56
57   gint *index = (gint *) data;
58   GdkRectangle *monitor;
59
60   g_assert (*index < _gdk_num_monitors);
61
62   monitor = _gdk_monitors + *index;
63
64   monitor_info.cbSize = sizeof (MONITORINFOEX);
65   (*p_GetMonitorInfoA) (hmonitor, (MONITORINFO *) &monitor_info);
66
67 #ifndef MONITORINFOF_PRIMARY
68 #define MONITORINFOF_PRIMARY 1
69 #endif
70
71   if (monitor_info.dwFlags & MONITORINFOF_PRIMARY)
72     {
73       /* For the primary monitor, use SPI_GETWORKAREA */
74       RECT rect;
75
76       SystemParametersInfo (SPI_GETWORKAREA, 0, &rect, 0);
77       monitor->x = rect.left;
78       monitor->y = rect.top;
79       monitor->width = rect.right - rect.left;
80       monitor->height = rect.bottom - rect.top;
81
82       /* Put primary monitor at index 0, just in case somebody needs
83        * to know which one is the primary.
84        */
85       if (*index != 0)
86         {
87           GdkRectangle temp = *monitor;
88           *monitor = _gdk_monitors[0];
89           _gdk_monitors[0] = temp;
90         }
91     }
92   else
93     {
94       monitor->x = monitor_info.rcMonitor.left;
95       monitor->y = monitor_info.rcMonitor.top;
96       monitor->width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
97       monitor->height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
98     }
99
100   (*index)++;
101
102   return TRUE;
103 }
104
105 GdkDisplay *
106 gdk_display_open (const gchar *display_name)
107 {
108   HMODULE user32;
109
110   if (_gdk_display != NULL)
111     return NULL; /* single display only */
112
113   _gdk_display = g_object_new (GDK_TYPE_DISPLAY, NULL);
114   _gdk_screen = g_object_new (GDK_TYPE_SCREEN, NULL);
115
116   user32 = GetModuleHandle ("user32.dll");
117   g_assert (user32 != NULL);
118
119   p_EnumDisplayMonitors = (t_EnumDisplayMonitors) GetProcAddress (user32, "EnumDisplayMonitors");
120   p_GetMonitorInfoA = (t_GetMonitorInfoA) GetProcAddress (user32, "GetMonitorInfoA");
121
122   CloseHandle (user32);
123   
124   if (p_EnumDisplayMonitors != NULL && p_GetMonitorInfoA != NULL)
125     {
126       gint i, index;
127
128       _gdk_num_monitors = 0;
129
130       (*p_EnumDisplayMonitors) (NULL, NULL, count_monitor, (LPARAM) &_gdk_num_monitors);
131
132       _gdk_monitors = g_new (GdkRectangle, _gdk_num_monitors);
133       index = 0;
134       (*p_EnumDisplayMonitors) (NULL, NULL, enum_monitor, (LPARAM) &index);
135 #if 1
136       _gdk_offset_x = G_MININT;
137       _gdk_offset_y = G_MININT;
138
139       /* Calculate offset */
140       for (i = 0; i < _gdk_num_monitors; i++)
141         {
142           _gdk_offset_x = MAX (_gdk_offset_x, -_gdk_monitors[i].x);
143           _gdk_offset_y = MAX (_gdk_offset_y, -_gdk_monitors[i].y);
144         }
145       GDK_NOTE (MISC, g_print ("Multi-monitor offset: (%d,%d)\n",
146                                _gdk_offset_x, _gdk_offset_y));
147
148       /* Translate monitor coords into GDK coordinate space */
149       for (i = 0; i < _gdk_num_monitors; i++)
150         {
151           _gdk_monitors[i].x += _gdk_offset_x;
152           _gdk_monitors[i].y += _gdk_offset_y;
153           GDK_NOTE (MISC, g_print ("Monitor %d: %dx%d@+%d+%d\n",
154                                    i, _gdk_monitors[i].width,
155                                    _gdk_monitors[i].height,
156                                    _gdk_monitors[i].x, _gdk_monitors[i].y));
157         }
158 #endif
159     }
160   else
161     {
162       RECT rect;
163
164       _gdk_num_monitors = 1;
165       _gdk_monitors = g_new (GdkRectangle, 1);
166       SystemParametersInfo (SPI_GETWORKAREA, 0, &rect, 0);
167       _gdk_monitors[0].x = rect.left;
168       _gdk_monitors[0].y = rect.top;
169       _gdk_monitors[0].width = rect.right - rect.left;
170       _gdk_monitors[0].height = rect.bottom - rect.top;
171       _gdk_offset_x = 0;
172       _gdk_offset_y = 0;
173     }
174
175   _gdk_visual_init ();
176   gdk_screen_set_default_colormap (_gdk_screen,
177                                    gdk_screen_get_system_colormap (_gdk_screen));
178   _gdk_windowing_window_init ();
179   _gdk_windowing_image_init ();
180   _gdk_events_init ();
181   _gdk_input_init (_gdk_display);
182   _gdk_dnd_init ();
183
184   g_signal_emit_by_name (gdk_display_manager_get (),
185                          "display_opened", _gdk_display);
186
187   return _gdk_display;
188 }
189
190 G_CONST_RETURN gchar *
191 gdk_display_get_name (GdkDisplay *display)
192 {
193   return gdk_get_display_arg_name ();
194 }
195
196 gint
197 gdk_display_get_n_screens (GdkDisplay *display)
198 {
199   return 1;
200 }
201
202 GdkScreen *
203 gdk_display_get_screen (GdkDisplay *display,
204                         gint        screen_num)
205 {
206   return _gdk_screen;
207 }
208
209 GdkScreen *
210 gdk_display_get_default_screen (GdkDisplay *display)
211 {
212   return _gdk_screen;
213 }
214