From 27c3d0b780788bc5f36eb6bc67456a0277c74915 Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Tue, 8 Aug 2023 16:08:53 +0200 Subject: [PATCH] Wayland: improve layout of struct fl_wld_draw_buffer --- FL/platform_types.h | 2 +- documentation/src/wayland.dox | 30 +++++++----- .../Fl_Wayland_Copy_Surface_Driver.cxx | 2 +- .../Wayland/Fl_Wayland_Gl_Window_Driver.cxx | 4 +- .../Wayland/Fl_Wayland_Graphics_Driver.H | 21 +++++---- .../Wayland/Fl_Wayland_Graphics_Driver.cxx | 47 +++++++------------ .../Fl_Wayland_Image_Surface_Driver.cxx | 22 ++++----- .../Wayland/Fl_Wayland_Screen_Driver.cxx | 9 ++-- .../Wayland/Fl_Wayland_Window_Driver.cxx | 22 ++++----- .../Wayland/fl_wayland_clipboard_dnd.cxx | 14 +++--- 10 files changed, 87 insertions(+), 86 deletions(-) diff --git a/FL/platform_types.h b/FL/platform_types.h index fd2dced5d..0f7300474 100644 --- a/FL/platform_types.h +++ b/FL/platform_types.h @@ -39,7 +39,7 @@ typedef opaque fl_uintptr_t; Platform-specific value representing an offscreen drawing buffer. \note This value can be safely cast to these types on each platform: \li X11: Pixmap - \li Wayland: struct fl_wld_buffer * + \li Wayland: struct fl_wld_draw_buffer * \li Windows: HBITMAP \li macOS: CGContextRef */ diff --git a/documentation/src/wayland.dox b/documentation/src/wayland.dox index bc94aa1e3..bfca4ff3a 100644 --- a/documentation/src/wayland.dox +++ b/documentation/src/wayland.dox @@ -1133,24 +1133,32 @@ struct wld_window { \anchor fl_wld_buffer -

struct fl_wld_buffer

-Defined in \c Fl_Wayland_Graphics_Driver.H. One such record is created when and by: -- an Fl_Window is show()'n or resized, by \c Fl_Wayland_Graphics_Driver::create_shm_buffer(); -- an Fl_Image_Surface object is created, by the \c Fl_Wayland_Image_Surface_Driver c'tor; -- a custom cursor shape is created or text is dragged, by -\c Fl_Wayland_Graphics_Driver::create_shm_buffer(). +

struct fl_wld_buffer and struct fl_wld_draw_buffer

+Defined in \c Fl_Wayland_Graphics_Driver.H. +One struct fl_wld_buffer record is created +by \c Fl_Wayland_Graphics_Driver::create_shm_buffer() when +an Fl_Window is show()'n or resized, +when a custom cursor shape is created, or when text is dragged. + +A struct fl_wld_draw_buffer record is created when an Fl_Image_Surface object +is created by the \c Fl_Wayland_Image_Surface_Driver c'tor. +One such record is also embedded inside each struct fl_wld_buffer record.
-struct fl_wld_buffer {
-  struct wl_buffer *wl_buffer; // the Wayland buffer
-  void *data; // address of the beginning of the Wayland buffer's byte array
+struct fl_wld_draw_buffer { // Under Wayland, Fl_Offscreen points to this structure
   size_t data_size; // of wl_buffer and draw_buffer
   int stride; // bytes per line
   int width;
-  unsigned char *draw_buffer; // address of the beginning of the Cairo image surface's byte array
+  unsigned char *buffer; // address of the beginning of the Cairo image surface's byte array
+  cairo_t *cairo_; // used when drawing to the Cairo image surface
+};
+
+struct fl_wld_buffer {
+  struct fl_wld_draw_buffer draw_buffer;
+  struct wl_buffer *wl_buffer; // the Wayland buffer
+  void *data; // address of the beginning of the Wayland buffer's byte array
   struct wl_callback *cb; // non-NULL while Wayland buffer is being committed
   bool draw_buffer_needs_commit; // true when draw_buffer has been modified but not yet committed
-  cairo_t *cairo_; // used when drawing to the Cairo image surface
   struct wl_shm_pool *shm_pool; // pter to wl_shm_pool from which this wl_buffer comes
   struct wl_list link; // links all buffers from the same wl_shm_pool
 };
diff --git a/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
index b1c34b2ec..141f865ec 100644
--- a/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
@@ -46,7 +46,7 @@ Fl_Wayland_Copy_Surface_Driver::~Fl_Wayland_Copy_Surface_Driver() {
 
 void Fl_Wayland_Copy_Surface_Driver::set_current() {
   Fl_Surface_Device::set_current();
-  ((Fl_Wayland_Graphics_Driver*)driver())->set_buffer((struct fl_wld_buffer *)img_surf->offscreen());
+  ((Fl_Wayland_Graphics_Driver*)driver())->set_cairo(((struct fl_wld_draw_buffer *)img_surf->offscreen())->cairo_);
 }
 
 
diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
index bb32695fa..dba7acf79 100644
--- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
@@ -114,9 +114,9 @@ char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n,
   fl_draw(str, n, 0, fl_height() - fl_descent());
   // get the R channel only of the bitmap
   char *alpha_buf = new char[w*h], *r = alpha_buf;
-  struct fl_wld_buffer *off = (struct fl_wld_buffer *)surf->offscreen();
+  struct fl_wld_draw_buffer *off = (struct fl_wld_draw_buffer *)surf->offscreen();
   for (int i = 0; i < h; i++) {
-    uchar *q = off->draw_buffer + i * off->stride;
+    uchar *q = off->buffer + i * off->stride;
     for (int j = 0; j < w; j++) {
       *r++ = *q;
       q += 4;
diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H
index 81a3dbf8f..76ee7fe39 100644
--- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H
+++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H
@@ -27,38 +27,39 @@
 #include  // for wl_list
 
 
-struct fl_wld_buffer {
-  struct wl_buffer *wl_buffer;
-  void *data;
+struct fl_wld_draw_buffer { // Under Wayland, Fl_Offscreen points to this structure
   size_t data_size; // of wl_buffer and draw_buffer
   int stride;
   int width;
-  unsigned char *draw_buffer;
+  unsigned char *buffer;
+  cairo_t *cairo_;
+};
+
+
+struct fl_wld_buffer {
+  struct fl_wld_draw_buffer draw_buffer;
+  struct wl_buffer *wl_buffer;
+  void *data;
   struct wl_callback *cb;
   bool draw_buffer_needs_commit;
-  cairo_t *cairo_;
   struct wl_shm_pool *shm_pool;
   struct wl_list link; // links all buffers from the same wl_shm_pool
 };
 
 
 class Fl_Wayland_Graphics_Driver : public Fl_Cairo_Graphics_Driver {
-private:
-  struct fl_wld_buffer *buffer_;
 public:
   struct wld_shm_pool_data { // one record attached to each wl_shm_pool object
     char *pool_memory; // start of mmap'ed memory encapsulated by the wl_shm_pool
     int pool_size; // size of encapsulated memory
     struct wl_list buffers; // to list of fl_wld_buffer's from this pool
   };
-  Fl_Wayland_Graphics_Driver();
   static const uint32_t wld_format;
-  void set_buffer(struct fl_wld_buffer *buffer, float scale = 0);
   void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) FL_OVERRIDE;
   static struct fl_wld_buffer *create_shm_buffer(int width, int height);
   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 fl_wld_buffer *buffer, int width, int height, int stride, cairo_format_t format);
+  static void cairo_init(struct fl_wld_draw_buffer *buffer, int width, int height, int stride, cairo_format_t format);
 };
 
 #endif // FL_WAYLAND_GRAPHICS_DRIVER_H
diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
index bede37b60..3fa9c7094 100644
--- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
@@ -44,7 +44,7 @@ struct fl_wld_buffer *Fl_Wayland_Graphics_Driver::create_shm_buffer(int width, i
   if (pool) {
     // last fl_wld_buffer created from current pool
     struct fl_wld_buffer *record = wl_container_of(pool_data->buffers.next, record, link);
-    chunk_offset = ((char*)record->data - pool_data->pool_memory) + record->data_size;
+    chunk_offset = ((char*)record->data - pool_data->pool_memory) + record->draw_buffer.data_size;
   }
   if (!pool || chunk_offset + size > pool_size) { // if true, a new pool is needed
     chunk_offset = 0;
@@ -70,7 +70,7 @@ struct fl_wld_buffer *Fl_Wayland_Graphics_Driver::create_shm_buffer(int width, i
     wl_shm_pool_set_user_data(pool, pool_data);
   }
   buffer = (struct fl_wld_buffer*)calloc(1, sizeof(struct fl_wld_buffer));
-  buffer->stride = stride;
+  buffer->draw_buffer.stride = stride;
   buffer->wl_buffer = wl_shm_pool_create_buffer(pool, chunk_offset, width, height, stride, Fl_Wayland_Graphics_Driver::wld_format);
   // add this buffer to head of list of current pool's buffers
   wl_list_insert(&pool_data->buffers, &buffer->link);
@@ -79,7 +79,7 @@ struct fl_wld_buffer *Fl_Wayland_Graphics_Driver::create_shm_buffer(int width, i
 //fprintf(stderr, "last=%p chunk_offset=%d ", pool_data->buffers.next, chunk_offset);
   buffer->draw_buffer_needs_commit = true;
 //fprintf(stderr, "create_shm_buffer: %dx%d = %d\n", width, height, size);
-  cairo_init(buffer, width, height, stride, Fl_Cairo_Graphics_Driver::cairo_format);
+  cairo_init(&buffer->draw_buffer, width, height, stride, Fl_Cairo_Graphics_Driver::cairo_format);
   return buffer;
 }
 
@@ -115,15 +115,15 @@ static void copy_region(struct wld_window *window, struct flCairoRegion *r) {
     int top = r->rects[i].y * f;
     int width = r->rects[i].width * f;
     int height = r->rects[i].height * f;
-    int offset = top * buffer->stride + 4 * left;
+    int offset = top * buffer->draw_buffer.stride + 4 * left;
     int W4 = 4 * width;
     for (int l = 0; l < height; l++) {
-      if (offset + W4 >= (int)buffer->data_size) {
-        W4 = buffer->data_size - offset;
+      if (offset + W4 >= (int)buffer->draw_buffer.data_size) {
+        W4 = buffer->draw_buffer.data_size - offset;
         if (W4 <= 0) break;
       }
-      memcpy((uchar*)buffer->data + offset, buffer->draw_buffer + offset, W4);
-      offset += buffer->stride;
+      memcpy((uchar*)buffer->data + offset, buffer->draw_buffer.buffer + offset, W4);
+      offset += buffer->draw_buffer.stride;
     }
     wl_surface_damage_buffer(window->wl_surface, left, top, width, height);
   }
@@ -132,11 +132,11 @@ static void copy_region(struct wld_window *window, struct flCairoRegion *r) {
 
 void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window,
                                 struct flCairoRegion *r) {
-  cairo_surface_t *surf = cairo_get_target(window->buffer->cairo_);
+  cairo_surface_t *surf = cairo_get_target(window->buffer->draw_buffer.cairo_);
   cairo_surface_flush(surf);
   if (r) copy_region(window, r);
   else {
-    memcpy(window->buffer->data, window->buffer->draw_buffer, window->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);
   }
   wl_surface_attach(window->wl_surface, window->buffer->wl_buffer, 0, 0);
@@ -150,11 +150,11 @@ void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window,
 }
 
 
-void Fl_Wayland_Graphics_Driver::cairo_init(struct fl_wld_buffer *buffer, int width, int height, int stride, cairo_format_t format) {
+void Fl_Wayland_Graphics_Driver::cairo_init(struct fl_wld_draw_buffer *buffer, int width, int height, int stride, cairo_format_t format) {
   buffer->data_size = stride * height;
-  buffer->draw_buffer = new uchar[buffer->data_size];
+  buffer->buffer = new uchar[buffer->data_size];
   buffer->width = width;
-  cairo_surface_t *surf = cairo_image_surface_create_for_data(buffer->draw_buffer, format,
+  cairo_surface_t *surf = cairo_image_surface_create_for_data(buffer->buffer, format,
                                                         width, height, stride);
   if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) {
     Fl::fatal("Can't create Cairo surface with cairo_image_surface_create_for_data()\n");
@@ -167,7 +167,7 @@ void Fl_Wayland_Graphics_Driver::cairo_init(struct fl_wld_buffer *buffer, int wi
     return;
   }
   cairo_surface_destroy(surf);
-  memset(buffer->draw_buffer, 0, buffer->data_size); // useful for transparent windows
+  memset(buffer->buffer, 0, buffer->data_size); // useful for transparent windows
   cairo_set_source_rgba(buffer->cairo_, .0, .0, .0, 1.0); // Black default color
   cairo_save(buffer->cairo_);
 }
@@ -192,9 +192,9 @@ void Fl_Wayland_Graphics_Driver::buffer_release(struct wld_window *window)
       free(pool_data);
       if (my_pool == pool) pool = NULL;
     }
-    delete[] window->buffer->draw_buffer;
-    window->buffer->draw_buffer = NULL;
-    cairo_destroy(window->buffer->cairo_);
+    delete[] window->buffer->draw_buffer.buffer;
+    window->buffer->draw_buffer.buffer = NULL;
+    cairo_destroy(window->buffer->draw_buffer.cairo_);
     free(window->buffer);
     window->buffer = NULL;
   }
@@ -204,20 +204,9 @@ void Fl_Wayland_Graphics_Driver::buffer_release(struct wld_window *window)
 const uint32_t Fl_Wayland_Graphics_Driver::wld_format = WL_SHM_FORMAT_ARGB8888;
 
 
-Fl_Wayland_Graphics_Driver::Fl_Wayland_Graphics_Driver () : Fl_Cairo_Graphics_Driver() {
-  buffer_ = NULL;
-}
-
-
-void Fl_Wayland_Graphics_Driver::set_buffer(struct fl_wld_buffer *buffer, float scale) {
-  this->buffer_ = buffer;
-  set_cairo(buffer->cairo_, scale);
-}
-
-
 void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen src, int srcx, int srcy) {
   // draw portion srcx,srcy,w,h of osrc to position x,y (top-left) of the graphics driver's surface
-  struct fl_wld_buffer *osrc = (struct fl_wld_buffer *)src;
+  struct fl_wld_draw_buffer *osrc = (struct fl_wld_draw_buffer *)src;
   cairo_matrix_t matrix;
   cairo_get_matrix(cairo_, &matrix);
   double s = matrix.xx;
diff --git a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx
index a3e003e54..42de33854 100644
--- a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx
@@ -32,7 +32,7 @@ Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, i
       w = int(w * d);
       h = int(h * d);
     }
-    struct fl_wld_buffer *off_ = (struct fl_wld_buffer*)calloc(1, sizeof(struct fl_wld_buffer));
+    struct fl_wld_draw_buffer *off_ = (struct fl_wld_draw_buffer*)calloc(1, sizeof(struct fl_wld_draw_buffer));
     off_->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
     offscreen = (Fl_Offscreen)off_;
     Fl_Wayland_Graphics_Driver::cairo_init(off_, w, h, off_->stride, CAIRO_FORMAT_RGB24);
@@ -44,23 +44,23 @@ Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, i
 
 Fl_Wayland_Image_Surface_Driver::~Fl_Wayland_Image_Surface_Driver() {
   if (offscreen && !external_offscreen) {
-    cairo_destroy(((struct fl_wld_buffer *)offscreen)->cairo_);
-    delete[] ((struct fl_wld_buffer *)offscreen)->draw_buffer;
-    free((struct fl_wld_buffer *)offscreen);
+    cairo_destroy(((struct fl_wld_draw_buffer *)offscreen)->cairo_);
+    delete[] ((struct fl_wld_draw_buffer *)offscreen)->buffer;
+    free((struct fl_wld_draw_buffer *)offscreen);
   }
   delete driver();
 }
 
 void Fl_Wayland_Image_Surface_Driver::set_current() {
   Fl_Surface_Device::set_current();
-  ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer((struct fl_wld_buffer*)offscreen);
+  ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_cairo(((struct fl_wld_draw_buffer*)offscreen)->cairo_);
   pre_window = Fl_Wayland_Window_Driver::wld_window;
   Fl_Wayland_Window_Driver::wld_window = NULL;
   fl_window = 0;
 }
 
 void Fl_Wayland_Image_Surface_Driver::end_current() {
-  cairo_surface_t *surf = cairo_get_target(((struct fl_wld_buffer *)offscreen)->cairo_);
+  cairo_surface_t *surf = cairo_get_target(((struct fl_wld_draw_buffer *)offscreen)->cairo_);
   cairo_surface_flush(surf);
   Fl_Wayland_Window_Driver::wld_window = pre_window;
   fl_window = (Window)pre_window;
@@ -77,20 +77,20 @@ void Fl_Wayland_Image_Surface_Driver::untranslate() {
 
 Fl_RGB_Image* Fl_Wayland_Image_Surface_Driver::image() {
   // Convert depth-4 image in draw_buffer to a depth-3 image while exchanging R and B colors
-  int height = ((struct fl_wld_buffer *)offscreen)->data_size / ((struct fl_wld_buffer *)offscreen)->stride;
-  uchar *rgb = new uchar[((struct fl_wld_buffer *)offscreen)->width * height * 3];
+  int height = ((struct fl_wld_draw_buffer *)offscreen)->data_size / ((struct fl_wld_draw_buffer *)offscreen)->stride;
+  uchar *rgb = new uchar[((struct fl_wld_draw_buffer *)offscreen)->width * height * 3];
   uchar *p = rgb;
   uchar *q;
   for (int j = 0; j < height; j++) {
-    q = ((struct fl_wld_buffer *)offscreen)->draw_buffer + j*((struct fl_wld_buffer *)offscreen)->stride;
-    for (int i = 0; i < ((struct fl_wld_buffer *)offscreen)->width; i++) { // exchange R and B colors, transmit G
+    q = ((struct fl_wld_draw_buffer *)offscreen)->buffer + j*((struct fl_wld_draw_buffer *)offscreen)->stride;
+    for (int i = 0; i < ((struct fl_wld_draw_buffer *)offscreen)->width; i++) { // exchange R and B colors, transmit G
       *p = *(q+2);
       *(p+1) = *(q+1);
       *(p+2) = *q;
       p += 3; q += 4;
     }
   }
-  Fl_RGB_Image *image = new Fl_RGB_Image(rgb, ((struct fl_wld_buffer *)offscreen)->width, height, 3);
+  Fl_RGB_Image *image = new Fl_RGB_Image(rgb, ((struct fl_wld_draw_buffer *)offscreen)->width, height, 3);
   image->alloc_array = 1;
   return image;
 }
diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
index 0df7ab07b..764a4e8df 100644
--- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
@@ -22,6 +22,7 @@
 #include "xdg-shell-client-protocol.h"
 #include "../Posix/Fl_Posix_System_Driver.H"
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1494,7 +1495,9 @@ 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,
                                                            bool ignore, bool *p_ignore) {
   struct wld_window* xid = win ? fl_wl_xid(win) : NULL;
-  struct fl_wld_buffer *buffer = win ? xid->buffer : (struct fl_wld_buffer *)Fl_Surface_Device::surface()->driver()->gc();
+  struct fl_wld_draw_buffer *buffer = win ? &xid->buffer->draw_buffer :
+    (struct fl_wld_draw_buffer *)
+      (((Fl_Image_Surface*)Fl_Surface_Device::surface())->offscreen());//to check
   float s = win ?
     Fl_Wayland_Window_Driver::driver(win)->wld_scale() * scale(win->screen_num()) :
                   Fl_Surface_Device::surface()->driver()->scale();
@@ -1511,7 +1514,7 @@ Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w,
   uchar *data = new uchar[ws * hs * 3];
   uchar *p = data, *q;
   for (int j = 0; j < hs; j++) {
-    q = buffer->draw_buffer + (j+Ys) * buffer->stride + 4 * Xs;
+    q = buffer->buffer + (j+Ys) * buffer->stride + 4 * Xs;
     for (int i = 0; i < ws; i++) {
       *p++ = *(q+2); // R
       *p++ = *(q+1); // G
@@ -1527,7 +1530,7 @@ Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w,
 
 void Fl_Wayland_Screen_Driver::offscreen_size(Fl_Offscreen off_, int &width, int &height)
 {
-  struct fl_wld_buffer *off = (struct fl_wld_buffer *)off_;
+  struct fl_wld_draw_buffer *off = (struct fl_wld_draw_buffer *)off_;
   width = off->width;
   height = off->data_size / off->stride;
 }
diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
index 28001ff4f..c6aa4d9e1 100644
--- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
@@ -352,10 +352,10 @@ 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_buffer(window->buffer, 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->cairo_, 0, *poffset);
+    cairo_translate(window->buffer->draw_buffer.cairo_, 0, *poffset);
   }
   cairo_rectangle_int_t *extents = subRect();
   if (extents) { // make damage-to-buffer not to leak outside parent
@@ -593,8 +593,8 @@ 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 + (dest_y + i) * buffer->stride + 4 * dest_x,
-             buffer->draw_buffer + (src_y + i) * 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
@@ -605,8 +605,8 @@ 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 + (src_y + i) * buffer->stride + 4 * dest_x,
-             buffer->draw_buffer + (src_y + i) * 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;
     }
   }
@@ -1628,15 +1628,15 @@ int Fl_Wayland_Window_Driver::set_cursor_4args(const Fl_RGB_Image *rgb, int hotx
   new_cursor->images[0] = (struct wl_cursor_image*)new_image;
   new_cursor->name = strdup("custom cursor");
   // draw the rgb image to the cursor's drawing buffer
-  Fl_Image_Surface *img_surf = new Fl_Image_Surface(new_image->image.width, new_image->image.height, 0, (Fl_Offscreen)offscreen);
+  Fl_Image_Surface *img_surf = new Fl_Image_Surface(new_image->image.width, new_image->image.height, 0, (Fl_Offscreen)&offscreen->draw_buffer);
   Fl_Surface_Device::push_current(img_surf);
   Fl_Wayland_Graphics_Driver *driver = (Fl_Wayland_Graphics_Driver*)img_surf->driver();
   cairo_scale(driver->cr(), scale, scale);
-  memset(offscreen->draw_buffer, 0, offscreen->data_size);
+  memset(offscreen->draw_buffer.buffer, 0, offscreen->draw_buffer.data_size);
   ((Fl_RGB_Image*)rgb)->draw(0, 0);
   Fl_Surface_Device::pop_current();
   delete img_surf;
-  memcpy(offscreen->data, offscreen->draw_buffer, offscreen->data_size);
+  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_cursor_(xid, keep_copy);
   //have this new cursor used
@@ -1681,7 +1681,7 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
     int stride = cairo_format_stride_for_width(
                  Fl_Cairo_Graphics_Driver::cairo_format, int(W * scale) );
     size_t bsize = stride * int(H * scale);
-    true_rescale = (bsize != fl_win->buffer->data_size);
+    true_rescale = (bsize != fl_win->buffer->draw_buffer.data_size);
   }
   int is_a_resize = (W != w() || H != h() || true_rescale);
   if (is_a_move) force_position(1);
@@ -1827,7 +1827,7 @@ 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, 0, xid->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();
diff --git a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx
index d414fcbda..b543154b5 100644
--- a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx
+++ b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx
@@ -176,7 +176,7 @@ static const struct wl_data_source_listener data_source_listener = {
 };
 
 
-static Fl_Offscreen offscreen_from_text(const char *text, int scale) {
+static struct fl_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);
@@ -196,9 +196,9 @@ static Fl_Offscreen offscreen_from_text(const char *text, int scale) {
   if (width > 300*scale) width = 300*scale;
   height = nl * fl_height() + 3;
   width += 6;
-  struct fl_wld_buffer * off = Fl_Wayland_Graphics_Driver::create_shm_buffer(width, height);
-  memset(off->draw_buffer, 0, off->data_size);
-  Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 0, (Fl_Offscreen)off);
+  struct fl_wld_buffer *off = Fl_Wayland_Graphics_Driver::create_shm_buffer(width, height);
+  memset(off->draw_buffer.buffer, 0, off->draw_buffer.data_size);
+  Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 0, (Fl_Offscreen)&off->draw_buffer);
   Fl_Surface_Device::push_current(surf);
   p = text;
   fl_font(FL_HELVETICA, 10 * scale);
@@ -217,9 +217,9 @@ static Fl_Offscreen offscreen_from_text(const char *text, int scale) {
   }
   Fl_Surface_Device::pop_current();
   delete surf;
-  cairo_surface_flush( cairo_get_target(off->cairo_) );
-  memcpy(off->data, off->draw_buffer, off->data_size);
-  return (Fl_Offscreen)off;
+  cairo_surface_flush( cairo_get_target(off->draw_buffer.cairo_) );
+  memcpy(off->data, off->draw_buffer.buffer, off->draw_buffer.data_size);
+  return off;
 }