]> Pileus Git - ~andy/gtk/blobdiff - gdk/quartz/gdkscreen-quartz.c
x11: Get rid of XSettingsSetting
[~andy/gtk] / gdk / quartz / gdkscreen-quartz.c
index 741e35fdc8fc7860fbbd1e556497c07553ad360a..eafaf20c3d9da08b4585192f29ae629ef8c0a9f2 100644 (file)
@@ -1,6 +1,7 @@
 /* gdkscreen-quartz.c
  *
  * Copyright (C) 2005 Imendio AB
+ * Copyright (C) 2009,2010  Kristian Rietveld  <kris@gtk.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "config.h"
-#include "gdk.h"
+
+#include <gdk/gdk.h>
+
 #include "gdkprivate-quartz.h"
  
-/* FIXME: If we want to do it properly, this should be stored
- * in a proper GdkScreen subclass.
+
+/* A couple of notes about this file are in order.  In GDK, a
+ * GdkScreen can contain multiple monitors.  A GdkScreen has an
+ * associated root window, in which the monitors are placed.  The
+ * root window "spans" all monitors.  The origin is at the top-left
+ * corner of the root window.
+ *
+ * Cocoa works differently.  The system has a "screen" (NSScreen) for
+ * each monitor that is connected (note the conflicting definitions
+ * of screen).  The screen containing the menu bar is screen 0 and the
+ * bottom-left corner of this screen is the origin of the "monitor
+ * coordinate space".  All other screens are positioned according to this
+ * origin.  If the menu bar is on a secondary screen (for example on
+ * a monitor hooked up to a laptop), then this screen is screen 0 and
+ * other monitors will be positioned according to the "secondary screen".
+ * The main screen is the monitor that shows the window that is currently
+ * active (has focus), the position of the menu bar does not have influence
+ * on this!
+ *
+ * Upon start up and changes in the layout of screens, we calculate the
+ * size of the GdkScreen root window that is needed to be able to place
+ * all monitors in the root window.  Once that size is known, we iterate
+ * over the monitors and translate their Cocoa position to a position
+ * in the root window of the GdkScreen.  This happens below in the
+ * function gdk_quartz_screen_calculate_layout().
+ *
+ * A Cocoa coordinate is always relative to the origin of the monitor
+ * coordinate space.  Such coordinates are mapped to their respective
+ * position in the GdkScreen root window (_gdk_quartz_window_xy_to_gdk_xy)
+ * and vice versa (_gdk_quartz_window_gdk_xy_to_xy).  Both functions can
+ * be found in gdkwindow-quartz.c.  Note that Cocoa coordinates can have
+ * negative values (in case a monitor is located left or below of screen 0),
+ * but GDK coordinates can *not*!
  */
-static GdkColormap *default_colormap = NULL;
-static int n_screens = 0;
-static GdkRectangle *screen_rects = NULL;
 
+static void  gdk_quartz_screen_dispose          (GObject         *object);
+static void  gdk_quartz_screen_finalize         (GObject         *object);
+static void  gdk_quartz_screen_calculate_layout (GdkQuartzScreen *screen);
+
+static void display_reconfiguration_callback (CGDirectDisplayID            display,
+                                              CGDisplayChangeSummaryFlags  flags,
+                                              void                        *userInfo);
+
+G_DEFINE_TYPE (GdkQuartzScreen, gdk_quartz_screen, GDK_TYPE_SCREEN);
+
+static void
+gdk_quartz_screen_init (GdkQuartzScreen *quartz_screen)
+{
+  GdkScreen *screen = GDK_SCREEN (quartz_screen);
+  NSScreen *nsscreen;
+
+  nsscreen = [[NSScreen screens] objectAtIndex:0];
+  gdk_screen_set_resolution (screen,
+                             72.0 * [nsscreen userSpaceScaleFactor]);
+
+  gdk_quartz_screen_calculate_layout (quartz_screen);
+
+  CGDisplayRegisterReconfigurationCallback (display_reconfiguration_callback,
+                                            screen);
+
+  quartz_screen->emit_monitors_changed = FALSE;
+}
+
+static void
+gdk_quartz_screen_dispose (GObject *object)
+{
+  GdkQuartzScreen *screen = GDK_QUARTZ_SCREEN (object);
+
+  if (screen->screen_changed_id)
+    {
+      g_source_remove (screen->screen_changed_id);
+      screen->screen_changed_id = 0;
+    }
+
+  CGDisplayRemoveReconfigurationCallback (display_reconfiguration_callback,
+                                          screen);
+
+  G_OBJECT_CLASS (gdk_quartz_screen_parent_class)->dispose (object);
+}
+
+static void
+gdk_quartz_screen_screen_rects_free (GdkQuartzScreen *screen)
+{
+  screen->n_screens = 0;
+
+  if (screen->screen_rects)
+    {
+      g_free (screen->screen_rects);
+      screen->screen_rects = NULL;
+    }
+}
 
 static void
