[gtk/wip/chergert/quartz4u] macos: load monitor information
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/quartz4u] macos: load monitor information
- Date: Tue, 5 May 2020 19:55:12 +0000 (UTC)
commit 54d0da41438c893176c2182061fb668bca732e83
Author: Christian Hergert <chergert redhat com>
Date: Tue May 5 12:54:17 2020 -0700
macos: load monitor information
gdk/macos/gdkmacosdisplay.c | 39 ++++++---
gdk/macos/gdkmacosmonitor-private.h | 1 +
gdk/macos/gdkmacosmonitor.c | 167 ++++++++++++++++++++++++++++++++++++
3 files changed, 194 insertions(+), 13 deletions(-)
---
diff --git a/gdk/macos/gdkmacosdisplay.c b/gdk/macos/gdkmacosdisplay.c
index bfc00190e7..5b504404f9 100644
--- a/gdk/macos/gdkmacosdisplay.c
+++ b/gdk/macos/gdkmacosdisplay.c
@@ -188,41 +188,54 @@ gdk_macos_display_remove_monitor (GdkMacosDisplay *self,
}
static void
-gdk_macos_display_load_monitors (GdkMacosDisplay *self)
+gdk_macos_display_update_bounds (GdkMacosDisplay *self)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
- NSArray *screens;
int max_x = 0;
int max_y = 0;
g_assert (GDK_IS_MACOS_DISPLAY (self));
- screens = [NSScreen screens];
+ self->min_x = 0;
+ self->min_y = 0;
- for (id obj in screens)
+ for (id obj in [NSScreen screens])
{
- CGDirectDisplayID screen_id;
- GdkMacosMonitor *monitor;
- NSRect geom;
+ NSRect geom = [(NSScreen *)obj frame];
- geom = [obj frame];
self->min_x = MIN (self->min_x, geom.origin.x);
self->min_y = MIN (self->min_y, geom.origin.y);
max_x = MAX (max_x, geom.origin.x + geom.size.width);
max_y = MAX (max_y, geom.origin.y + geom.size.height);
+ }
+
+ self->width = max_x - self->min_x;
+ self->height = max_y - self->min_y;
+
+ GDK_END_MACOS_ALLOC_POOL;
+}
+
+static void
+gdk_macos_display_load_monitors (GdkMacosDisplay *self)
+{
+ GDK_BEGIN_MACOS_ALLOC_POOL;
+
+ g_assert (GDK_IS_MACOS_DISPLAY (self));
+
+ gdk_macos_display_update_bounds (self);
+
+ for (id obj in [NSScreen screens])
+ {
+ CGDirectDisplayID screen_id;
+ GdkMacosMonitor *monitor;
screen_id = [[[obj deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue];
monitor = _gdk_macos_monitor_new (self, screen_id);
-
gdk_macos_display_add_monitor (self, monitor);
-
g_object_unref (monitor);
}
- self->width = max_x - self->min_x;
- self->height = max_y - self->min_y;
-
GDK_END_MACOS_ALLOC_POOL;
}
diff --git a/gdk/macos/gdkmacosmonitor-private.h b/gdk/macos/gdkmacosmonitor-private.h
index 8e65e73c3d..3c6f058bd0 100644
--- a/gdk/macos/gdkmacosmonitor-private.h
+++ b/gdk/macos/gdkmacosmonitor-private.h
@@ -32,6 +32,7 @@ G_BEGIN_DECLS
GdkMacosMonitor *_gdk_macos_monitor_new (GdkMacosDisplay *display,
CGDirectDisplayID screen_id);
CGDirectDisplayID _gdk_macos_monitor_get_screen_id (GdkMacosMonitor *self);
+gboolean _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self);
G_END_DECLS
diff --git a/gdk/macos/gdkmacosmonitor.c b/gdk/macos/gdkmacosmonitor.c
index 755f16d831..80cd56d484 100644
--- a/gdk/macos/gdkmacosmonitor.c
+++ b/gdk/macos/gdkmacosmonitor.c
@@ -20,6 +20,7 @@
#include "config.h"
#include <gdk/gdk.h>
+#include <math.h>
#include "gdkmacosdisplay-private.h"
#include "gdkmacosmonitor-private.h"
@@ -29,6 +30,7 @@ struct _GdkMacosMonitor
{
GdkMonitor parent_instance;
CGDirectDisplayID screen_id;
+ guint has_opengl : 1;
};
struct _GdkMacosMonitorClass
@@ -94,6 +96,168 @@ gdk_macos_monitor_init (GdkMacosMonitor *self)
{
}
+static GdkSubpixelLayout
+GetSubpixelLayout (CGDirectDisplayID screen_id)
+{
+#if 0
+ GDK_BEGIN_MACOS_ALLOC_POOL;
+
+ GdkSubpixelLayout subpixel_layout = GDK_SUBPIXEL_LAYOUT_UNKNOWN;
+ io_service_t iosvc;
+ NSDictionary *dict;
+ guint layout;
+ gboolean rotation;
+
+ rotation = CGDisplayRotation (screen_id);
+ iosvc = CGDisplayIOServicePort (screen_id);
+ dict = (NSDictionary *)IODisplayCreateInfoDictionary (iosvc, kIODisplayOnlyPreferredName);
+ layout = [[dict objectForKey:@kDisplaySubPixelLayout] unsignedIntValue];
+
+ switch (layout)
+ {
+ case kDisplaySubPixelLayoutRGB:
+ if (rotation == 0.0)
+ subpixel_layout = GDK_SUBPIXEL_LAYOUT_HORIZONTAL_RGB;
+ else if (rotation == 90.0)
+ subpixel_layout = GDK_SUBPIXEL_LAYOUT_VERTICAL_RGB;
+ else if (rotation == 180.0 || rotation == -180.0)
+ subpixel_layout = GDK_SUBPIXEL_LAYOUT_HORIZONTAL_BGR;
+ else if (rotation == -90.0)
+ subpixel_layout = GDK_SUBPIXEL_LAYOUT_VERTICAL_BGR;
+ break;
+
+ case kDisplaySubPixelLayoutBGR:
+ if (rotation == 0.0)
+ subpixel_layout = GDK_SUBPIXEL_LAYOUT_HORIZONTAL_BGR;
+ else if (rotation == 90.0)
+ subpixel_layout = GDK_SUBPIXEL_LAYOUT_VERTICAL_BGR;
+ else if (rotation == 180.0 || rotation == -180.0)
+ subpixel_layout = GDK_SUBPIXEL_LAYOUT_HORIZONTAL_RGB;
+ else if (rotation == -90.0 || rotation == 270.0)
+ subpixel_layout = GDK_SUBPIXEL_LAYOUT_VERTICAL_RGB;
+ break;
+
+ default:
+ break;
+ }
+
+ GDK_END_MACOS_ALLOC_POOL;
+
+ return subpixel_layout;
+#endif
+
+ return GDK_SUBPIXEL_LAYOUT_UNKNOWN;
+}
+
+static char *
+GetLocalizedName (CGDirectDisplayID screen_id)
+{
+ GDK_BEGIN_MACOS_ALLOC_POOL;
+
+ char *name = NULL;
+
+ for (id obj in [NSScreen screens])
+ {
+ CGDirectDisplayID this_id = [[[obj deviceDescription] objectForKey:@"NSScreenNumber"]
unsignedIntValue];
+
+ if (screen_id == this_id)
+ {
+ NSString *str = [(NSScreen *)obj localizedName];
+ name = g_strdup ([str UTF8String]);
+ break;
+ }
+ }
+
+ GDK_END_MACOS_ALLOC_POOL;
+
+ return g_steal_pointer (&name);
+}
+
+static gchar *
+GetConnectorName (CGDirectDisplayID screen_id)
+{
+ guint unit = CGDisplayUnitNumber (screen_id);
+ return g_strdup_printf ("unit-%u", unit);
+}
+
+gboolean
+_gdk_macos_monitor_reconfigure (GdkMacosMonitor *self)
+{
+ GdkSubpixelLayout subpixel_layout;
+ CGDisplayModeRef mode;
+ GdkMacosDisplay *display;
+ GdkRectangle geom;
+ gboolean has_opengl;
+ CGSize size;
+ CGRect bounds;
+ CGRect main_bounds;
+ size_t width;
+ size_t pixel_width;
+ gchar *connector;
+ gchar *name;
+ int refresh_rate;
+ int scale_factor = 1;
+ int width_mm;
+ int height_mm;
+
+ g_return_val_if_fail (GDK_IS_MACOS_MONITOR (self), FALSE);
+
+ if (!(mode = CGDisplayCopyDisplayMode (self->screen_id)))
+ return FALSE;
+
+ size = CGDisplayScreenSize (self->screen_id);
+ bounds = CGDisplayBounds (self->screen_id);
+ main_bounds = CGDisplayBounds (CGMainDisplayID ());
+ width = CGDisplayModeGetWidth (mode);
+ pixel_width = CGDisplayModeGetPixelWidth (mode);
+ refresh_rate = CGDisplayModeGetRefreshRate (mode);
+ has_opengl = CGDisplayUsesOpenGLAcceleration (self->screen_id);
+ subpixel_layout = GetSubpixelLayout (self->screen_id);
+ name = GetLocalizedName (self->screen_id);
+ connector = GetConnectorName (self->screen_id);
+
+ if (width != 0 && pixel_width != 0)
+ scale_factor = MAX (1, pixel_width / width);
+
+ width_mm = size.width;
+ height_mm = size.height;
+
+ CGDisplayModeRelease (mode);
+
+ /* This requires that the display bounds have been
+ * updated before the monitor is reconfigured.
+ */
+ display = GDK_MACOS_DISPLAY (GDK_MONITOR (self)->display);
+ _gdk_macos_display_from_display_coords (display,
+ bounds.origin.x,
+ bounds.origin.y,
+ &geom.x, &geom.y);
+ geom.width = bounds.size.width;
+ geom.height = bounds.size.height;
+
+ gdk_monitor_set_connector (GDK_MONITOR (self), connector);
+ gdk_monitor_set_model (GDK_MONITOR (self), name);
+ gdk_monitor_set_position (GDK_MONITOR (self), geom.x, geom.y);
+ gdk_monitor_set_size (GDK_MONITOR (self), geom.width, geom.height);
+ gdk_monitor_set_physical_size (GDK_MONITOR (self), width_mm, height_mm);
+ gdk_monitor_set_scale_factor (GDK_MONITOR (self), scale_factor);
+ gdk_monitor_set_refresh_rate (GDK_MONITOR (self), refresh_rate);
+ gdk_monitor_set_subpixel_layout (GDK_MONITOR (self), GDK_SUBPIXEL_LAYOUT_UNKNOWN);
+
+ /* We might be able to use this at some point to change which GSK renderer
+ * we use for surfaces on this monitor. For example, it might be better
+ * to use cairo if we cannot use OpenGL (or it would be software) anyway.
+ * Presumably that is more common in cases where macOS is running under
+ * an emulator such as QEMU.
+ */
+ self->has_opengl = !!has_opengl;
+
+ g_free (name);
+ g_free (connector);
+
+ return TRUE;
+}
+
GdkMacosMonitor *
_gdk_macos_monitor_new (GdkMacosDisplay *display,
CGDirectDisplayID screen_id)
@@ -105,8 +269,11 @@ _gdk_macos_monitor_new (GdkMacosDisplay *display,
self = g_object_new (GDK_TYPE_MACOS_MONITOR,
"display", display,
NULL);
+
self->screen_id = screen_id;
+ _gdk_macos_monitor_reconfigure (self);
+
return g_steal_pointer (&self);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]