diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2023-10-05 17:00:07 +0200 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2023-10-05 17:07:55 +0200 |
| commit | 6571bd2f28d916b0aa0e0091ff3b84018454ed80 (patch) | |
| tree | 72a1d335c39bff7a7eded427b19ce82f3ce41b86 | |
| parent | e8f633cf2f6a8fe7d1d23bd5bc987f22ef0a3319 (diff) | |
Wayland: whitespace only changes
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H | 3 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx | 44 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H | 6 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx | 19 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.H | 2 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx | 15 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Screen_Driver.H | 3 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx | 328 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.H | 12 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 242 | ||||
| -rw-r--r-- | src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx | 92 | ||||
| -rw-r--r-- | src/drivers/Wayland/fl_wayland_platform_init.cxx | 2 |
12 files changed, 493 insertions, 275 deletions
diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H index d9cb641e5..83b13e155 100644 --- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H @@ -54,7 +54,8 @@ private: void redraw_overlay() FL_OVERRIDE; void gl_start() FL_OVERRIDE; void gl_visual(Fl_Gl_Choice *c) FL_OVERRIDE; - char *alpha_mask_for_string(const char *str, int n, int w, int h, Fl_Fontsize fs) FL_OVERRIDE; + char *alpha_mask_for_string( + const char *str, int n, int w, int h, Fl_Fontsize fs) FL_OVERRIDE; void init(); public: //virtual bool need_scissor() { return true; } // CONTROL_LEAKING_SUB_GL_WINDOWS diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx index 34b2a6551..4e145e594 100644 --- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx @@ -53,6 +53,7 @@ public: } }; + struct gl_start_support { // to support use of gl_start / gl_finish struct wl_surface *surface; struct wl_subsurface *subsurface; @@ -60,12 +61,15 @@ struct gl_start_support { // to support use of gl_start / gl_finish EGLSurface egl_surface; }; + static EGLConfig wld_egl_conf = NULL; + EGLDisplay Fl_Wayland_Gl_Window_Driver::egl_display = EGL_NO_DISPLAY; -Fl_Wayland_Gl_Window_Driver::Fl_Wayland_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) { +Fl_Wayland_Gl_Window_Driver::Fl_Wayland_Gl_Window_Driver(Fl_Gl_Window *win) : + Fl_Gl_Window_Driver(win) { if (egl_display == EGL_NO_DISPLAY) init(); egl_window = NULL; egl_surface = NULL; @@ -94,14 +98,14 @@ void Fl_Wayland_Gl_Window_Driver::init() { Fl::fatal("Can't initialise egl display\n"); } //printf("EGL major: %d, minor %d\n", major, minor); - //eglGetConfigs(egl_display, NULL, 0, &configs_count); //printf("EGL has %d configs\n", configs_count); eglBindAPI(EGL_OPENGL_API); } -char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, int w, int h, Fl_Fontsize fs) +char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, + int w, int h, Fl_Fontsize fs) { // write str to a bitmap just big enough Fl_Image_Surface *surf = new Fl_Image_Surface(w, h); @@ -133,7 +137,8 @@ Fl_Gl_Choice *Fl_Wayland_Gl_Window_Driver::find(int m, const int *alistp) { m |= FL_DOUBLE; //if (pWindow->parent()) m |= FL_ALPHA; // CONTROL_LEAKING_SUB_GL_WINDOWS - Fl_Wayland_Gl_Choice *g = (Fl_Wayland_Gl_Choice*)Fl_Gl_Window_Driver::find_begin(m, alistp); + Fl_Wayland_Gl_Choice *g = (Fl_Wayland_Gl_Choice*)Fl_Gl_Window_Driver::find_begin( + m, alistp); if (g) return g; EGLint n; @@ -176,7 +181,10 @@ GLContext Fl_Wayland_Gl_Window_Driver::create_gl_context(Fl_Window* window, 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?(EGLContext)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); @@ -203,7 +211,8 @@ void Fl_Wayland_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context float s = Fl::screen_scale(w->screen_num()); Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); // the GL scene will be a transparent subsurface above the cairo-drawn surface - dr->gl_start_support_->surface = wl_compositor_create_surface(scr_driver->wl_compositor); + dr->gl_start_support_->surface = + wl_compositor_create_surface(scr_driver->wl_compositor); dr->gl_start_support_->subsurface = wl_subcompositor_get_subsurface( scr_driver->wl_subcompositor, dr->gl_start_support_->surface, win->wl_surface); wl_subsurface_set_position(dr->gl_start_support_->subsurface, w->x() * s, w->y() * s); @@ -216,7 +225,8 @@ void Fl_Wayland_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context if (context != cached_context || w != cached_window) { cached_context = context; cached_window = w; - if (eglMakeCurrent(egl_display, target_egl_surface, target_egl_surface, (EGLContext)context)) { + if (eglMakeCurrent(egl_display, target_egl_surface, target_egl_surface, + (EGLContext)context)) { //fprintf(stderr, "EGLContext %p made current\n", context); } else { Fl::error("eglMakeCurrent() failed\n"); @@ -247,12 +257,8 @@ void Fl_Wayland_Gl_Window_Driver::delete_gl_context(GLContext context) { cached_context = 0; cached_window = 0; } -//EGLBoolean b = 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); -//fprintf(stderr,"EGLSurface %p destroyed %s\n", egl_surface, b==EGL_TRUE?"successfully":"w/ error"); egl_surface = NULL; wl_egl_window_destroy(egl_window); egl_window = NULL; @@ -261,12 +267,11 @@ void Fl_Wayland_Gl_Window_Driver::delete_gl_context(GLContext context) { void Fl_Wayland_Gl_Window_Driver::make_overlay_current() { -//fprintf(stderr, "make_overlay_current\n"); glDrawBuffer(GL_FRONT); } + void Fl_Wayland_Gl_Window_Driver::redraw_overlay() { -//fprintf(stderr, "redraw_overlay\n"); pWindow->redraw(); } @@ -281,12 +286,9 @@ void Fl_Wayland_Gl_Window_Driver::make_current_before() { egl_window = wl_egl_window_create(surface, (W/scale)*scale, (H/scale)*scale); if (egl_window == EGL_NO_SURFACE) { Fl::fatal("Can't create egl window with wl_egl_window_create()\n"); - } else { - //fprintf(stderr, "Created egl window=%p\n", egl_window); } Fl_Wayland_Gl_Choice *g = (Fl_Wayland_Gl_Choice*)this->g(); egl_surface = eglCreateWindowSurface(egl_display, g->egl_conf, egl_window, NULL); -//fprintf(stderr, "Created egl surface=%p at scale=%d\n", egl_surface, win->scale); wl_surface_set_buffer_scale(surface, scale); // Tested apps: shape, glpuzzle, cube, fractals, gl_overlay, fullscreen, unittests, // OpenGL3-glut-test, OpenGL3test. @@ -327,7 +329,7 @@ void Fl_Wayland_Gl_Window_Driver::swap_buffers() { glPushMatrix(); glLoadIdentity(); glScalef(2.0f/wo, 2.0f/ho, 1.0f); - glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f); // set transform so 0,0 is bottom/left of Gl_Window + glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f); // set transform so 0,0 is bottom/left of window glRasterPos2i(0,0); // set glRasterPos to bottom left corner { // Emulate overlay by doing copypixels @@ -367,7 +369,8 @@ public: } } void destroy(struct gl_start_support *gl_start_support_) FL_OVERRIDE { - eglDestroySurface(Fl_Wayland_Gl_Window_Driver::egl_display, gl_start_support_->egl_surface); + eglDestroySurface(Fl_Wayland_Gl_Window_Driver::egl_display, + gl_start_support_->egl_surface); wl_egl_window_destroy(gl_start_support_->egl_window); wl_subsurface_destroy(gl_start_support_->subsurface); wl_surface_destroy(gl_start_support_->surface); @@ -375,13 +378,16 @@ public: } }; + static Fl_Wayland_Gl_Plugin Gl_Overlay_Plugin; + /* CONTROL_LEAKING_SUB_GL_WINDOWS static void delayed_scissor(Fl_Wayland_Gl_Window_Driver *dr) { dr->apply_scissor(); }*/ + void Fl_Wayland_Gl_Window_Driver::resize(int is_a_resize, int W, int H) { if (!egl_window) return; float f = Fl::screen_scale(pWindow->screen_num()); @@ -392,8 +398,6 @@ void Fl_Wayland_Gl_Window_Driver::resize(int is_a_resize, int W, int H) { wl_egl_window_get_attached_size(egl_window, &W2, &H2); if (W2 != W || H2 != H) { wl_egl_window_resize(egl_window, W, H, 0, 0); - //fprintf(stderr, "Fl_Wayland_Gl_Window_Driver::resize from %dx%d to %dx%d\n", - // W2, H2, W, H); } /* CONTROL_LEAKING_SUB_GL_WINDOWS if (Fl_Wayland_Window_Driver::driver(pWindow)->subRect()) { diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H index 00bc6af4d..103b026a9 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H @@ -53,12 +53,14 @@ public: struct wl_list buffers; // to list of fl_wld_buffer's from this pool }; static const uint32_t wld_format; - void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) FL_OVERRIDE; + void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, + int srcx, int srcy) FL_OVERRIDE; static struct wld_buffer *create_wld_buffer(int width, int height, bool with_shm = true); static void create_shm_buffer(wld_buffer *buffer); static void buffer_release(struct wld_window *window); static void buffer_commit(struct wld_window *window, struct flCairoRegion *r = NULL); - static void cairo_init(struct draw_buffer *buffer, int width, int height, int stride, cairo_format_t format); + static void cairo_init(struct draw_buffer *buffer, int width, int height, int stride, + cairo_format_t format); static struct draw_buffer *offscreen_buffer(Fl_Offscreen); static const cairo_user_data_key_t key; static Fl_Image_Surface *custom_offscreen(int w, int h, struct wld_buffer **buffer); diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx index 0cc0d9c6a..81e99832d 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx @@ -62,7 +62,8 @@ void Fl_Wayland_Graphics_Driver::create_shm_buffer( if (pool && !wl_list_empty(&pool_data->buffers)) { // last wld_buffer created from current pool struct wld_buffer *record = wl_container_of(pool_data->buffers.next, record, link); - chunk_offset = ((char*)record->data - pool_data->pool_memory) + record->draw_buffer.data_size; + chunk_offset = ((char*)record->data - pool_data->pool_memory) + + record->draw_buffer.data_size; } if (!pool || chunk_offset + buffer->draw_buffer.data_size > pool_size) { // if true, a new pool is needed @@ -120,12 +121,10 @@ struct Fl_Wayland_Graphics_Driver::wld_buffer * // used to support both normal and progressive drawing static void surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) { struct wld_window *window = (struct wld_window *)data; -//fprintf(stderr,"surface_frame_done: draw_buffer_needs_commit=%d\n", window->buffer->draw_buffer_needs_commit); wl_callback_destroy(cb); if (window->buffer) { // fix for issue #712 window->buffer->cb = NULL; if (window->buffer->draw_buffer_needs_commit) { - //fprintf(stderr,"surface_frame_done calls buffer_commit\n"); Fl_Wayland_Graphics_Driver::buffer_commit(window); } } @@ -169,18 +168,18 @@ void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window, cairo_surface_flush(surf); if (r) copy_region(window, r); else { - memcpy(window->buffer->data, window->buffer->draw_buffer.buffer, window->buffer->draw_buffer.data_size); + memcpy(window->buffer->data, window->buffer->draw_buffer.buffer, + window->buffer->draw_buffer.data_size); wl_surface_damage_buffer(window->wl_surface, 0, 0, 1000000, 1000000); } window->buffer->in_use = true; wl_surface_attach(window->wl_surface, window->buffer->wl_buffer, 0, 0); - wl_surface_set_buffer_scale(window->wl_surface, - Fl_Wayland_Window_Driver::driver(window->fl_win)->wld_scale()); + wl_surface_set_buffer_scale( window->wl_surface, + Fl_Wayland_Window_Driver::driver(window->fl_win)->wld_scale() ); window->buffer->cb = wl_surface_frame(window->wl_surface); wl_callback_add_listener(window->buffer->cb, &surface_frame_listener, window); wl_surface_commit(window->wl_surface); window->buffer->draw_buffer_needs_commit = false; -//fprintf(stderr,"buffer_commit %s\n", window->fl_win->parent()?"child":"top"); } @@ -244,12 +243,14 @@ void Fl_Wayland_Graphics_Driver::buffer_release(struct wld_window *window) } } + // this refers to the same memory layout for pixel data as does CAIRO_FORMAT_ARGB32 const uint32_t Fl_Wayland_Graphics_Driver::wld_format = WL_SHM_FORMAT_ARGB8888; 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 + // draw portion srcx,srcy,w,h of osrc to position x,y (top-left) of + // the graphics driver's surface cairo_matrix_t matrix; cairo_get_matrix(cairo_, &matrix); double s = matrix.xx; @@ -267,8 +268,10 @@ void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_O cairo_restore(cairo_); } + const cairo_user_data_key_t Fl_Wayland_Graphics_Driver::key = {}; + struct Fl_Wayland_Graphics_Driver::draw_buffer *Fl_Wayland_Graphics_Driver::offscreen_buffer( Fl_Offscreen offscreen) { diff --git a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.H b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.H index 86bf2dd83..285222ced 100644 --- a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.H @@ -1,7 +1,7 @@ // // Draw-to-image code for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2021 by Bill Spitzak and others. +// Copyright 1998-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this diff --git a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx index 5c9672179..691749cbf 100644 --- a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx @@ -20,12 +20,15 @@ #include "Fl_Wayland_Image_Surface_Driver.H" -Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off) : Fl_Image_Surface_Driver(w, h, high_res, off) { +Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, + int high_res, Fl_Offscreen off) : Fl_Image_Surface_Driver(w, h, high_res, off) { float d = 1; if (!off) { fl_open_display(); if (Fl_Wayland_Window_Driver::wld_window) { - d = Fl_Wayland_Window_Driver::driver(Fl_Wayland_Window_Driver::wld_window->fl_win)->wld_scale(); + d = Fl_Wayland_Window_Driver::driver( + Fl_Wayland_Window_Driver::wld_window->fl_win + )->wld_scale(); } d *= fl_graphics_driver->scale(); if (d != 1 && high_res) { @@ -56,6 +59,7 @@ Fl_Wayland_Image_Surface_Driver::~Fl_Wayland_Image_Surface_Driver() { delete driver(); } + void Fl_Wayland_Image_Surface_Driver::set_current() { Fl_Surface_Device::set_current(); ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_cairo((cairo_t*)offscreen); @@ -64,6 +68,7 @@ void Fl_Wayland_Image_Surface_Driver::set_current() { fl_window = 0; } + void Fl_Wayland_Image_Surface_Driver::end_current() { cairo_surface_t *surf = cairo_get_target((cairo_t*)offscreen); cairo_surface_flush(surf); @@ -72,17 +77,21 @@ void Fl_Wayland_Image_Surface_Driver::end_current() { Fl_Surface_Device::end_current(); } + void Fl_Wayland_Image_Surface_Driver::translate(int x, int y) { ((Fl_Wayland_Graphics_Driver*)driver())->ps_translate(x, y); } + void Fl_Wayland_Image_Surface_Driver::untranslate() { ((Fl_Wayland_Graphics_Driver*)driver())->ps_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 - struct Fl_Wayland_Graphics_Driver::draw_buffer *off_buf = Fl_Wayland_Graphics_Driver::offscreen_buffer(offscreen); + struct Fl_Wayland_Graphics_Driver::draw_buffer *off_buf = + Fl_Wayland_Graphics_Driver::offscreen_buffer(offscreen); int height = off_buf->data_size / off_buf->stride; uchar *rgb = new uchar[off_buf->width * height * 3]; uchar *p = rgb; diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H index a28c58dd5..5e53e7813 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H @@ -146,7 +146,8 @@ public: int dnd(int unused) FL_OVERRIDE; int compose(int &del) FL_OVERRIDE; void compose_reset() FL_OVERRIDE; - Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, bool may_capture_subwins, bool *did_capture_subwins) FL_OVERRIDE; + Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, + bool may_capture_subwins, bool *did_capture_subwins) FL_OVERRIDE; int get_mouse(int &x, int &y) FL_OVERRIDE; void open_display_platform() FL_OVERRIDE; void close_display() FL_OVERRIDE; diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx index 9ccebc669..1e8f5500f 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx @@ -124,7 +124,8 @@ struct pointer_output { static Fl_Int_Vector key_vector; // used by Fl_Wayland_Screen_Driver::event_key() -Fl_Wayland_Screen_Driver::compositor_name Fl_Wayland_Screen_Driver::compositor = Fl_Wayland_Screen_Driver::unspecified; +Fl_Wayland_Screen_Driver::compositor_name Fl_Wayland_Screen_Driver::compositor = + Fl_Wayland_Screen_Driver::unspecified; extern "C" { @@ -133,11 +134,13 @@ extern "C" { } } + static void xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial) { xdg_wm_base_pong(xdg_wm_base, serial); } + static const struct xdg_wm_base_listener xdg_wm_base_listener = { .ping = xdg_wm_base_ping, }; @@ -150,8 +153,8 @@ extern const char *fl_bg2; // end of extern additions workaround -static void do_set_cursor(struct Fl_Wayland_Screen_Driver::seat *seat, struct wl_cursor *wl_cursor = NULL) -{ +static void do_set_cursor(struct Fl_Wayland_Screen_Driver::seat *seat, + struct wl_cursor *wl_cursor = NULL) { struct wl_cursor_image *image; struct wl_buffer *buffer; const int scale = seat->pointer_scale; @@ -173,6 +176,7 @@ static void do_set_cursor(struct Fl_Wayland_Screen_Driver::seat *seat, struct wl wl_surface_commit(seat->cursor_surface); } + static uint32_t ptime; static uint32_t wld_event_time; static int px, py; @@ -187,6 +191,7 @@ static void set_event_xy(Fl_Window *win) { } } + // if this is same event as last && is_click, increment click count: static inline void checkdouble() { if (Fl::e_is_click == Fl::e_keysym) { @@ -227,18 +232,15 @@ static Fl_Window *event_coords_from_surface(struct wl_surface *surface, } -static void pointer_enter(void *data, - struct wl_pointer *wl_pointer, - uint32_t serial, - struct wl_surface *surface, - wl_fixed_t surface_x, - wl_fixed_t surface_y) -{ +static void pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, + struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { Fl_Window *win = event_coords_from_surface(surface, surface_x, surface_y); if (!win) return; // use custom cursor if present - struct wl_cursor *cursor = fl_wl_xid(win)->custom_cursor ? fl_wl_xid(win)->custom_cursor->wl_cursor : NULL; - struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; + struct wl_cursor *cursor = + fl_wl_xid(win)->custom_cursor ? fl_wl_xid(win)->custom_cursor->wl_cursor : NULL; + struct Fl_Wayland_Screen_Driver::seat *seat = + (struct Fl_Wayland_Screen_Driver::seat*)data; do_set_cursor(seat, cursor); seat->serial = serial; seat->pointer_enter_serial = serial; @@ -249,11 +251,8 @@ static void pointer_enter(void *data, } -static void pointer_leave(void *data, - struct wl_pointer *wl_pointer, - uint32_t serial, - struct wl_surface *surface) -{ +static void pointer_leave(void *data, struct wl_pointer *wl_pointer, + uint32_t serial, struct wl_surface *surface) { struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; if (seat->pointer_focus == surface) seat->pointer_focus = NULL; Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(surface); @@ -266,13 +265,10 @@ static void pointer_leave(void *data, } -static void pointer_motion(void *data, - struct wl_pointer *wl_pointer, - uint32_t time, - wl_fixed_t surface_x, - wl_fixed_t surface_y) -{ - struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; +static void pointer_motion(void *data, struct wl_pointer *wl_pointer, + uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { + struct Fl_Wayland_Screen_Driver::seat *seat = + (struct Fl_Wayland_Screen_Driver::seat*)data; Fl_Window *win = event_coords_from_surface(seat->pointer_focus, surface_x, surface_y); if (!win) return; // If there's an active grab() and the pointer is in a window other than the grab(), @@ -295,14 +291,16 @@ static void pointer_button(void *data, uint32_t button, uint32_t state) { - struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; + struct Fl_Wayland_Screen_Driver::seat *seat = + (struct Fl_Wayland_Screen_Driver::seat*)data; seat->serial = serial; int event = 0; Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(seat->pointer_focus); if (!win) return; win = win->top_window(); wld_event_time = time; - if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED && seat->pointer_focus == NULL && + if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED && + seat->pointer_focus == NULL && (fl_wl_xid(win))->kind == Fl_Wayland_Window_Driver::DECORATED) { // click on titlebar libdecor_frame_move(fl_wl_xid(win)->frame, seat->wl_seat, serial); @@ -333,12 +331,9 @@ static void pointer_button(void *data, Fl::handle(event, win); } -static void pointer_axis(void *data, - struct wl_pointer *wl_pointer, - uint32_t time, - uint32_t axis, - wl_fixed_t value) -{ + +static void pointer_axis(void *data, struct wl_pointer *wl_pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) { struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(seat->pointer_focus); if (!win) return; @@ -369,6 +364,7 @@ static void pointer_axis(void *data, } } + static struct wl_pointer_listener pointer_listener = { pointer_enter, pointer_leave, @@ -377,17 +373,20 @@ static struct wl_pointer_listener pointer_listener = { pointer_axis }; + static const char *proxy_tag = "FLTK for Wayland"; + bool Fl_Wayland_Screen_Driver::own_output(struct wl_output *output) { return wl_proxy_get_tag((struct wl_proxy *)output) == &proxy_tag; } + static void init_cursors(struct Fl_Wayland_Screen_Driver::seat *seat); -static void try_update_cursor(struct Fl_Wayland_Screen_Driver::seat *seat) -{ + +static void try_update_cursor(struct Fl_Wayland_Screen_Driver::seat *seat) { if (wl_list_empty(&seat->pointer_outputs)) return; struct pointer_output *pointer_output; int scale = 1; @@ -408,22 +407,23 @@ static void output_scale(void *data, struct wl_output *wl_output, int32_t factor static void cursor_surface_enter(void *data, - struct wl_surface *wl_surface, - struct wl_output *wl_output) -{ + struct wl_surface *wl_surface, struct wl_output *wl_output) { // Runs when the seat's cursor_surface enters a display - struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; + struct Fl_Wayland_Screen_Driver::seat *seat = + (struct Fl_Wayland_Screen_Driver::seat*)data; struct pointer_output *pointer_output; if (!Fl_Wayland_Screen_Driver::own_output(wl_output)) return; pointer_output = (struct pointer_output *)calloc(1, sizeof(struct pointer_output)); - pointer_output->output = (Fl_Wayland_Screen_Driver::output *)wl_output_get_user_data(wl_output); + pointer_output->output = + (Fl_Wayland_Screen_Driver::output *)wl_output_get_user_data(wl_output); //fprintf(stderr, "cursor_surface_enter: wl_output_get_user_data(%p)=%p\n", wl_output, pointer_output->output); wl_list_insert(&seat->pointer_outputs, &pointer_output->link); try_update_cursor(seat); - Fl_Wayland_Screen_Driver::output *output = (Fl_Wayland_Screen_Driver::output*)wl_output_get_user_data(wl_output); + Fl_Wayland_Screen_Driver::output *output = + (Fl_Wayland_Screen_Driver::output*)wl_output_get_user_data(wl_output); output_scale(output, wl_output, output->wld_scale); // rescale custom cursors // maintain custom or standard window cursor Fl_Window *win = Fl::first_window(); @@ -437,13 +437,11 @@ static void cursor_surface_enter(void *data, } -static void cursor_surface_leave(void *data, - struct wl_surface *wl_surface, - struct wl_output *wl_output) -{ - struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; +static void cursor_surface_leave(void *data, struct wl_surface *wl_surface, + struct wl_output *wl_output) { + struct Fl_Wayland_Screen_Driver::seat *seat = + (struct Fl_Wayland_Screen_Driver::seat*)data; struct pointer_output *pointer_output, *tmp; - wl_list_for_each_safe(pointer_output, tmp, &seat->pointer_outputs, link) { if (pointer_output->output->wl_output == wl_output) { wl_list_remove(&pointer_output->link); @@ -457,17 +455,16 @@ static void cursor_surface_leave(void *data, struct wld_window *xid = fl_wl_xid(win); if (xid->custom_cursor) do_set_cursor(seat, xid->custom_cursor->wl_cursor); } - } + static struct wl_surface_listener cursor_surface_listener = { cursor_surface_enter, cursor_surface_leave, }; -static void init_cursors(struct Fl_Wayland_Screen_Driver::seat *seat) -{ +static void init_cursors(struct Fl_Wayland_Screen_Driver::seat *seat) { char *name; int size; struct wl_cursor_theme *theme; @@ -489,8 +486,10 @@ static void init_cursors(struct Fl_Wayland_Screen_Driver::seat *seat) } seat->cursor_theme = theme; } - if (seat->cursor_theme) - seat->default_cursor = scr_driver->xc_arrow = wl_cursor_theme_get_cursor(seat->cursor_theme, "left_ptr"); + if (seat->cursor_theme) { + seat->default_cursor = scr_driver->xc_arrow = + wl_cursor_theme_get_cursor(seat->cursor_theme, "left_ptr"); + } if (!seat->cursor_surface) { seat->cursor_surface = wl_compositor_create_surface(scr_driver->wl_compositor); wl_surface_add_listener(seat->cursor_surface, &cursor_surface_listener, seat); @@ -499,9 +498,9 @@ static void init_cursors(struct Fl_Wayland_Screen_Driver::seat *seat) static void wl_keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, - uint32_t format, int32_t fd, uint32_t size) -{ - struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; + uint32_t format, int32_t fd, uint32_t size) { + struct Fl_Wayland_Screen_Driver::seat *seat = + (struct Fl_Wayland_Screen_Driver::seat*)data; assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1); char *map_shm = (char*)mmap(NULL, size, PROT_READ, @@ -509,7 +508,7 @@ static void wl_keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, assert(map_shm != MAP_FAILED); struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_string(seat->xkb_context, map_shm, - XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); + XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); munmap(map_shm, size); close(fd); if (xkb_keymap) { @@ -558,10 +557,9 @@ static int process_wld_key(struct xkb_state *xkb_state, uint32_t key, static void wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface, - struct wl_array *keys) -{ - struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; + uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { + struct Fl_Wayland_Screen_Driver::seat *seat = + (struct Fl_Wayland_Screen_Driver::seat*)data; //fprintf(stderr, "keyboard enter fl_win=%p; keys pressed are: ", Fl_Wayland_Window_Driver::surface_to_window(surface)); key_vector.size(0); // Replace wl_array_for_each(p, keys) rejected by C++ @@ -570,7 +568,9 @@ static void wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, (p)++) { int for_key_vector = process_wld_key(seat->xkb_state, *p, NULL, NULL); //fprintf(stderr, "%d ", for_key_vector); - if (search_int_vector(key_vector, for_key_vector) < 0) key_vector.push_back(for_key_vector); + if (search_int_vector(key_vector, for_key_vector) < 0) { + key_vector.push_back(for_key_vector); + } } //fprintf(stderr, "\n"); seat->keyboard_surface = surface; @@ -582,28 +582,36 @@ static void wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, } } + struct key_repeat_data_t { uint32_t time; Fl_Window *window; }; + #define KEY_REPEAT_DELAY 0.5 // sec #define KEY_REPEAT_INTERVAL 0.05 // sec + static void key_repeat_timer_cb(key_repeat_data_t *key_repeat_data) { - if ((Fl::event() == FL_KEYDOWN || (Fl_Window_Driver::menu_parent() && Fl::event() == FL_ENTER)) && wld_event_time == key_repeat_data->time) { + if ((Fl::event() == FL_KEYDOWN || (Fl_Window_Driver::menu_parent() && + Fl::event() == FL_ENTER)) && wld_event_time == key_repeat_data->time) { Fl::handle(FL_KEYDOWN, key_repeat_data->window); - Fl::add_timeout(KEY_REPEAT_INTERVAL, (Fl_Timeout_Handler)key_repeat_timer_cb, key_repeat_data); + Fl::add_timeout(KEY_REPEAT_INTERVAL, (Fl_Timeout_Handler)key_repeat_timer_cb, + key_repeat_data); } else delete key_repeat_data; } + int Fl_Wayland_Screen_Driver::next_marked_length = 0; + int Fl_Wayland_Screen_Driver::has_marked_text() const { return 1; } + int Fl_Wayland_Screen_Driver::insertion_point_x = 0; int Fl_Wayland_Screen_Driver::insertion_point_y = 0; int Fl_Wayland_Screen_Driver::insertion_point_width = 0; @@ -630,8 +638,9 @@ void Fl_Wayland_Screen_Driver::insertion_point_location(int x, int y, int height insertion_point_width = s*5; insertion_point_height = s*height; if (zwp_text_input_v3_get_user_data(scr_driver->seat->text_input) ) { - zwp_text_input_v3_set_cursor_rectangle(scr_driver->seat->text_input, insertion_point_x, - insertion_point_y, insertion_point_width, insertion_point_height); + zwp_text_input_v3_set_cursor_rectangle(scr_driver->seat->text_input, + insertion_point_x, insertion_point_y, + insertion_point_width, insertion_point_height); zwp_text_input_v3_commit(scr_driver->seat->text_input); } } @@ -639,9 +648,9 @@ void Fl_Wayland_Screen_Driver::insertion_point_location(int x, int y, int height // computes window coordinates & size of insertion point -bool Fl_Wayland_Screen_Driver::insertion_point_location(int *px, int *py, int *pwidth, int *pheight) -// return true if the current coordinates and size of the insertion point are available -{ +bool Fl_Wayland_Screen_Driver::insertion_point_location(int *px, int *py, + int *pwidth, int *pheight) { + // return true if the current coordinates and size of the insertion point are available if ( ! insertion_point_location_is_valid ) return false; *px = insertion_point_x; *py = insertion_point_y; @@ -650,10 +659,13 @@ bool Fl_Wayland_Screen_Driver::insertion_point_location(int *px, int *py, int *p return true; } + int Fl_Wayland_Screen_Driver::compose(int& del) { unsigned char ascii = (unsigned char)Fl::e_text[0]; - int condition = (Fl::e_state & (FL_ALT | FL_META | FL_CTRL)) && ascii < 128 ; // letter+modifier key - condition |= (Fl::e_keysym >= FL_Shift_L && Fl::e_keysym <= FL_Alt_R); // pressing modifier key + // letter+modifier key + int condition = (Fl::e_state & (FL_ALT | FL_META | FL_CTRL)) && ascii < 128 ; + // pressing modifier key + condition |= (Fl::e_keysym >= FL_Shift_L && Fl::e_keysym <= FL_Alt_R); condition |= (Fl::e_keysym >= FL_Home && Fl::e_keysym <= FL_Help); condition |= Fl::e_keysym == FL_Tab; //fprintf(stderr, "compose: condition=%d e_state=%x ascii=%d\n", condition, Fl::e_state, ascii); @@ -666,19 +678,21 @@ int Fl_Wayland_Screen_Driver::compose(int& del) { return 1; } -void Fl_Wayland_Screen_Driver::compose_reset() -{ + +void Fl_Wayland_Screen_Driver::compose_reset() { if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl::compose_state = 0; next_marked_length = 0; xkb_compose_state_reset(seat->xkb_compose_state); } + struct dead_key_struct { xkb_keysym_t keysym; // the keysym obtained when hitting a dead key const char *marked_text; // the temporary text to display for that dead key }; + static dead_key_struct dead_keys[] = { {XKB_KEY_dead_grave, "`"}, {XKB_KEY_dead_acute, "´"}, @@ -697,13 +711,14 @@ static dead_key_struct dead_keys[] = { {XKB_KEY_dead_doublegrave, " ̏"}, }; + const int dead_key_count = sizeof(dead_keys)/sizeof(struct dead_key_struct); static void wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, uint32_t time, uint32_t key, uint32_t state) -{ - struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; + uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { + struct Fl_Wayland_Screen_Driver::seat *seat = + (struct Fl_Wayland_Screen_Driver::seat*)data; seat->serial = serial; static char buf[128]; uint32_t keycode; @@ -716,7 +731,9 @@ fprintf(stderr, "key %s: sym: %-12s(%d) code:%u fl_win=%p, ", action, buf, sym, //fprintf(stderr, "utf8: '%s' e_length=%d [%d]\n", buf, (int)strlen(buf), *buf); Fl::e_keysym = for_key_vector; if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { - if (search_int_vector(key_vector, for_key_vector) < 0) key_vector.push_back(for_key_vector); + if (search_int_vector(key_vector, for_key_vector) < 0) { + key_vector.push_back(for_key_vector); + } } else { remove_int_vector(key_vector, for_key_vector); } @@ -758,23 +775,26 @@ fprintf(stderr, "key %s: sym: %-12s(%d) code:%u fl_win=%p, ", action, buf, sym, int event = (state == WL_KEYBOARD_KEY_STATE_PRESSED ? FL_KEYDOWN : FL_KEYUP); // Send event to focus-containing top window as defined by FLTK, // otherwise send it to Wayland-defined focus window - Fl_Window *win = ( Fl::focus() ? Fl::focus()->top_window() : Fl_Wayland_Window_Driver::surface_to_window(seat->keyboard_surface) ); + Fl_Window *win = ( Fl::focus() ? Fl::focus()->top_window() : + Fl_Wayland_Window_Driver::surface_to_window(seat->keyboard_surface) ); if (win) { set_event_xy(win); Fl::e_is_click = 0; Fl::handle(event, win); } - if (event == FL_KEYDOWN && status == XKB_COMPOSE_NOTHING && !(sym >= FL_Shift_L && sym <= FL_Alt_R)) { + if (event == FL_KEYDOWN && status == XKB_COMPOSE_NOTHING && + !(sym >= FL_Shift_L && sym <= FL_Alt_R)) { key_repeat_data_t *key_repeat_data = new key_repeat_data_t; key_repeat_data->time = time; key_repeat_data->window = win; - Fl::add_timeout(KEY_REPEAT_DELAY, (Fl_Timeout_Handler)key_repeat_timer_cb, key_repeat_data); + Fl::add_timeout(KEY_REPEAT_DELAY, (Fl_Timeout_Handler)key_repeat_timer_cb, + key_repeat_data); } } + static void wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface) -{ + uint32_t serial, struct wl_surface *surface) { struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; //fprintf(stderr, "keyboard leave fl_win=%p\n", Fl_Wayland_Window_Driver::surface_to_window(surface)); seat->keyboard_surface = NULL; @@ -784,32 +804,36 @@ static void wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, key_vector.size(0); } + static void wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) -{ - struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; - xkb_state_update_mask(seat->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group); + uint32_t group) { + struct Fl_Wayland_Screen_Driver::seat *seat = + (struct Fl_Wayland_Screen_Driver::seat*)data; + xkb_state_update_mask(seat->xkb_state, mods_depressed, mods_latched, mods_locked, + 0, 0, group); Fl::e_state &= ~(FL_SHIFT+FL_CTRL+FL_ALT+FL_CAPS_LOCK+FL_NUM_LOCK); - if (xkb_state_mod_name_is_active(seat->xkb_state, XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_DEPRESSED)) - Fl::e_state |= FL_SHIFT; - if (xkb_state_mod_name_is_active(seat->xkb_state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_DEPRESSED)) - Fl::e_state |= FL_CTRL; - if (xkb_state_mod_name_is_active(seat->xkb_state, XKB_MOD_NAME_ALT, XKB_STATE_MODS_DEPRESSED)) - Fl::e_state |= FL_ALT; - if (xkb_state_mod_name_is_active(seat->xkb_state, XKB_MOD_NAME_CAPS, XKB_STATE_MODS_LOCKED)) - Fl::e_state |= FL_CAPS_LOCK; - if (xkb_state_mod_name_is_active(seat->xkb_state, XKB_MOD_NAME_NUM, XKB_STATE_MODS_LOCKED)) - Fl::e_state |= FL_NUM_LOCK; + if (xkb_state_mod_name_is_active(seat->xkb_state, XKB_MOD_NAME_SHIFT, + XKB_STATE_MODS_DEPRESSED)) Fl::e_state |= FL_SHIFT; + if (xkb_state_mod_name_is_active(seat->xkb_state, XKB_MOD_NAME_CTRL, + XKB_STATE_MODS_DEPRESSED)) Fl::e_state |= FL_CTRL; + if (xkb_state_mod_name_is_active(seat->xkb_state, XKB_MOD_NAME_ALT, + XKB_STATE_MODS_DEPRESSED)) Fl::e_state |= FL_ALT; + if (xkb_state_mod_name_is_active(seat->xkb_state, XKB_MOD_NAME_CAPS, + XKB_STATE_MODS_LOCKED)) Fl::e_state |= FL_CAPS_LOCK; + if (xkb_state_mod_name_is_active(seat->xkb_state, XKB_MOD_NAME_NUM, + XKB_STATE_MODS_LOCKED)) Fl::e_state |= FL_NUM_LOCK; //fprintf(stderr, "mods_depressed=%u Fl::e_state=%X\n", mods_depressed, Fl::e_state); } + static void wl_keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay) { // wl_keyboard is version 3 under Debian, but that event isn't sent until version 4 } + static const struct wl_keyboard_listener wl_keyboard_listener = { .keymap = wl_keyboard_keymap, .enter = wl_keyboard_enter, @@ -833,6 +857,7 @@ void text_input_enter(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, wl_display_roundtrip(Fl_Wayland_Screen_Driver::wl_display); } + void text_input_leave(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, struct wl_surface *surface) { //puts("text_input_leave"); @@ -841,6 +866,7 @@ void text_input_leave(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, zwp_text_input_v3_commit(zwp_text_input_v3); } + void text_input_preedit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text, int32_t cursor_begin, int32_t cursor_end) { //printf("text_input_preedit_string %s cursor_begin=%d cursor_end=%d\n",text, cursor_begin, cursor_end); @@ -856,6 +882,7 @@ void text_input_preedit_string(void *data, struct zwp_text_input_v3 *zwp_text_in Fl::handle(FL_KEYDOWN, win); } + void text_input_commit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text) { //printf("text_input_commit_string %s\n",text); @@ -871,16 +898,21 @@ void text_input_commit_string(void *data, struct zwp_text_input_v3 *zwp_text_inp Fl::compose_state = 0; } -void text_input_delete_surrounding_text(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, - uint32_t before_length, uint32_t after_length) { - fprintf(stderr, "delete_surrounding_text before=%d adfter=%d\n",before_length,after_length); + +void text_input_delete_surrounding_text(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + uint32_t before_length, uint32_t after_length) { + fprintf(stderr, "delete_surrounding_text before=%d adfter=%d\n", + before_length,after_length); } + void text_input_done(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t serial) { //puts("text_input_done"); } + static const struct zwp_text_input_v3_listener text_input_listener = { .enter = text_input_enter, .leave = text_input_leave, @@ -893,7 +925,8 @@ static const struct zwp_text_input_v3_listener text_input_listener = { void Fl_Wayland_Screen_Driver::enable_im() { if (text_input_base && !seat->text_input) { - seat->text_input = zwp_text_input_manager_v3_get_text_input(text_input_base, seat->wl_seat); + seat->text_input = zwp_text_input_manager_v3_get_text_input(text_input_base, + seat->wl_seat); //printf("seat->text_input=%p\n",seat->text_input); zwp_text_input_v3_add_listener(seat->text_input, &text_input_listener, NULL); } @@ -912,7 +945,8 @@ void Fl_Wayland_Screen_Driver::disable_im() { static void seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities) { - struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; + struct Fl_Wayland_Screen_Driver::seat *seat = + (struct Fl_Wayland_Screen_Driver::seat*)data; if ((capabilities & WL_SEAT_CAPABILITY_POINTER) && !seat->wl_pointer) { seat->wl_pointer = wl_seat_get_pointer(wl_seat); wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, seat); @@ -938,16 +972,19 @@ static void seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capa scr_driver->enable_im(); } + static void seat_name(void *data, struct wl_seat *wl_seat, const char *name) { struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; seat->name = strdup(name); } + static struct wl_seat_listener seat_listener = { seat_capabilities, seat_name }; + static void output_geometry(void *data, struct wl_output *wl_output, int32_t x, @@ -966,6 +1003,7 @@ static void output_geometry(void *data, output->dpi = 96; // to elaborate } + static void output_mode(void *data, struct wl_output *wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) { @@ -975,6 +1013,7 @@ static void output_mode(void *data, struct wl_output *wl_output, uint32_t flags, //fprintf(stderr, "output_mode: [%p]=%dx%d\n",output->wl_output,width,height); } + static void output_done(void *data, struct wl_output *wl_output) { // Runs at startup and when desktop scale factor is changed @@ -1060,12 +1099,16 @@ static void registry_handle_global(void *user_data, struct wl_registry *wl_regis } else if (strcmp(interface, "wl_seat") == 0) { if (version < 2) { - Fl::fatal("%s version 2 required but only version %i is available\n", interface, version); + Fl::fatal("%s version 2 required but only version %i is available\n", + interface, version); } - if (!scr_driver->seat) scr_driver->seat = (struct Fl_Wayland_Screen_Driver::seat*)calloc(1, sizeof(struct Fl_Wayland_Screen_Driver::seat)); + if (!scr_driver->seat) scr_driver->seat = + (struct Fl_Wayland_Screen_Driver::seat*)calloc(1, + sizeof(struct Fl_Wayland_Screen_Driver::seat)); //fprintf(stderr, "registry_handle_global: seat=%p\n", scr_driver->seat); wl_list_init(&scr_driver->seat->pointer_outputs); - scr_driver->seat->wl_seat = (wl_seat*)wl_registry_bind(wl_registry, id, &wl_seat_interface, 2); + scr_driver->seat->wl_seat = (wl_seat*)wl_registry_bind(wl_registry, id, + &wl_seat_interface, 2); scr_driver->seat->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (scr_driver->seat->xkb_context) { const char *locale = getenv("LC_ALL"); @@ -1075,29 +1118,47 @@ static void registry_handle_global(void *user_data, struct wl_registry *wl_regis locale = getenv("LANG"); if (!locale || !*locale) locale = "C"; - struct xkb_compose_table *table = xkb_compose_table_new_from_locale(scr_driver->seat->xkb_context, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); - if (table) scr_driver->seat->xkb_compose_state = xkb_compose_state_new(table, XKB_COMPOSE_STATE_NO_FLAGS); + struct xkb_compose_table *table = + xkb_compose_table_new_from_locale(scr_driver->seat->xkb_context, locale, + XKB_COMPOSE_COMPILE_NO_FLAGS); + if (table) { + scr_driver->seat->xkb_compose_state = + xkb_compose_state_new(table, XKB_COMPOSE_STATE_NO_FLAGS); + } } wl_seat_add_listener(scr_driver->seat->wl_seat, &seat_listener, scr_driver->seat); if (scr_driver->seat->data_device_manager) { - scr_driver->seat->data_device = wl_data_device_manager_get_data_device(scr_driver->seat->data_device_manager, scr_driver->seat->wl_seat); - wl_data_device_add_listener(scr_driver->seat->data_device, Fl_Wayland_Screen_Driver::p_data_device_listener, NULL); + scr_driver->seat->data_device = + wl_data_device_manager_get_data_device(scr_driver->seat->data_device_manager, + scr_driver->seat->wl_seat); + wl_data_device_add_listener(scr_driver->seat->data_device, + Fl_Wayland_Screen_Driver::p_data_device_listener, NULL); } } else if (strcmp(interface, wl_data_device_manager_interface.name) == 0) { - if (!scr_driver->seat) scr_driver->seat = (struct Fl_Wayland_Screen_Driver::seat*)calloc(1, sizeof(struct Fl_Wayland_Screen_Driver::seat)); - scr_driver->seat->data_device_manager = (struct wl_data_device_manager*)wl_registry_bind(wl_registry, id, &wl_data_device_manager_interface, fl_min(version, 3)); + if (!scr_driver->seat) scr_driver->seat = + (struct Fl_Wayland_Screen_Driver::seat*)calloc(1, + sizeof(struct Fl_Wayland_Screen_Driver::seat)); + scr_driver->seat->data_device_manager = + (struct wl_data_device_manager*)wl_registry_bind(wl_registry, id, + &wl_data_device_manager_interface, + fl_min(version, 3)); if (scr_driver->seat->wl_seat) { - scr_driver->seat->data_device = wl_data_device_manager_get_data_device(scr_driver->seat->data_device_manager, scr_driver->seat->wl_seat); - wl_data_device_add_listener(scr_driver->seat->data_device, Fl_Wayland_Screen_Driver::p_data_device_listener, NULL); + scr_driver->seat->data_device = + wl_data_device_manager_get_data_device(scr_driver->seat->data_device_manager, + scr_driver->seat->wl_seat); + wl_data_device_add_listener(scr_driver->seat->data_device, + Fl_Wayland_Screen_Driver::p_data_device_listener, NULL); } //fprintf(stderr, "registry_handle_global: %s\n", interface); } else if (strcmp(interface, "wl_output") == 0) { if (version < 2) { - Fl::fatal("%s version 2 required but only version %i is available\n", interface, version); + Fl::fatal("%s version 2 required but only version %i is available\n", + interface, version); } - Fl_Wayland_Screen_Driver::output *output = (Fl_Wayland_Screen_Driver::output*)calloc(1, sizeof *output); + Fl_Wayland_Screen_Driver::output *output = + (Fl_Wayland_Screen_Driver::output*)calloc(1, sizeof *output); output->id = id; output->wld_scale = 1; output->wl_output = (struct wl_output*)wl_registry_bind(wl_registry, @@ -1111,8 +1172,9 @@ static void registry_handle_global(void *user_data, struct wl_registry *wl_regis } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { //fprintf(stderr, "registry_handle_global interface=%s\n", interface); - scr_driver->xdg_wm_base = (struct xdg_wm_base *)wl_registry_bind(wl_registry, id, &xdg_wm_base_interface, 1); - xdg_wm_base_add_listener(scr_driver->xdg_wm_base, &xdg_wm_base_listener, NULL); + scr_driver->xdg_wm_base = (struct xdg_wm_base *)wl_registry_bind(wl_registry, id, + &xdg_wm_base_interface, 1); + xdg_wm_base_add_listener(scr_driver->xdg_wm_base, &xdg_wm_base_listener, NULL); } else if (strcmp(interface, "gtk_shell1") == 0) { Fl_Wayland_Screen_Driver::compositor = Fl_Wayland_Screen_Driver::MUTTER; //fprintf(stderr, "Running the Mutter compositor\n"); @@ -1126,7 +1188,8 @@ static void registry_handle_global(void *user_data, struct wl_registry *wl_regis Fl_Wayland_Screen_Driver::compositor = Fl_Wayland_Screen_Driver::OWL; //fprintf(stderr, "Running the Owl compositor\n"); if (wl_list_length(&scr_driver->outputs) == 0) { - Fl_Wayland_Screen_Driver::output *output = (Fl_Wayland_Screen_Driver::output*)calloc(1, sizeof *output); + Fl_Wayland_Screen_Driver::output *output = + (Fl_Wayland_Screen_Driver::output*)calloc(1, sizeof *output); output->id = 1; output->wld_scale = 1; output->gui_scale = 1.f; @@ -1136,18 +1199,18 @@ static void registry_handle_global(void *user_data, struct wl_registry *wl_regis scr_driver->screen_count_set(1); } } else if (strcmp(interface, zwp_text_input_manager_v3_interface.name) == 0) { - scr_driver->text_input_base = (struct zwp_text_input_manager_v3 *) wl_registry_bind(wl_registry, id, &zwp_text_input_manager_v3_interface, 1); - //printf("scr_driver->text_input_base=%p version=%d\n",scr_driver->text_input_base,version); + scr_driver->text_input_base = (struct zwp_text_input_manager_v3 *) + wl_registry_bind(wl_registry, id, &zwp_text_input_manager_v3_interface, 1); +//printf("scr_driver->text_input_base=%p version=%d\n",scr_driver->text_input_base,version); } } -static void registry_handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) -{//TODO to be tested +static void registry_handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) {//TODO to be tested Fl_Wayland_Screen_Driver::output *output, *tmp; //fprintf(stderr, "registry_handle_global_remove data=%p id=%u\n", data, name); Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); - wl_list_for_each_safe(output, tmp, &(scr_driver->outputs), link) { // all screens of the system + wl_list_for_each_safe(output, tmp, &(scr_driver->outputs), link) { // all screens if (output->id == name) { // the screen being removed again: Fl_X *xp = Fl_X::first; @@ -1301,7 +1364,8 @@ void Fl_Wayland_Screen_Driver::close_display() { seat->data_source = NULL; } wl_data_device_destroy(seat->data_device); seat->data_device = NULL; - wl_data_device_manager_destroy(seat->data_device_manager); seat->data_device_manager = NULL; + wl_data_device_manager_destroy(seat->data_device_manager); + seat->data_device_manager = NULL; wl_seat_destroy(seat->wl_seat); seat->wl_seat = NULL; if (seat->name) free(seat->name); delete seat; seat = NULL; @@ -1345,6 +1409,7 @@ int Fl_Wayland_Screen_Driver::x() { return workarea_xywh[0] / (output->gui_scale * output->wld_scale); } + int Fl_Wayland_Screen_Driver::y() { if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl_Wayland_Screen_Driver::output *output; @@ -1354,6 +1419,7 @@ int Fl_Wayland_Screen_Driver::y() { return workarea_xywh[1] / (output->gui_scale * output->wld_scale); } + int Fl_Wayland_Screen_Driver::w() { if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl_Wayland_Screen_Driver::output *output; @@ -1363,6 +1429,7 @@ int Fl_Wayland_Screen_Driver::w() { return workarea_xywh[2] / (output->gui_scale * output->wld_scale); } + int Fl_Wayland_Screen_Driver::h() { if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl_Wayland_Screen_Driver::output *output; @@ -1477,8 +1544,9 @@ static void set_selection_color(uchar r, uchar g, uchar b) Fl::set_color(FL_SELECTION_COLOR,r,g,b); } -static void getsyscolor(const char *key1, const char* key2, const char *arg, const char *defarg, void (*func)(uchar,uchar,uchar)) -{ + +static void getsyscolor(const char *key1, const char* key2, const char *arg, + const char *defarg, void (*func)(uchar,uchar,uchar)) { uchar r, g, b; if (!arg) arg = defarg; if (!Fl::screen_driver()->parse_color(arg, r, g, b)) @@ -1504,7 +1572,8 @@ void Fl_Wayland_Screen_Driver::get_system_colors() } -Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, +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) { struct wld_window* xid = win ? fl_wl_xid(win) : NULL; if (win && (!xid || !xid->buffer)) return NULL; @@ -1579,37 +1648,45 @@ void Fl_Wayland_Screen_Driver::set_cursor() { do_set_cursor(seat); } + struct wl_cursor *Fl_Wayland_Screen_Driver::default_cursor() { return seat->default_cursor; } + void Fl_Wayland_Screen_Driver::default_cursor(struct wl_cursor *cursor) { seat->default_cursor = cursor; do_set_cursor(seat); } + struct wl_cursor *Fl_Wayland_Screen_Driver::cache_cursor(const char *cursor_name) { return wl_cursor_theme_get_cursor(seat->cursor_theme, cursor_name); } + void Fl_Wayland_Screen_Driver::reset_cursor() { xc_arrow = xc_ns = xc_wait = xc_insert = xc_hand = xc_help = xc_cross = xc_move = xc_north = xc_south = xc_west = xc_east = xc_we = xc_nesw = xc_nwse = xc_sw = xc_se = xc_ne = xc_nw = NULL; } + uint32_t Fl_Wayland_Screen_Driver::get_serial() { return seat->serial; } + struct wl_seat*Fl_Wayland_Screen_Driver::get_wl_seat() { return seat->wl_seat; } + char *Fl_Wayland_Screen_Driver::get_seat_name() { return seat->name; } + struct xkb_keymap *Fl_Wayland_Screen_Driver::get_xkb_keymap() { return seat->xkb_keymap; } @@ -1674,7 +1751,8 @@ void *Fl_Wayland_Screen_Driver::control_maximize_button(void *data) { Fl_Window *win = Fl::first_window(); while (win) { if (!win->parent() && win->border() && - !( ((struct wld_window*)Fl_X::flx(win)->xid)->state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ) { + !( ((struct wld_window*)Fl_X::flx(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.H b/src/drivers/Wayland/Fl_Wayland_Window_Driver.H index c3a8f41a3..03c0a41d3 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.H @@ -56,7 +56,7 @@ private: Fl_Image* shape_; ///< shape image cairo_pattern_t *mask_pattern_; } *shape_data_; - cairo_rectangle_int_t *subRect_; // makes sure subwindow remains inside its parent window + cairo_rectangle_int_t *subRect_; // makes sure subwindow remains inside its parent window static bool in_flush_; // useful for progressive window drawing Fl_Cursor standard_cursor_; // window's standard custom kind void delete_cursor_(struct wld_window *, bool delete_rgb = true); @@ -88,7 +88,9 @@ public: static struct wld_window *wld_window; static Fl_Window *surface_to_window(struct wl_surface *); - static inline Fl_Wayland_Window_Driver* driver(const Fl_Window *w) {return (Fl_Wayland_Window_Driver*)Fl_Window_Driver::driver(w);} + static inline Fl_Wayland_Window_Driver* driver(const Fl_Window *w) { + return (Fl_Wayland_Window_Driver*)Fl_Window_Driver::driver(w); + } static void resize_after_screen_change(void *data); static Fl_Wayland_Plugin *gl_plugin(); @@ -122,8 +124,10 @@ public: int set_cursor_4args(const Fl_RGB_Image*, int, int, bool); void shape(const Fl_Image* img) FL_OVERRIDE; - void capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_RGB_Image*& left, Fl_RGB_Image*& bottom, Fl_RGB_Image*& right) FL_OVERRIDE; - int 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) FL_OVERRIDE; + void capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_RGB_Image*& left, + Fl_RGB_Image*& bottom, Fl_RGB_Image*& right) FL_OVERRIDE; + int 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) FL_OVERRIDE; void wait_for_expose() FL_OVERRIDE; // menu-related stuff void reposition_menu_window(int x, int y) FL_OVERRIDE; diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 37a470b01..a15fc4f80 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -78,8 +78,8 @@ void Fl_Wayland_Window_Driver::delete_cursor_(struct wld_window *xid, bool delet struct wl_cursor *wl_cursor = custom->wl_cursor; struct cursor_image *new_image = (struct cursor_image*)wl_cursor->images[0]; struct Fl_Wayland_Graphics_Driver::wld_buffer *offscreen = - (struct Fl_Wayland_Graphics_Driver::wld_buffer *) - wl_buffer_get_user_data(new_image->buffer); + (struct Fl_Wayland_Graphics_Driver::wld_buffer *) + wl_buffer_get_user_data(new_image->buffer); struct wld_window fake_xid; fake_xid.buffer = offscreen; Fl_Wayland_Graphics_Driver::buffer_release(&fake_xid); @@ -88,7 +88,9 @@ void Fl_Wayland_Window_Driver::delete_cursor_(struct wld_window *xid, bool delet free(wl_cursor->name); free(wl_cursor); Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); - if (scr_driver->default_cursor() == wl_cursor) scr_driver->default_cursor(scr_driver->xc_arrow); + if (scr_driver->default_cursor() == wl_cursor) { + scr_driver->default_cursor(scr_driver->xc_arrow); + } if (delete_rgb) delete custom->rgb; delete custom; xid->custom_cursor = NULL; @@ -113,8 +115,6 @@ Fl_Wayland_Window_Driver::~Fl_Wayland_Window_Driver() } -// --- private - void Fl_Wayland_Window_Driver::decorated_win_size(int &w, int &h) { Fl_Window *win = pWindow; @@ -128,8 +128,6 @@ void Fl_Wayland_Window_Driver::decorated_win_size(int &w, int &h) } -// --- window data - int Fl_Wayland_Window_Driver::decorated_h() { int w, h; @@ -137,6 +135,7 @@ int Fl_Wayland_Window_Driver::decorated_h() return h; } + int Fl_Wayland_Window_Driver::decorated_w() { int w, h; @@ -144,6 +143,7 @@ int Fl_Wayland_Window_Driver::decorated_w() return w; } + struct xdg_toplevel *Fl_Wayland_Window_Driver::xdg_toplevel() { struct wld_window * w = fl_wl_xid(pWindow); struct xdg_toplevel *top = NULL; @@ -152,6 +152,7 @@ struct xdg_toplevel *Fl_Wayland_Window_Driver::xdg_toplevel() { return top; } + void Fl_Wayland_Window_Driver::take_focus() { struct wld_window *w = fl_wl_xid(pWindow); @@ -160,7 +161,8 @@ void Fl_Wayland_Window_Driver::take_focus() 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()); + Fl_Wayland_Window_Driver *top_dr = + Fl_Wayland_Window_Driver::driver(old_first->top_window()); xdg_toplevel_set_parent(xdg_toplevel(), top_dr->xdg_toplevel()); // this will remove the parent-child relationship old_first->wait_for_expose(); @@ -219,7 +221,7 @@ void Fl_Wayland_Window_Driver::shape_alpha_(Fl_Image* img, int offset) { uchar byte, onebit; // build a CAIRO_FORMAT_A1 surface covering the non-fully transparent/black part of the image uchar* bits = new uchar[h*bytesperrow]; // to store the surface data - const uchar* alpha = (const uchar*)*img->data() + offset; // points to alpha value of rgba pixels + const uchar* alpha = (const uchar*)*img->data() + offset; // points to alpha value of pixels for (i = 0; i < h; i++) { uchar *p = (uchar*)bits + i * bytesperrow; byte = 0; @@ -243,7 +245,8 @@ void Fl_Wayland_Window_Driver::shape_alpha_(Fl_Image* img, int offset) { alpha += d; // point to alpha value of next img pixel } } - cairo_surface_t *mask_surf = cairo_image_surface_create_for_data(bits, CAIRO_FORMAT_A1, w, h, bytesperrow); + cairo_surface_t *mask_surf = cairo_image_surface_create_for_data(bits, CAIRO_FORMAT_A1, + w, h, bytesperrow); shape_data_->mask_pattern_ = cairo_pattern_create_for_surface(mask_surf); cairo_surface_destroy(mask_surf); shape_data_->shape_ = img; @@ -251,6 +254,7 @@ void Fl_Wayland_Window_Driver::shape_alpha_(Fl_Image* img, int offset) { shape_data_->lh_ = h; } + void Fl_Wayland_Window_Driver::shape(const Fl_Image* img) { if (shape_data_) { if (shape_data_->mask_pattern_) { @@ -276,6 +280,7 @@ void Fl_Wayland_Window_Driver::shape(const Fl_Image* img) { else if ((d == 1 || d == 3) && img->count() == 1) shape_alpha_((Fl_Image*)img, 0); } + void Fl_Wayland_Window_Driver::draw_end() { if (shape_data_ && shape_data_->mask_pattern_) { @@ -298,7 +303,8 @@ void Fl_Wayland_Window_Driver::draw_end() Returned images can be deleted after use. Their depth and size may be platform-dependent. The top and bottom images extend from left of the left border to right of the right border. */ -void Fl_Wayland_Window_Driver::capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_RGB_Image*& left, Fl_RGB_Image*& bottom, Fl_RGB_Image*& right) +void Fl_Wayland_Window_Driver::capture_titlebar_and_borders(Fl_RGB_Image*& top, + Fl_RGB_Image*& left, Fl_RGB_Image*& bottom, Fl_RGB_Image*& right) { top = left = bottom = right = NULL; if (pWindow->decorated_h() == h()) return; @@ -354,7 +360,8 @@ void Fl_Wayland_Window_Driver::make_current() { ((Fl_Cairo_Graphics_Driver*)fl_graphics_driver)->needs_commit_tag( &window->buffer->draw_buffer_needs_commit); } - ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_cairo(window->buffer->draw_buffer.cairo_, f * wld_s); + ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_cairo( + window->buffer->draw_buffer.cairo_, f * wld_s); int *poffset = Fl_Window_Driver::menu_offset_y(pWindow); if (poffset) { // for tall menu windows under KWIN to offset drawing inside window cairo_translate(window->buffer->draw_buffer.cairo_, 0, *poffset); @@ -362,7 +369,7 @@ void Fl_Wayland_Window_Driver::make_current() { cairo_rectangle_int_t *extents = subRect(); if (extents) { // make damage-to-buffer not to leak outside parent Fl_Region clip_region = fl_graphics_driver->XRectangleRegion(extents->x, extents->y, - extents->width, extents->height); + extents->width, extents->height); //printf("make_current: %dx%d %dx%d\n",extents->x, extents->y, extents->width, extents->height); Fl_X::flx(pWindow)->region = clip_region; } @@ -385,7 +392,9 @@ void Fl_Wayland_Window_Driver::flush() { Fl_Window_Driver::flush(); Fl_Wayland_Window_Driver::in_flush_ = false; gl_plugin()->do_swap(pWindow); // useful only for GL win with overlay - if (scale != fl_graphics_driver->scale() || W != pWindow->w() || H != pWindow->h()) gl_plugin()->invalidate(pWindow); + if (scale != fl_graphics_driver->scale() || W != pWindow->w() || H != pWindow->h()) { + gl_plugin()->invalidate(pWindow); + } return; } struct wld_window *window = fl_wl_xid(pWindow); @@ -435,7 +444,6 @@ void Fl_Wayland_Window_Driver::hide() { 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); if (wld_win->kind == SUBWINDOW && wld_win->subsurface) { wl_subsurface_destroy(wld_win->subsurface); wld_win->subsurface = NULL; @@ -470,8 +478,9 @@ void Fl_Wayland_Window_Driver::hide() { wl_list_remove(&s_output->link); free(s_output); } - if (Fl_Wayland_Window_Driver::wld_window == wld_win) Fl_Wayland_Window_Driver::wld_window = NULL; -//fprintf(stderr, "After 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); + if (Fl_Wayland_Window_Driver::wld_window == wld_win) { + Fl_Wayland_Window_Driver::wld_window = NULL; + } free(wld_win); } delete ip; @@ -485,7 +494,8 @@ void Fl_Wayland_Window_Driver::map() { 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); + wl_win->subsurface = wl_subcompositor_get_subsurface(scr_driver->wl_subcompositor, + wl_win->wl_surface, parent->wl_surface); float f = Fl::screen_scale(pWindow->top_window()->screen_num()); wl_subsurface_set_position(wl_win->subsurface, pWindow->x() * f, pWindow->y() * f); wl_subsurface_set_desync(wl_win->subsurface); // important @@ -556,7 +566,8 @@ void Fl_Wayland_Window_Driver::iconize() { } -void Fl_Wayland_Window_Driver::decoration_sizes(int *top, int *left, int *right, int *bottom) { +void Fl_Wayland_Window_Driver::decoration_sizes(int *top, int *left, int *right, int *bottom) +{ struct wld_window *xid = (struct wld_window*)fl_xid(pWindow); if (xid && xid->kind == DECORATED) { libdecor_frame_translate_coordinate(xid->frame, 0, 0, left, top); @@ -568,8 +579,9 @@ 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) +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) { struct wld_window * xid = fl_wl_xid(pWindow); struct Fl_Wayland_Graphics_Driver::wld_buffer *buffer = xid->buffer; @@ -590,8 +602,10 @@ int Fl_Wayland_Window_Driver::scroll(int src_x, int src_y, int src_w, int src_h, i = src_h - 1; to = -1; step = -1; } while (i != to) { - memcpy(buffer->draw_buffer.buffer + (dest_y + i) * buffer->draw_buffer.stride + 4 * dest_x, - buffer->draw_buffer.buffer + (src_y + i) * buffer->draw_buffer.stride + 4 * src_x, 4 * src_w); + memcpy( + buffer->draw_buffer.buffer + (dest_y + i) * buffer->draw_buffer.stride + 4 * dest_x, + buffer->draw_buffer.buffer + (src_y + i) * buffer->draw_buffer.stride + 4 * src_x, + 4 * src_w); i += step; } } else { // horizontal scroll @@ -602,8 +616,10 @@ int Fl_Wayland_Window_Driver::scroll(int src_x, int src_y, int src_w, int src_h, i = src_h - 1; to = -1; step = -1; } while (i != to) { - memmove(buffer->draw_buffer.buffer + (src_y + i) * buffer->draw_buffer.stride + 4 * dest_x, - buffer->draw_buffer.buffer + (src_y + i) * buffer->draw_buffer.stride + 4 * src_x, 4 * src_w); + memmove( + buffer->draw_buffer.buffer + (src_y + i) * buffer->draw_buffer.stride + 4 * dest_x, + buffer->draw_buffer.buffer + (src_y + i) * buffer->draw_buffer.stride + 4 * src_x, + 4 * src_w); i += step; } } @@ -616,6 +632,7 @@ static void handle_error(struct libdecor *libdecor_context, enum libdecor_error Fl::fatal("Caught error (%d): %s\n", error, message); } + static struct libdecor_interface libdecor_iface = { .error = handle_error, }; @@ -661,7 +678,8 @@ static void surface_enter(void *data, struct wl_surface *wl_surface, if (!Fl_Wayland_Screen_Driver::own_output(wl_output)) return; - Fl_Wayland_Screen_Driver::output *output = (Fl_Wayland_Screen_Driver::output*)wl_output_get_user_data(wl_output); + Fl_Wayland_Screen_Driver::output *output = + (Fl_Wayland_Screen_Driver::output*)wl_output_get_user_data(wl_output); if (output == NULL) return; @@ -688,7 +706,8 @@ static void surface_leave(void *data, struct wl_surface *wl_surface, if (!Fl_Wayland_Screen_Driver::own_output(wl_output)) return; struct wld_window *window = (struct wld_window*)data; - Fl_Wayland_Screen_Driver::output *output = (Fl_Wayland_Screen_Driver::output*)wl_output_get_user_data(wl_output); + Fl_Wayland_Screen_Driver::output *output = + (Fl_Wayland_Screen_Driver::output*)wl_output_get_user_data(wl_output); Fl_Wayland_Window_Driver *win_driver = Fl_Wayland_Window_Driver::driver(window->fl_win); float pre_scale = Fl::screen_scale(win_driver->screen_num()) * win_driver->wld_scale(); struct Fl_Wayland_Window_Driver::surface_output *s_output; @@ -744,15 +763,15 @@ static struct Fl_Wayland_Screen_Driver::output *screen_num_to_output(int num_scr // true while the GUI is interactively resizing a decorated window static bool in_decorated_window_resizing = false; + // libdecor's configure cb function for xdg_toplevel objects static void (*decor_xdg_toplevel_configure)(void*, struct xdg_toplevel *, int32_t, int32_t, struct wl_array *); -static void fltk_xdg_toplevel_configure(void *user_data, - struct xdg_toplevel *xdg_toplevel, - int32_t width, - int32_t height, - struct wl_array *states) { + +static void fltk_xdg_toplevel_configure(void *user_data, struct xdg_toplevel *xdg_toplevel, + int32_t width, int32_t height, + struct wl_array *states) { uint32_t *p; in_decorated_window_resizing = false; // Replace wl_array_for_each(p, states) rejected by C++ @@ -767,6 +786,7 @@ static void fltk_xdg_toplevel_configure(void *user_data, decor_xdg_toplevel_configure(user_data, xdg_toplevel, width, height, states); } + struct wl_object { // copied from wayland-private.h const struct wl_interface *interface; const void *implementation; @@ -797,6 +817,7 @@ static void use_FLTK_toplevel_configure_cb(struct libdecor_frame *frame) { /* === End of hack that would become un-needed if libdecor accepted MR!131 === */ #endif // LIBDECOR_MR131 + static void handle_configure(struct libdecor_frame *frame, struct libdecor_configuration *configuration, void *user_data) { @@ -811,9 +832,9 @@ static void handle_configure(struct libdecor_frame *frame, // true exactly for the 2nd run of handle_configure() for this window bool is_2nd_run = (window->xdg_surface != 0 && driver->wait_for_expose_value); float f = Fl::screen_scale(window->fl_win->screen_num()); - + if (!window->xdg_surface) window->xdg_surface = libdecor_frame_get_xdg_surface(frame); - + #ifdef LIBDECOR_MR131 if (is_1st_run) use_FLTK_toplevel_configure_cb(frame); #endif @@ -822,7 +843,8 @@ static void handle_configure(struct libdecor_frame *frame, if (window->fl_win->fullscreen_active()) { if (!(window->state & LIBDECOR_WINDOW_STATE_FULLSCREEN)) { if (Fl_Window_Driver::driver(window->fl_win)->force_position()) { - struct Fl_Wayland_Screen_Driver::output *output = screen_num_to_output(window->fl_win->screen_num()); + struct Fl_Wayland_Screen_Driver::output *output = + screen_num_to_output(window->fl_win->screen_num()); if (output) wl_output = output->wl_output; } libdecor_frame_set_fullscreen(window->frame, wl_output); @@ -839,10 +861,11 @@ static void handle_configure(struct libdecor_frame *frame, window->fl_win->redraw(); } window->state = window_state; - + // Weston, KWin, and some versions of Mutter, on purpose, don't set the // window width x height when xdg_toplevel_configure runs twice - // during resizable window creation (see https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/6). + // during resizable window creation + // (see https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/6). // Consequently, libdecor_configuration_get_content_size() may return false twice. // In that case libdecor_frame_get_content_{width,height}() give the desired window size if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) { @@ -898,10 +921,13 @@ static void handle_configure(struct libdecor_frame *frame, Fl::handle(FL_FOCUS, window->fl_win); } if (!window->fl_win->border()) libdecor_frame_set_visibility(window->frame, false); - else if (!libdecor_frame_is_visible(window->frame)) libdecor_frame_set_visibility(window->frame, true); + else if (!libdecor_frame_is_visible(window->frame)) { + libdecor_frame_set_visibility(window->frame, true); + } } - if (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) state = libdecor_state_new(width, height); + if (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) state = libdecor_state_new(width, + height); else state = libdecor_state_new(int(ceil(width/f)*f), int(ceil(height/f)*f)); libdecor_frame_commit(frame, state, configuration); if (libdecor_frame_is_floating(frame)) { // store floating dimensions @@ -936,7 +962,8 @@ void Fl_Wayland_Window_Driver::wait_for_expose() if (!xid) return; if (pWindow->fullscreen_active()) { if (xid->kind == DECORATED) { - while (!(xid->state & LIBDECOR_WINDOW_STATE_FULLSCREEN) || !(xid->state & LIBDECOR_WINDOW_STATE_ACTIVE)) { + while (!(xid->state & LIBDECOR_WINDOW_STATE_FULLSCREEN) || + !(xid->state & LIBDECOR_WINDOW_STATE_ACTIVE)) { wl_display_dispatch(Fl_Wayland_Screen_Driver::wl_display); } } else if (xid->kind == UNFRAMED) { @@ -979,10 +1006,12 @@ static void handle_commit(struct libdecor_frame *frame, void *user_data) if (wl_win->wl_surface) wl_surface_commit(wl_win->wl_surface); } + static void handle_dismiss_popup(struct libdecor_frame *frame, const char *seat_name, void *user_data) { } + static struct libdecor_frame_interface libdecor_frame_iface = { handle_configure, handle_close, @@ -998,7 +1027,8 @@ static void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, u xdg_surface_ack_configure(xdg_surface, serial); //fprintf(stderr, "xdg_surface_configure: surface=%p\n", window->wl_surface); - if (window->fl_win->w() != window->configured_width || window->fl_win->h() != window->configured_height) { + if (window->fl_win->w() != window->configured_width || + window->fl_win->h() != window->configured_height) { if (window->buffer) { Fl_Wayland_Graphics_Driver::buffer_release(window); } @@ -1009,6 +1039,7 @@ static void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, u window->fl_win->clear_damage(); } + static const struct xdg_surface_listener xdg_surface_listener = { .configure = xdg_surface_configure, }; @@ -1037,7 +1068,8 @@ static void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel if (window->fl_win->fullscreen_active() && !parse_states_fullscreen(states)) { struct wl_output *wl_output = NULL; if (Fl_Window_Driver::driver(window->fl_win)->force_position()) { - struct Fl_Wayland_Screen_Driver::output *output = screen_num_to_output(window->fl_win->screen_num()); + struct Fl_Wayland_Screen_Driver::output *output = + screen_num_to_output(window->fl_win->screen_num()); if (output) wl_output = output->wl_output; } xdg_toplevel_set_fullscreen(xdg_toplevel, wl_output); @@ -1046,14 +1078,17 @@ static void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel Fl::screen_xywh(X, Y, width, height, window->fl_win->screen_num()); } } - if (window->configured_width) Fl_Window_Driver::driver(window->fl_win)->wait_for_expose_value = 0; + if (window->configured_width) { + Fl_Window_Driver::driver(window->fl_win)->wait_for_expose_value = 0; + } float f = Fl::screen_scale(window->fl_win->screen_num()); if (width == 0 || height == 0) { width = window->fl_win->w() * f; height = window->fl_win->h() * f; } window->fl_win->size(ceil(width / f), ceil(height / f)); - if (window->buffer && (ceil(width / f) != window->configured_width || ceil(height / f) != window->configured_height)) { + if (window->buffer && (ceil(width / f) != window->configured_width || + ceil(height / f) != window->configured_height)) { Fl_Wayland_Graphics_Driver::buffer_release(window); } window->configured_width = ceil(width / f); @@ -1065,6 +1100,7 @@ static void xdg_toplevel_close(void *data, struct xdg_toplevel *toplevel) { } + static const struct xdg_toplevel_listener xdg_toplevel_listener = { .configure = xdg_toplevel_configure, .close = xdg_toplevel_close, @@ -1078,7 +1114,8 @@ struct win_positioner { }; -static void popup_configure(void *data, struct xdg_popup *xdg_popup, int32_t x, int32_t y, int32_t width, int32_t height) { +static void popup_configure(void *data, struct xdg_popup *xdg_popup, int32_t x, int32_t y, + int32_t width, int32_t height) { struct win_positioner *win_pos = (struct win_positioner *)data; struct wld_window *window = win_pos->window; //printf("popup_configure %p asked:%dx%d got:%dx%d\n",window->fl_win, win_pos->x,win_pos->y, x,y); @@ -1114,13 +1151,16 @@ static void popup_done(void *data, struct xdg_popup *xdg_popup) { } } + static const struct xdg_popup_listener popup_listener = { .configure = popup_configure, .popup_done = popup_done, }; + bool Fl_Wayland_Window_Driver::in_flush_ = false; + // Compute the parent window of the transient scale window static Fl_Window *calc_transient_parent(int ¢er_x, int ¢er_y) { // Find top, the topmost window, but not a transient window itself @@ -1223,13 +1263,15 @@ bool Fl_Wayland_Window_Driver::process_menu_or_tooltip(struct wld_window *new_wi previous_floatingtitle = pWindow; return true; } - new_window->xdg_surface = xdg_wm_base_get_xdg_surface(scr_driver->xdg_wm_base, new_window->wl_surface); + new_window->xdg_surface = xdg_wm_base_get_xdg_surface(scr_driver->xdg_wm_base, + new_window->wl_surface); xdg_surface_add_listener(new_window->xdg_surface, &xdg_surface_listener, new_window); Fl_Wayland_Window_Driver::new_popup = true; Fl_Window *menu_origin = NULL; if (pWindow->menu_window()) { menu_origin = Fl_Window_Driver::menu_leftorigin(pWindow); - if (!menu_origin && !previous_floatingtitle) menu_origin = Fl_Window_Driver::menu_title(pWindow); + if (!menu_origin && !previous_floatingtitle) menu_origin = + Fl_Window_Driver::menu_title(pWindow); } Fl_Widget *target = (pWindow->tooltip_window() ? Fl_Tooltip::current() : NULL); if (!target) target = Fl_Window_Driver::menu_parent(); @@ -1247,7 +1289,9 @@ bool Fl_Wayland_Window_Driver::process_menu_or_tooltip(struct wld_window *new_wi //xdg_positioner_get_version(positioner) <== gives 1 under Debian and Sway int popup_x, popup_y; if (Fl_Window_Driver::menu_title(pWindow) && Fl_Window_Driver::menu_bartitle(pWindow)) { - xdg_positioner_set_anchor_rect(positioner, 0, 0, Fl_Window_Driver::menu_title(pWindow)->w() * f, Fl_Window_Driver::menu_title(pWindow)->h() * f); + xdg_positioner_set_anchor_rect(positioner, 0, 0, + Fl_Window_Driver::menu_title(pWindow)->w() * f, + Fl_Window_Driver::menu_title(pWindow)->h() * f); popup_x = 0; popup_y = Fl_Window_Driver::menu_title(pWindow)->h() * f; } else { @@ -1258,12 +1302,14 @@ bool Fl_Wayland_Window_Driver::process_menu_or_tooltip(struct wld_window *new_wi popup_y -= menu_origin->y() * f; } if (popup_x >= origin_win->w() * f) popup_x = origin_win->w() * f - 1; - if (!Fl_Window_Driver::menu_title(pWindow) && !Fl_Window_Driver::menu_bartitle(pWindow) && !Fl_Window_Driver::menu_leftorigin(pWindow)) { + if (!Fl_Window_Driver::menu_title(pWindow) && !Fl_Window_Driver::menu_bartitle(pWindow) && + !Fl_Window_Driver::menu_leftorigin(pWindow)) { // prevent first popup from going above the permissible source window popup_y = fl_max(popup_y, - pWindow->h() * f); } if (parent_xid->kind == Fl_Wayland_Window_Driver::DECORATED) - libdecor_frame_translate_coordinate(parent_xid->frame, popup_x, popup_y, &popup_x, &popup_y); + libdecor_frame_translate_coordinate(parent_xid->frame, popup_x, popup_y, + &popup_x, &popup_y); xdg_positioner_set_anchor_rect(positioner, popup_x, 0, 1, 1); popup_y++; } @@ -1280,7 +1326,8 @@ bool Fl_Wayland_Window_Driver::process_menu_or_tooltip(struct wld_window *new_wi if (!(Fl_Window_Driver::menu_title(pWindow) && Fl_Window_Driver::menu_bartitle(pWindow))) { xdg_positioner_set_offset(positioner, 0, popup_y); } - new_window->xdg_popup = xdg_surface_get_popup(new_window->xdg_surface, parent_xdg, positioner); + new_window->xdg_popup = xdg_surface_get_popup(new_window->xdg_surface, + parent_xdg, positioner); struct win_positioner *win_pos = new struct win_positioner; win_pos->window = new_window; win_pos->x = popup_x; @@ -1326,7 +1373,8 @@ void Fl_Wayland_Window_Driver::makeWindow() wl_region_destroy(opaque); } - if (pWindow->user_data() == &Fl_Screen_Driver::transient_scale_display && Fl::first_window()) { + if (pWindow->user_data() == &Fl_Screen_Driver::transient_scale_display && + Fl::first_window()) { // put transient scale win at center of top window by making it a child of top int center_x, center_y; Fl_Window *top = calc_transient_parent(center_x, center_y); @@ -1342,11 +1390,12 @@ void 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); + 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()); - libdecor_frame_set_app_id(new_window->frame, get_prog_name()); // appears in the Gnome desktop menu bar + &libdecor_frame_iface, new_window); + // appears in the Gnome desktop menu bar + libdecor_frame_set_app_id(new_window->frame, get_prog_name()); libdecor_frame_set_title(new_window->frame, pWindow->label()?pWindow->label():""); if (!pWindow->resizable()) { libdecor_frame_unset_capabilities(new_window->frame, LIBDECOR_ACTION_RESIZE); @@ -1360,13 +1409,16 @@ void Fl_Wayland_Window_Driver::makeWindow() } else if (pWindow->parent()) { // for subwindows (GL or non-GL) new_window->kind = SUBWINDOW; 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); + 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()); wl_subsurface_set_position(new_window->subsurface, pWindow->x() * f, pWindow->y() * f); wl_subsurface_set_desync(new_window->subsurface); // important // next 3 statements ensure the subsurface will be mapped because: - // "A sub-surface becomes mapped, when a non-NULL wl_buffer is applied and the parent surface is mapped." + // "A sub-surface becomes mapped, when a non-NULL wl_buffer is applied + // and the parent surface is mapped." new_window->configured_width = pWindow->w(); new_window->configured_height = pWindow->h(); if (Fl_Wayland_Screen_Driver::compositor != Fl_Wayland_Screen_Driver::OWL) { @@ -1379,7 +1431,8 @@ void Fl_Wayland_Window_Driver::makeWindow() } else { // a window without decoration new_window->kind = UNFRAMED; - new_window->xdg_surface = xdg_wm_base_get_xdg_surface(scr_driver->xdg_wm_base, new_window->wl_surface); + new_window->xdg_surface = xdg_wm_base_get_xdg_surface(scr_driver->xdg_wm_base, + new_window->wl_surface); //fprintf(stderr, "makeWindow: xdg_wm_base_get_xdg_surface=%p\n", new_window->xdg_surface); xdg_surface_add_listener(new_window->xdg_surface, &xdg_surface_listener, new_window); new_window->xdg_toplevel = xdg_surface_get_toplevel(new_window->xdg_surface); @@ -1446,16 +1499,19 @@ void Fl_Wayland_Window_Driver::makeWindow() struct wld_window *xid = fl_wl_xid(previous_floatingtitle); xid->xdg_surface = xdg_wm_base_get_xdg_surface(scr_driver->xdg_wm_base, xid->wl_surface); xdg_surface_add_listener(xid->xdg_surface, &xdg_surface_listener, xid); - struct xdg_positioner *positioner = xdg_wm_base_create_positioner(scr_driver->xdg_wm_base); + struct xdg_positioner *positioner = + xdg_wm_base_create_positioner(scr_driver->xdg_wm_base); xdg_positioner_set_anchor_rect(positioner, 0, 0, 1, 1); int snum = Fl_Window_Driver::menu_parent()->screen_num(); float f = Fl::screen_scale(snum); // put it on same screen as parent menu Fl_Window_Driver::driver(previous_floatingtitle)->screen_num(snum); - xdg_positioner_set_size(positioner, previous_floatingtitle->w() * f , previous_floatingtitle->h() * f ); + xdg_positioner_set_size(positioner, previous_floatingtitle->w() * f , + previous_floatingtitle->h() * f ); xdg_positioner_set_anchor(positioner, XDG_POSITIONER_ANCHOR_TOP_LEFT); xdg_positioner_set_gravity(positioner, XDG_POSITIONER_GRAVITY_TOP_RIGHT); - xid->xdg_popup = xdg_surface_get_popup(xid->xdg_surface, new_window->xdg_surface, positioner); + xid->xdg_popup = xdg_surface_get_popup(xid->xdg_surface, new_window->xdg_surface, + positioner); xdg_positioner_destroy(positioner); struct win_positioner *win_pos = new struct win_positioner; win_pos->window = xid; @@ -1472,12 +1528,15 @@ void Fl_Wayland_Window_Driver::makeWindow() } } + Fl_Wayland_Window_Driver::type_for_resize_window_between_screens Fl_Wayland_Window_Driver::data_for_resize_window_between_screens_ = {0, false}; + void Fl_Wayland_Window_Driver::resize_after_screen_change(void *data) { Fl_Window *win = (Fl_Window*)data; float f = Fl::screen_driver()->scale(data_for_resize_window_between_screens_.screen); - Fl_Window_Driver::driver(win)->resize_after_scale_change(data_for_resize_window_between_screens_.screen, f, f); + Fl_Window_Driver::driver(win)->resize_after_scale_change( + data_for_resize_window_between_screens_.screen, f, f); data_for_resize_window_between_screens_.busy = false; } @@ -1494,7 +1553,8 @@ int Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor c) { scr_driver->default_cursor(scr_driver->xc_arrow); break; case FL_CURSOR_NS: - if (!scr_driver->xc_ns) scr_driver->xc_ns = scr_driver->cache_cursor("sb_v_double_arrow"); + if (!scr_driver->xc_ns) scr_driver->xc_ns = + scr_driver->cache_cursor("sb_v_double_arrow"); if (!scr_driver->xc_ns) return 0; scr_driver->default_cursor(scr_driver->xc_ns); break; @@ -1531,7 +1591,8 @@ int Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor c) { scr_driver->default_cursor(scr_driver->xc_move); break; case FL_CURSOR_WE: - if (!scr_driver->xc_we) scr_driver->xc_we = scr_driver->cache_cursor("sb_h_double_arrow"); + if (!scr_driver->xc_we) scr_driver->xc_we = + scr_driver->cache_cursor("sb_h_double_arrow"); if (!scr_driver->xc_we) return 0; scr_driver->default_cursor(scr_driver->xc_we); break; @@ -1551,27 +1612,32 @@ int Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor c) { scr_driver->default_cursor(scr_driver->xc_west); break; case FL_CURSOR_S: - if (!scr_driver->xc_south) scr_driver->xc_south = scr_driver->cache_cursor("bottom_side"); + if (!scr_driver->xc_south) scr_driver->xc_south = + scr_driver->cache_cursor("bottom_side"); if (!scr_driver->xc_south) return 0; scr_driver->default_cursor(scr_driver->xc_south); break; case FL_CURSOR_NESW: - if (!scr_driver->xc_nesw) scr_driver->xc_nesw = scr_driver->cache_cursor("fd_double_arrow"); + if (!scr_driver->xc_nesw) scr_driver->xc_nesw = + scr_driver->cache_cursor("fd_double_arrow"); if (!scr_driver->xc_nesw) return 0; scr_driver->default_cursor(scr_driver->xc_nesw); break; case FL_CURSOR_NWSE: - if (!scr_driver->xc_nwse) scr_driver->xc_nwse = scr_driver->cache_cursor("bd_double_arrow"); + if (!scr_driver->xc_nwse) scr_driver->xc_nwse = + scr_driver->cache_cursor("bd_double_arrow"); if (!scr_driver->xc_nwse) return 0; scr_driver->default_cursor(scr_driver->xc_nwse); break; case FL_CURSOR_SW: - if (!scr_driver->xc_sw) scr_driver->xc_sw = scr_driver->cache_cursor("bottom_left_corner"); + if (!scr_driver->xc_sw) scr_driver->xc_sw = + scr_driver->cache_cursor("bottom_left_corner"); if (!scr_driver->xc_sw) return 0; scr_driver->default_cursor(scr_driver->xc_sw); break; case FL_CURSOR_SE: - if (!scr_driver->xc_se) scr_driver->xc_se = scr_driver->cache_cursor("bottom_right_corner"); + if (!scr_driver->xc_se) scr_driver->xc_se = + scr_driver->cache_cursor("bottom_right_corner"); if (!scr_driver->xc_se) return 0; scr_driver->default_cursor(scr_driver->xc_se); break; @@ -1674,7 +1740,8 @@ int Fl_Wayland_Window_Driver::set_cursor_4args(const Fl_RGB_Image *rgb, int hotx // build a new wl_cursor and its image struct wld_window *xid = (struct wld_window *)Fl_Window_Driver::xid(pWindow); 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)); + struct cursor_image *new_image = (struct cursor_image*)calloc(1, + sizeof(struct cursor_image)); int scale = wld_scale(); new_image->image.width = rgb->w() * scale; new_image->image.height = rgb->h() * scale; @@ -1700,7 +1767,8 @@ int Fl_Wayland_Window_Driver::set_cursor_4args(const Fl_RGB_Image *rgb, int hotx Fl_Surface_Device::pop_current(); delete img_surf; memcpy(offscreen->data, offscreen->draw_buffer.buffer, offscreen->draw_buffer.data_size); - // delete the previous custom cursor, if there was one, and keep its Fl_RGB_Image if appropriate + // delete the previous custom cursor, if there was one, + // and keep its Fl_RGB_Image if appropriate delete_cursor_(xid, keep_copy); //have this new cursor used xid->custom_cursor = new wld_window::custom_cursor_; @@ -1760,7 +1828,8 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) { x(X); y(Y); //fprintf(stderr, "move menuwin=%p x()=%d\n", pWindow, X); } else { - //"a deliberate design trait of Wayland makes application windows ignorant of their exact placement on screen" + //"a deliberate design trait of Wayland makes application windows ignorant of + // their exact placement on screen" x(0); y(0); } } @@ -1777,7 +1846,8 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) { if (!in_handle_configure && xdg_toplevel()) { if (Fl_Window::is_a_rescale()) size_range(); struct libdecor_state *state = libdecor_state_new(int(W * f), int(H * f)); - libdecor_frame_commit(fl_win->frame, state, NULL); // necessary only if resize is initiated by prog + // necessary only if resize is initiated by prog + libdecor_frame_commit(fl_win->frame, state, NULL); libdecor_state_free(state); if (libdecor_frame_is_floating(fl_win->frame)) { fl_win->floating_width = int(W*f); @@ -1836,7 +1906,8 @@ static void crect_intersect(cairo_rectangle_int_t *to, cairo_rectangle_int_t *wi static bool crect_equal(cairo_rectangle_int_t *to, cairo_rectangle_int_t *with) { - return (to->x == with->x && to->y == with->y && to->width == with->width && to->height == with->height); + return (to->x == with->x && to->y == with->y && to->width == with->width && + to->height == with->height); } @@ -1892,7 +1963,8 @@ void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) { *Fl_Window_Driver::menu_offset_y(pWindow) += (y - pWindow->y()); struct wld_window *xid = fl_wl_xid(pWindow); wl_surface_set_opaque_region(xid->wl_surface, NULL); - if (xid->buffer) memset(xid->buffer->draw_buffer.buffer, 0, xid->buffer->draw_buffer.data_size); + if (xid->buffer) memset(xid->buffer->draw_buffer.buffer, 0, + xid->buffer->draw_buffer.data_size); //printf("offset_y=%d\n", *Fl_Window_Driver::menu_offset_y(pWindow)); this->y(y); pWindow->redraw(); @@ -1916,7 +1988,8 @@ void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) { Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); xid_menu->wl_surface = wl_compositor_create_surface(scr_driver->wl_compositor); wl_surface_add_listener(xid_menu->wl_surface, &surface_listener, xid_menu); - xid_menu->xdg_surface = xdg_wm_base_get_xdg_surface(scr_driver->xdg_wm_base, xid_menu->wl_surface); + 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); struct wld_window * parent_xid = fl_wl_xid(menu_origin); @@ -1927,15 +2000,19 @@ void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) { popup_y -= menu_origin->y() * f; } if (popup_x >= menu_origin->w() * f) popup_x = menu_origin->w() * f - 1; - if (parent_xid->kind == DECORATED) - libdecor_frame_translate_coordinate(parent_xid->frame, popup_x, popup_y, &popup_x, &popup_y); + if (parent_xid->kind == DECORATED) { + libdecor_frame_translate_coordinate(parent_xid->frame, popup_x, popup_y, + &popup_x, &popup_y); + } xdg_positioner_set_anchor_rect(positioner, popup_x, 0, 1, 1); xdg_positioner_set_size(positioner, pWindow->w() * f , pWindow->h() * f ); xdg_positioner_set_anchor(positioner, XDG_POSITIONER_ANCHOR_TOP_LEFT); xdg_positioner_set_gravity(positioner, XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT); - xdg_positioner_set_constraint_adjustment(positioner, XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X); + xdg_positioner_set_constraint_adjustment(positioner, + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X); xdg_positioner_set_offset(positioner, 0, popup_y); - xid_menu->xdg_popup = xdg_surface_get_popup(xid_menu->xdg_surface, parent_xid->xdg_surface, positioner); + xid_menu->xdg_popup = xdg_surface_get_popup(xid_menu->xdg_surface, parent_xid->xdg_surface, + positioner); xdg_positioner_destroy(positioner); struct win_positioner *win_pos = new struct win_positioner; win_pos->window = xid_menu; @@ -1946,7 +2023,8 @@ void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) { wl_surface_commit(xid_menu->wl_surface); wl_display_roundtrip(Fl_Wayland_Screen_Driver::wl_display); // necessary with sway // delete the previous popup - struct win_positioner *old_win_pos = (struct win_positioner*)xdg_popup_get_user_data(old_popup); + struct win_positioner *old_win_pos = + (struct win_positioner*)xdg_popup_get_user_data(old_popup); xdg_popup_destroy(old_popup); delete old_win_pos; xdg_surface_destroy(old_xdg); diff --git a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx index 7e215a2e5..3b432f800 100644 --- a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx +++ b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx @@ -74,10 +74,13 @@ void write_data_source_cb(FL_SOCKET fd, data_source_write_struct *data) { close(fd); } -static void data_source_handle_send(void *data, struct wl_data_source *source, const char *mime_type, int fd) { + +static void data_source_handle_send(void *data, struct wl_data_source *source, + const char *mime_type, int fd) { fl_intptr_t rank = (fl_intptr_t)data; //fprintf(stderr, "data_source_handle_send: %s fd=%d l=%d\n", mime_type, fd, fl_selection_length[1]); - if (((!strcmp(mime_type, wld_plain_text_clipboard) || !strcmp(mime_type, "text/plain")) && fl_selection_type[rank] == Fl::clipboard_plain_text) + if (((!strcmp(mime_type, wld_plain_text_clipboard) || !strcmp(mime_type, "text/plain")) && + fl_selection_type[rank] == Fl::clipboard_plain_text) || (!strcmp(mime_type, "image/bmp") && fl_selection_type[rank] == Fl::clipboard_image) ) { data_source_write_struct *write_data = new data_source_write_struct; @@ -90,12 +93,14 @@ static void data_source_handle_send(void *data, struct wl_data_source *source, c } } + static Fl_Window *fl_dnd_target_window = 0; static wl_surface *fl_dnd_target_surface = 0; static bool doing_dnd = false; // true when DnD is in action static wl_surface *dnd_icon = NULL; // non null when DnD uses text as cursor static wl_cursor* save_cursor = NULL; // non null when DnD uses "dnd-copy" cursor + static void data_source_handle_cancelled(void *data, struct wl_data_source *source) { // An application has replaced the clipboard contents or DnD finished //fprintf(stderr, "data_source_handle_cancelled: %p\n", source); @@ -140,9 +145,12 @@ static void data_source_handle_target(void *data, struct wl_data_source *source, } } + static uint32_t last_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; -static void data_source_handle_action(void *data, struct wl_data_source *source, uint32_t dnd_action) { + +static void data_source_handle_action(void *data, struct wl_data_source *source, + uint32_t dnd_action) { last_dnd_action = dnd_action; switch (dnd_action) { case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY: @@ -154,10 +162,12 @@ static void data_source_handle_action(void *data, struct wl_data_source *source, } } + static void data_source_handle_dnd_drop_performed(void *data, struct wl_data_source *source) { //printf("Drop performed\n"); } + static void data_source_handle_dnd_finished(void *data, struct wl_data_source *source) { switch (last_dnd_action) { case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE: @@ -169,6 +179,7 @@ static void data_source_handle_dnd_finished(void *data, struct wl_data_source *s } } + static const struct wl_data_source_listener data_source_listener = { .target = data_source_handle_target, .send = data_source_handle_send, @@ -179,7 +190,8 @@ static const struct wl_data_source_listener data_source_listener = { }; -static struct Fl_Wayland_Graphics_Driver::wld_buffer *offscreen_from_text(const char *text, int scale) { +static struct Fl_Wayland_Graphics_Driver::wld_buffer *offscreen_from_text(const char *text, + int scale) { const char *p, *q; int width = 0, height, w2, ltext = strlen(text); fl_font(FL_HELVETICA, 10 * scale); @@ -248,7 +260,8 @@ int Fl_Wayland_Screen_Driver::dnd(int use_selection) { } else dnd_icon = NULL; doing_dnd = true; wl_data_device_start_drag(scr_driver->seat->data_device, source, - scr_driver->seat->pointer_focus, dnd_icon, scr_driver->seat->serial); + scr_driver->seat->pointer_focus, dnd_icon, + scr_driver->seat->serial); if (use_selection) { wl_surface_attach(dnd_icon, off->wl_buffer, 0, 0); wl_surface_set_buffer_scale(dnd_icon, s); @@ -267,13 +280,15 @@ int Fl_Wayland_Screen_Driver::dnd(int use_selection) { } -static void data_offer_handle_offer(void *data, struct wl_data_offer *offer, const char *mime_type) { +static void data_offer_handle_offer(void *data, struct wl_data_offer *offer, + const char *mime_type) { // runs when app becomes active and lists possible clipboard types //fprintf(stderr, "Clipboard offer=%p supports MIME type: %s\n", offer, mime_type); if (strcmp(mime_type, "image/png") == 0) { fl_selection_type[1] = Fl::clipboard_image; fl_selection_offer_type = "image/png"; - } else if (strcmp(mime_type, "image/bmp") == 0 && (!fl_selection_offer_type || strcmp(fl_selection_offer_type, "image/png"))) { + } else if (strcmp(mime_type, "image/bmp") == 0 && (!fl_selection_offer_type || + strcmp(fl_selection_offer_type, "image/png"))) { fl_selection_type[1] = Fl::clipboard_image; fl_selection_offer_type = "image/bmp"; } else if (strcmp(mime_type, "text/uri-list") == 0 && !fl_selection_type[1]) { @@ -286,13 +301,16 @@ static void data_offer_handle_offer(void *data, struct wl_data_offer *offer, con } -static void data_offer_handle_source_actions(void *data, struct wl_data_offer *offer, uint32_t actions) { +static void data_offer_handle_source_actions(void *data, struct wl_data_offer *offer, + uint32_t actions) { if (actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) { //printf("Drag supports the copy action\n"); } } -static void data_offer_handle_action(void *data, struct wl_data_offer *offer, uint32_t dnd_action) { + +static void data_offer_handle_action(void *data, struct wl_data_offer *offer, + uint32_t dnd_action) { switch (dnd_action) { case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE: //printf("A move action would be performed if dropped\n"); @@ -306,13 +324,16 @@ static void data_offer_handle_action(void *data, struct wl_data_offer *offer, ui } } + static const struct wl_data_offer_listener data_offer_listener = { .offer = data_offer_handle_offer, .source_actions = data_offer_handle_source_actions, .action = data_offer_handle_action, }; -static void data_device_handle_data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer) { + +static void data_device_handle_data_offer(void *data, struct wl_data_device *data_device, + struct wl_data_offer *offer) { // An application has created a new data source //fprintf(stderr, "data_device_handle_data_offer offer=%p\n", offer); fl_selection_type[1] = NULL; @@ -321,7 +342,8 @@ static void data_device_handle_data_offer(void *data, struct wl_data_device *dat } -static void data_device_handle_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer) { +static void data_device_handle_selection(void *data, struct wl_data_device *data_device, + struct wl_data_offer *offer) { // An application has set the clipboard contents. W //fprintf(stderr, "data_device_handle_selection\n"); if (fl_selection_offer) wl_data_offer_destroy(fl_selection_offer); @@ -405,12 +427,15 @@ way_out: Fl::e_clipboard_type = Fl::clipboard_plain_text; } + static struct wl_data_offer *current_drag_offer = NULL; static uint32_t fl_dnd_serial; -static void data_device_handle_enter(void *data, struct wl_data_device *data_device, uint32_t serial, - struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer) { +static void data_device_handle_enter(void *data, struct wl_data_device *data_device, + uint32_t serial, struct wl_surface *surface, + wl_fixed_t x, wl_fixed_t y, + struct wl_data_offer *offer) { Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(surface); //printf("Drag entered our surface %p(win=%p) at %dx%d\n", surface, win, wl_fixed_to_int(x), wl_fixed_to_int(y)); if (win) { @@ -435,8 +460,9 @@ static void data_device_handle_enter(void *data, struct wl_data_device *data_dev wl_data_offer_set_actions(offer, supported_actions, preferred_action); } -static void data_device_handle_motion(void *data, struct wl_data_device *data_device, uint32_t time, - wl_fixed_t x, wl_fixed_t y) { + +static void data_device_handle_motion(void *data, struct wl_data_device *data_device, + uint32_t time, wl_fixed_t x, wl_fixed_t y) { if (!current_drag_offer) return; //printf("data_device_handle_motion fl_dnd_target_window=%p\n", fl_dnd_target_window); int ret = 0; @@ -455,16 +481,18 @@ static void data_device_handle_motion(void *data, struct wl_data_device *data_de ret = Fl::handle(FL_DND_DRAG, fl_dnd_target_window); if (Fl::belowmouse()) Fl::belowmouse()->take_focus(); } - uint32_t supported_actions = ret && (Fl::pushed() || !doing_dnd) ? WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY : WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; + uint32_t supported_actions = ret && (Fl::pushed() || !doing_dnd) ? + WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY : WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; uint32_t preferred_action = supported_actions; wl_data_offer_set_actions(current_drag_offer, supported_actions, preferred_action); wl_display_roundtrip(Fl_Wayland_Screen_Driver::wl_display); if (ret && current_drag_offer) wl_data_offer_accept(current_drag_offer, fl_dnd_serial, "text/plain"); } + static void data_device_handle_leave(void *data, struct wl_data_device *data_device) { -//printf("Drag left our surface\n"); -if (current_drag_offer) Fl::handle(FL_DND_LEAVE, fl_dnd_target_window); + //printf("Drag left our surface\n"); + if (current_drag_offer) Fl::handle(FL_DND_LEAVE, fl_dnd_target_window); } @@ -497,6 +525,7 @@ static void data_device_handle_drop(void *data, struct wl_data_device *data_devi current_drag_offer = NULL; } + static const struct wl_data_device_listener data_device_listener = { .data_offer = data_device_handle_data_offer, .enter = data_device_handle_enter, @@ -507,7 +536,8 @@ static const struct wl_data_device_listener data_device_listener = { }; -const struct wl_data_device_listener *Fl_Wayland_Screen_Driver::p_data_device_listener = &data_device_listener; +const struct wl_data_device_listener *Fl_Wayland_Screen_Driver::p_data_device_listener = + &data_device_listener; // Reads from the clipboard an image which can be in image/bmp or image/png MIME type. @@ -540,7 +570,8 @@ static int get_clipboard_image() { int ld = shared->ld() ? shared->ld() : shared->w() * shared->d(); uchar *rgb = new uchar[shared->w() * shared->h() * shared->d()]; memcpy(rgb, shared->data()[0], ld * shared->h() ); - Fl_RGB_Image *image = new Fl_RGB_Image(rgb, shared->w(), shared->h(), shared->d(), shared->ld()); + Fl_RGB_Image *image = new Fl_RGB_Image(rgb, shared->w(), shared->h(), shared->d(), + shared->ld()); shared->release(); image->alloc_array = 1; Fl::e_clipboard_data = (void*)image; @@ -553,7 +584,8 @@ static int get_clipboard_image() { int w, h; // size of the BMP image Fl_Unix_System_Driver::read_int(buf + 18, w); Fl_Unix_System_Driver::read_int(buf + 22, h); - int R = ((3*w+3)/4) * 4; // the number of bytes per row of BMP image, rounded up to multiple of 4 + // the number of bytes per row of BMP image, rounded up to multiple of 4 + int R = ((3*w+3)/4) * 4; bmp = new char[R * h + 54]; memcpy(bmp, buf, 54); char *from = bmp + 54; @@ -618,7 +650,8 @@ void Fl_Wayland_Screen_Driver::paste(Fl_Widget &receiver, int clipboard, const c } -void Fl_Wayland_Screen_Driver::copy(const char *stuff, int len, int clipboard, const char *type) { +void Fl_Wayland_Screen_Driver::copy(const char *stuff, int len, int clipboard, + const char *type) { if (!stuff || len < 0) return; if (clipboard >= 2) @@ -636,11 +669,14 @@ void Fl_Wayland_Screen_Driver::copy(const char *stuff, int len, int clipboard, c fl_selection_type[clipboard] = Fl::clipboard_plain_text; if (clipboard == 1) { Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); - scr_driver->seat->data_source = wl_data_device_manager_create_data_source(scr_driver->seat->data_device_manager); + scr_driver->seat->data_source = + wl_data_device_manager_create_data_source(scr_driver->seat->data_device_manager); // we transmit the adequate value of index in fl_selection_buffer[index] - wl_data_source_add_listener(scr_driver->seat->data_source, &data_source_listener, (void*)1); + wl_data_source_add_listener(scr_driver->seat->data_source, &data_source_listener, + (void*)1); wl_data_source_offer(scr_driver->seat->data_source, wld_plain_text_clipboard); - wl_data_device_set_selection(scr_driver->seat->data_device, scr_driver->seat->data_source, scr_driver->seat->keyboard_enter_serial); + wl_data_device_set_selection(scr_driver->seat->data_device, scr_driver->seat->data_source, + scr_driver->seat->keyboard_enter_serial); //fprintf(stderr, "wl_data_device_set_selection len=%d to %d\n", len, clipboard); } } @@ -650,7 +686,8 @@ void Fl_Wayland_Screen_Driver::copy(const char *stuff, int len, int clipboard, c void Fl_Wayland_Screen_Driver::copy_image(const unsigned char *data, int W, int H){ if (!data || W <= 0 || H <= 0) return; delete[] fl_selection_buffer[1]; - fl_selection_buffer[1] = (char *)Fl_Unix_System_Driver::create_bmp(data,W,H,&fl_selection_length[1]); + fl_selection_buffer[1] = + (char *)Fl_Unix_System_Driver::create_bmp(data,W,H,&fl_selection_length[1]); fl_selection_buffer_length[1] = fl_selection_length[1]; fl_i_own_selection[1] = 1; fl_selection_type[1] = Fl::clipboard_image; @@ -658,7 +695,8 @@ void Fl_Wayland_Screen_Driver::copy_image(const unsigned char *data, int W, int // we transmit the adequate value of index in fl_selection_buffer[index] wl_data_source_add_listener(seat->data_source, &data_source_listener, (void*)1); wl_data_source_offer(seat->data_source, "image/bmp"); - wl_data_device_set_selection(seat->data_device, seat->data_source, seat->keyboard_enter_serial); + wl_data_device_set_selection(seat->data_device, seat->data_source, + seat->keyboard_enter_serial); //fprintf(stderr, "copy_image: len=%d\n", fl_selection_length[1]); } diff --git a/src/drivers/Wayland/fl_wayland_platform_init.cxx b/src/drivers/Wayland/fl_wayland_platform_init.cxx index 765a0a1f6..bd6089f96 100644 --- a/src/drivers/Wayland/fl_wayland_platform_init.cxx +++ b/src/drivers/Wayland/fl_wayland_platform_init.cxx @@ -58,7 +58,7 @@ static bool attempt_wayland() { 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); + fprintf(stderr, "Error: no Wayland connection available, FLTK_BACKEND='wayland'\n"); exit(1); } return true; |