-screen_rects_init (void)
+gdk_quartz_screen_finalize (GObject *object)
+{
+  GdkQuartzScreen *screen = GDK_QUARTZ_SCREEN (object);
+
+  gdk_quartz_screen_screen_rects_free (screen);
+}
+
+
+static void
+gdk_quartz_screen_calculate_layout (GdkQuartzScreen *screen)
 {
   NSArray *array;
-  NSRect largest_rect;
   int i;
+  int max_x, max_y;
 
   GDK_QUARTZ_ALLOC_POOL;
 
-  array = [NSScreen screens];
+  gdk_quartz_screen_screen_rects_free (screen);
 
-  n_screens = [array count];
-  screen_rects = g_new0 (GdkRectangle, n_screens);
+  array = [NSScreen screens];
 
-  /* FIXME: as stated above the get_width() and get_height() functions
-   * in this file, we only support horizontal screen layouts for now.
-   */
+  screen->width = 0;
+  screen->height = 0;
+  screen->min_x = 0;
+  screen->min_y = 0;
+  max_x = max_y = 0;
 
-  /* Find the monitor with the largest height.  All monitors should be
-   * offset to this one in the GDK screen space instead of offset to
-   * the screen with the menu bar.
+  /* We determine the minimum and maximum x and y coordinates
+   * covered by the monitors.  From this we can deduce the width
+   * and height of the root screen.
    */
-  largest_rect = [[array objectAtIndex:0] frame];
-  for (i = 1; i < [array count]; i++)
+  for (i = 0; i < [array count]; i++)
     {
       NSRect rect = [[array objectAtIndex:i] frame];
 
-      if (rect.size.height > largest_rect.size.height)
-        largest_rect = [[array objectAtIndex:i] frame];
+      screen->min_x = MIN (screen->min_x, rect.origin.x);
+      max_x = MAX (max_x, rect.origin.x + rect.size.width);
+
+      screen->min_y = MIN (screen->min_y, rect.origin.y);
+      max_y = MAX (max_y, rect.origin.y + rect.size.height);
     }
 
-  for (i = 0; i < n_screens; i++)
+  screen->width = max_x - screen->min_x;
+  screen->height = max_y - screen->min_y;
+
+  screen->n_screens = [array count];
+  screen->screen_rects = g_new0 (GdkRectangle, screen->n_screens);
+
+  for (i = 0; i < screen->n_screens; i++)
     {
       NSScreen *nsscreen;
       NSRect rect;
@@ -69,139 +172,155 @@ screen_rects_init (void)
       nsscreen = [array objectAtIndex:i];
       rect = [nsscreen frame];
 
-      screen_rects[i].x = rect.origin.x;
-      screen_rects[i].width = rect.size.width;
-      screen_rects[i].height = rect.size.height;
-
-      if (largest_rect.size.height - rect.size.height == 0)
-        screen_rects[i].y = 0;
-      else
-        screen_rects[i].y = largest_rect.size.height - rect.size.height + largest_rect.origin.y;
+      screen->screen_rects[i].x = rect.origin.x - screen->min_x;
+      screen->screen_rects[i].y
+          = screen->height - (rect.origin.y + rect.size.height) + screen->min_y;
+      screen->screen_rects[i].width = rect.size.width;
+      screen->screen_rects[i].height = rect.size.height;
     }
 
   GDK_QUARTZ_RELEASE_POOL;
 }
 
 void
