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"
|
||||
"}\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,
|
||||
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()
|
||||
{
|
||||
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);
|
||||
Gtk::Allocation allocation = drawing_area->get_allocation();
|
||||
output_window_width = allocation.get_width();
|
||||
|
@ -350,7 +371,9 @@ bool S9xOpenGLDisplayDriver::create_context()
|
|||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
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;
|
||||
context = &wl;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,15 @@
|
|||
#include "snes9x_imgui.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)
|
||||
{
|
||||
window = _window;
|
||||
|
@ -83,7 +92,7 @@ void S9xVulkanDisplayDriver::refresh()
|
|||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
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();
|
||||
}
|
||||
else
|
||||
|
@ -113,7 +122,9 @@ int S9xVulkanDisplayDriver::init()
|
|||
if (GDK_IS_WAYLAND_WINDOW(drawing_area->get_window()->gobj()))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -33,15 +33,10 @@ WaylandEGLContext::~WaylandEGLContext()
|
|||
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->attach(widget);
|
||||
wayland_surface->attach(display, surface, m);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -109,9 +104,9 @@ bool WaylandEGLContext::create_context()
|
|||
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();
|
||||
wl_egl_window_resize(egl_window, width, height, 0, 0);
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include "gtk_opengl_context.h"
|
||||
#include "gtk_wayland_surface.h"
|
||||
#include "gtk_compat.h"
|
||||
|
||||
#include <epoxy/egl.h>
|
||||
#include <memory>
|
||||
|
@ -20,16 +19,15 @@ class WaylandEGLContext : public OpenGLContext
|
|||
public:
|
||||
WaylandEGLContext();
|
||||
~WaylandEGLContext();
|
||||
bool attach(GtkWidget *widget);
|
||||
bool attach(wl_display *display, wl_surface *surface, WaylandSurface::Metrics m);
|
||||
bool create_context();
|
||||
void resize();
|
||||
void resize() {};
|
||||
void resize(WaylandSurface::Metrics m);
|
||||
void swap_buffers();
|
||||
void swap_interval(int frames);
|
||||
void make_current();
|
||||
bool ready();
|
||||
|
||||
GdkWindow *gdk_window;
|
||||
|
||||
EGLDisplay egl_display;
|
||||
EGLSurface egl_surface;
|
||||
EGLContext egl_context;
|
||||
|
|
|
@ -106,19 +106,11 @@ wp_fractional_scale_v1_listener fractional_scale_v1_listener =
|
|||
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);
|
||||
|
||||
if (!GDK_IS_WAYLAND_WINDOW(window))
|
||||
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);
|
||||
metrics = m;
|
||||
this->display = display;
|
||||
parent = surface;
|
||||
registry = wl_display_get_registry(display);
|
||||
|
||||
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_subsurface_set_desync(subsurface);
|
||||
wl_subsurface_set_position(subsurface, x, y);
|
||||
wl_subsurface_set_position(subsurface, m.x, m.y);
|
||||
|
||||
if (fractional_scale_manager)
|
||||
{
|
||||
|
@ -147,29 +139,26 @@ bool WaylandSurface::attach(GtkWidget *widget)
|
|||
zwp_idle_inhibit_manager_v1_create_inhibitor(idle_inhibit_manager, child);
|
||||
}
|
||||
|
||||
resize();
|
||||
resize(m);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::tuple<int, int> WaylandSurface::get_size()
|
||||
{
|
||||
gdk_window_get_geometry(gdk_window, &x, &y, &width, &height);
|
||||
|
||||
if (actual_scale == 0.0)
|
||||
{
|
||||
gdk_scale = gdk_window_get_scale_factor(gdk_window);
|
||||
|
||||
return { width * gdk_scale, height * gdk_scale };
|
||||
return { metrics.width * metrics.scale, metrics.height * metrics.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();
|
||||
wl_subsurface_set_position(subsurface, x, y);
|
||||
wl_subsurface_set_position(subsurface, m.x, m.y);
|
||||
|
||||
if (!viewport)
|
||||
viewport = wp_viewporter_get_viewport(viewporter, child);
|
||||
|
@ -177,7 +166,7 @@ void WaylandSurface::resize()
|
|||
wp_viewport_set_source(viewport,
|
||||
wl_fixed_from_int(0), wl_fixed_from_int(0),
|
||||
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(parent);
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "gtk_compat.h"
|
||||
#include "viewporter-client-protocol.h"
|
||||
#include "fractional-scale-v1.h"
|
||||
|
||||
|
@ -15,11 +14,14 @@ class WaylandSurface
|
|||
public:
|
||||
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_registry *registry;
|
||||
|
@ -31,11 +33,7 @@ class WaylandSurface
|
|||
struct wl_subsurface *subsurface;
|
||||
struct wl_region *region;
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
int gdk_scale;
|
||||
Metrics metrics;
|
||||
double actual_scale;
|
||||
|
||||
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
||||
|
|
Loading…
Reference in New Issue