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

Zhiyi Zhang zzhang at codeweavers.com
Tue Apr 23 01:33:49 CDT 2019



On 4/23/19 12:27 PM, Ken Thomases wrote:
> 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.
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;
>> +}
>




More information about the wine-devel mailing list