-_gdk_quartz_screen_init (void)
+_gdk_quartz_screen_update_window_sizes (GdkScreen *screen)
 {
-  gdk_screen_set_default_colormap (_gdk_screen,
-                                   gdk_screen_get_system_colormap (_gdk_screen));
+  GList *windows, *list;
+
+  /* The size of the root window is so that it can contain all
+   * monitors attached to this machine.  The monitors are laid out
+   * within this root window.  We calculate the size of the root window
+   * and the positions of the different monitors in gdkscreen-quartz.c.
+   *
+   * This data is updated when the monitor configuration is changed.
+   */
 
-  screen_rects_init ();
-}
+  /* FIXME: At some point, fetch the root window from GdkScreen.  But
+   * on OS X will we only have a single root window anyway.
+   */
+  _gdk_root->x = 0;
+  _gdk_root->y = 0;
+  _gdk_root->abs_x = 0;
+  _gdk_root->abs_y = 0;
+  _gdk_root->width = gdk_screen_get_width (screen);
+  _gdk_root->height = gdk_screen_get_height (screen);
 
-GdkDisplay *
-gdk_screen_get_display (GdkScreen *screen)
-{
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+  windows = gdk_screen_get_toplevel_windows (screen);
 
-  return _gdk_display;
-}
+  for (list = windows; list; list = list->next)
+    _gdk_quartz_window_update_position (list->data);
 
+  g_list_free (windows);
+}
 
-GdkWindow *
-gdk_screen_get_root_window (GdkScreen *screen)
+static void
+process_display_reconfiguration (GdkQuartzScreen *screen)
 {
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+  int width, height;
 
-  return _gdk_root;
-}
+  width = gdk_screen_get_width (GDK_SCREEN (screen));
+  height = gdk_screen_get_height (GDK_SCREEN (screen));
 
-gint
-gdk_screen_get_number (GdkScreen *screen)
-{
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+  gdk_quartz_screen_calculate_layout (GDK_QUARTZ_SCREEN (screen));
 
-  return 0;
-}
+  _gdk_quartz_screen_update_window_sizes (GDK_SCREEN (screen));
 
-gchar * 
-_gdk_windowing_substitute_screen_number (const gchar *display_name,
-                                        int          screen_number)
-{
-  if (screen_number != 0)
-    return NULL;
+  if (screen->emit_monitors_changed)
+    {
+      g_signal_emit_by_name (screen, "monitors-changed");
+      screen->emit_monitors_changed = FALSE;
+    }
 
-  return g_strdup (display_name);
+  if (width != gdk_screen_get_width (GDK_SCREEN (screen))
+      || height != gdk_screen_get_height (GDK_SCREEN (screen)))
+    g_signal_emit_by_name (screen, "size-changed");
 }
 
-GdkColormap*
-gdk_screen_get_default_colormap (GdkScreen *screen)
+static gboolean
+screen_changed_idle (gpointer data)
 {
-  return default_colormap;
-}
+  GdkQuartzScreen *screen = data;
 
-void
-gdk_screen_set_default_colormap (GdkScreen   *screen,
-                                GdkColormap *colormap)
-{
-  GdkColormap *old_colormap;
-  
-  g_return_if_fail (GDK_IS_SCREEN (screen));
-  g_return_if_fail (GDK_IS_COLORMAP (colormap));
+  process_display_reconfiguration (data);
 
-  old_colormap = default_colormap;
+  screen->screen_changed_id = 0;
 
-  default_colormap = g_object_ref (colormap);
-  
-  if (old_colormap)
-    g_object_unref (old_colormap);
+  return FALSE;
 }
 
