mirror of https://github.com/snes9xgit/snes9x.git
Gtk: Make wayland surfaces toolkit-agnostic.
This commit is contained in:
parent
02ebcb496a
commit
cb6df570a4
|
@ -65,6 +65,14 @@ static const GLchar *stock_fragment_shader_140 =
|
||||||
" fragcolor = texture(texmap, texcoord);\n"
|
" fragcolor = texture(texmap, texcoord);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
|
static WaylandSurface::Metrics get_metrics(Gtk::DrawingArea &w)
|
||||||
|
{
|
||||||
|
int x, y, width, height;
|
||||||
|
w.get_window()->get_geometry(x, y, width, height);
|
||||||
|
return { x, y, width, height, w.get_window()->get_scale_factor() };
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static GLfloat coords[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
|
static GLfloat coords[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
|
||||||
0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, };
|
0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, };
|
||||||
|
@ -335,7 +343,20 @@ void S9xOpenGLDisplayDriver::refresh()
|
||||||
|
|
||||||
void S9xOpenGLDisplayDriver::resize()
|
void S9xOpenGLDisplayDriver::resize()
|
||||||
{
|
{
|
||||||
context->resize();
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
|
if (GDK_IS_WAYLAND_WINDOW(gdk_window))
|
||||||
|
{
|
||||||
|
((WaylandEGLContext *)context)->resize(get_metrics(*drawing_area));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef GDK_WINDOWING_X11
|
||||||
|
if (GDK_IS_X11_WINDOW(gdk_window))
|
||||||
|
{
|
||||||
|
context->resize();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
context->swap_interval(config->sync_to_vblank);
|
context->swap_interval(config->sync_to_vblank);
|
||||||
Gtk::Allocation allocation = drawing_area->get_allocation();
|
Gtk::Allocation allocation = drawing_area->get_allocation();
|
||||||
output_window_width = allocation.get_width();
|
output_window_width = allocation.get_width();
|
||||||
|
@ -350,7 +371,9 @@ bool S9xOpenGLDisplayDriver::create_context()
|
||||||
#ifdef GDK_WINDOWING_WAYLAND
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
if (GDK_IS_WAYLAND_WINDOW(gdk_window))
|
if (GDK_IS_WAYLAND_WINDOW(gdk_window))
|
||||||
{
|
{
|
||||||
if (!wl.attach(GTK_WIDGET(drawing_area->gobj())))
|
wl_surface *surface = gdk_wayland_window_get_wl_surface(drawing_area->get_window()->gobj());
|
||||||
|
wl_display *display = gdk_wayland_display_get_wl_display(drawing_area->get_display()->gobj());
|
||||||
|
if (!wl.attach(display, surface, get_metrics(*drawing_area)))
|
||||||
return false;
|
return false;
|
||||||
context = &wl;
|
context = &wl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,15 @@
|
||||||
#include "snes9x_imgui.h"
|
#include "snes9x_imgui.h"
|
||||||
#include "../../external/imgui/imgui_impl_vulkan.h"
|
#include "../../external/imgui/imgui_impl_vulkan.h"
|
||||||
|
|
||||||
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
|
static WaylandSurface::Metrics get_metrics(Gtk::DrawingArea &w)
|
||||||
|
{
|
||||||
|
int x, y, width, height;
|
||||||
|
w.get_window()->get_geometry(x, y, width, height);
|
||||||
|
return { x, y, width, height, w.get_window()->get_scale_factor() };
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
S9xVulkanDisplayDriver::S9xVulkanDisplayDriver(Snes9xWindow *_window, Snes9xConfig *_config)
|
S9xVulkanDisplayDriver::S9xVulkanDisplayDriver(Snes9xWindow *_window, Snes9xConfig *_config)
|
||||||
{
|
{
|
||||||
window = _window;
|
window = _window;
|
||||||
|
@ -83,7 +92,7 @@ void S9xVulkanDisplayDriver::refresh()
|
||||||
#ifdef GDK_WINDOWING_WAYLAND
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
if (GDK_IS_WAYLAND_WINDOW(drawing_area->get_window()->gobj()))
|
if (GDK_IS_WAYLAND_WINDOW(drawing_area->get_window()->gobj()))
|
||||||
{
|
{
|
||||||
wayland_surface->resize();
|
wayland_surface->resize(get_metrics(*drawing_area));
|
||||||
std::tie(new_width, new_height) = wayland_surface->get_size();
|
std::tie(new_width, new_height) = wayland_surface->get_size();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -113,7 +122,9 @@ int S9xVulkanDisplayDriver::init()
|
||||||
if (GDK_IS_WAYLAND_WINDOW(drawing_area->get_window()->gobj()))
|
if (GDK_IS_WAYLAND_WINDOW(drawing_area->get_window()->gobj()))
|
||||||
{
|
{
|
||||||
wayland_surface = std::make_unique<WaylandSurface>();
|
wayland_surface = std::make_unique<WaylandSurface>();
|
||||||
if (!wayland_surface->attach(GTK_WIDGET(drawing_area->gobj())))
|
wl_surface *surface = gdk_wayland_window_get_wl_surface(drawing_area->get_window()->gobj());
|
||||||
|
wl_display *display = gdk_wayland_display_get_wl_display(drawing_area->get_display()->gobj());
|
||||||
|
if (!wayland_surface->attach(display, surface, get_metrics(*drawing_area)))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,15 +33,10 @@ WaylandEGLContext::~WaylandEGLContext()
|
||||||
wl_egl_window_destroy(egl_window);
|
wl_egl_window_destroy(egl_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaylandEGLContext::attach(GtkWidget *widget)
|
bool WaylandEGLContext::attach(wl_display *display, wl_surface *surface, WaylandSurface::Metrics m)
|
||||||
{
|
{
|
||||||
GdkWindow *window = gtk_widget_get_window(widget);
|
|
||||||
|
|
||||||
if (!GDK_IS_WAYLAND_WINDOW(window))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
wayland_surface = std::make_unique<WaylandSurface>();
|
wayland_surface = std::make_unique<WaylandSurface>();
|
||||||
wayland_surface->attach(widget);
|
wayland_surface->attach(display, surface, m);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -109,9 +104,9 @@ bool WaylandEGLContext::create_context()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaylandEGLContext::resize()
|
void WaylandEGLContext::resize(WaylandSurface::Metrics m)
|
||||||
{
|
{
|
||||||
wayland_surface->resize();
|
wayland_surface->resize(m);
|
||||||
|
|
||||||
std::tie(width, height) = wayland_surface->get_size();
|
std::tie(width, height) = wayland_surface->get_size();
|
||||||
wl_egl_window_resize(egl_window, width, height, 0, 0);
|
wl_egl_window_resize(egl_window, width, height, 0, 0);
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include "gtk_opengl_context.h"
|
#include "gtk_opengl_context.h"
|
||||||
#include "gtk_wayland_surface.h"
|
#include "gtk_wayland_surface.h"
|
||||||
#include "gtk_compat.h"
|
|
||||||
|
|
||||||
#include <epoxy/egl.h>
|
#include <epoxy/egl.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -20,16 +19,15 @@ class WaylandEGLContext : public OpenGLContext
|
||||||
public:
|
public:
|
||||||
WaylandEGLContext();
|
WaylandEGLContext();
|
||||||
~WaylandEGLContext();
|
~WaylandEGLContext();
|
||||||
bool attach(GtkWidget *widget);
|
bool attach(wl_display *display, wl_surface *surface, WaylandSurface::Metrics m);
|
||||||
bool create_context();
|
bool create_context();
|
||||||
void resize();
|
void resize() {};
|
||||||
|
void resize(WaylandSurface::Metrics m);
|
||||||
void swap_buffers();
|
void swap_buffers();
|
||||||
void swap_interval(int frames);
|
void swap_interval(int frames);
|
||||||
void make_current();
|
void make_current();
|
||||||
bool ready();
|
bool ready();
|
||||||
|
|
||||||
GdkWindow *gdk_window;
|
|
||||||
|
|
||||||
EGLDisplay egl_display;
|
EGLDisplay egl_display;
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
EGLContext egl_context;
|
EGLContext egl_context;
|
||||||
|
|
|
@ -106,19 +106,11 @@ wp_fractional_scale_v1_listener fractional_scale_v1_listener =
|
||||||
preferred_scale
|
preferred_scale
|
||||||
};
|
};
|
||||||
|
|
||||||
bool WaylandSurface::attach(GtkWidget *widget)
|
bool WaylandSurface::attach(wl_display *display, wl_surface *surface, Metrics m)
|
||||||
{
|
{
|
||||||
GdkWindow *window = gtk_widget_get_window(widget);
|
metrics = m;
|
||||||
|
this->display = display;
|
||||||
if (!GDK_IS_WAYLAND_WINDOW(window))
|
parent = surface;
|
||||||
return false;
|
|
||||||
|
|
||||||
gdk_window = window;
|
|
||||||
gdk_window_get_geometry(gdk_window, &x, &y, &width, &height);
|
|
||||||
gdk_scale = gdk_window_get_scale_factor(gdk_window);
|
|
||||||
|
|
||||||
display = gdk_wayland_display_get_wl_display(gdk_window_get_display(gdk_window));
|
|
||||||
parent = gdk_wayland_window_get_wl_surface(gdk_window);
|
|
||||||
registry = wl_display_get_registry(display);
|
registry = wl_display_get_registry(display);
|
||||||
|
|
||||||
wl_registry_add_listener(registry, &wl_registry_listener, this);
|
wl_registry_add_listener(registry, &wl_registry_listener, this);
|
||||||
|
@ -133,7 +125,7 @@ bool WaylandSurface::attach(GtkWidget *widget)
|
||||||
|
|
||||||
wl_surface_set_input_region(child, region);
|
wl_surface_set_input_region(child, region);
|
||||||
wl_subsurface_set_desync(subsurface);
|
wl_subsurface_set_desync(subsurface);
|
||||||
wl_subsurface_set_position(subsurface, x, y);
|
wl_subsurface_set_position(subsurface, m.x, m.y);
|
||||||
|
|
||||||
if (fractional_scale_manager)
|
if (fractional_scale_manager)
|
||||||
{
|
{
|
||||||
|
@ -147,29 +139,26 @@ bool WaylandSurface::attach(GtkWidget *widget)
|
||||||
zwp_idle_inhibit_manager_v1_create_inhibitor(idle_inhibit_manager, child);
|
zwp_idle_inhibit_manager_v1_create_inhibitor(idle_inhibit_manager, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
resize();
|
resize(m);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<int, int> WaylandSurface::get_size()
|
std::tuple<int, int> WaylandSurface::get_size()
|
||||||
{
|
{
|
||||||
gdk_window_get_geometry(gdk_window, &x, &y, &width, &height);
|
|
||||||
|
|
||||||
if (actual_scale == 0.0)
|
if (actual_scale == 0.0)
|
||||||
{
|
{
|
||||||
gdk_scale = gdk_window_get_scale_factor(gdk_window);
|
return { metrics.width * metrics.scale, metrics.height * metrics.scale };
|
||||||
|
|
||||||
return { width * gdk_scale, height * gdk_scale };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { width * actual_scale, height * actual_scale };
|
return { metrics.width * actual_scale, metrics.height * actual_scale };
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaylandSurface::resize()
|
void WaylandSurface::resize(Metrics m)
|
||||||
{
|
{
|
||||||
|
metrics = m;
|
||||||
auto [w, h] = get_size();
|
auto [w, h] = get_size();
|
||||||
wl_subsurface_set_position(subsurface, x, y);
|
wl_subsurface_set_position(subsurface, m.x, m.y);
|
||||||
|
|
||||||
if (!viewport)
|
if (!viewport)
|
||||||
viewport = wp_viewporter_get_viewport(viewporter, child);
|
viewport = wp_viewporter_get_viewport(viewporter, child);
|
||||||
|
@ -177,7 +166,7 @@ void WaylandSurface::resize()
|
||||||
wp_viewport_set_source(viewport,
|
wp_viewport_set_source(viewport,
|
||||||
wl_fixed_from_int(0), wl_fixed_from_int(0),
|
wl_fixed_from_int(0), wl_fixed_from_int(0),
|
||||||
wl_fixed_from_int(w), wl_fixed_from_int(h));
|
wl_fixed_from_int(w), wl_fixed_from_int(h));
|
||||||
wp_viewport_set_destination(viewport, width, height);
|
wp_viewport_set_destination(viewport, m.width, m.height);
|
||||||
|
|
||||||
wl_surface_commit(child);
|
wl_surface_commit(child);
|
||||||
wl_surface_commit(parent);
|
wl_surface_commit(parent);
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "gtk_compat.h"
|
|
||||||
#include "viewporter-client-protocol.h"
|
#include "viewporter-client-protocol.h"
|
||||||
#include "fractional-scale-v1.h"
|
#include "fractional-scale-v1.h"
|
||||||
|
|
||||||
|
@ -15,11 +14,14 @@ class WaylandSurface
|
||||||
public:
|
public:
|
||||||
WaylandSurface();
|
WaylandSurface();
|
||||||
~WaylandSurface();
|
~WaylandSurface();
|
||||||
bool attach(GtkWidget *widget);
|
|
||||||
void resize();
|
|
||||||
std::tuple<int, int> get_size();
|
|
||||||
|
|
||||||
GdkWindow *gdk_window;
|
struct Metrics {
|
||||||
|
int x, y, width, height, scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool attach(wl_display *display, wl_surface *surface, Metrics source_metrics);
|
||||||
|
void resize(Metrics new_metrics);
|
||||||
|
std::tuple<int, int> get_size();
|
||||||
|
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
struct wl_registry *registry;
|
struct wl_registry *registry;
|
||||||
|
@ -31,11 +33,7 @@ class WaylandSurface
|
||||||
struct wl_subsurface *subsurface;
|
struct wl_subsurface *subsurface;
|
||||||
struct wl_region *region;
|
struct wl_region *region;
|
||||||
|
|
||||||
int x;
|
Metrics metrics;
|
||||||
int y;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int gdk_scale;
|
|
||||||
double actual_scale;
|
double actual_scale;
|
||||||
|
|
||||||
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
||||||
|
|
Loading…
Reference in New Issue