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