-/* FIXME: note on the get_width() and the get_height() methods.  For
- * now we only support screen layouts where the screens are laid out
- * horizontally.  Mac OS X also supports laying out the screens vertically
- * and the screens having "non-standard" offsets from eachother.  In the
- * future we need a much more sophiscated algorithm to translate these
- * layouts to GDK coordinate space and GDK screen layout.
- */
-gint
-gdk_screen_get_width (GdkScreen *screen)
+static void
+display_reconfiguration_callback (CGDirectDisplayID            display,
+                                  CGDisplayChangeSummaryFlags  flags,
+                                  void                        *userInfo)
 {
-  int i;
-  int width;
-  NSArray *array;
-
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+  GdkQuartzScreen *screen = userInfo;
 
-  GDK_QUARTZ_ALLOC_POOL;
-  array = [NSScreen screens];
-
-  width = 0;
-  for (i = 0; i < [array count]; i++) 
+  if (flags & kCGDisplayBeginConfigurationFlag)
     {
-      NSRect rect = [[array objectAtIndex:i] frame];
-      width += rect.size.width;
+      /* Ignore the begin configuration signal. */
+      return;
     }
+  else
+    {
+      /* We save information about the changes, so we can emit
+       * ::monitors-changed when appropriate.  This signal must be
+       * emitted when the number, size of position of one of the
+       * monitors changes.
+       */
+      if (flags & kCGDisplayMovedFlag
+          || flags & kCGDisplayAddFlag
+          || flags & kCGDisplayRemoveFlag
+          || flags & kCGDisplayEnabledFlag
+          || flags & kCGDisplayDisabledFlag)
+        screen->emit_monitors_changed = TRUE;
+
+      /* At this point Cocoa does not know about the new screen data
+       * yet, so we delay our refresh into an idle handler.
+       */
+      if (!screen->screen_changed_id)
+        screen->screen_changed_id = gdk_threads_add_idle (screen_changed_idle,
+                                                          screen);
+    }
+}
 
-  GDK_QUARTZ_RELEASE_POOL;
-
-  return width;
+static GdkDisplay *
+gdk_quartz_screen_get_display (GdkScreen *screen)
+{
+  return _gdk_display;
 }
 
-gint
-gdk_screen_get_height (GdkScreen *screen)
+static GdkWindow *
+gdk_quartz_screen_get_root_window (GdkScreen *screen)
 {
-  int i;
-  int height;
-  NSArray *array;
+  return _gdk_root;
+}
 
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+static gint
+gdk_quartz_screen_get_number (GdkScreen *screen)
+{
+  return 0;
+}
 
-  GDK_QUARTZ_ALLOC_POOL;
-  array = [NSScreen screens];
+gchar *
+_gdk_windowing_substitute_screen_number (const gchar *display_name,
+                                        int          screen_number)
+{
+  if (screen_number != 0)
+    return NULL;
 
-  height = 0;
-  for (i = 0; i < [array count]; i++) 
-    {
-      NSRect rect = [[array objectAtIndex:i] frame];
-      height = MAX (height, rect.size.height);
-    }
+  return g_strdup (display_name);
+}
 
-  GDK_QUARTZ_RELEASE_POOL;
+static gint
+gdk_quartz_screen_get_width (GdkScreen *screen)
+{
+  return GDK_QUARTZ_SCREEN (screen)->width;
+}
 
-  return height;
+static gint
+gdk_quartz_screen_get_height (GdkScreen *screen)
+{
+  return GDK_QUARTZ_SCREEN (screen)->height;
 }
 
 static gint
@@ -220,151 +339,166 @@ get_mm_from_pixels (NSScreen *screen, int pixels)
   return (pixels / dpi) * 25.4;
 }
 
-gint
-gdk_screen_get_width_mm (GdkScreen *screen)
+static NSScreen *
+get_nsscreen_for_monitor (gint monitor_num)
 {
-  int i;
-  gint width;
   NSArray *array;
-
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+  NSScreen *screen;
 
   GDK_QUARTZ_ALLOC_POOL;
-  array = [NSScreen screens];
 
-  width = 0;
-  for (i = 0; i < [array count]; i++)
-    {
-      NSScreen *screen = [array objectAtIndex:i];
-      NSRect rect = [screen frame];
-      width += get_mm_from_pixels (screen, rect.size.width);
-    }
+  array = [NSScreen screens];
+  screen = [array objectAtIndex:monitor_num];
 
   GDK_QUARTZ_RELEASE_POOL;
 
-  return width;
+  return screen;
 }
 
-gint
-gdk_screen_get_height_mm (GdkScreen *screen)
+static gint
+gdk_quartz_screen_get_width_mm (GdkScreen *screen)
 {
-  int i;
-  gint height;
-  NSArray *array;
-
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
-
-  GDK_QUARTZ_ALLOC_POOL;
-  array = [NSScreen screens];
-
-  height = 0;
-  for (i = 0; i < [array count]; i++)
-    {
-      NSScreen *screen = [array objectAtIndex:i];
-      NSRect rect = [screen frame];
-      gint h = get_mm_from_pixels (screen, rect.size.height);
-      height = MAX (height, h);
-    }
-
-  GDK_QUARTZ_RELEASE_POOL;
-
-  return height;
+  return get_mm_from_pixels (get_nsscreen_for_monitor (0),
+                             GDK_QUARTZ_SCREEN (screen)->width);
 }
 
