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

Ken Thomases ken at codeweavers.com
Mon Apr 22 23:27:33 CDT 2019


On Apr 22, 2019, at 7:13 AM, Zhiyi Zhang <zzhang at codeweavers.com> wrote:
> 
> 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;
> +            }

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;
> +}





More information about the wine-devel mailing list