mirror of https://github.com/snes9xgit/snes9x.git
Add wayland helper files.
This commit is contained in:
parent
daec5ccc57
commit
35cdf9c182
|
@ -0,0 +1,184 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "gtk_wayland_helpers.h"
|
||||||
|
|
||||||
|
static void wl_global (void *data,
|
||||||
|
struct wl_registry *wl_registry,
|
||||||
|
uint32_t name,
|
||||||
|
const char *interface,
|
||||||
|
uint32_t version)
|
||||||
|
{
|
||||||
|
struct wlgl_helper *wl = (struct wlgl_helper *) data;
|
||||||
|
|
||||||
|
if (!strcmp (interface, "wl_compositor"))
|
||||||
|
wl->compositor = (struct wl_compositor *) wl_registry_bind (wl_registry, name, &wl_compositor_interface, 1);
|
||||||
|
else if (!strcmp (interface, "wl_subcompositor"))
|
||||||
|
wl->subcompositor = (struct wl_subcompositor *) wl_registry_bind (wl_registry, name, &wl_subcompositor_interface, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wl_global_remove (void *data,
|
||||||
|
struct wl_registry *wl_registry,
|
||||||
|
uint32_t name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_registry_listener wl_registry_listener = {
|
||||||
|
wl_global,
|
||||||
|
wl_global_remove
|
||||||
|
};
|
||||||
|
|
||||||
|
wlgl_helper::wlgl_helper ()
|
||||||
|
{
|
||||||
|
display = NULL;
|
||||||
|
registry = NULL;
|
||||||
|
compositor = NULL;
|
||||||
|
subcompositor = NULL;
|
||||||
|
parent = NULL;
|
||||||
|
child = NULL;
|
||||||
|
subsurface = NULL;
|
||||||
|
egl_display = NULL;
|
||||||
|
egl_surface = NULL;
|
||||||
|
egl_context = NULL;
|
||||||
|
egl_config = NULL;
|
||||||
|
egl_window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlgl_helper::~wlgl_helper ()
|
||||||
|
{
|
||||||
|
if (subsurface)
|
||||||
|
wl_subsurface_destroy (subsurface);
|
||||||
|
|
||||||
|
if (region)
|
||||||
|
wl_region_destroy (region);
|
||||||
|
|
||||||
|
if (child)
|
||||||
|
wl_surface_destroy (child);
|
||||||
|
|
||||||
|
if (egl_context)
|
||||||
|
eglDestroyContext (egl_display, egl_context);
|
||||||
|
|
||||||
|
if (egl_surface)
|
||||||
|
eglDestroySurface (egl_display, egl_surface);
|
||||||
|
|
||||||
|
if (egl_window)
|
||||||
|
wl_egl_window_destroy (egl_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wlgl_helper::attach (GdkWindow *window)
|
||||||
|
{
|
||||||
|
int x, y, w, h;
|
||||||
|
|
||||||
|
if (!GDK_IS_WAYLAND_WINDOW (window))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
gdk_window = window;
|
||||||
|
gdk_window_get_geometry (gdk_window, &x, &y, &w, &h);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
wl_registry_add_listener (registry, &wl_registry_listener, this);
|
||||||
|
wl_display_roundtrip (display);
|
||||||
|
|
||||||
|
if (!compositor || !subcompositor)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
child = wl_compositor_create_surface (compositor);
|
||||||
|
region = wl_compositor_create_region (compositor);
|
||||||
|
subsurface = wl_subcompositor_get_subsurface (subcompositor, child, parent);
|
||||||
|
|
||||||
|
wl_surface_set_input_region (child, region);
|
||||||
|
wl_subsurface_set_desync (subsurface);
|
||||||
|
wl_subsurface_set_position (subsurface, x, y);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wlgl_helper::create_egl_context (int width, int height)
|
||||||
|
{
|
||||||
|
int scale = gdk_window_get_scale_factor (gdk_window);
|
||||||
|
|
||||||
|
EGLint surface_attribs[] = {
|
||||||
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
EGLint context_attribs[] = {
|
||||||
|
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
EGLint num_configs = 0;
|
||||||
|
|
||||||
|
if (!subsurface)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
egl_display = eglGetDisplay ((EGLNativeDisplayType) display);
|
||||||
|
eglInitialize (egl_display, NULL, NULL);
|
||||||
|
|
||||||
|
if (!eglChooseConfig (egl_display, surface_attribs, &egl_config, 1, &num_configs))
|
||||||
|
{
|
||||||
|
printf ("Couldn't find matching config.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
eglBindAPI (EGL_OPENGL_API);
|
||||||
|
|
||||||
|
egl_window = wl_egl_window_create (child, width * scale, height * scale);
|
||||||
|
if (!egl_window)
|
||||||
|
{
|
||||||
|
printf ("Couldn't create window.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
egl_surface = eglCreateWindowSurface (egl_display, egl_config, (EGLNativeWindowType) egl_window, NULL);
|
||||||
|
if (!egl_surface)
|
||||||
|
{
|
||||||
|
printf ("Couldn't create surface.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
egl_context = eglCreateContext (egl_display, egl_config, EGL_NO_CONTEXT, context_attribs);
|
||||||
|
if (!egl_context)
|
||||||
|
{
|
||||||
|
printf ("Couldn't create context.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlgl_helper::resize (int width, int height)
|
||||||
|
{
|
||||||
|
int x, y, w, h, scale;
|
||||||
|
|
||||||
|
gdk_window_get_geometry (gdk_window, &x, &y, &w, &h);
|
||||||
|
scale = gdk_window_get_scale_factor (gdk_window);
|
||||||
|
|
||||||
|
wl_egl_window_resize (egl_window, w * scale, h * scale, 0, 0);
|
||||||
|
wl_subsurface_set_position (subsurface, x, y);
|
||||||
|
|
||||||
|
make_current ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlgl_helper::swap_buffers ()
|
||||||
|
{
|
||||||
|
eglSwapBuffers (egl_display, egl_surface);
|
||||||
|
wl_surface_commit (child);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlgl_helper::make_current ()
|
||||||
|
{
|
||||||
|
eglMakeCurrent (egl_display, egl_surface, egl_surface, egl_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlgl_helper::swap_interval (int frames)
|
||||||
|
{
|
||||||
|
eglSwapInterval (egl_display, frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
#include <gdk/gdkwayland.h>
|
||||||
|
#include <wayland-egl.h>
|
||||||
|
#include <epoxy/egl.h>
|
||||||
|
|
||||||
|
struct wlgl_helper
|
||||||
|
{
|
||||||
|
wlgl_helper ();
|
||||||
|
~wlgl_helper ();
|
||||||
|
bool attach (GdkWindow *window);
|
||||||
|
bool create_egl_context (int width, int height);
|
||||||
|
void resize (int width, int height);
|
||||||
|
void swap_buffers ();
|
||||||
|
void swap_interval (int frames);
|
||||||
|
void make_current ();
|
||||||
|
|
||||||
|
GdkWindow *gdk_window;
|
||||||
|
|
||||||
|
struct wl_display *display;
|
||||||
|
struct wl_registry *registry;
|
||||||
|
struct wl_compositor *compositor;
|
||||||
|
struct wl_subcompositor *subcompositor;
|
||||||
|
|
||||||
|
struct wl_surface *parent;
|
||||||
|
struct wl_surface *child;
|
||||||
|
struct wl_subsurface *subsurface;
|
||||||
|
struct wl_region *region;
|
||||||
|
|
||||||
|
EGLDisplay egl_display;
|
||||||
|
EGLSurface egl_surface;
|
||||||
|
EGLContext egl_context;
|
||||||
|
EGLConfig egl_config;
|
||||||
|
|
||||||
|
wl_egl_window *egl_window;
|
||||||
|
};
|
Loading…
Reference in New Issue