-int
-gdk_screen_get_n_monitors (GdkScreen *screen)
+static gint
+gdk_quartz_screen_get_height_mm (GdkScreen *screen)
 {
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
-
-  return n_screens;
+  return get_mm_from_pixels (get_nsscreen_for_monitor (0),
+                             GDK_QUARTZ_SCREEN (screen)->height);
 }
 
-static NSScreen *
-get_nsscreen_for_monitor (gint monitor_num)
+static gint
+gdk_quartz_screen_get_n_monitors (GdkScreen *screen)
 {
-  NSArray *array;
-  NSScreen *screen;
-
-  GDK_QUARTZ_ALLOC_POOL;
-
-  array = [NSScreen screens];
-  screen = [array objectAtIndex:monitor_num];
-
-  GDK_QUARTZ_RELEASE_POOL;
-
-  return screen;
+  return GDK_QUARTZ_SCREEN (screen)->n_screens;
 }
 
-gint
-gdk_screen_get_monitor_width_mm        (GdkScreen *screen,
-                                gint       monitor_num)
+static gint
+gdk_quartz_screen_get_primary_monitor (GdkScreen *screen)
 {
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
-  g_return_val_if_fail (monitor_num < gdk_screen_get_n_monitors (screen), 0);
-  g_return_val_if_fail (monitor_num >= 0, 0);
+  return 0;
+}
 
+static gint
+gdk_quartz_screen_get_monitor_width_mm (GdkScreen *screen,
+                                        gint       monitor_num)
+{
   return get_mm_from_pixels (get_nsscreen_for_monitor (monitor_num),
-                             screen_rects[monitor_num].width);
+                             GDK_QUARTZ_SCREEN (screen)->screen_rects[monitor_num].width);
 }
 
-gint
-gdk_screen_get_monitor_height_mm (GdkScreen *screen,
-                                  gint       monitor_num)
+static gint
+gdk_quartz_screen_get_monitor_height_mm (GdkScreen *screen,
+                                         gint       monitor_num)
 {
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
-  g_return_val_if_fail (monitor_num < gdk_screen_get_n_monitors (screen), 0);
-  g_return_val_if_fail (monitor_num >= 0, 0);
-
   return get_mm_from_pixels (get_nsscreen_for_monitor (monitor_num),
-                             screen_rects[monitor_num].height);
+                             GDK_QUARTZ_SCREEN (screen)->screen_rects[monitor_num].height);
 }
 
-gchar *
-gdk_screen_get_monitor_plug_name (GdkScreen *screen,
-                                 gint       monitor_num)
+static gchar *
+gdk_quartz_screen_get_monitor_plug_name (GdkScreen *screen,
+                                         gint       monitor_num)
 {
   /* FIXME: Is there some useful name we could use here? */
   return NULL;
 }
 
-void
-gdk_screen_get_monitor_geometry (GdkScreen    *screen, 
-                                gint          monitor_num,
-                                GdkRectangle *dest)
+static void
+gdk_quartz_screen_get_monitor_geometry (GdkScreen    *screen,
+                                        gint          monitor_num,
+                                        GdkRectangle *dest)
+{
+  *dest = GDK_QUARTZ_SCREEN (screen)->screen_rects[monitor_num];
+}
+
+static void
+gdk_quartz_screen_get_monitor_workarea (GdkScreen    *screen,
+                                        gint          monitor_num,
+                                        GdkRectangle *dest)
 {
-  g_return_if_fail (GDK_IS_SCREEN (screen));
-  g_return_if_fail (monitor_num < gdk_screen_get_n_monitors (screen));
-  g_return_if_fail (monitor_num >= 0);
+  GdkQuartzScreen *quartz_screen = GDK_QUARTZ_SCREEN (screen);
+  NSArray *array;
+  NSScreen *nsscreen;
+  NSRect rect;
 
-  *dest = screen_rects[monitor_num];
+  GDK_QUARTZ_ALLOC_POOL;
+
+  array = [NSScreen screens];
+  nsscreen = [array objectAtIndex:monitor_num];
+  rect = [nsscreen visibleFrame];
+
+  dest->x = rect.origin.x - quartz_screen->min_x;
+  dest->y = quartz_screen->height - (rect.origin.y + rect.size.height) + quartz_screen->min_y;
+  dest->width = rect.size.width;
+  dest->height = rect.size.height;
+
+  GDK_QUARTZ_RELEASE_POOL;
 }
 
