mirror of
https://github.com/libretro/RetroArch
synced 2025-03-03 13:14:04 +00:00
Wayland: keep track of all outputs (displays)
Required to support multiple monitors with varying scales (HiDPI/LoDPI)
This commit is contained in:
parent
056c7fffe1
commit
60c8f51009
@ -68,6 +68,19 @@ typedef struct touch_pos
|
||||
unsigned y;
|
||||
} touch_pos_t;
|
||||
|
||||
typedef struct output_info
|
||||
{
|
||||
struct wl_output *output;
|
||||
uint32_t global_id;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned physical_width;
|
||||
unsigned physical_height;
|
||||
int refresh_rate;
|
||||
unsigned scale;
|
||||
struct wl_list link; // wl->all_outputs
|
||||
} output_info_t;
|
||||
|
||||
static int num_active_touches;
|
||||
static touch_pos_t active_touch_positions[MAX_TOUCHES];
|
||||
|
||||
@ -87,9 +100,6 @@ typedef struct gfx_ctx_wayland_data
|
||||
int prev_height;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned physical_width;
|
||||
unsigned physical_height;
|
||||
int refresh_rate;
|
||||
struct wl_registry *registry;
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_surface *surface;
|
||||
@ -110,6 +120,7 @@ typedef struct gfx_ctx_wayland_data
|
||||
struct zxdg_toplevel_decoration_v1 *deco;
|
||||
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
||||
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
|
||||
struct wl_list all_outputs;
|
||||
int swap_interval;
|
||||
bool core_hw_context_enable;
|
||||
|
||||
@ -738,6 +749,18 @@ static const struct wl_shell_surface_listener shell_surface_listener = {
|
||||
shell_surface_handle_popup_done,
|
||||
};
|
||||
|
||||
static output_info_t *get_current_output(gfx_ctx_wayland_data_t *wl)
|
||||
{
|
||||
// Just return the first one.
|
||||
output_info_t *oi;
|
||||
|
||||
wl_list_for_each(oi, &wl->all_outputs, link) {
|
||||
return oi;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void display_handle_geometry(void *data,
|
||||
struct wl_output *output,
|
||||
int x, int y,
|
||||
@ -756,9 +779,9 @@ static void display_handle_geometry(void *data,
|
||||
(void)model;
|
||||
(void)transform;
|
||||
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
wl->physical_width = physical_width;
|
||||
wl->physical_height = physical_height;
|
||||
output_info_t *oi = (output_info_t*)data;
|
||||
oi->physical_width = physical_width;
|
||||
oi->physical_height = physical_height;
|
||||
|
||||
RARCH_LOG("[Wayland]: Physical width: %d mm x %d mm.\n",
|
||||
physical_width, physical_height);
|
||||
@ -774,10 +797,10 @@ static void display_handle_mode(void *data,
|
||||
(void)output;
|
||||
(void)flags;
|
||||
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
wl->width = width;
|
||||
wl->height = height;
|
||||
wl->refresh_rate = refresh;
|
||||
output_info_t *oi = (output_info_t*)data;
|
||||
oi->width = width;
|
||||
oi->height = height;
|
||||
oi->refresh_rate = refresh;
|
||||
|
||||
/* Certain older Wayland implementations report in Hz,
|
||||
* but it should be mHz. */
|
||||
@ -796,10 +819,10 @@ static void display_handle_scale(void *data,
|
||||
struct wl_output *output,
|
||||
int32_t factor)
|
||||
{
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
output_info_t *oi = (output_info_t*)data;
|
||||
|
||||
RARCH_LOG("[Wayland]: Setting buffer scale factor to %d.\n", factor);
|
||||
wl->buffer_scale = factor;
|
||||
RARCH_LOG("[Wayland]: Display scale factor %d.\n", factor);
|
||||
oi->scale = factor;
|
||||
}
|
||||
|
||||
static const struct wl_output_listener output_listener = {
|
||||
@ -813,7 +836,6 @@ static const struct wl_output_listener output_listener = {
|
||||
static void registry_handle_global(void *data, struct wl_registry *reg,
|
||||
uint32_t id, const char *interface, uint32_t version)
|
||||
{
|
||||
struct wl_output *output = NULL;
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
|
||||
(void)version;
|
||||
@ -823,9 +845,12 @@ static void registry_handle_global(void *data, struct wl_registry *reg,
|
||||
id, &wl_compositor_interface, 3);
|
||||
else if (string_is_equal(interface, "wl_output"))
|
||||
{
|
||||
output = (struct wl_output*)wl_registry_bind(reg,
|
||||
output_info_t *oi = calloc(1, sizeof(output_info_t));
|
||||
oi->global_id = id;
|
||||
oi->output = (struct wl_output*)wl_registry_bind(reg,
|
||||
id, &wl_output_interface, 2);
|
||||
wl_output_add_listener(output, &output_listener, wl);
|
||||
wl_output_add_listener(oi->output, &output_listener, oi);
|
||||
wl_list_insert(&wl->all_outputs, &oi->link);
|
||||
wl_display_roundtrip(wl->input.dpy);
|
||||
}
|
||||
else if (string_is_equal(interface, "xdg_wm_base"))
|
||||
@ -855,9 +880,16 @@ static void registry_handle_global(void *data, struct wl_registry *reg,
|
||||
static void registry_handle_global_remove(void *data,
|
||||
struct wl_registry *registry, uint32_t id)
|
||||
{
|
||||
(void)data;
|
||||
(void)registry;
|
||||
(void)id;
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
output_info_t *oi, *tmp;
|
||||
|
||||
wl_list_for_each_safe(oi, tmp, &wl->all_outputs, link) {
|
||||
if (oi->global_id == id) {
|
||||
wl_list_remove(&oi->link);
|
||||
free(oi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
@ -1115,21 +1147,26 @@ static bool gfx_ctx_wl_get_metrics(void *data,
|
||||
{
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
|
||||
if (!wl || wl->physical_width == 0 || wl->physical_height == 0)
|
||||
if (!wl)
|
||||
return false;
|
||||
|
||||
output_info_t *oi = get_current_output(wl);
|
||||
|
||||
if (!oi || oi->physical_width == 0 || oi->physical_height == 0)
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DISPLAY_METRIC_MM_WIDTH:
|
||||
*value = (float)wl->physical_width;
|
||||
*value = (float)oi->physical_width;
|
||||
break;
|
||||
|
||||
case DISPLAY_METRIC_MM_HEIGHT:
|
||||
*value = (float)wl->physical_height;
|
||||
*value = (float)oi->physical_height;
|
||||
break;
|
||||
|
||||
case DISPLAY_METRIC_DPI:
|
||||
*value = (float)wl->width * 25.4f / (float)wl->physical_width;
|
||||
*value = (float)oi->width * 25.4f / (float)oi->physical_width;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1204,6 +1241,8 @@ static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver)
|
||||
|
||||
(void)video_driver;
|
||||
|
||||
wl_list_init(&wl->all_outputs);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
switch (wl_api)
|
||||
{
|
||||
@ -1870,7 +1909,15 @@ static float gfx_ctx_wl_get_refresh_rate(void *data)
|
||||
{
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
|
||||
return (float) wl->refresh_rate / 1000.0f;
|
||||
if (!wl)
|
||||
return false;
|
||||
|
||||
output_info_t *oi = get_current_output(wl);
|
||||
|
||||
if (!oi)
|
||||
return false;
|
||||
|
||||
return (float) oi->refresh_rate / 1000.0f;
|
||||
}
|
||||
|
||||
const gfx_ctx_driver_t gfx_ctx_wayland = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user