]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkdisplay-win32.c
Change FSF Address
[~andy/gtk] / gdk / win32 / gdkdisplay-win32.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 2002,2005 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, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include "config.h"
20 #include "gdk.h"
21 #include "gdkprivate-win32.h"
22 #include "gdkdisplayprivate.h"
23 #include "gdkwin32display.h"
24 #include "gdkwin32screen.h"
25 #include "gdkwin32window.h"
26 #include "gdkwin32.h"
27
28 #define HAVE_MONITOR_INFO
29
30 #if defined(_MSC_VER) && (WINVER < 0x500) && (WINVER > 0x0400)
31 #include <multimon.h>
32 #elif defined(_MSC_VER) && (WINVER <= 0x0400)
33 #undef HAVE_MONITOR_INFO
34 #endif
35
36 void
37 _gdk_windowing_set_default_display (GdkDisplay *display)
38 {
39   g_assert (display == NULL || _gdk_display == display);
40 }
41
42 static gulong
43 gdk_win32_display_get_next_serial (GdkDisplay *display)
44 {
45         return 0;
46 }
47
48 #ifdef HAVE_MONITOR_INFO
49 static BOOL CALLBACK
50 count_monitor (HMONITOR hmonitor,
51                HDC      hdc,
52                LPRECT   rect,
53                LPARAM   data)
54 {
55   gint *n = (gint *) data;
56
57   (*n)++;
58
59   return TRUE;
60 }
61
62 static BOOL CALLBACK
63 enum_monitor (HMONITOR hmonitor,
64               HDC      hdc,
65               LPRECT   rect,
66               LPARAM   data)
67 {
68   /* The struct MONITORINFOEX definition is for some reason different
69    * in the winuser.h bundled with mingw64 from that in MSDN and the
70    * official 32-bit mingw (the MONITORINFO part is in a separate "mi"
71    * member). So to keep this easily compileable with either, repeat
72    * the MSDN definition it here.
73    */
74   typedef struct tagMONITORINFOEXA2 {
75     DWORD cbSize;
76     RECT  rcMonitor;
77     RECT  rcWork;
78     DWORD dwFlags;
79     CHAR szDevice[CCHDEVICENAME];
80   } MONITORINFOEXA2;
81
82   MONITORINFOEXA2 monitor_info;
83   HDC hDC;
84
85   gint *index = (gint *) data;
86   GdkWin32Monitor *monitor;
87
88   g_assert (*index < _gdk_num_monitors);
89
90   monitor = _gdk_monitors + *index;
91
92   monitor_info.cbSize = sizeof (MONITORINFOEX);
93   GetMonitorInfoA (hmonitor, (MONITORINFO *) &monitor_info);
94
95 #ifndef MONITORINFOF_PRIMARY
96 #define MONITORINFOF_PRIMARY 1
97 #endif
98
99   monitor->name = g_strdup (monitor_info.szDevice);
100   hDC = CreateDCA ("DISPLAY", monitor_info.szDevice, NULL, NULL);
101   monitor->width_mm = GetDeviceCaps (hDC, HORZSIZE);
102   monitor->height_mm = GetDeviceCaps (hDC, VERTSIZE);
103   DeleteDC (hDC);
104   monitor->rect.x = monitor_info.rcMonitor.left;
105   monitor->rect.y = monitor_info.rcMonitor.top;
106   monitor->rect.width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
107   monitor->rect.height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
108
109   if (monitor_info.dwFlags & MONITORINFOF_PRIMARY &&
110       *index != 0)
111     {
112       /* Put primary monitor at index 0, just in case somebody needs
113        * to know which one is the primary.
114        */
115       GdkWin32Monitor temp = *monitor;
116       *monitor = _gdk_monitors[0];
117       _gdk_monitors[0] = temp;
118     }
119
120   (*index)++;
121
122   return TRUE;
123 }
124 #endif /* HAVE_MONITOR_INFO */
125
126 void
127 _gdk_monitor_init (void)
128 {
129 #ifdef HAVE_MONITOR_INFO
130   gint i, index;
131
132   _gdk_num_monitors = 0;
133
134   EnumDisplayMonitors (NULL, NULL, count_monitor, (LPARAM) &_gdk_num_monitors);
135
136   _gdk_monitors = g_renew (GdkWin32Monitor, _gdk_monitors, _gdk_num_monitors);
137
138   index = 0;
139   EnumDisplayMonitors (NULL, NULL, enum_monitor, (LPARAM) &index);
140
141   _gdk_offset_x = G_MININT;
142   _gdk_offset_y = G_MININT;
143
144   /* Calculate offset */
145   for (i = 0; i < _gdk_num_monitors; i++)
146     {
147       _gdk_offset_x = MAX (_gdk_offset_x, -_gdk_monitors[i].rect.x);
148       _gdk_offset_y = MAX (_gdk_offset_y, -_gdk_monitors[i].rect.y);
149     }
150   GDK_NOTE (MISC, g_print ("Multi-monitor offset: (%d,%d)\n",
151                            _gdk_offset_x, _gdk_offset_y));
152
153   /* Translate monitor coords into GDK coordinate space */
154   for (i = 0; i < _gdk_num_monitors; i++)
155     {
156       _gdk_monitors[i].rect.x += _gdk_offset_x;
157       _gdk_monitors[i].rect.y += _gdk_offset_y;
158       GDK_NOTE (MISC, g_print ("Monitor %d: %dx%d@%+d%+d\n",
159                                i, _gdk_monitors[i].rect.width,
160                                _gdk_monitors[i].rect.height,
161                                _gdk_monitors[i].rect.x,
162                                _gdk_monitors[i].rect.y));
163     }
164 #else
165   HDC hDC;
166
167   _gdk_num_monitors = 1;
168   _gdk_monitors = g_renew (GdkWin32Monitor, _gdk_monitors, 1);
169
170   _gdk_monitors[0].name = g_strdup ("DISPLAY");
171   hDC = GetDC (NULL);
172   _gdk_monitors[0].width_mm = GetDeviceCaps (hDC, HORZSIZE);
173   _gdk_monitors[0].height_mm = GetDeviceCaps (hDC, VERTSIZE);
174   ReleaseDC (NULL, hDC);
175   _gdk_monitors[0].rect.x = 0;
176   _gdk_monitors[0].rect.y = 0;
177   _gdk_monitors[0].rect.width = GetSystemMetrics (SM_CXSCREEN);
178   _gdk_monitors[0].rect.height = GetSystemMetrics (SM_CYSCREEN);
179   _gdk_offset_x = 0;
180   _gdk_offset_y = 0;
181 #endif
182 }
183
184 GdkDisplay *
185 _gdk_win32_display_open (const gchar *display_name)
186 {
187   GDK_NOTE (MISC, g_print ("gdk_display_open: %s\n", (display_name ? display_name : "NULL")));
188
189   if (display_name == NULL ||
190       g_ascii_strcasecmp (display_name,
191                           gdk_display_get_name (_gdk_display)) == 0)
192     {
193       if (_gdk_display != NULL)
194         {
195           GDK_NOTE (MISC, g_print ("... return _gdk_display\n"));
196           return _gdk_display;
197         }
198     }
199   else
200     {
201       GDK_NOTE (MISC, g_print ("... return NULL\n"));
202       return NULL;
203     }
204
205   _gdk_display = g_object_new (GDK_TYPE_WIN32_DISPLAY, NULL);
206   _gdk_screen = g_object_new (GDK_TYPE_WIN32_SCREEN, NULL);
207
208   _gdk_monitor_init ();
209   _gdk_visual_init ();
210   _gdk_windowing_window_init (_gdk_screen);
211   _gdk_events_init ();
212   _gdk_input_init (_gdk_display);
213   _gdk_dnd_init ();
214
215   /* Precalculate display name */
216   (void) gdk_display_get_name (_gdk_display);
217
218   g_signal_emit_by_name (gdk_display_manager_get (),
219                          "display_opened", _gdk_display);
220
221   GDK_NOTE (MISC, g_print ("... _gdk_display now set up\n"));
222
223   return _gdk_display;
224 }
225
226 struct _GdkWin32Display
227 {
228   GdkDisplay display;
229 };
230
231 struct _GdkWin32DisplayClass
232 {
233   GdkDisplayClass display_class;
234 };
235
236 G_DEFINE_TYPE (GdkWin32Display, gdk_win32_display, GDK_TYPE_DISPLAY)
237
238 static const gchar *
239 gdk_win32_display_get_name (GdkDisplay *display)
240 {
241   HDESK hdesk = GetThreadDesktop (GetCurrentThreadId ());
242   char dummy;
243   char *desktop_name;
244   HWINSTA hwinsta = GetProcessWindowStation ();
245   char *window_station_name;
246   DWORD n;
247   DWORD session_id;
248   char *display_name;
249   static const char *display_name_cache = NULL;
250   typedef BOOL (WINAPI *PFN_ProcessIdToSessionId) (DWORD, DWORD *);
251   PFN_ProcessIdToSessionId processIdToSessionId;
252
253   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
254
255   if (display_name_cache != NULL)
256     return display_name_cache;
257
258   n = 0;
259   GetUserObjectInformation (hdesk, UOI_NAME, &dummy, 0, &n);
260   if (n == 0)
261     desktop_name = "Default";
262   else
263     {
264       n++;
265       desktop_name = g_alloca (n + 1);
266       memset (desktop_name, 0, n + 1);
267
268       if (!GetUserObjectInformation (hdesk, UOI_NAME, desktop_name, n, &n))
269         desktop_name = "Default";
270     }
271
272   n = 0;
273   GetUserObjectInformation (hwinsta, UOI_NAME, &dummy, 0, &n);
274   if (n == 0)
275     window_station_name = "WinSta0";
276   else
277     {
278       n++;
279       window_station_name = g_alloca (n + 1);
280       memset (window_station_name, 0, n + 1);
281
282       if (!GetUserObjectInformation (hwinsta, UOI_NAME, window_station_name, n, &n))
283         window_station_name = "WinSta0";
284     }
285
286   processIdToSessionId = (PFN_ProcessIdToSessionId) GetProcAddress (GetModuleHandle ("kernel32.dll"), "ProcessIdToSessionId");
287   if (!processIdToSessionId || !processIdToSessionId (GetCurrentProcessId (), &session_id))
288     session_id = 0;
289
290   display_name = g_strdup_printf ("%ld\\%s\\%s",
291                                   session_id,
292                                   window_station_name,
293                                   desktop_name);
294
295   GDK_NOTE (MISC, g_print ("gdk_win32_display_get_name: %s\n", display_name));
296
297   display_name_cache = display_name;
298
299   return display_name_cache;
300 }
301
302 static gint
303 gdk_win32_display_get_n_screens (GdkDisplay *display)
304 {
305   g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
306
307   return 1;
308 }
309
310 static GdkScreen *
311 gdk_win32_display_get_screen (GdkDisplay *display,
312                               gint        screen_num)
313 {
314   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
315   g_return_val_if_fail (screen_num == 0, NULL);
316
317   return _gdk_screen;
318 }
319
320 static GdkScreen *
321 gdk_win32_display_get_default_screen (GdkDisplay *display)
322 {
323   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
324
325   return _gdk_screen;
326 }
327
328 static GdkWindow *
329 gdk_win32_display_get_default_group (GdkDisplay *display)
330 {
331   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
332
333   g_warning ("gdk_display_get_default_group not yet implemented");
334
335   return NULL;
336 }
337
338 static gboolean
339 gdk_win32_display_supports_selection_notification (GdkDisplay *display)
340 {
341   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
342
343   return TRUE;
344 }
345
346 static HWND _hwnd_next_viewer = NULL;
347 static int debug_indent = 0;
348
349 /*
350  * maybe this should be integrated with the default message loop - or maybe not ;-)
351  */
352 static LRESULT CALLBACK
353 inner_clipboard_window_procedure (HWND   hwnd,
354                                   UINT   message,
355                                   WPARAM wparam,
356                                   LPARAM lparam)
357 {
358   switch (message)
359     {
360     case WM_DESTROY: /* remove us from chain */
361       {
362         ChangeClipboardChain (hwnd, _hwnd_next_viewer);
363         PostQuitMessage (0);
364         return 0;
365       }
366     case WM_CHANGECBCHAIN:
367       {
368         HWND hwndRemove = (HWND) wparam; /* handle of window being removed */
369         HWND hwndNext   = (HWND) lparam; /* handle of next window in chain */
370
371         if (hwndRemove == _hwnd_next_viewer)
372           _hwnd_next_viewer = hwndNext == hwnd ? NULL : hwndNext;
373         else if (_hwnd_next_viewer != NULL)
374           return SendMessage (_hwnd_next_viewer, message, wparam, lparam);
375
376         return 0;
377       }
378 #ifdef WM_CLIPBOARDUPDATE
379     case WM_CLIPBOARDUPDATE:
380 #endif
381     case WM_DRAWCLIPBOARD:
382       {
383         int success;
384         HWND hwndOwner;
385 #ifdef G_ENABLE_DEBUG
386         UINT nFormat = 0;
387 #endif
388         GdkEvent *event;
389         GdkWindow *owner;
390
391         success = OpenClipboard (hwnd);
392         g_return_val_if_fail (success, 0);
393         hwndOwner = GetClipboardOwner ();
394         owner = gdk_win32_window_lookup_for_display (_gdk_display, hwndOwner);
395         if (owner == NULL)
396           owner = gdk_win32_window_foreign_new_for_display (_gdk_display, hwndOwner);
397
398         GDK_NOTE (DND, g_print (" drawclipboard owner: %p", hwndOwner));
399
400 #ifdef G_ENABLE_DEBUG
401         if (_gdk_debug_flags & GDK_DEBUG_DND)
402           {
403             while ((nFormat = EnumClipboardFormats (nFormat)) != 0)
404               g_print ("%s ", _gdk_win32_cf_to_string (nFormat));
405           }
406 #endif
407
408         GDK_NOTE (DND, g_print (" \n"));
409
410
411         event = gdk_event_new (GDK_OWNER_CHANGE);
412         event->owner_change.window = _gdk_root;
413         event->owner_change.owner = owner;
414         event->owner_change.reason = GDK_OWNER_CHANGE_NEW_OWNER;
415         event->owner_change.selection = GDK_SELECTION_CLIPBOARD;
416         event->owner_change.time = _gdk_win32_get_next_tick (0);
417         event->owner_change.selection_time = GDK_CURRENT_TIME;
418         _gdk_win32_append_event (event);
419
420         CloseClipboard ();
421
422         if (_hwnd_next_viewer != NULL)
423           return SendMessage (_hwnd_next_viewer, message, wparam, lparam);
424
425         /* clear error to avoid confusing SetClipboardViewer() return */
426         SetLastError (0);
427         return 0;
428       }
429     default:
430       /* Otherwise call DefWindowProcW(). */
431       GDK_NOTE (EVENTS, g_print (" DefWindowProcW"));
432       return DefWindowProc (hwnd, message, wparam, lparam);
433     }
434 }
435
436 static LRESULT CALLBACK
437 _clipboard_window_procedure (HWND   hwnd,
438                              UINT   message,
439                              WPARAM wparam,
440                              LPARAM lparam)
441 {
442   LRESULT retval;
443
444   GDK_NOTE (EVENTS, g_print ("%s%*s%s %p",
445                              (debug_indent > 0 ? "\n" : ""),
446                              debug_indent, "",
447                              _gdk_win32_message_to_string (message), hwnd));
448   debug_indent += 2;
449   retval = inner_clipboard_window_procedure (hwnd, message, wparam, lparam);
450   debug_indent -= 2;
451
452   GDK_NOTE (EVENTS, g_print (" => %I64d%s", (gint64) retval, (debug_indent == 0 ? "\n" : "")));
453
454   return retval;
455 }
456
457 /*
458  * Creates a hidden window and adds it to the clipboard chain
459  */
460 static HWND
461 _gdk_win32_register_clipboard_notification (void)
462 {
463   WNDCLASS wclass = { 0, };
464   HWND     hwnd;
465   ATOM     klass;
466
467   wclass.lpszClassName = "GdkClipboardNotification";
468   wclass.lpfnWndProc   = _clipboard_window_procedure;
469   wclass.hInstance     = _gdk_app_hmodule;
470
471   klass = RegisterClass (&wclass);
472   if (!klass)
473     return NULL;
474
475   hwnd = CreateWindow (MAKEINTRESOURCE (klass),
476                        NULL, WS_POPUP,
477                        0, 0, 0, 0, NULL, NULL,
478                        _gdk_app_hmodule, NULL);
479   if (!hwnd)
480     goto failed;
481
482   SetLastError (0);
483   _hwnd_next_viewer = SetClipboardViewer (hwnd);
484
485   if (_hwnd_next_viewer == NULL && GetLastError() != 0)
486     goto failed;
487
488   /* FIXME: http://msdn.microsoft.com/en-us/library/ms649033(v=VS.85).aspx */
489   /* This is only supported by Vista, and not yet by mingw64 */
490   /* if (AddClipboardFormatListener (hwnd) == FALSE) */
491   /*   goto failed; */
492
493   return hwnd;
494
495 failed:
496   g_critical ("Failed to install clipboard viewer");
497   UnregisterClass (MAKEINTRESOURCE (klass), _gdk_app_hmodule);
498   return NULL;
499 }
500
501 static gboolean 
502 gdk_win32_display_request_selection_notification (GdkDisplay *display,
503                                                   GdkAtom     selection)
504
505 {
506   static HWND hwndViewer = NULL;
507   gboolean ret = FALSE;
508
509   GDK_NOTE (DND,
510             g_print ("gdk_display_request_selection_notification (..., %s)",
511                      gdk_atom_name (selection)));
512
513   if (selection == GDK_SELECTION_CLIPBOARD ||
514       selection == GDK_SELECTION_PRIMARY)
515     {
516       if (!hwndViewer)
517         {
518           hwndViewer = _gdk_win32_register_clipboard_notification ();
519           GDK_NOTE (DND, g_print (" registered"));
520         }
521       ret = (hwndViewer != NULL);
522     }
523   else
524     {
525       GDK_NOTE (DND, g_print (" unsupported"));
526       ret = FALSE;
527     }
528
529   GDK_NOTE (DND, g_print (" -> %s\n", ret ? "TRUE" : "FALSE"));
530   return ret;
531 }
532
533 static gboolean
534 gdk_win32_display_supports_clipboard_persistence (GdkDisplay *display)
535 {
536   return FALSE;
537 }
538
539 static void
540 gdk_win32_display_store_clipboard (GdkDisplay    *display,
541                              GdkWindow     *clipboard_window,
542                              guint32        time_,
543                              const GdkAtom *targets,
544                              gint           n_targets)
545 {
546 }
547
548 static gboolean 
549 gdk_win32_display_supports_shapes (GdkDisplay *display)
550 {
551   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
552
553   return TRUE;
554 }
555
556 static gboolean
557 gdk_win32_display_supports_input_shapes (GdkDisplay *display)
558 {
559   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
560
561   /* Not yet implemented. See comment in
562    * gdk_window_input_shape_combine_mask().
563    */
564
565   return FALSE;
566 }
567
568 static gboolean
569 gdk_win32_display_supports_composite (GdkDisplay *display)
570 {
571   return FALSE;
572 }
573
574 static void
575 gdk_win32_display_beep (GdkDisplay *display)
576 {
577   g_return_if_fail (display == gdk_display_get_default());
578   if (!MessageBeep (-1))
579     Beep(1000, 50);
580 }
581
582 static void
583 gdk_win32_display_flush (GdkDisplay * display)
584 {
585   g_return_if_fail (display == _gdk_display);
586
587   GdiFlush ();
588 }
589
590
591 static void
592 gdk_win32_display_sync (GdkDisplay * display)
593 {
594   g_return_if_fail (display == _gdk_display);
595
596   GdiFlush ();
597 }
598
599 static void
600 gdk_win32_display_dispose (GObject *object)
601 {
602 }
603
604 static void
605 gdk_win32_display_finalize (GObject *object)
606 {
607 }
608
609 static void
610 gdk_win32_display_init(GdkWin32Display *display)
611 {
612 }
613
614 static void
615 gdk_win32_display_before_process_all_updates (GdkDisplay  *display)
616 {
617   /* nothing */
618 }
619 static void
620 gdk_win32_display_after_process_all_updates (GdkDisplay  *display)
621 {
622   /* nothing */
623 }
624 static void
625 gdk_win32_display_notify_startup_complete (GdkDisplay  *display,
626                                            const gchar *startup_id)
627 {
628   /* nothing */
629 }
630 static void
631 gdk_win32_display_event_data_copy (GdkDisplay    *display,
632                                    const GdkEvent *src,
633                                    GdkEvent       *dst)
634 {
635   /* nothing */
636 }
637 static void
638 gdk_win32_display_event_data_free (GdkDisplay *display,
639                                    GdkEvent *event)
640 {
641   /* nothing */
642 }
643 static void
644 gdk_win32_display_push_error_trap (GdkDisplay *display)
645 {
646   /* nothing */
647 }
648 static gint
649 gdk_win32_display_pop_error_trap (GdkDisplay *display,
650                                   gboolean    ignored)
651 {
652   return 0;
653 }
654 static void
655 gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
656 {
657   GObjectClass *object_class = G_OBJECT_CLASS (klass);
658   GdkDisplayClass *display_class = GDK_DISPLAY_CLASS (klass);
659
660   object_class->dispose = gdk_win32_display_dispose;
661   object_class->finalize = gdk_win32_display_finalize;
662
663   display_class->window_type = GDK_TYPE_WIN32_WINDOW;
664
665   display_class->get_name = gdk_win32_display_get_name;
666   display_class->get_n_screens = gdk_win32_display_get_n_screens;
667   display_class->get_screen = gdk_win32_display_get_screen;
668   display_class->get_default_screen = gdk_win32_display_get_default_screen;
669   display_class->beep = gdk_win32_display_beep;
670   display_class->sync = gdk_win32_display_sync;
671   display_class->flush = gdk_win32_display_flush;
672   display_class->has_pending = _gdk_win32_display_has_pending;
673   display_class->queue_events = _gdk_win32_display_queue_events;
674   display_class->get_default_group = gdk_win32_display_get_default_group;
675
676   display_class->supports_selection_notification = gdk_win32_display_supports_selection_notification;
677   display_class->request_selection_notification = gdk_win32_display_request_selection_notification;
678   display_class->supports_clipboard_persistence = gdk_win32_display_supports_clipboard_persistence;
679   display_class->store_clipboard = gdk_win32_display_store_clipboard;
680   display_class->supports_shapes = gdk_win32_display_supports_shapes;
681   display_class->supports_input_shapes = gdk_win32_display_supports_input_shapes;
682   display_class->supports_composite = gdk_win32_display_supports_composite;
683
684   display_class->list_devices = _gdk_win32_display_list_devices;
685   //? display_class->get_app_launch_context = _gdk_win32_display_get_app_launch_context;
686   display_class->get_cursor_for_type = _gdk_win32_display_get_cursor_for_type;
687   display_class->get_cursor_for_name = _gdk_win32_display_get_cursor_for_name;
688   display_class->get_cursor_for_pixbuf = _gdk_win32_display_get_cursor_for_pixbuf;
689   display_class->get_default_cursor_size = _gdk_win32_display_get_default_cursor_size;
690   display_class->get_maximal_cursor_size = _gdk_win32_display_get_maximal_cursor_size;
691   display_class->supports_cursor_alpha = _gdk_win32_display_supports_cursor_alpha;
692   display_class->supports_cursor_color = _gdk_win32_display_supports_cursor_color;
693
694   display_class->before_process_all_updates = gdk_win32_display_before_process_all_updates;
695   display_class->after_process_all_updates = gdk_win32_display_after_process_all_updates;
696   display_class->get_next_serial = gdk_win32_display_get_next_serial;
697   display_class->notify_startup_complete = gdk_win32_display_notify_startup_complete;
698   display_class->event_data_copy = gdk_win32_display_event_data_copy;
699   display_class->event_data_free = gdk_win32_display_event_data_free;
700   display_class->create_window_impl = _gdk_win32_display_create_window_impl;
701
702   display_class->get_keymap = _gdk_win32_display_get_keymap;
703   display_class->push_error_trap = gdk_win32_display_push_error_trap;
704   display_class->pop_error_trap = gdk_win32_display_pop_error_trap;
705   display_class->get_selection_owner = _gdk_win32_display_get_selection_owner;
706   display_class->set_selection_owner = _gdk_win32_display_set_selection_owner;
707   display_class->send_selection_notify = _gdk_win32_display_send_selection_notify;
708   display_class->get_selection_property = _gdk_win32_display_get_selection_property;
709   display_class->convert_selection = _gdk_win32_display_convert_selection;
710   display_class->text_property_to_utf8_list = _gdk_win32_display_text_property_to_utf8_list;
711   display_class->utf8_to_string_target = _gdk_win32_display_utf8_to_string_target;
712 }