-gchar *
-gdk_screen_make_display_name (GdkScreen *screen)
+static gchar *
+gdk_quartz_screen_make_display_name (GdkScreen *screen)
 {
   return g_strdup (gdk_display_get_name (_gdk_display));
 }
 
-GdkWindow *
-gdk_screen_get_active_window (GdkScreen *screen)
+static GdkWindow *
+gdk_quartz_screen_get_active_window (GdkScreen *screen)
 {
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
-
   return NULL;
 }
 
-GList *
-gdk_screen_get_window_stack (GdkScreen *screen)
+static GList *
+gdk_quartz_screen_get_window_stack (GdkScreen *screen)
 {
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
-
   return NULL;
 }
 
-gboolean
-gdk_screen_is_composited (GdkScreen *screen)
+static gboolean
+gdk_quartz_screen_is_composited (GdkScreen *screen)
 {
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
-
   return TRUE;
 }
+
+static void
+gdk_quartz_screen_class_init (GdkQuartzScreenClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GdkScreenClass *screen_class = GDK_SCREEN_CLASS (klass);
+
+  object_class->dispose = gdk_quartz_screen_dispose;
+  object_class->finalize = gdk_quartz_screen_finalize;
+
+  screen_class->get_display = gdk_quartz_screen_get_display;
+  screen_class->get_width = gdk_quartz_screen_get_width;
+  screen_class->get_height = gdk_quartz_screen_get_height;
+  screen_class->get_width_mm = gdk_quartz_screen_get_width_mm;
+  screen_class->get_height_mm = gdk_quartz_screen_get_height_mm;
+  screen_class->get_number = gdk_quartz_screen_get_number;
+  screen_class->get_root_window = gdk_quartz_screen_get_root_window;
+  screen_class->get_n_monitors = gdk_quartz_screen_get_n_monitors;
+  screen_class->get_primary_monitor = gdk_quartz_screen_get_primary_monitor;
+  screen_class->get_monitor_width_mm = gdk_quartz_screen_get_monitor_width_mm;
+  screen_class->get_monitor_height_mm = gdk_quartz_screen_get_monitor_height_mm;
+  screen_class->get_monitor_plug_name = gdk_quartz_screen_get_monitor_plug_name;
+  screen_class->get_monitor_geometry = gdk_quartz_screen_get_monitor_geometry;
+  screen_class->get_monitor_workarea = gdk_quartz_screen_get_monitor_workarea;
+  screen_class->is_composited = gdk_quartz_screen_is_composited;
+  screen_class->make_display_name = gdk_quartz_screen_make_display_name;
+  screen_class->get_active_window = gdk_quartz_screen_get_active_window;
+  screen_class->get_window_stack = gdk_quartz_screen_get_window_stack;
+  screen_class->broadcast_client_message = _gdk_quartz_screen_broadcast_client_message;
+  screen_class->get_setting = _gdk_quartz_screen_get_setting;
+  screen_class->get_rgba_visual = _gdk_quartz_screen_get_rgba_visual;
+  screen_class->get_system_visual = _gdk_quartz_screen_get_system_visual;
+  screen_class->visual_get_best_depth = _gdk_quartz_screen_visual_get_best_depth;
+  screen_class->visual_get_best_type = _gdk_quartz_screen_visual_get_best_type;
+  screen_class->visual_get_best = _gdk_quartz_screen_visual_get_best;
+  screen_class->visual_get_best_with_depth = _gdk_quartz_screen_visual_get_best_with_depth;
+  screen_class->visual_get_best_with_type = _gdk_quartz_screen_visual_get_best_with_type;
+  screen_class->visual_get_best_with_both = _gdk_quartz_screen_visual_get_best_with_both;
+  screen_class->query_depths = _gdk_quartz_screen_query_depths;
+  screen_class->query_visual_types = _gdk_quartz_screen_query_visual_types;
+  screen_class->list_visuals = _gdk_quartz_screen_list_visuals;
+}