Commit b35f4424 authored by Alexandros Frantzis's avatar Alexandros Frantzis Committed by Alexandre Julliard

winewayland.drv: Report all advertised monitor modes to Wine.

parent 697b58f4
......@@ -90,8 +90,8 @@ static void wayland_add_device_monitor(const struct gdi_device_manager *device_m
struct gdi_monitor monitor = {0};
SetRect(&monitor.rc_monitor, 0, 0,
output->current_mode.width,
output->current_mode.height);
output->current_mode->width,
output->current_mode->height);
/* We don't have a direct way to get the work area in Wayland. */
monitor.rc_work = monitor.rc_monitor;
......@@ -117,12 +117,17 @@ static void populate_devmode(struct wayland_output_mode *output_mode, DEVMODEW *
mode->dmDisplayFrequency = output_mode->refresh / 1000;
}
static void wayland_add_device_mode(const struct gdi_device_manager *device_manager,
void *param, struct wayland_output *output)
static void wayland_add_device_modes(const struct gdi_device_manager *device_manager,
void *param, struct wayland_output *output)
{
DEVMODEW mode;
populate_devmode(&output->current_mode, &mode);
device_manager->add_mode(&mode, param);
struct wayland_output_mode *output_mode;
RB_FOR_EACH_ENTRY(output_mode, &output->modes, struct wayland_output_mode, entry)
{
DEVMODEW mode;
populate_devmode(output_mode, &mode);
device_manager->add_mode(&mode, param);
}
}
/***********************************************************************
......@@ -144,10 +149,10 @@ BOOL WAYLAND_UpdateDisplayDevices(const struct gdi_device_manager *device_manage
wl_list_for_each(output, &process_wayland->output_list, link)
{
if (!output->current_mode.refresh) continue;
if (!output->current_mode) continue;
wayland_add_device_adapter(device_manager, param, output_id);
wayland_add_device_monitor(device_manager, param, output);
wayland_add_device_mode(device_manager, param, output);
wayland_add_device_modes(device_manager, param, output);
output_id++;
}
......
......@@ -39,6 +39,64 @@ static uint32_t next_output_id = 0;
* Output handling
*/
/* Compare a mode rb_tree key with the provided mode rb_entry and return -1 if
* the key compares less than the entry, 0 if the key compares equal to the
* entry, and 1 if the key compares greater than the entry.
*
* The comparison is based on comparing the width, height and refresh in that
* order. */
static int wayland_output_mode_cmp_rb(const void *key,
const struct rb_entry *entry)
{
const struct wayland_output_mode *key_mode = key;
const struct wayland_output_mode *entry_mode =
RB_ENTRY_VALUE(entry, const struct wayland_output_mode, entry);
if (key_mode->width < entry_mode->width) return -1;
if (key_mode->width > entry_mode->width) return 1;
if (key_mode->height < entry_mode->height) return -1;
if (key_mode->height > entry_mode->height) return 1;
if (key_mode->refresh < entry_mode->refresh) return -1;
if (key_mode->refresh > entry_mode->refresh) return 1;
return 0;
}
static void wayland_output_add_mode(struct wayland_output *output,
int32_t width, int32_t height,
int32_t refresh, BOOL current)
{
struct rb_entry *mode_entry;
struct wayland_output_mode *mode;
struct wayland_output_mode key =
{
.width = width,
.height = height,
.refresh = refresh,
};
mode_entry = rb_get(&output->modes, &key);
if (mode_entry)
{
mode = RB_ENTRY_VALUE(mode_entry, struct wayland_output_mode, entry);
}
else
{
mode = calloc(1, sizeof(*mode));
if (!mode)
{
ERR("Failed to allocate space for wayland_output_mode\n");
return;
}
mode->width = width;
mode->height = height;
mode->refresh = refresh;
rb_put(&output->modes, mode, &mode->entry);
}
if (current) output->current_mode = mode;
}
static void output_handle_geometry(void *data, struct wl_output *wl_output,
int32_t x, int32_t y,
int32_t physical_width, int32_t physical_height,
......@@ -54,22 +112,26 @@ static void output_handle_mode(void *data, struct wl_output *wl_output,
{
struct wayland_output *output = data;
if (!(flags & WL_OUTPUT_MODE_CURRENT)) return;
/* Windows apps don't expect a zero refresh rate, so use a default value. */
if (refresh == 0) refresh = default_refresh;
output->current_mode.width = width;
output->current_mode.height = width;
output->current_mode.refresh = refresh;
wayland_output_add_mode(output, width, height, refresh,
(flags & WL_OUTPUT_MODE_CURRENT));
}
static void output_handle_done(void *data, struct wl_output *wl_output)
{
struct wayland_output *output = data;
struct wayland_output_mode *mode;
TRACE("name=%s\n", output->name);
TRACE("name=%s mode=%dx%d\n",
output->name, output->current_mode.width, output->current_mode.height);
RB_FOR_EACH_ENTRY(mode, &output->modes, struct wayland_output_mode, entry)
{
TRACE("mode %dx%d @ %d %s\n",
mode->width, mode->height, mode->refresh,
output->current_mode == mode ? "*" : "");
}
wayland_init_display_devices();
}
......@@ -108,6 +170,7 @@ BOOL wayland_output_create(uint32_t id, uint32_t version)
wl_output_add_listener(output->wl_output, &output_listener, output);
wl_list_init(&output->link);
rb_init(&output->modes, wayland_output_mode_cmp_rb);
snprintf(output->name, sizeof(output->name), "WaylandOutput%d",
next_output_id++);
......@@ -121,6 +184,11 @@ err:
return FALSE;
}
static void wayland_output_mode_free_rb(struct rb_entry *entry, void *ctx)
{
free(RB_ENTRY_VALUE(entry, struct wayland_output_mode, entry));
}
/**********************************************************************
* wayland_output_destroy
*
......@@ -128,6 +196,7 @@ err:
*/
void wayland_output_destroy(struct wayland_output *output)
{
rb_destroy(&output->modes, wayland_output_mode_free_rb, NULL);
wl_list_remove(&output->link);
wl_output_destroy(output->wl_output);
free(output);
......
......@@ -30,6 +30,7 @@
#include "windef.h"
#include "winbase.h"
#include "wine/gdi_driver.h"
#include "wine/rbtree.h"
#include "unixlib.h"
......@@ -53,6 +54,7 @@ struct wayland
struct wayland_output_mode
{
struct rb_entry entry;
int32_t width;
int32_t height;
int32_t refresh;
......@@ -62,7 +64,8 @@ struct wayland_output
{
struct wl_list link;
struct wl_output *wl_output;
struct wayland_output_mode current_mode;
struct rb_tree modes;
struct wayland_output_mode *current_mode;
char name[20];
uint32_t global_id;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment