Signed-off-by: Zhiyi Zhang zzhang@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 */
On Apr 22, 2019, at 7:13 AM, Zhiyi Zhang zzhang@codeweavers.com wrote:
Signed-off-by: Zhiyi Zhang zzhang@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;
}
This swap is inside the "i" loop. That means that you could keep swapping those two elements an arbitrary number of times.
}
- }
- *new_monitors = monitors;
- *count = monitor_count;
- ret = 0;
+fail:
- macdrv_free_displays(displays);
- if (ret)
free(monitors);
- return ret;
+}
On 4/23/19 12:27 PM, Ken Thomases wrote:
On Apr 22, 2019, at 7:13 AM, Zhiyi Zhang zzhang@codeweavers.com wrote:
Signed-off-by: Zhiyi Zhang zzhang@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;
}
This swap is inside the "i" loop. That means that you could keep swapping those two elements an arbitrary number of times.
Thanks. I must have messed it up during refactoring.
}
- }
- *new_monitors = monitors;
- *count = monitor_count;
- ret = 0;
+fail:
- macdrv_free_displays(displays);
- if (ret)
free(monitors);
- return ret;
+}