[PATCH 5/7] winemac.drv: Add macdrv_get_monitors() helper.

Zhiyi Zhang zzhang at codeweavers.com
Mon Apr 22 07:13:51 CDT 2019


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/winemac.drv/cocoa_display.m | 108 +++++++++++++++++++++++++++++++++++++++
 dlls/winemac.drv/macdrv_cocoa.h  |  18 +++++++
 2 files changed, 126 insertions(+)

diff --git a/dlls/winemac.drv/cocoa_display.m b/dlls/winemac.drv/cocoa_display.m
index d95cda59c9..0005e2ac37 100644
--- a/dlls/winemac.drv/cocoa_display.m
+++ b/dlls/winemac.drv/cocoa_display.m
@@ -343,3 +343,111 @@ void macdrv_free_adapters(struct macdrv_adapter* adapters)
 {
     free(adapters);
 }
+
+/***********************************************************************
+ *              macdrv_get_monitors
+ *
+ * Get a list of monitors under adapter_id. The first monitor is primary if adapter is primary.
+ * Call macdrv_free_monitors() when you are done using the data.
+ *
+ * Return -1 on failure with parameters unchanged.
+ */
+int macdrv_get_monitors(uint32_t adapter_id, struct macdrv_monitor** new_monitors, int* count)
+{
+    struct macdrv_monitor* monitors = NULL;
+    struct macdrv_monitor* realloc_monitors;
+    struct macdrv_display* displays = NULL;
+    CGDirectDisplayID display_ids[16];
+    uint32_t display_id_count;
+    int primary_index = 0;
+    int monitor_count = 0;
+    int display_count;
+    int capacity;
+    int i, j;
+    int ret = -1;
+
+    /* 2 should be enough for most cases */
+    capacity = 2;
+    monitors = calloc(capacity, sizeof(*monitors));
+    if (!monitors)
+        return -1;
+
+    /* Report an inactive monitor */
+    if (!CGDisplayIsActive(adapter_id) && !CGDisplayIsInMirrorSet(adapter_id))
+    {
+        strcpy(monitors[monitor_count].name, "Generic Non-PnP Monitor");
+        monitors[monitor_count].state_flags = DISPLAY_DEVICE_ATTACHED;
+        monitor_count++;
+    }
+    /* Report active monitor and mirrored monitors in the same mirroring set */
+    else
+    {
+        if (CGGetOnlineDisplayList(sizeof(display_ids) / sizeof(display_ids[0]), display_ids, &display_id_count)
+            != kCGErrorSuccess)
+            goto fail;
+
+        if (macdrv_get_displays(&displays, &display_count))
+            goto fail;
+
+        for (i = 0; i < display_id_count; i++)
+        {
+            if (display_ids[i] != adapter_id && CGDisplayMirrorsDisplay(display_ids[i]) != adapter_id)
+                continue;
+
+            /* Find and fill in monitor info */
+            for (j = 0; j < display_count; j++)
+            {
+                if (displays[i].displayID == display_ids[j]
+                    || CGDisplayMirrorsDisplay(display_ids[i]) == displays[j].displayID)
+                {
+                    /* Allocate more space if needed */
+                    if (monitor_count >= capacity)
+                    {
+                        capacity *= 2;
+                        realloc_monitors = realloc(monitors, sizeof(*monitors) * capacity);
+                        if (!realloc_monitors)
+                            goto fail;
+                        monitors = realloc_monitors;
+                    }
+
+                    if (!primary_index && CGDisplayIsMain(display_ids[j]))
+                        primary_index = monitor_count;
+
+                    strcpy(monitors[monitor_count].name, "Generic Non-PnP Monitor");
+                    monitors[monitor_count].state_flags = DISPLAY_DEVICE_ATTACHED | DISPLAY_DEVICE_ACTIVE;
+                    monitors[monitor_count].rc_monitor = displays[j].frame;
+                    monitors[monitor_count].rc_work = displays[j].work_frame;
+                    monitor_count++;
+                }
+            }
+
+            /* Make sure the first monitor on primary adapter is primary */
+            if (primary_index)
+            {
+                struct macdrv_monitor tmp;
+                tmp = monitors[0];
+                monitors[0] = monitors[primary_index];
+                monitors[primary_index] = tmp;
+            }
+        }
+    }
+
+    *new_monitors = monitors;
+    *count = monitor_count;
+    ret = 0;
+fail:
+    macdrv_free_displays(displays);
+    if (ret)
+        free(monitors);
+    return ret;
+}
+
+/***********************************************************************
+ *              macdrv_free_monitors
+ *
+ * Free an monitor list allocated from macdrv_get_monitors()
+ */
+void macdrv_free_monitors(struct macdrv_monitor* monitors)
+{
+    free(monitors);
+}
diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h
index a57b94c125..8997131f1e 100644
--- a/dlls/winemac.drv/macdrv_cocoa.h
+++ b/dlls/winemac.drv/macdrv_cocoa.h
@@ -261,6 +261,9 @@ static inline CGPoint cgpoint_win_from_mac(CGPoint point)
 /* Used DISPLAY_DEVICE.StateFlags for adapters */
 #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP      0x00000001
 #define DISPLAY_DEVICE_PRIMARY_DEVICE           0x00000004
+/* Used DISPLAY_DEVICE.StateFlags for monitors */
+#define DISPLAY_DEVICE_ACTIVE                   0x00000001
+#define DISPLAY_DEVICE_ATTACHED                 0x00000002
 
 /* Represent a physical GPU in the PCI slots */
 struct macdrv_gpu
@@ -285,6 +288,19 @@ static inline CGPoint cgpoint_win_from_mac(CGPoint point)
     uint32_t state_flags;
 };
 
+/* Represent a monitor in EnumDisplayDevices context */
+struct macdrv_monitor
+{
+    /* Name, in UTF-8 encoding */
+    char name[128];
+    /* as RcMonitor in MONITORINFO struct after conversion by rect_from_cgrect */
+    CGRect rc_monitor;
+    /* as RcWork in MONITORINFO struct after conversion by rect_from_cgrect */
+    CGRect rc_work;
+    /* StateFlags in DISPLAY_DEVICE struct */
+    uint32_t state_flags;
+};
+
 extern int macdrv_get_displays(struct macdrv_display** displays, int* count) DECLSPEC_HIDDEN;
 extern void macdrv_free_displays(struct macdrv_display* displays) DECLSPEC_HIDDEN;
 extern int macdrv_set_display_mode(const struct macdrv_display* display,
@@ -293,6 +309,8 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
 extern void macdrv_free_gpus(struct macdrv_gpu* gpus) DECLSPEC_HIDDEN;
 extern int macdrv_get_adapters(uint64_t gpu_id, struct macdrv_adapter** adapters, int* count) DECLSPEC_HIDDEN;
 extern void macdrv_free_adapters(struct macdrv_adapter* adapters) DECLSPEC_HIDDEN;
+extern int macdrv_get_monitors(uint32_t adapter_id, struct macdrv_monitor** monitors, int* count) DECLSPEC_HIDDEN;
+extern void macdrv_free_monitors(struct macdrv_monitor* monitors) DECLSPEC_HIDDEN;
 
 
 /* event */
-- 
2.15.2 (Apple Git-101.1)





More information about the wine-devel mailing list