From c0c2cf7d408fc6bfefd9eecbfe5aabcbc4d55ff3 Mon Sep 17 00:00:00 2001
From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
Date: Wed, 8 Jan 2025 14:37:57 +0100
Subject: [PATCH] Make draw to image and draw to clipboard behave equally in
 X11 and Wayland

---
 src/drivers/Cairo/Fl_X11_Cairo_Graphics_Driver.cxx  |  9 +++++++--
 .../Wayland/Fl_Wayland_Copy_Surface_Driver.cxx      | 13 ++++++-------
 .../Wayland/Fl_Wayland_Image_Surface_Driver.cxx     |  8 +++-----
 src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx    |  7 ++++---
 4 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/src/drivers/Cairo/Fl_X11_Cairo_Graphics_Driver.cxx b/src/drivers/Cairo/Fl_X11_Cairo_Graphics_Driver.cxx
index 3ad9a0d88..926121bdb 100644
--- a/src/drivers/Cairo/Fl_X11_Cairo_Graphics_Driver.cxx
+++ b/src/drivers/Cairo/Fl_X11_Cairo_Graphics_Driver.cxx
@@ -48,8 +48,13 @@ void Fl_X11_Cairo_Graphics_Driver::scale(float f) {
 }
 
 
-void Fl_X11_Cairo_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) {
-  XCopyArea(fl_display, pixmap, fl_window, (GC)Fl_Graphics_Driver::default_driver().gc(), int(srcx*scale()), int(srcy*scale()), int(w*scale()), int(h*scale()), int(x*scale()), int(y*scale()));
+void Fl_X11_Cairo_Graphics_Driver::copy_offscreen(int x, int y, int w, int h,
+                                                  Fl_Offscreen pixmap, int srcx, int srcy) {
+  cairo_matrix_t mat;
+  if (cairo_) cairo_get_matrix(cairo_, &mat);
+  else cairo_matrix_init_identity(&mat);
+  XCopyArea(fl_display, pixmap, fl_window, (GC)Fl_Graphics_Driver::default_driver().gc(), int(srcx*scale()), int(srcy*scale()), int(w*scale()), int(h*scale()),
+            int(x*scale()) + mat.x0, int(y*scale()) + mat.y0);
 }
 
 
diff --git a/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
index 90ca9ac27..0b84a037b 100644
--- a/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
@@ -22,15 +22,14 @@
 
 
 Fl_Wayland_Copy_Surface_Driver::Fl_Wayland_Copy_Surface_Driver(int w, int h) : Fl_Copy_Surface_Driver(w, h) {
-  struct Fl_Wayland_Window_Driver::surface_output *s_output = NULL;
-  if (Fl_Wayland_Window_Driver::wld_window &&
-      !wl_list_empty(&Fl_Wayland_Window_Driver::wld_window->outputs)) {
-    s_output = wl_container_of(Fl_Wayland_Window_Driver::wld_window->outputs.next, s_output, link);
+  float os_scale = Fl_Graphics_Driver::default_driver().scale();
+  int d = 1;
+  if (Fl::first_window()) {
+    d = Fl_Wayland_Window_Driver::driver(Fl::first_window())->wld_scale();
   }
-  int os_scale = (s_output ? s_output->output->wld_scale : 1);
-  img_surf = new Fl_Image_Surface(w * os_scale, h * os_scale);
+  img_surf = new Fl_Image_Surface(int(w * os_scale) * d, int(h * os_scale) * d);
   driver(img_surf->driver());
-  driver()->scale(os_scale);
+  driver()->scale(d * os_scale);
 }
 
 
diff --git a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx
index de72e175a..a3850f6da 100644
--- a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx
@@ -27,12 +27,10 @@ Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h,
   int 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();
+    if (Fl::first_window()) {
+      d = Fl_Wayland_Window_Driver::driver(Fl::first_window())->wld_scale();
     }
-    s = fl_graphics_driver->scale();
+    s =  Fl_Graphics_Driver::default_driver().scale();
     if (d*s != 1 && high_res) {
       w = int(w * s) * d;
       h = int(h * s) * d;
diff --git a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx
index 8fab122fe..c905dbbad 100644
--- a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx
+++ b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx
@@ -45,7 +45,6 @@ Fl_Xlib_Copy_Surface_Driver::Fl_Xlib_Copy_Surface_Driver(int w, int h) : Fl_Copy
   cairo_surface_t *surf = cairo_xlib_surface_create(fl_display, xid->offscreen(), fl_visual->visual, w * s, h * s);
   cairo_ = cairo_create(surf);
   cairo_surface_destroy(surf);
-  cairo_scale(cairo_, 1/s, 1/s);
   cairo_save(cairo_);
   ((Fl_X11_Cairo_Graphics_Driver*)driver())->set_cairo(cairo_);
 #endif
@@ -62,8 +61,10 @@ Fl_Xlib_Copy_Surface_Driver::~Fl_Xlib_Copy_Surface_Driver() {
   Fl_RGB_Image *rgb = Fl::screen_driver()->read_win_rectangle(0, 0, width, height, 0);
   fl_window = old_win;
   if (is_current()) end_current();
-  Fl_X11_Screen_Driver::copy_image(rgb->array, rgb->w(), rgb->h(), 1);
-  delete rgb;
+  if (rgb) {
+    Fl_X11_Screen_Driver::copy_image(rgb->array, rgb->w(), rgb->h(), 1);
+    delete rgb;
+  }
   delete xid;
 #if FLTK_USE_CAIRO
   cairo_destroy(cairo_);
-- 
GitLab