summaryrefslogtreecommitdiff
path: root/src/drivers/Wayland
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/Wayland')
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx2
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx20
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx3
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx37
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Screen_Driver.H4
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx44
-rw-r--r--src/drivers/Wayland/Fl_Wayland_System_Driver.cxx3
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx86
-rw-r--r--src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx17
-rw-r--r--src/drivers/Wayland/fl_wayland_gl_platform_init.cxx5
-rw-r--r--src/drivers/Wayland/fl_wayland_platform_init.cxx88
11 files changed, 200 insertions, 109 deletions
diff --git a/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
index 07b3038f0..60a0cad51 100644
--- a/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
@@ -43,7 +43,7 @@ Fl_Wayland_Copy_Surface_Driver::~Fl_Wayland_Copy_Surface_Driver() {
void Fl_Wayland_Copy_Surface_Driver::set_current() {
Fl_Surface_Device::set_current();
- ((Fl_Wayland_Graphics_Driver*)driver())->set_buffer(img_surf->offscreen());
+ ((Fl_Wayland_Graphics_Driver*)driver())->set_buffer((struct fl_wld_buffer *)img_surf->offscreen());
}
diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
index 979cef3d8..89014826f 100644
--- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
@@ -94,7 +94,7 @@ char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n,
{
// write str to a bitmap just big enough
Fl_Image_Surface *surf = new Fl_Image_Surface(w, h);
- Fl_Font f=fl_font();
+ Fl_Font f = fl_font();
Fl_Surface_Device::push_current(surf);
fl_color(FL_BLACK);
fl_rectf(0, 0, w, h);
@@ -104,7 +104,8 @@ char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n,
// get the R channel only of the bitmap
char *alpha_buf = new char[w*h], *r = alpha_buf, *q;
for (int i = 0; i < h; i++) {
- q = (char*)surf->offscreen()->draw_buffer + i * surf->offscreen()->stride;
+ struct fl_wld_buffer *off = (struct fl_wld_buffer *)surf->offscreen();
+ q = (char*)off->draw_buffer + i * off->stride;
for (int j = 0; j < w; j++) {
*r++ = *q;
q += 4;
@@ -174,7 +175,7 @@ GLContext Fl_Wayland_Gl_Window_Driver::create_gl_context(Fl_Window* window, cons
if (context_list && nContext) shared_ctx = context_list[0];
static const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
- GLContext ctx = (GLContext)eglCreateContext(egl_display, ((Fl_Wayland_Gl_Choice*)g)->egl_conf, shared_ctx?shared_ctx:EGL_NO_CONTEXT, context_attribs);
+ GLContext ctx = (GLContext)eglCreateContext(egl_display, ((Fl_Wayland_Gl_Choice*)g)->egl_conf, shared_ctx?(EGLContext)shared_ctx:EGL_NO_CONTEXT, context_attribs);
//fprintf(stderr, "eglCreateContext=%p shared_ctx=%p\n", ctx, shared_ctx);
if (ctx)
add_context(ctx);
@@ -183,7 +184,7 @@ GLContext Fl_Wayland_Gl_Window_Driver::create_gl_context(Fl_Window* window, cons
void Fl_Wayland_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
- struct wld_window *win = fl_xid(w);
+ struct wld_window *win = fl_wl_xid(w);
if (!win) return;
Fl_Wayland_Window_Driver *dr = Fl_Wayland_Window_Driver::driver(w);
EGLSurface target_egl_surface = NULL;
@@ -221,7 +222,7 @@ void Fl_Wayland_Gl_Window_Driver::delete_gl_context(GLContext context) {
cached_window = 0;
}
//EGLBoolean b =
- eglDestroyContext(egl_display, context);
+ eglDestroyContext(egl_display, (EGLContext)context);
//fprintf(stderr,"EGL context %p destroyed %s\n", context, b==EGL_TRUE?"successfully":"w/ error");
//b =
eglDestroySurface(egl_display, egl_surface);
@@ -246,7 +247,7 @@ void Fl_Wayland_Gl_Window_Driver::redraw_overlay() {
void Fl_Wayland_Gl_Window_Driver::make_current_before() {
if (!egl_window) {
- struct wld_window *win = fl_xid(pWindow);
+ struct wld_window *win = fl_wl_xid(pWindow);
struct wl_surface *surface = win->wl_surface;
egl_window = wl_egl_window_create(surface, pWindow->pixel_w(), pWindow->pixel_h());
if (egl_window == EGL_NO_SURFACE) {
@@ -270,7 +271,7 @@ void Fl_Wayland_Gl_Window_Driver::make_current_before() {
float Fl_Wayland_Gl_Window_Driver::pixels_per_unit()
{
int ns = Fl_Window_Driver::driver(pWindow)->screen_num();
- int wld_scale = pWindow->shown() ? fl_xid(pWindow)->scale : 1;
+ int wld_scale = pWindow->shown() ? fl_wl_xid(pWindow)->scale : 1;
return wld_scale * Fl::screen_driver()->scale(ns);
}
@@ -360,7 +361,7 @@ static void delayed_flush(Fl_Gl_Window *win) {
void Fl_Wayland_Gl_Window_Driver::resize(int is_a_resize, int W, int H) {
if (!egl_window) return;
- struct wld_window *win = fl_xid(pWindow);
+ struct wld_window *win = fl_wl_xid(pWindow);
float f = Fl::screen_scale(pWindow->screen_num());
W = (W * win->scale) * f;
H = (H * win->scale) * f;
@@ -404,4 +405,7 @@ void Fl_Wayland_Gl_Window_Driver::gl_start() {
glClear(GL_COLOR_BUFFER_BIT);
}
+
+FL_EXPORT EGLContext fl_wl_glcontext(GLContext rc) { return (EGLContext)rc; }
+
#endif // HAVE_GL
diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
index 78586dc59..986d25ddf 100644
--- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
@@ -149,8 +149,9 @@ void Fl_Wayland_Graphics_Driver::set_color(Fl_Color i, unsigned c) {
}
-void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) {
+void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen src, int srcx, int srcy) {
// draw portion srcx,srcy,w,h of osrc to position x,y (top-left) of the graphics driver's surface
+ struct fl_wld_buffer *osrc = (struct fl_wld_buffer *)src;
int height = osrc->data_size / osrc->stride;
cairo_matrix_t matrix;
cairo_get_matrix(cairo_, &matrix);
diff --git a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx
index 1638cf0d2..4f64434d8 100644
--- a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx
@@ -33,12 +33,13 @@ Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, i
w = int(w*d);
h = int(h*d);
}
- offscreen = (struct fl_wld_buffer*)calloc(1, sizeof(struct fl_wld_buffer));
- offscreen->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
- offscreen->data_size = offscreen->stride * h;
- offscreen->draw_buffer = (uchar*)malloc(offscreen->data_size);
- offscreen->width = w;
- Fl_Wayland_Graphics_Driver::cairo_init(offscreen, w, h, offscreen->stride, CAIRO_FORMAT_RGB24);
+ struct fl_wld_buffer *off_ = (struct fl_wld_buffer*)calloc(1, sizeof(struct fl_wld_buffer));
+ off_->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
+ off_->data_size = off_->stride * h;
+ off_->draw_buffer = (uchar*)malloc(off_->data_size);
+ off_->width = w;
+ offscreen = (Fl_Offscreen)off_;
+ Fl_Wayland_Graphics_Driver::cairo_init(off_, w, h, off_->stride, CAIRO_FORMAT_RGB24);
}
driver(new Fl_Wayland_Graphics_Driver());
if (d != 1 && high_res) driver()->scale(d);
@@ -47,24 +48,24 @@ Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, i
Fl_Wayland_Image_Surface_Driver::~Fl_Wayland_Image_Surface_Driver() {
if (offscreen && !external_offscreen) {
- cairo_destroy(offscreen->cairo_);
- free(offscreen->draw_buffer);
- free(offscreen);
+ cairo_destroy(((struct fl_wld_buffer *)offscreen)->cairo_);
+ free(((struct fl_wld_buffer *)offscreen)->draw_buffer);
+ free((struct fl_wld_buffer *)offscreen);
}
delete driver();
}
void Fl_Wayland_Image_Surface_Driver::set_current() {
Fl_Surface_Device::set_current();
- ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer(offscreen);
+ ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer((struct fl_wld_buffer*)offscreen);
pre_window = Fl_Wayland_Window_Driver::wld_window;
- fl_window = Fl_Wayland_Window_Driver::wld_window = NULL;
+ Fl_Wayland_Window_Driver::wld_window = NULL;
}
void Fl_Wayland_Image_Surface_Driver::end_current() {
- cairo_surface_t *surf = cairo_get_target(offscreen->cairo_);
+ cairo_surface_t *surf = cairo_get_target(((struct fl_wld_buffer *)offscreen)->cairo_);
cairo_surface_flush(surf);
- fl_window = Fl_Wayland_Window_Driver::wld_window = pre_window;
+ Fl_Wayland_Window_Driver::wld_window = pre_window;
}
void Fl_Wayland_Image_Surface_Driver::translate(int x, int y) {
@@ -77,20 +78,20 @@ void Fl_Wayland_Image_Surface_Driver::untranslate() {
Fl_RGB_Image* Fl_Wayland_Image_Surface_Driver::image() {
// Convert depth-4 image in draw_buffer to a depth-3 image while exchanging R and B colors
- int height = offscreen->data_size / offscreen->stride;
- uchar *rgb = new uchar[offscreen->width * height * 3];
+ int height = ((struct fl_wld_buffer *)offscreen)->data_size / ((struct fl_wld_buffer *)offscreen)->stride;
+ uchar *rgb = new uchar[((struct fl_wld_buffer *)offscreen)->width * height * 3];
uchar *p = rgb;
uchar *q;
for (int j = 0; j < height; j++) {
- q = offscreen->draw_buffer + j*offscreen->stride;
- for (int i = 0; i < offscreen->width; i++) { // exchange R and B colors, transmit G
+ q = ((struct fl_wld_buffer *)offscreen)->draw_buffer + j*((struct fl_wld_buffer *)offscreen)->stride;
+ for (int i = 0; i < ((struct fl_wld_buffer *)offscreen)->width; i++) { // exchange R and B colors, transmit G
*p = *(q+2);
*(p+1) = *(q+1);
*(p+2) = *q;
p += 3; q += 4;
}
}
- Fl_RGB_Image *image = new Fl_RGB_Image(rgb, offscreen->width, height, 3);
+ Fl_RGB_Image *image = new Fl_RGB_Image(rgb, ((struct fl_wld_buffer *)offscreen)->width, height, 3);
image->alloc_array = 1;
return image;
}
diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H
index 196f07d5e..a7a3f9512 100644
--- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H
+++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H
@@ -64,6 +64,10 @@ class Fl_Wayland_Screen_Driver : public Fl_Screen_Driver
static bool insertion_point_location_is_valid;
public:
static struct wl_display *wl_display;
+ // use it to make sure the Wayland leg was selected and fl_open_display() has run
+ static struct wl_registry *wl_registry;
+ // true when an app is forbidden to use its Wayland leg
+ static bool wld_disabled;
static void insertion_point_location(int x, int y, int height);
static bool insertion_point_location(int *px, int *py, int *pwidth, int *pheight);
int get_mouse_unscaled(int &xx, int &yy);
diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
index 372d08b32..821bdd56a 100644
--- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
@@ -227,13 +227,16 @@ static inline void checkdouble() {
struct wl_display *Fl_Wayland_Screen_Driver::wl_display = NULL;
+struct wl_registry *Fl_Wayland_Screen_Driver::wl_registry = NULL;
+bool Fl_Wayland_Screen_Driver::wld_disabled = false;
+
Fl_Window *Fl_Wayland_Screen_Driver::surface_to_window(struct wl_surface *surface) {
if (surface) {
Fl_X *xp = Fl_X::first;
while (xp) {
- if (xp->xid->wl_surface == surface) return xp->w;
+ if (((struct wld_window*)xp->xid)->wl_surface == surface) return xp->w;
xp = xp->next;
}
}
@@ -335,9 +338,9 @@ static void pointer_button(void *data,
win = win->top_window();
wld_event_time = time;
if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED && seat->pointer_focus == NULL &&
- fl_xid(win)->kind == Fl_Wayland_Window_Driver::DECORATED) {
+ (fl_wl_xid(win))->kind == Fl_Wayland_Window_Driver::DECORATED) {
// click on titlebar
- libdecor_frame_move(fl_xid(win)->frame, seat->wl_seat, serial);
+ libdecor_frame_move(fl_wl_xid(win)->frame, seat->wl_seat, serial);
return;
}
int b = 0;
@@ -907,7 +910,7 @@ static void output_done(void *data, struct wl_output *wl_output)
//fprintf(stderr, "output_done output=%p\n",output);
Fl_X *xp = Fl_X::first;
while (xp) { // all mapped windows
- struct wld_window *win = xp->xid;
+ struct wld_window *win = (struct wld_window*)xp->xid;
wl_list_for_each(window_output, &(win->outputs), link) { // all Fl_Wayland_Window_Driver::window_output for this window
if (window_output->output == output) {
Fl_Wayland_Window_Driver *win_driver = Fl_Wayland_Window_Driver::driver(win->fl_win);
@@ -1041,7 +1044,7 @@ static void registry_handle_global_remove(void *data, struct wl_registry *regist
if (output->id == name) { // the screen being removed
Fl_X *xp = Fl_X::first;
while (xp) { // all mapped windows
- struct wld_window *win = xp->xid;
+ struct wld_window *win = (struct wld_window*)xp->xid;
wl_list_for_each_safe(window_output, tmp, &(win->outputs), link) { // all Fl_Wayland_Window_Driver::window_output for this window
if (window_output->output == output) {
wl_list_remove(&window_output->link);
@@ -1086,16 +1089,16 @@ Fl_Wayland_Screen_Driver::Fl_Wayland_Screen_Driver() : Fl_Screen_Driver() {
}
void Fl_Wayland_Screen_Driver::open_display_platform() {
- struct wl_registry *wl_registry;
-
static bool beenHereDoneThat = false;
if (beenHereDoneThat)
return;
beenHereDoneThat = true;
- wl_display = wl_display_connect(NULL);
if (!wl_display) {
- Fl::fatal("No Wayland connection\n");
+ wl_display = wl_display_connect(NULL);
+ if (!wl_display) {
+ Fl::fatal("No Wayland connection\n");
+ }
}
wl_list_init(&seats);
wl_list_init(&outputs);
@@ -1121,6 +1124,7 @@ void Fl_Wayland_Screen_Driver::close_display() {
Fl::remove_fd(wl_display_get_fd(Fl_Wayland_Screen_Driver::wl_display));
wl_display_disconnect(Fl_Wayland_Screen_Driver::wl_display);
Fl_Wayland_Screen_Driver::wl_display = NULL;
+ Fl_Wayland_Screen_Driver::wl_registry = NULL;
}
@@ -1141,7 +1145,7 @@ void Fl_Wayland_Screen_Driver::init_workarea()
int Fl_Wayland_Screen_Driver::x() {
- if (!Fl_Wayland_Screen_Driver::wl_display) open_display();
+ if (!Fl_Wayland_Screen_Driver::wl_registry) open_display();
Fl_Wayland_Screen_Driver::output *output;
wl_list_for_each(output, &outputs, link) {
break;
@@ -1150,7 +1154,7 @@ int Fl_Wayland_Screen_Driver::x() {
}
int Fl_Wayland_Screen_Driver::y() {
- if (!Fl_Wayland_Screen_Driver::wl_display) open_display();
+ if (!Fl_Wayland_Screen_Driver::wl_registry) open_display();
Fl_Wayland_Screen_Driver::output *output;
wl_list_for_each(output, &outputs, link) {
break;
@@ -1159,7 +1163,7 @@ int Fl_Wayland_Screen_Driver::y() {
}
int Fl_Wayland_Screen_Driver::w() {
- if (!Fl_Wayland_Screen_Driver::wl_display) open_display();
+ if (!Fl_Wayland_Screen_Driver::wl_registry) open_display();
Fl_Wayland_Screen_Driver::output *output;
wl_list_for_each(output, &outputs, link) {
break;
@@ -1168,7 +1172,7 @@ int Fl_Wayland_Screen_Driver::w() {
}
int Fl_Wayland_Screen_Driver::h() {
- if (!Fl_Wayland_Screen_Driver::wl_display) open_display();
+ if (!Fl_Wayland_Screen_Driver::wl_registry) open_display();
Fl_Wayland_Screen_Driver::output *output;
wl_list_for_each(output, &outputs, link) {
break;
@@ -1178,7 +1182,7 @@ int Fl_Wayland_Screen_Driver::h() {
void Fl_Wayland_Screen_Driver::init() {
- if (!Fl_Wayland_Screen_Driver::wl_display) open_display();
+ if (!Fl_Wayland_Screen_Driver::wl_registry) open_display();
}
@@ -1315,8 +1319,8 @@ const char *Fl_Wayland_Screen_Driver::get_system_scheme()
Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win,
bool ignore, bool *p_ignore) {
- Window xid = win ? fl_xid(win) : NULL;
- struct fl_wld_buffer *buffer = win ? xid->buffer : (Fl_Offscreen)Fl_Surface_Device::surface()->driver()->gc();
+ struct wld_window* xid = win ? fl_wl_xid(win) : NULL;
+ struct fl_wld_buffer *buffer = win ? xid->buffer : (struct fl_wld_buffer *)Fl_Surface_Device::surface()->driver()->gc();
float s = win ? xid->scale * scale(win->screen_num()) :
Fl_Surface_Device::surface()->driver()->scale();
int Xs, Ys, ws, hs;
@@ -1346,8 +1350,9 @@ Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w,
}
-void Fl_Wayland_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &height)
+void Fl_Wayland_Screen_Driver::offscreen_size(Fl_Offscreen off_, int &width, int &height)
{
+ struct fl_wld_buffer *off = (struct fl_wld_buffer *)off_;
width = off->width;
height = off->data_size / off->stride;
}
@@ -1457,3 +1462,8 @@ void Fl_Wayland_Screen_Driver::reset_spot() {
Fl_Wayland_Screen_Driver::next_marked_length = 0;
Fl_Wayland_Screen_Driver::insertion_point_location_is_valid = false;
}
+
+
+struct wl_display *fl_wl_display() {
+ return Fl_Wayland_Screen_Driver::wl_display;
+}
diff --git a/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx
index a54e2ac5f..4b26a17ea 100644
--- a/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx
@@ -18,6 +18,7 @@
#include "Fl_Wayland_System_Driver.H"
#include <FL/Fl.H>
#include "Fl_Wayland_Window_Driver.H"
+#include "Fl_Wayland_Screen_Driver.H"
#include <FL/platform.H>
#include "../../../libdecor/src/libdecor.h"
@@ -55,7 +56,7 @@ void *Fl_Wayland_System_Driver::control_maximize_button(void *data) {
Fl_Window *win = Fl::first_window();
while (win) {
if (!win->parent() && win->border() &&
- !(Fl_X::i(win)->xid->state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ) {
+ !( ((struct wld_window*)Fl_X::i(win)->xid)->state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ) {
win_dims *dim = new win_dims;
dim->tracker = new Fl_Widget_Tracker(win);
Fl_Window_Driver *dr = Fl_Window_Driver::driver(win);
diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
index 38230b3db..96985c10b 100644
--- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
@@ -49,7 +49,7 @@ extern "C" {
#define fl_max(a,b) ((a) > (b) ? (a) : (b))
-Window fl_window;
+
struct wld_window *Fl_Wayland_Window_Driver::wld_window = NULL;
@@ -112,7 +112,7 @@ void Fl_Wayland_Window_Driver::decorated_win_size(int &w, int &h)
h = win->h();
if (!win->shown() || win->parent() || !win->border() || !win->visible()) return;
int X, titlebar_height;
- libdecor_frame_translate_coordinate(fl_xid(win)->frame, 0, 0, &X, &titlebar_height);
+ libdecor_frame_translate_coordinate(fl_wl_xid(win)->frame, 0, 0, &X, &titlebar_height);
//printf("titlebar_height=%d\n",titlebar_height);
h = win->h() + ceil(titlebar_height / Fl::screen_scale(win->screen_num()));
}
@@ -135,7 +135,7 @@ int Fl_Wayland_Window_Driver::decorated_w()
}
struct xdg_toplevel *Fl_Wayland_Window_Driver::xdg_toplevel() {
- Window w = fl_xid(pWindow);
+ struct wld_window * w = fl_wl_xid(pWindow);
struct xdg_toplevel *top = NULL;
if (w->kind == DECORATED) top = libdecor_frame_get_xdg_toplevel(w->frame);
else if (w->kind == UNFRAMED) top = w->xdg_toplevel;
@@ -144,10 +144,10 @@ struct xdg_toplevel *Fl_Wayland_Window_Driver::xdg_toplevel() {
void Fl_Wayland_Window_Driver::take_focus()
{
- Window w = fl_xid(pWindow);
+ struct wld_window *w = fl_wl_xid(pWindow);
if (w) {
Fl_Window *old_first = Fl::first_window();
- Window first_xid = (old_first ? fl_xid(old_first->top_window()) : NULL);
+ struct wld_window *first_xid = (old_first ? fl_wl_xid(old_first->top_window()) : NULL);
if (first_xid && first_xid != w && xdg_toplevel()) {
// this will move the target window to the front
Fl_Wayland_Window_Driver *top_dr = Fl_Wayland_Window_Driver::driver(old_first->top_window());
@@ -157,7 +157,7 @@ void Fl_Wayland_Window_Driver::take_focus()
xdg_toplevel_set_parent(xdg_toplevel(), NULL);
}
// this sets the first window
- fl_find(w);
+ fl_wl_find(w);
}
}
@@ -185,7 +185,7 @@ void Fl_Wayland_Window_Driver::flush_overlay()
fl_copy_offscreen(0, 0, oWindow->w(), oWindow->h(), other_xid, 0, 0);
}
if (overlay() == oWindow) oWindow->draw_overlay();
- Window xid = fl_xid(pWindow);
+ struct wld_window * xid = fl_wl_xid(pWindow);
wl_surface_damage_buffer(xid->wl_surface, 0, 0, pWindow->w() * xid->scale, pWindow->h() * xid->scale);
}
@@ -295,7 +295,7 @@ void Fl_Wayland_Window_Driver::capture_titlebar_and_borders(Fl_RGB_Image*& top,
top = left = bottom = right = NULL;
if (pWindow->decorated_h() == h()) return;
int htop = pWindow->decorated_h() - pWindow->h();
- struct wld_window *wwin = fl_xid(pWindow);
+ struct wld_window *wwin = fl_wl_xid(pWindow);
int width, height, stride;
uchar *cairo_data = fl_libdecor_titlebar_buffer(wwin->frame, &width, &height, &stride);
if (!cairo_data) return;
@@ -342,7 +342,7 @@ void Fl_Wayland_Window_Driver::make_current() {
Fl::fatal(err_message);
}
- struct wld_window *window = fl_xid(pWindow);
+ struct wld_window *window = fl_wl_xid(pWindow);
if (window->buffer) {
((Fl_Cairo_Graphics_Driver*)fl_graphics_driver)->needs_commit_tag(
&window->buffer->draw_buffer_needs_commit);
@@ -355,7 +355,7 @@ void Fl_Wayland_Window_Driver::make_current() {
}
fl_graphics_driver->clip_region(0);
- fl_window = Fl_Wayland_Window_Driver::wld_window = window;
+ Fl_Wayland_Window_Driver::wld_window = window;
float scale = Fl::screen_scale(pWindow->screen_num()) * window->scale;
if (!window->buffer) {
window->buffer = Fl_Wayland_Graphics_Driver::create_shm_buffer(
@@ -385,11 +385,11 @@ void Fl_Wayland_Window_Driver::flush() {
if (scale != fl_graphics_driver->scale() || W != pWindow->w() || H != pWindow->h()) gl_plugin()->invalidate(pWindow);
return;
}
- struct wld_window *window = fl_xid(pWindow);
+ struct wld_window *window = fl_wl_xid(pWindow);
if (!window || !window->configured_width) return;
Fl_X *i = Fl_X::i(pWindow);
- Fl_Region r = i->region;
+ struct flCairoRegion* r = (struct flCairoRegion*)i->region;
float f = Fl::screen_scale(pWindow->screen_num());
if (r && window->buffer) {
for (int i = 0; i < r->count; i++) {
@@ -440,7 +440,7 @@ void Fl_Wayland_Window_Driver::hide() {
ip->region = 0;
}
screen_num_ = -1;
- struct wld_window *wld_win = ip->xid;
+ struct wld_window *wld_win = (struct wld_window*)ip->xid;
if (wld_win) { // this test makes sure ip->xid has not been destroyed already
Fl_Wayland_Graphics_Driver::buffer_release(wld_win);
//fprintf(stderr, "Before hide: sub=%p frame=%p xdg=%p top=%p pop=%p surf=%p\n", wld_win->subsurface, wld_win->frame, wld_win->xdg_surface, wld_win->xdg_toplevel, wld_win->xdg_popup, wld_win->wl_surface);
@@ -479,7 +479,7 @@ void Fl_Wayland_Window_Driver::hide() {
}
free(wld_win);
if (pWindow->as_gl_window() && in_flush) {
- ip->xid = NULL;
+ ip->xid = 0;
ip->next = NULL; // to end the loop in calling Fl::flush()
Fl::add_timeout(.01, (Fl_Timeout_Handler)delayed_delete_Fl_X, ip);
} else {
@@ -490,9 +490,9 @@ void Fl_Wayland_Window_Driver::hide() {
void Fl_Wayland_Window_Driver::map() {
Fl_X* ip = Fl_X::i(pWindow);
- struct wld_window *wl_win = ip->xid;
+ struct wld_window *wl_win = (struct wld_window*)ip->xid;
if (wl_win->kind == SUBWINDOW && !wl_win->subsurface) {
- struct wld_window *parent = fl_xid(pWindow->window());
+ struct wld_window *parent = fl_wl_xid(pWindow->window());
if (parent) {
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
wl_win->subsurface = wl_subcompositor_get_subsurface(scr_driver->wl_subcompositor, wl_win->wl_surface, parent->wl_surface);
@@ -512,7 +512,7 @@ void Fl_Wayland_Window_Driver::map() {
void Fl_Wayland_Window_Driver::unmap() {
Fl_X* ip = Fl_X::i(pWindow);
- struct wld_window *wl_win = ip->xid;
+ struct wld_window *wl_win = (struct wld_window*)ip->xid;
if (wl_win->kind == SUBWINDOW && wl_win->wl_surface) {
wl_surface_attach(wl_win->wl_surface, NULL, 0, 0);
Fl_Wayland_Graphics_Driver::buffer_release(wl_win);
@@ -525,7 +525,7 @@ void Fl_Wayland_Window_Driver::unmap() {
void Fl_Wayland_Window_Driver::size_range() {
if (shown()) {
Fl_X* ip = Fl_X::i(pWindow);
- struct wld_window *wl_win = ip->xid;
+ struct wld_window *wl_win = (struct wld_window*)ip->xid;
float f = Fl::screen_scale(pWindow->screen_num());
if (wl_win->kind == DECORATED && wl_win->frame) {
int X,Y,W,H;
@@ -553,7 +553,7 @@ void Fl_Wayland_Window_Driver::size_range() {
void Fl_Wayland_Window_Driver::iconize() {
Fl_X* ip = Fl_X::i(pWindow);
- struct wld_window *wl_win = ip->xid;
+ struct wld_window *wl_win = (struct wld_window*)ip->xid;
if (wl_win->kind == DECORATED) {
libdecor_frame_set_minimized(wl_win->frame);
Fl::handle(FL_HIDE, pWindow);
@@ -577,7 +577,7 @@ void Fl_Wayland_Window_Driver::decoration_sizes(int *top, int *left, int *right
int Fl_Wayland_Window_Driver::scroll(int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y,
void (*draw_area)(void*, int,int,int,int), void* data)
{
- Window xid = fl_xid(pWindow);
+ struct wld_window * xid = fl_wl_xid(pWindow);
struct fl_wld_buffer *buffer = xid->buffer;
float s = xid->scale * fl_graphics_driver->scale();
if (s != 1) {
@@ -781,7 +781,7 @@ static void handle_configure(struct libdecor_frame *frame,
void Fl_Wayland_Window_Driver::wait_for_expose()
{
Fl_Window_Driver::wait_for_expose();
- Window xid = fl_xid(pWindow);
+ struct wld_window * xid = fl_wl_xid(pWindow);
if (pWindow->fullscreen_active()) {
if (xid->kind == DECORATED) {
while (!(xid->state & LIBDECOR_WINDOW_STATE_FULLSCREEN) || !(xid->state & LIBDECOR_WINDOW_STATE_ACTIVE)) {
@@ -897,7 +897,7 @@ static void popup_done(void *data, struct xdg_popup *xdg_popup) {
#if USE_GRAB_POPUP
if (mem_grabbing_popup == xdg_popup) {
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
- libdecor_frame_popup_ungrab(fl_xid(mem_parent)->frame, scr_driver->get_seat_name());
+ libdecor_frame_popup_ungrab(fl_wl_xid(mem_parent)->frame, scr_driver->get_seat_name());
mem_grabbing_popup = NULL;
mem_parent = NULL;
}
@@ -1003,7 +1003,7 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow()
if (!target) target = Fl::first_window();
Fl_Window *parent_win = target->top_window();
while (parent_win && parent_win->menu_window()) parent_win = Fl::next_window(parent_win);
- Window parent_xid = fl_xid(parent_win);
+ struct wld_window * parent_xid = fl_wl_xid(parent_win);
struct xdg_surface *parent_xdg = parent_xid->xdg_surface;
float f = Fl::screen_scale(parent_win->screen_num());
//fprintf(stderr, "menu parent_win=%p pos:%dx%d size:%dx%d\n", parent_win, pWindow->x(), pWindow->y(), pWindow->w(), pWindow->h());
@@ -1029,7 +1029,8 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow()
} else if ( pWindow->border() && !pWindow->parent() ) { // a decorated window
new_window->kind = DECORATED;
- if (!scr_driver->libdecor_context) scr_driver->libdecor_context = libdecor_new(Fl_Wayland_Screen_Driver::wl_display, &libdecor_iface);
+ if (!scr_driver->libdecor_context)
+ scr_driver->libdecor_context = libdecor_new(Fl_Wayland_Screen_Driver::wl_display, &libdecor_iface);
new_window->frame = libdecor_decorate(scr_driver->libdecor_context, new_window->wl_surface,
&libdecor_frame_iface, new_window);
//fprintf(stderr, "makeWindow: libdecor_decorate=%p pos:%dx%d\n", new_window->frame, pWindow->x(), pWindow->y());
@@ -1046,7 +1047,7 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow()
} else if (pWindow->parent()) { // for subwindows (GL or non-GL)
new_window->kind = SUBWINDOW;
- struct wld_window *parent = fl_xid(pWindow->window());
+ struct wld_window *parent = fl_wl_xid(pWindow->window());
new_window->subsurface = wl_subcompositor_get_subsurface(scr_driver->wl_subcompositor, new_window->wl_surface, parent->wl_surface);
//fprintf(stderr, "makeWindow: subsurface=%p\n", new_window->subsurface);
float f = Fl::screen_scale(pWindow->top_window()->screen_num());
@@ -1073,9 +1074,9 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow()
}
Fl_Window *old_first = Fl::first_window();
- Window first_xid = (old_first ? fl_xid(old_first) : NULL);
+ struct wld_window * first_xid = (old_first ? fl_wl_xid(old_first) : NULL);
Fl_X *xp = new Fl_X;
- xp->xid = new_window;
+ xp->xid = (fl_uintptr_t)new_window;
other_xid = 0;
xp->w = pWindow;
i(xp);
@@ -1244,7 +1245,7 @@ int Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor c) {
void Fl_Wayland_Window_Driver::update_scale()
{
- struct wld_window *window = fl_xid(pWindow);
+ struct wld_window *window = fl_wl_xid(pWindow);
int scale = 0;
Fl_Wayland_Window_Driver::window_output *window_output;
@@ -1265,7 +1266,7 @@ void Fl_Wayland_Window_Driver::update_scale()
void Fl_Wayland_Window_Driver::use_border() {
if (!shown() || pWindow->parent()) return;
pWindow->wait_for_expose(); // useful for border(0) just after show()
- struct libdecor_frame *frame = fl_xid(pWindow)->frame;
+ struct libdecor_frame *frame = fl_wl_xid(pWindow)->frame;
if (frame && Fl_Wayland_Screen_Driver::compositor != Fl_Wayland_Screen_Driver::KDE) {
libdecor_frame_set_visibility(frame, pWindow->border());
pWindow->redraw();
@@ -1310,10 +1311,10 @@ void Fl_Wayland_Window_Driver::fullscreen_off(int X, int Y, int W, int H) {
void Fl_Wayland_Window_Driver::label(const char *name, const char *iname) {
- if (shown() && !parent() && fl_xid(pWindow)->kind == DECORATED) {
+ if (shown() && !parent() && fl_wl_xid(pWindow)->kind == DECORATED) {
if (!name) name = "";
if (!iname) iname = fl_filename_name(name);
- libdecor_frame_set_title(fl_xid(pWindow)->frame, name);
+ libdecor_frame_set_title(fl_wl_xid(pWindow)->frame, name);
}
}
@@ -1322,7 +1323,7 @@ int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int
// build a new wl_cursor and its image
struct wl_cursor *new_cursor = (struct wl_cursor*)malloc(sizeof(struct wl_cursor));
struct cursor_image *new_image = (struct cursor_image*)calloc(1, sizeof(struct cursor_image));
- int scale = fl_xid(pWindow)->scale;
+ int scale = fl_wl_xid(pWindow)->scale;
new_image->image.width = rgb->w() * scale;
new_image->image.height = rgb->h() * scale;
new_image->image.hotspot_x = hotx * scale;
@@ -1338,7 +1339,7 @@ int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int
new_cursor->images[0] = (struct wl_cursor_image*)new_image;
new_cursor->name = strdup("custom cursor");
// draw the rgb image to the cursor's drawing buffer
- Fl_Image_Surface *img_surf = new Fl_Image_Surface(new_image->image.width, new_image->image.height, 0, offscreen);
+ Fl_Image_Surface *img_surf = new Fl_Image_Surface(new_image->image.width, new_image->image.height, 0, (Fl_Offscreen)offscreen);
Fl_Surface_Device::push_current(img_surf);
Fl_Wayland_Graphics_Driver *driver = (Fl_Wayland_Graphics_Driver*)img_surf->driver();
cairo_scale(driver->cr(), scale, scale);
@@ -1361,7 +1362,7 @@ int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int
// This is only to fix a bug in libdecor where what libdecor_frame_set_min_content_size()
// does is often destroyed by libdecor-cairo.
static void delayed_minsize(Fl_Window *win) {
- struct wld_window *wl_win = fl_xid(win);
+ struct wld_window *wl_win = fl_wl_xid(win);
Fl_Window_Driver *driver = Fl_Window_Driver::driver(win);
if (wl_win->kind == Fl_Wayland_Window_Driver::DECORATED) {
float f = Fl::screen_scale(win->screen_num());
@@ -1377,7 +1378,7 @@ static void delayed_minsize(Fl_Window *win) {
void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
- struct wld_window *fl_win = fl_xid(pWindow);
+ struct wld_window *fl_win = fl_wl_xid(pWindow);
if (fl_win && fl_win->kind == DECORATED && !xdg_toplevel()) {
pWindow->wait_for_expose();
}
@@ -1448,7 +1449,7 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
}
void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) {
- Window xid_menu = fl_xid(pWindow);
+ struct wld_window * xid_menu = fl_wl_xid(pWindow);
if (y == pWindow->y() && y >= 0) return;
int true_y = y;
int y_offset = 0;
@@ -1468,7 +1469,7 @@ void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) {
xid_menu->xdg_surface = xdg_wm_base_get_xdg_surface(scr_driver->xdg_wm_base, xid_menu->wl_surface);
xdg_surface_add_listener(xid_menu->xdg_surface, &xdg_surface_listener, xid_menu);
struct xdg_positioner *positioner = xdg_wm_base_create_positioner(scr_driver->xdg_wm_base);
- Window parent_xid = fl_xid(Fl_Window_Driver::menu_parent());
+ struct wld_window * parent_xid = fl_wl_xid(Fl_Window_Driver::menu_parent());
float f = Fl::screen_scale(Fl_Window_Driver::menu_parent()->screen_num());
int popup_x = x * f, popup_y = y * f;
if (parent_xid->kind == DECORATED)
@@ -1504,7 +1505,7 @@ void Fl_Wayland_Window_Driver::menu_window_area(int &X, int &Y, int &W, int &H,
}
-struct wl_surface *fl_wl_surface(Window xid) {
+FL_EXPORT struct wl_surface *fl_wl_surface(struct wld_window *xid) {
return xid->wl_surface;
}
@@ -1514,8 +1515,13 @@ cairo_t *fl_wl_cairo() {
}
-struct wl_display *fl_wl_display() {
- return Fl_Wayland_Screen_Driver::wl_display;
+Fl_Window *fl_wl_find(struct wld_window *xid) {
+ return Fl_Window_Driver::find((fl_uintptr_t)xid);
+}
+
+
+struct wld_window *fl_wl_xid(const Fl_Window *win) {
+ return (struct wld_window *)Fl_Window_Driver::xid(win);
}
diff --git a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx
index 07bcd3ed4..2dca84924 100644
--- a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx
+++ b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx
@@ -34,7 +34,6 @@
////////////////////////////////////////////////////////////////
// Code used for copy and paste and DnD into the program:
-//static Window fl_dnd_source_window;
static char *fl_selection_buffer[2];
static int fl_selection_length[2];
@@ -99,7 +98,7 @@ static void data_source_handle_cancelled(void *data, struct wl_data_source *sour
wl_data_source_destroy(source);
doing_dnd = false;
if (dnd_icon) {
- Fl_Offscreen off = (Fl_Offscreen)wl_surface_get_user_data(dnd_icon);
+ struct fl_wld_buffer * off = (struct fl_wld_buffer *)wl_surface_get_user_data(dnd_icon);
struct wld_window fake_window;
fake_window.buffer = off;
Fl_Wayland_Graphics_Driver::buffer_release(&fake_window);
@@ -190,9 +189,9 @@ static Fl_Offscreen offscreen_from_text(const char *text, int scale) {
if (width > 300*scale) width = 300*scale;
height = nl * fl_height() + 3;
width += 6;
- Fl_Offscreen off = Fl_Wayland_Graphics_Driver::create_shm_buffer(width, height);
+ struct fl_wld_buffer * off = Fl_Wayland_Graphics_Driver::create_shm_buffer(width, height);
memset(off->draw_buffer, 0, off->data_size);
- Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 0, off);
+ Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 0, (Fl_Offscreen)off);
Fl_Surface_Device::push_current(surf);
p = text;
fl_font(FL_HELVETICA, 10 * scale);
@@ -213,7 +212,7 @@ static Fl_Offscreen offscreen_from_text(const char *text, int scale) {
delete surf;
cairo_surface_flush( cairo_get_target(off->cairo_) );
memcpy(off->data, off->draw_buffer, off->data_size);
- return off;
+ return (Fl_Offscreen)off;
}
@@ -226,13 +225,13 @@ int Fl_Wayland_Screen_Driver::dnd(int use_selection) {
wl_data_source_add_listener(source, &data_source_listener, (void*)0);
wl_data_source_offer(source, wld_plain_text_clipboard);
wl_data_source_set_actions(source, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY);
- Fl_Offscreen off = NULL;
+ struct fl_wld_buffer * off = NULL;
int s = 1;
if (use_selection) {
// use the text as dragging icon
Fl_Widget *current = Fl::pushed() ? Fl::pushed() : Fl::first_window();
- s = fl_xid(current->top_window())->scale;
- off = offscreen_from_text(fl_selection_buffer[0], s);
+ s = fl_wl_xid(current->top_window())->scale;
+ off = (struct fl_wld_buffer *)offscreen_from_text(fl_selection_buffer[0], s);
dnd_icon = wl_compositor_create_surface(scr_driver->wl_compositor);
} else dnd_icon = NULL;
doing_dnd = true;
@@ -571,7 +570,7 @@ void Fl_Wayland_Screen_Driver::paste(Fl_Widget &receiver, int clipboard, const c
receiver.handle(FL_PASTE);
} else if (type == Fl::clipboard_image && clipboard_contains(Fl::clipboard_image)) {
if (get_clipboard_image()) return;
- Window xid = fl_xid(receiver.top_window());
+ struct wld_window * xid = fl_wl_xid(receiver.top_window());
if (xid && xid->scale > 1) {
Fl_RGB_Image *rgb = (Fl_RGB_Image*)Fl::e_clipboard_data;
rgb->scale(rgb->data_w() / xid->scale, rgb->data_h() / xid->scale);
diff --git a/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx b/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx
index 5a2a78bee..f80ee67ba 100644
--- a/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx
+++ b/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx
@@ -16,9 +16,12 @@
#include "Fl_Wayland_Gl_Window_Driver.H"
+#include "Fl_Wayland_Screen_Driver.H"
+#include "../X11/Fl_X11_Gl_Window_Driver.H"
Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
{
- return new Fl_Wayland_Gl_Window_Driver(w);
+ if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Gl_Window_Driver(w);
+ return new Fl_X11_Gl_Window_Driver(w);
}
diff --git a/src/drivers/Wayland/fl_wayland_platform_init.cxx b/src/drivers/Wayland/fl_wayland_platform_init.cxx
index 4500a0f45..8c81ab331 100644
--- a/src/drivers/Wayland/fl_wayland_platform_init.cxx
+++ b/src/drivers/Wayland/fl_wayland_platform_init.cxx
@@ -22,10 +22,61 @@
#include "Fl_Wayland_Window_Driver.H"
#include "Fl_Wayland_Image_Surface_Driver.H"
+#include "../Xlib/Fl_Xlib_Copy_Surface_Driver.H"
+#include <cairo-xlib.h>
+#include "../Cairo/Fl_Display_Cairo_Graphics_Driver.H"
+#include "../X11/Fl_X11_Screen_Driver.H"
+#include "../X11/Fl_X11_System_Driver.H"
+#include "../X11/Fl_X11_Window_Driver.H"
+#include "../Xlib/Fl_Xlib_Image_Surface_Driver.H"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+void fl_disable_wayland() {
+ if (Fl_Wayland_Screen_Driver::wl_display) {
+ wl_display_disconnect(Fl_Wayland_Screen_Driver::wl_display);
+ Fl_Wayland_Screen_Driver::wl_display = NULL;
+ delete Fl_Screen_Driver::system_driver;
+ Fl_Screen_Driver::system_driver = NULL;
+ }
+ Fl_Wayland_Screen_Driver::wld_disabled = true;
+ Fl::system_driver();
+}
+
-Fl_Copy_Surface_Driver *Fl_Copy_Surface_Driver::newCopySurfaceDriver(int w, int h)
+Fl_System_Driver *Fl_System_Driver::newSystemDriver()
{
- return new Fl_Wayland_Copy_Surface_Driver(w, h);
+ const char *backend = ::getenv("FLTK_BACKEND");
+ // fprintf(stderr, "FLTK_BACKEND='%s' XDG_RUNTIME_DIR='%s'\n",backend ? backend : "", xdg ? xdg : "");
+ if (backend && strcmp(backend, "wayland") == 0) {
+ Fl_Wayland_Screen_Driver::wl_display = wl_display_connect(NULL);
+ if (!Fl_Wayland_Screen_Driver::wl_display) {
+ fprintf(stderr, "Error: no Wayland connection available, FLTK_BACKEND = '%s'\n", backend);
+ exit(1);
+ }
+ return new Fl_Wayland_System_Driver();
+ }
+ else if (backend && strcmp(backend, "x11") == 0) {
+ return new Fl_X11_System_Driver();
+ }
+ else if (!backend) {
+ if (!Fl_Wayland_Screen_Driver::wld_disabled && ::getenv("XDG_RUNTIME_DIR")) {
+ // env var XDG_RUNTIME_DIR is necessary for wayland
+ // is a Wayland connection available ?
+ Fl_Wayland_Screen_Driver::wl_display = wl_display_connect(NULL);
+ if (Fl_Wayland_Screen_Driver::wl_display) { // Yes, use Wayland drivers
+ // puts("using wayland");
+ return new Fl_Wayland_System_Driver();
+ }
+ }
+ return new Fl_X11_System_Driver();
+ }
+ fprintf(stderr, "Error: unexpected value of FLTK_BACKEND: '%s'\n", backend);
+ exit(1);
+ return NULL;
}
@@ -52,32 +103,43 @@ static Fl_Fontdesc built_in_table[] = { // Pango font names
FL_EXPORT Fl_Fontdesc *fl_fonts = built_in_table;
-Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver()
-{
- fl_graphics_driver = new Fl_Wayland_Graphics_Driver();
+Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver() {
+ if (Fl_Wayland_Screen_Driver::wl_display) {
+ fl_graphics_driver = new Fl_Wayland_Graphics_Driver();
+puts("using Fl_Wayland_Graphics_Driver");
+ } else {
+ fl_graphics_driver = new Fl_Display_Cairo_Graphics_Driver();
+puts("using Fl_Display_Cairo_Graphics_Driver");
+ }
return fl_graphics_driver;
}
-Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver()
-{
- return new Fl_Wayland_Screen_Driver();
+Fl_Copy_Surface_Driver *Fl_Copy_Surface_Driver::newCopySurfaceDriver(int w, int h) {
+ if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Copy_Surface_Driver(w, h);
+ return new Fl_Xlib_Copy_Surface_Driver(w, h);
}
-Fl_System_Driver *Fl_System_Driver::newSystemDriver()
-{
- return new Fl_Wayland_System_Driver();
+Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver() {
+ if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Screen_Driver();
+
+ Fl_X11_Screen_Driver *d = new Fl_X11_Screen_Driver();
+ for (int i = 0; i < MAX_SCREENS; i++) d->screens[i].scale = 1;
+ d->current_xft_dpi = 0.; // means the value of the Xft.dpi resource is still unknown
+ return d;
}
Fl_Window_Driver *Fl_Window_Driver::newWindowDriver(Fl_Window *w)
{
- return new Fl_Wayland_Window_Driver(w);
+ if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Window_Driver(w);
+ return new Fl_X11_Window_Driver(w);
}
Fl_Image_Surface_Driver *Fl_Image_Surface_Driver::newImageSurfaceDriver(int w, int h, int high_res, Fl_Offscreen off)
{
- return new Fl_Wayland_Image_Surface_Driver(w, h, high_res, off);
+ if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Image_Surface_Driver(w, h, high_res, off);
+ return new Fl_Xlib_Image_Surface_Driver(w, h, high_res, off);
}