From c720aae51515907ae82ee02df80bd084f291d4b1 Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Tue, 15 Mar 2022 06:42:06 +0100 Subject: Make hybrid Wayland/X11 platform. --- .../Cairo/Fl_Display_Cairo_Graphics_Driver.H | 37 +++++++++ .../Cairo/Fl_Display_Cairo_Graphics_Driver.cxx | 64 ++++++++++++++++ src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx | 30 +++++--- src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm | 2 +- src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx | 6 +- src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx | 14 +++- src/drivers/Darwin/Fl_Darwin_System_Driver.cxx | 2 + src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx | 4 +- src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx | 14 ++-- src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx | 6 +- src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx | 18 ++--- src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H | 2 +- src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx | 8 +- .../Quartz/Fl_Quartz_Copy_Surface_Driver.cxx | 2 +- src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx | 14 +++- .../Quartz/Fl_Quartz_Graphics_Driver_image.cxx | 2 +- .../Quartz/Fl_Quartz_Graphics_Driver_rect.cxx | 15 ++-- .../Quartz/Fl_Quartz_Image_Surface_Driver.H | 2 +- .../Quartz/Fl_Quartz_Image_Surface_Driver.cxx | 46 +++++------ .../Wayland/Fl_Wayland_Copy_Surface_Driver.cxx | 2 +- .../Wayland/Fl_Wayland_Gl_Window_Driver.cxx | 20 +++-- src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx | 3 +- .../Wayland/Fl_Wayland_Image_Surface_Driver.cxx | 37 ++++----- src/drivers/Wayland/Fl_Wayland_Screen_Driver.H | 4 + src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx | 44 ++++++----- src/drivers/Wayland/Fl_Wayland_System_Driver.cxx | 3 +- src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 86 +++++++++++---------- src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx | 17 ++--- .../Wayland/fl_wayland_gl_platform_init.cxx | 5 +- src/drivers/Wayland/fl_wayland_platform_init.cxx | 88 ++++++++++++++++++---- src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx | 14 ++-- src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx | 2 +- src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx | 38 ++++++---- src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx | 18 +++-- src/drivers/X11/Fl_X11_Screen_Driver.cxx | 4 +- src/drivers/X11/Fl_X11_Window_Driver.H | 8 ++ src/drivers/X11/Fl_X11_Window_Driver.cxx | 71 +++++++++++++++-- src/drivers/X11/fl_X11_platform_init.cxx | 11 ++- src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H | 6 ++ src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx | 39 +++++++++- src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H | 2 +- src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx | 12 +-- .../Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx | 6 +- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx | 16 ++-- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx | 26 +++---- src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H | 6 ++ src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx | 41 ++++++++-- 47 files changed, 652 insertions(+), 265 deletions(-) create mode 100644 src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H create mode 100644 src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx (limited to 'src/drivers') diff --git a/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H b/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H new file mode 100644 index 000000000..76986af9a --- /dev/null +++ b/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H @@ -0,0 +1,37 @@ +// +// Support for using Cairo to draw into X11 windows for the Fast Light Tool Kit (FLTK). +// +// Copyright 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 +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +/* \file + Declaration of class Fl_Display_Cairo_Graphics_Driver. +*/ + +#ifndef FL_DISPLAY_CAIRO_GRAPHICS_DRIVER_H +# define FL_DISPLAY_CAIRO_GRAPHICS_DRIVER_H + +#include "Fl_Cairo_Graphics_Driver.H" + +class Fl_Display_Cairo_Graphics_Driver : public Fl_Cairo_Graphics_Driver { +private: + static void *gc_; +public: + virtual void scale(float f); + virtual float scale() {return Fl_Graphics_Driver::scale();} + virtual void gc(void *value); + virtual void* gc(); + virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy); + }; + +#endif // FL_DISPLAY_CAIRO_GRAPHICS_DRIVER_H diff --git a/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx b/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx new file mode 100644 index 000000000..02df902d8 --- /dev/null +++ b/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx @@ -0,0 +1,64 @@ +// +// Support for using Cairo to draw into X11 windows for the Fast Light Tool Kit (FLTK). +// +// Copyright 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 +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +/* \file + Implementation of class Fl_Display_Cairo_Graphics_Driver . +*/ + +#include "Fl_Display_Cairo_Graphics_Driver.H" +#include +#include +#include +#include + + +void *Fl_Display_Cairo_Graphics_Driver::gc_ = NULL; +GC fl_gc; + + +ulong fl_xpixel(uchar r,uchar g,uchar b) { + return 0; +} +ulong fl_xpixel(Fl_Color i) { + return 0; +} + + +void Fl_Display_Cairo_Graphics_Driver::scale(float f) { + Fl_Graphics_Driver::scale(f); + if (cairo_) { + cairo_restore(cairo_); + cairo_save(cairo_); + cairo_scale(cairo_, f, f); + cairo_translate(cairo_, 0.5, 0.5); + } +} + + +void Fl_Display_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_Display_Cairo_Graphics_Driver::gc(void *value) { + gc_ = value; + fl_gc = (GC)gc_; +} + + +void *Fl_Display_Cairo_Graphics_Driver::gc() { + return gc_; +} diff --git a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx index 6491332e3..d1ed8df1e 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx @@ -1,7 +1,7 @@ // // Class Fl_Cocoa_Gl_Window_Driver for the Fast Light Tool Kit (FLTK). // -// Copyright 2021 by Bill Spitzak and others. +// Copyright 2021-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 @@ -66,7 +66,7 @@ GLContext Fl_Cocoa_Gl_Window_Driver::create_gl_context(Fl_Window* window, const // resets the pile of string textures used to draw strings // necessary before the first context is created if (!shared_ctx) gl_texture_reset(); - context = Fl_Cocoa_Window_Driver::create_GLcontext_for_window(((Fl_Cocoa_Gl_Choice*)g)->pixelformat, shared_ctx, window); + context = Fl_Cocoa_Window_Driver::create_GLcontext_for_window(((Fl_Cocoa_Gl_Choice*)g)->pixelformat, (NSOpenGLContext*)shared_ctx, window); if (!context) return 0; add_context(context); return (context); @@ -76,7 +76,7 @@ void Fl_Cocoa_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) if (context != cached_context || w != cached_window) { cached_context = context; cached_window = w; - Fl_Cocoa_Window_Driver::GLcontext_makecurrent(context); + Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)context); } } @@ -86,7 +86,7 @@ void Fl_Cocoa_Gl_Window_Driver::delete_gl_context(GLContext context) { cached_window = 0; Fl_Cocoa_Window_Driver::GL_cleardrawable(); } - Fl_Cocoa_Window_Driver::GLcontext_release(context); + Fl_Cocoa_Window_Driver::GLcontext_release((NSOpenGLContext*)context); del_context(context); } @@ -143,7 +143,7 @@ void Fl_Cocoa_Gl_Window_Driver::make_current_before() { if (d->changed_resolution()){ d->changed_resolution(false); pWindow->invalidate(); - Fl_Cocoa_Window_Driver::GLcontext_update(pWindow->context()); + Fl_Cocoa_Window_Driver::GLcontext_update((NSOpenGLContext*)pWindow->context()); } } @@ -179,13 +179,13 @@ void Fl_Cocoa_Gl_Window_Driver::swap_buffers() { glRasterPos3f(pos[0], pos[1], pos[2]); // restore original glRasterPos } else - Fl_Cocoa_Window_Driver::flush_context(pWindow->context());//aglSwapBuffers((AGLContext)context_); + Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)pWindow->context());//aglSwapBuffers((AGLContext)context_); } char Fl_Cocoa_Gl_Window_Driver::swap_type() {return copy;} void Fl_Cocoa_Gl_Window_Driver::resize(int is_a_resize, int w, int h) { - Fl_Cocoa_Window_Driver::GLcontext_update(pWindow->context()); + Fl_Cocoa_Window_Driver::GLcontext_update((NSOpenGLContext*)pWindow->context()); } /* Some old Apple hardware doesn't implement the GL_EXT_texture_rectangle extension. @@ -202,7 +202,7 @@ char *Fl_Cocoa_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, i fl_draw(str, n, 0, fl_height() - fl_descent()); // get the alpha channel only of the bitmap char *alpha_buf = new char[w*h], *r = alpha_buf, *q; - q = (char*)CGBitmapContextGetData(surf->offscreen()); + q = (char*)CGBitmapContextGetData((CGContextRef)surf->offscreen()); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { *r++ = *(q+3); @@ -215,7 +215,7 @@ char *Fl_Cocoa_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, i } void Fl_Cocoa_Gl_Window_Driver::gl_start() { - Fl_Cocoa_Window_Driver::gl_start(gl_start_context); + Fl_Cocoa_Window_Driver::gl_start((NSOpenGLContext*)gl_start_context); } // convert BGRA to RGB and also exchange top and bottom @@ -247,8 +247,8 @@ Fl_RGB_Image* Fl_Cocoa_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int if (factor != 1) { w *= factor; h *= factor; x *= factor; y *= factor; } - Fl_Cocoa_Window_Driver::GLcontext_makecurrent(glw->context()); - Fl_Cocoa_Window_Driver::flush_context(glw->context()); // to capture also the overlay and for directGL demo + Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)glw->context()); + Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)glw->context()); // to capture also the overlay and for directGL demo // Read OpenGL context pixels directly. // For extra safety, save & restore OpenGL states that are changed glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); @@ -266,10 +266,16 @@ Fl_RGB_Image* Fl_Cocoa_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int baseAddress = convert_BGRA_to_RGB(baseAddress, w, h, mByteWidth); Fl_RGB_Image *img = new Fl_RGB_Image(baseAddress, w, h, 3, 3 * w); img->alloc_array = 1; - Fl_Cocoa_Window_Driver::flush_context(glw->context()); + Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)glw->context()); return img; } + +FL_EXPORT NSOpenGLContext *fl_mac_glcontext(GLContext rc) { + return (NSOpenGLContext*)rc; +} + + class Fl_Gl_Cocoa_Plugin : public Fl_Cocoa_Plugin { public: Fl_Gl_Cocoa_Plugin() : Fl_Cocoa_Plugin(name()) { } diff --git a/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm b/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm index fd278cf75..c587caf37 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm +++ b/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm @@ -347,7 +347,7 @@ int Fl_Cocoa_Printer_Driver::begin_page (void) CGContextSaveGState(gc); CGContextSaveGState(gc); fl_line_style(FL_SOLID); - fl_window = (Window)1; // TODO: something better + fl_window = (FLWindow*)1; // TODO: something better fl_clip_region(0); return status != noErr; } diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx index 01c3b0f95..33b0392c4 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx @@ -140,7 +140,7 @@ void Fl_Cocoa_Screen_Driver::grab(Fl_Window* win) { if (win) { if (!Fl::grab_) { - fl_capture = Fl_X::i(Fl::first_window())->xid; + fl_capture = (FLWindow*)(Fl_X::i(Fl::first_window())->xid); Fl_Cocoa_Window_Driver::driver(Fl::first_window())->set_key_window(); } Fl::grab_ = win; @@ -315,8 +315,8 @@ int Fl_Cocoa_Screen_Driver::input_widget_handle_key(int key, unsigned mods, unsi void Fl_Cocoa_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &height) { - width = CGBitmapContextGetWidth(off); - height = CGBitmapContextGetHeight(off); + width = CGBitmapContextGetWidth((CGContextRef)off); + height = CGBitmapContextGetHeight((CGContextRef)off); } Fl_RGB_Image *Fl_Cocoa_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *window, diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx index b7f213da0..019e2b7f5 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx @@ -224,10 +224,10 @@ void Fl_Cocoa_Window_Driver::hide() { if (ip && !parent()) pWindow->cursor(FL_CURSOR_DEFAULT); if ( hide_common() ) return; q_release_context(this); - if ( ip->xid == fl_window ) + if ( ip->xid == (fl_uintptr_t)fl_window ) fl_window = 0; if (ip->region) Fl_Graphics_Driver::default_driver().XDestroyRegion(ip->region); - destroy(ip->xid); + destroy((FLWindow*)ip->xid); delete subRect(); delete ip; } @@ -338,3 +338,13 @@ int Fl_Cocoa_Window_Driver::screen_num() { if (pWindow->parent()) return pWindow->top_window()->screen_num(); else return screen_num_; } + + +FLWindow *fl_mac_xid(const Fl_Window *win) { + return (FLWindow*)Fl_Window_Driver::xid(win); +} + + +Fl_Window *fl_mac_find(FLWindow *xid) { + return Fl_Window_Driver::find((fl_uintptr_t)xid); +} diff --git a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx index 0c8015dba..2c4c5a34b 100644 --- a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx +++ b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx @@ -93,6 +93,8 @@ Fl_Darwin_System_Driver::Fl_Darwin_System_Driver() : Fl_Posix_System_Driver() { // initialize key table key_table = darwin_key_table; key_table_size = sizeof(darwin_key_table)/sizeof(*darwin_key_table); + command_key = FL_META; + control_key = FL_CTRL; } int Fl_Darwin_System_Driver::single_arg(const char *arg) { diff --git a/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx b/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx index 29478a9c4..c44c0a77b 100644 --- a/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx +++ b/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx @@ -64,7 +64,7 @@ Fl_GDI_Copy_Surface_Driver::~Fl_GDI_Copy_Surface_Driver() { fl_color(FL_WHITE); // draw white background fl_rectf(0, 0, W, H); PlayEnhMetaFile((HDC)surf->driver()->gc(), hmf, &rect); // draw metafile to offscreen buffer - SetClipboardData(CF_BITMAP, surf->offscreen()); + SetClipboardData(CF_BITMAP, (HBITMAP)surf->offscreen()); Fl_Surface_Device::pop_current(); delete surf; @@ -80,7 +80,7 @@ Fl_GDI_Copy_Surface_Driver::~Fl_GDI_Copy_Surface_Driver() { void Fl_GDI_Copy_Surface_Driver::set_current() { driver()->gc(gc); - fl_window = (Window)1; + fl_window = (HWND)1; Fl_Surface_Device::set_current(); } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx index 87adc44f0..188bd1d2d 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx @@ -75,6 +75,10 @@ static FL_BLENDFUNCTION blendfunc = { 0, 0, 255, 1}; */ HDC fl_gc = 0; + +HDC fl_win32_gc() { return fl_gc; } + + Fl_GDI_Graphics_Driver::Fl_GDI_Graphics_Driver() { mask_bitmap_ = NULL; gc_ = NULL; @@ -157,7 +161,7 @@ void Fl_GDI_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offsc if (w <= 0 || h <= 0) return; HDC new_gc = CreateCompatibleDC(gc_); int save = SaveDC(new_gc); - SelectObject(new_gc, bitmap); + SelectObject(new_gc, (HBITMAP)bitmap); BitBlt(gc_, x, y, w, h, new_gc, srcx, srcy, SRCCOPY); RestoreDC(new_gc, save); DeleteDC(new_gc); @@ -211,8 +215,8 @@ void Fl_GDI_Graphics_Driver::untranslate_all() { #endif void Fl_GDI_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { - Fl_Region R = XRectangleRegion(X, Y, W, H); - CombineRgn(r, r, R, RGN_OR); + HRGN R = (HRGN)XRectangleRegion(X, Y, W, H); + CombineRgn((HRGN)r, (HRGN)r, R, RGN_OR); XDestroyRegion(R); } @@ -241,7 +245,7 @@ Fl_Region Fl_GDI_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { } void Fl_GDI_Graphics_Driver::XDestroyRegion(Fl_Region r) { - DeleteObject(r); + DeleteObject((HRGN)r); } @@ -287,7 +291,7 @@ HRGN Fl_GDI_Graphics_Driver::scale_region(HRGN r, float f, Fl_GDI_Graphics_Drive Fl_Region Fl_GDI_Graphics_Driver::scale_clip(float f) { - HRGN r = rstack[rstackptr]; + HRGN r = (HRGN)rstack[rstackptr]; HRGN r2 = scale_region(r, f, this); return (r == r2 ? NULL : (rstack[rstackptr] = r2, r)); } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx index 4cfc745c9..9e512d889 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx @@ -590,7 +590,7 @@ void Fl_GDI_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, RestoreDC(new_gc,save); DeleteDC(new_gc); } else if (img->d()==2 || img->d()==4) { - copy_offscreen_with_alpha(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(img), cx, cy); + copy_offscreen_with_alpha(X, Y, W, H, (HBITMAP)*Fl_Graphics_Driver::id(img), cx, cy); } else { copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(img), cx, cy); } @@ -653,7 +653,7 @@ void Fl_GDI_Printer_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, void Fl_GDI_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_uintptr_t &mask_) { if (id_) { - DeleteObject((Fl_Offscreen)id_); + DeleteObject((HBITMAP)id_); id_ = 0; } @@ -817,5 +817,5 @@ void Fl_GDI_Graphics_Driver::cache(Fl_Pixmap *img) { } void Fl_GDI_Graphics_Driver::uncache_pixmap(fl_uintptr_t offscreen) { - DeleteObject((Fl_Offscreen)offscreen); + DeleteObject((HBITMAP)offscreen); } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx index 76b546092..1b13ff0a9 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx @@ -138,10 +138,10 @@ void Fl_GDI_Graphics_Driver::polygon_unscaled(int x, int y, int x1, int y1, int // --- clipping void Fl_GDI_Graphics_Driver::push_clip(int x, int y, int w, int h) { - Fl_Region r; + HRGN r; if (w > 0 && h > 0) { - r = XRectangleRegion(x,y,w,h); - Fl_Region current = rstack[rstackptr]; + r = (HRGN)XRectangleRegion(x,y,w,h); + HRGN current = (HRGN)rstack[rstackptr]; if (current) { CombineRgn(r,r,current,RGN_AND); } @@ -155,14 +155,14 @@ void Fl_GDI_Graphics_Driver::push_clip(int x, int y, int w, int h) { int Fl_GDI_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ X = x; Y = y; W = w; H = h; - Fl_Region r = rstack[rstackptr]; + HRGN r = (HRGN)rstack[rstackptr]; if (!r) return 0; // The win32 API makes no distinction between partial and complete // intersection, so we have to check for partial intersection ourselves. // However, given that the regions may be composite, we have to do // some voodoo stuff... - Fl_Region rr = XRectangleRegion(x,y,w,h); - Fl_Region temp = CreateRectRgn(0,0,0,0); + HRGN rr = (HRGN)XRectangleRegion(x,y,w,h); + HRGN temp = CreateRectRgn(0,0,0,0); int ret; if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint W = H = 0; @@ -189,7 +189,7 @@ int Fl_GDI_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int Fl_GDI_Graphics_Driver::not_clipped(int x, int y, int w, int h) { if (x+w <= 0 || y+h <= 0) return 0; - Fl_Region r = rstack[rstackptr]; + HRGN r = (HRGN)rstack[rstackptr]; if (!r) return 1; RECT rect; if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { // in case of print context, convert coords from logical to device @@ -206,8 +206,8 @@ void Fl_GDI_Graphics_Driver::restore_clip() { fl_clip_state_number++; if (gc_) { HRGN r = NULL; - if (rstack[rstackptr]) r = scale_clip(scale()); - SelectClipRgn(gc_, rstack[rstackptr]); // if region is NULL, clip is automatically cleared + if (rstack[rstackptr]) r = (HRGN)scale_clip(scale()); + SelectClipRgn(gc_, (HRGN)rstack[rstackptr]); // if region is NULL, clip is automatically cleared if (r) unscale_clip(r); } } diff --git a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H index 979b7bd3a..a3d8ac6c6 100644 --- a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H +++ b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H @@ -24,7 +24,7 @@ class Fl_GDI_Image_Surface_Driver : public Fl_Image_Surface_Driver { virtual void end_current(); public: - Window pre_window; + HWND pre_window; int _savedc; Fl_GDI_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off); ~Fl_GDI_Image_Surface_Driver(); diff --git a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx index 7f655e291..6795fb06b 100644 --- a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx +++ b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx @@ -29,8 +29,8 @@ Fl_GDI_Image_Surface_Driver::Fl_GDI_Image_Surface_Driver(int w, int h, int high_ h = int(h*d); } HDC gc = (HDC)Fl_Graphics_Driver::default_driver().gc(); - offscreen = off ? off : CreateCompatibleBitmap( (gc ? gc : fl_GetDC(0) ) , w, h); - if (!offscreen) offscreen = CreateCompatibleBitmap(fl_GetDC(0), w, h); + offscreen = off ? off : (Fl_Offscreen)CreateCompatibleBitmap( (gc ? gc : fl_GetDC(0) ) , w, h); + if (!offscreen) offscreen = (Fl_Offscreen)CreateCompatibleBitmap(fl_GetDC(0), w, h); driver(Fl_Graphics_Driver::newMainGraphicsDriver()); if (d != 1 && high_res) ((Fl_GDI_Graphics_Driver*)driver())->scale(d); origin.x = origin.y = 0; @@ -38,13 +38,13 @@ Fl_GDI_Image_Surface_Driver::Fl_GDI_Image_Surface_Driver(int w, int h, int high_ Fl_GDI_Image_Surface_Driver::~Fl_GDI_Image_Surface_Driver() { - if (offscreen && !external_offscreen) DeleteObject(offscreen); + if (offscreen && !external_offscreen) DeleteObject((HBITMAP)offscreen); delete driver(); } void Fl_GDI_Image_Surface_Driver::set_current() { - HDC gc = fl_makeDC(offscreen); + HDC gc = fl_makeDC((HBITMAP)offscreen); driver()->gc(gc); SetWindowOrgEx(gc, origin.x, origin.y, NULL); Fl_Surface_Device::set_current(); diff --git a/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx index 3ededb5ab..77ecdaa0a 100644 --- a/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx @@ -49,7 +49,7 @@ Fl_Quartz_Copy_Surface_Driver::Fl_Quartz_Copy_Surface_Driver(int w, int h) : Fl_ void Fl_Quartz_Copy_Surface_Driver::set_current() { driver()->gc(gc); - fl_window = (Window)1; + fl_window = (FLWindow*)1; Fl_Surface_Device::set_current(); } diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx index b50309438..552da03f9 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx @@ -84,6 +84,10 @@ void Fl_Quartz_Graphics_Driver::global_gc() fl_gc = (CGContextRef)gc(); } + +CGContextRef fl_mac_gc() { return fl_gc; } + + void Fl_Quartz_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) { // draw portion srcx,srcy,w,h of osrc to position x,y (top-left) of the graphics driver's surface CGContextRef src = (CGContextRef)osrc; @@ -127,7 +131,8 @@ CGRect Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(int x, int y, int w, int h return CGRectMake(x - 0.5, y - 0.5, w, h); } -void Fl_Quartz_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { +void Fl_Quartz_Graphics_Driver::add_rectangle_to_region(Fl_Region r_, int X, int Y, int W, int H) { + struct flCocoaRegion *r = (struct flCocoaRegion*)r_; CGRect arg = Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(X, Y, W, H); int j; // don't add a rectangle totally inside the Fl_Region for(j = 0; j < r->count; j++) { @@ -140,15 +145,16 @@ void Fl_Quartz_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int } Fl_Region Fl_Quartz_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { - Fl_Region R = (Fl_Region)malloc(sizeof(*R)); + struct flCocoaRegion* R = (struct flCocoaRegion*)malloc(sizeof(struct flCocoaRegion)); R->count = 1; R->rects = (CGRect *)malloc(sizeof(CGRect)); *(R->rects) = Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(x, y, w, h); return R; } -void Fl_Quartz_Graphics_Driver::XDestroyRegion(Fl_Region r) { - if(r) { +void Fl_Quartz_Graphics_Driver::XDestroyRegion(Fl_Region r_) { + if (r_) { + struct flCocoaRegion *r = (struct flCocoaRegion*)r_; free(r->rects); free(r); } diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx index 558dc47c1..b97cfbba7 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx @@ -250,7 +250,7 @@ void Fl_Quartz_Graphics_Driver::cache(Fl_Pixmap *img) { Fl_Surface_Device::push_current(surf); fl_draw_pixmap(img->data(), 0, 0, FL_BLACK); Fl_Surface_Device::pop_current(); - CGContextRef src = Fl_Graphics_Driver::get_offscreen_and_delete_image_surface(surf); + CGContextRef src = (CGContextRef)Fl_Graphics_Driver::get_offscreen_and_delete_image_surface(surf); void *cgdata = CGBitmapContextGetData(src); int sw = CGBitmapContextGetWidth(src); int sh = CGBitmapContextGetHeight(src); diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx index 52b8c7f65..71daf0e10 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx @@ -218,11 +218,12 @@ void Fl_Quartz_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, in // --- clipping // intersects current and x,y,w,h rectangle and returns result as a new Fl_Region -static Fl_Region intersect_region_and_rect(Fl_Region current, int x,int y,int w, int h) +static Fl_Region intersect_region_and_rect(Fl_Region current_, int x,int y,int w, int h) { - if (current == NULL) return Fl_Graphics_Driver::default_driver().XRectangleRegion(x,y,w,h); + if (current_ == NULL) return Fl_Graphics_Driver::default_driver().XRectangleRegion(x,y,w,h); + struct flCocoaRegion* current = (struct flCocoaRegion*)current_; CGRect r = Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(x, y, w, h); - Fl_Region outr = (Fl_Region)malloc(sizeof(*outr)); + struct flCocoaRegion* outr = (struct flCocoaRegion*)malloc(sizeof(struct flCocoaRegion)); outr->count = current->count; outr->rects =(CGRect*)malloc(outr->count * sizeof(CGRect)); int j = 0; @@ -236,7 +237,7 @@ static Fl_Region intersect_region_and_rect(Fl_Region current, int x,int y,int w, } else { Fl_Graphics_Driver::default_driver().XDestroyRegion(outr); - outr = Fl_Graphics_Driver::default_driver().XRectangleRegion(0,0,0,0); + outr = (struct flCocoaRegion*)Fl_Graphics_Driver::default_driver().XRectangleRegion(0,0,0,0); } return outr; } @@ -261,7 +262,7 @@ void Fl_Quartz_Graphics_Driver::push_clip(int x, int y, int w, int h) { int Fl_Quartz_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ X = x; Y = y; W = w; H = h; - Fl_Region r = rstack[rstackptr]; + struct flCocoaRegion* r = (struct flCocoaRegion*)rstack[rstackptr]; if (!r) return 0; CGRect arg = fl_cgrectmake_cocoa(x, y, w, h); CGRect u = CGRectMake(0,0,0,0); @@ -283,7 +284,7 @@ int Fl_Quartz_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& int Fl_Quartz_Graphics_Driver::not_clipped(int x, int y, int w, int h) { if (x+w <= 0 || y+h <= 0) return 0; - Fl_Region r = rstack[rstackptr]; + struct flCocoaRegion* r = (struct flCocoaRegion*)rstack[rstackptr]; if (!r) return 1; CGRect arg = fl_cgrectmake_cocoa(x, y, w, h); for (int i = 0; i < r->count; i++) { @@ -295,7 +296,7 @@ int Fl_Quartz_Graphics_Driver::not_clipped(int x, int y, int w, int h) { void Fl_Quartz_Graphics_Driver::restore_clip() { fl_clip_state_number++; - Fl_Region r = rstack[rstackptr]; + struct flCocoaRegion* r = (struct flCocoaRegion*)rstack[rstackptr]; if ( fl_window || gc_ ) { // clipping for a true window or an offscreen buffer if (gc_) { CGContextRestoreGState(gc_); diff --git a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H index 4e6f8c79d..f70a43ed6 100644 --- a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H +++ b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H @@ -23,7 +23,7 @@ class Fl_Quartz_Image_Surface_Driver : public Fl_Image_Surface_Driver { virtual void end_current(); public: - Window pre_window; + FLWindow *pre_window; Fl_Quartz_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off); ~Fl_Quartz_Image_Surface_Driver(); void set_current(); diff --git a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx index c638bfb79..2f1acc5d9 100644 --- a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx @@ -32,25 +32,25 @@ Fl_Quartz_Image_Surface_Driver::Fl_Quartz_Image_Surface_Driver(int w, int h, int W *= s; H *= s; } CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); - offscreen = off ? off : CGBitmapContextCreate(calloc(W*H,4), W, H, 8, W*4, lut, kCGImageAlphaPremultipliedLast); + offscreen = off ? off : (Fl_Offscreen)CGBitmapContextCreate(calloc(W*H,4), W, H, 8, W*4, lut, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(lut); driver(new Fl_Quartz_Graphics_Driver); - CGContextTranslateCTM(offscreen, 0.5*s, -0.5*s); // as when drawing to a window + CGContextTranslateCTM((CGContextRef)offscreen, 0.5*s, -0.5*s); // as when drawing to a window if (high_res) { - CGContextScaleCTM(offscreen, s, s); + CGContextScaleCTM((CGContextRef)offscreen, s, s); driver()->scale(s); } - CGContextSetShouldAntialias(offscreen, false); - CGContextTranslateCTM(offscreen, 0, height); - CGContextScaleCTM(offscreen, 1.0f, -1.0f); - CGContextSaveGState(offscreen); - CGContextSetRGBFillColor(offscreen, 1, 1, 1, 0); - CGContextFillRect(offscreen, CGRectMake(0,0,w,h)); + CGContextSetShouldAntialias((CGContextRef)offscreen, false); + CGContextTranslateCTM((CGContextRef)offscreen, 0, height); + CGContextScaleCTM((CGContextRef)offscreen, 1.0f, -1.0f); + CGContextSaveGState((CGContextRef)offscreen); + CGContextSetRGBFillColor((CGContextRef)offscreen, 1, 1, 1, 0); + CGContextFillRect((CGContextRef)offscreen, CGRectMake(0,0,w,h)); } Fl_Quartz_Image_Surface_Driver::~Fl_Quartz_Image_Surface_Driver() { if (offscreen && !external_offscreen) { - void *data = CGBitmapContextGetData(offscreen); + void *data = CGBitmapContextGetData((CGContextRef)offscreen); free(data); CGContextRelease((CGContextRef)offscreen); } @@ -60,30 +60,30 @@ Fl_Quartz_Image_Surface_Driver::~Fl_Quartz_Image_Surface_Driver() { void Fl_Quartz_Image_Surface_Driver::set_current() { Fl_Surface_Device::set_current(); pre_window = fl_window; - driver()->gc(offscreen); + driver()->gc((CGContextRef)offscreen); fl_window = 0; - ((Fl_Quartz_Graphics_Driver*)driver())->high_resolution( CGBitmapContextGetWidth(offscreen) > (size_t)width ); + ((Fl_Quartz_Graphics_Driver*)driver())->high_resolution( CGBitmapContextGetWidth((CGContextRef)offscreen) > (size_t)width ); } void Fl_Quartz_Image_Surface_Driver::translate(int x, int y) { - CGContextRestoreGState(offscreen); - CGContextSaveGState(offscreen); - CGContextTranslateCTM(offscreen, x, y); - CGContextSaveGState(offscreen); + CGContextRestoreGState((CGContextRef)offscreen); + CGContextSaveGState((CGContextRef)offscreen); + CGContextTranslateCTM((CGContextRef)offscreen, x, y); + CGContextSaveGState((CGContextRef)offscreen); } void Fl_Quartz_Image_Surface_Driver::untranslate() { - CGContextRestoreGState(offscreen); + CGContextRestoreGState((CGContextRef)offscreen); } Fl_RGB_Image* Fl_Quartz_Image_Surface_Driver::image() { - CGContextFlush(offscreen); - int W = CGBitmapContextGetWidth(offscreen); - int H = CGBitmapContextGetHeight(offscreen); - int bpr = CGBitmapContextGetBytesPerRow(offscreen); - int bpp = CGBitmapContextGetBitsPerPixel(offscreen)/8; - uchar *base = (uchar*)CGBitmapContextGetData(offscreen); + CGContextFlush((CGContextRef)offscreen); + int W = CGBitmapContextGetWidth((CGContextRef)offscreen); + int H = CGBitmapContextGetHeight((CGContextRef)offscreen); + int bpr = CGBitmapContextGetBytesPerRow((CGContextRef)offscreen); + int bpp = CGBitmapContextGetBitsPerPixel((CGContextRef)offscreen)/8; + uchar *base = (uchar*)CGBitmapContextGetData((CGContextRef)offscreen); int idx, idy; uchar *pdst, *psrc; unsigned char *data = new uchar[W * H * 3]; diff --git a/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx index 07b3038f0..60a0cad51 100644 --- a/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx @@ -43,7 +43,7 @@ Fl_Wayland_Copy_Surface_Driver::~Fl_Wayland_Copy_Surface_Driver() { void Fl_Wayland_Copy_Surface_Driver::set_current() { Fl_Surface_Device::set_current(); - ((Fl_Wayland_Graphics_Driver*)driver())->set_buffer(img_surf->offscreen()); + ((Fl_Wayland_Graphics_Driver*)driver())->set_buffer((struct fl_wld_buffer *)img_surf->offscreen()); } diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx index 979cef3d8..89014826f 100644 --- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx @@ -94,7 +94,7 @@ char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, { // write str to a bitmap just big enough Fl_Image_Surface *surf = new Fl_Image_Surface(w, h); - Fl_Font f=fl_font(); + Fl_Font f = fl_font(); Fl_Surface_Device::push_current(surf); fl_color(FL_BLACK); fl_rectf(0, 0, w, h); @@ -104,7 +104,8 @@ char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, // get the R channel only of the bitmap char *alpha_buf = new char[w*h], *r = alpha_buf, *q; for (int i = 0; i < h; i++) { - q = (char*)surf->offscreen()->draw_buffer + i * surf->offscreen()->stride; + struct fl_wld_buffer *off = (struct fl_wld_buffer *)surf->offscreen(); + q = (char*)off->draw_buffer + i * off->stride; for (int j = 0; j < w; j++) { *r++ = *q; q += 4; @@ -174,7 +175,7 @@ GLContext Fl_Wayland_Gl_Window_Driver::create_gl_context(Fl_Window* window, cons if (context_list && nContext) shared_ctx = context_list[0]; static const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - GLContext ctx = (GLContext)eglCreateContext(egl_display, ((Fl_Wayland_Gl_Choice*)g)->egl_conf, shared_ctx?shared_ctx:EGL_NO_CONTEXT, context_attribs); + GLContext ctx = (GLContext)eglCreateContext(egl_display, ((Fl_Wayland_Gl_Choice*)g)->egl_conf, shared_ctx?(EGLContext)shared_ctx:EGL_NO_CONTEXT, context_attribs); //fprintf(stderr, "eglCreateContext=%p shared_ctx=%p\n", ctx, shared_ctx); if (ctx) add_context(ctx); @@ -183,7 +184,7 @@ GLContext Fl_Wayland_Gl_Window_Driver::create_gl_context(Fl_Window* window, cons void Fl_Wayland_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) { - struct wld_window *win = fl_xid(w); + struct wld_window *win = fl_wl_xid(w); if (!win) return; Fl_Wayland_Window_Driver *dr = Fl_Wayland_Window_Driver::driver(w); EGLSurface target_egl_surface = NULL; @@ -221,7 +222,7 @@ void Fl_Wayland_Gl_Window_Driver::delete_gl_context(GLContext context) { cached_window = 0; } //EGLBoolean b = - eglDestroyContext(egl_display, context); + eglDestroyContext(egl_display, (EGLContext)context); //fprintf(stderr,"EGL context %p destroyed %s\n", context, b==EGL_TRUE?"successfully":"w/ error"); //b = eglDestroySurface(egl_display, egl_surface); @@ -246,7 +247,7 @@ void Fl_Wayland_Gl_Window_Driver::redraw_overlay() { void Fl_Wayland_Gl_Window_Driver::make_current_before() { if (!egl_window) { - struct wld_window *win = fl_xid(pWindow); + struct wld_window *win = fl_wl_xid(pWindow); struct wl_surface *surface = win->wl_surface; egl_window = wl_egl_window_create(surface, pWindow->pixel_w(), pWindow->pixel_h()); if (egl_window == EGL_NO_SURFACE) { @@ -270,7 +271,7 @@ void Fl_Wayland_Gl_Window_Driver::make_current_before() { float Fl_Wayland_Gl_Window_Driver::pixels_per_unit() { int ns = Fl_Window_Driver::driver(pWindow)->screen_num(); - int wld_scale = pWindow->shown() ? fl_xid(pWindow)->scale : 1; + int wld_scale = pWindow->shown() ? fl_wl_xid(pWindow)->scale : 1; return wld_scale * Fl::screen_driver()->scale(ns); } @@ -360,7 +361,7 @@ static void delayed_flush(Fl_Gl_Window *win) { void Fl_Wayland_Gl_Window_Driver::resize(int is_a_resize, int W, int H) { if (!egl_window) return; - struct wld_window *win = fl_xid(pWindow); + struct wld_window *win = fl_wl_xid(pWindow); float f = Fl::screen_scale(pWindow->screen_num()); W = (W * win->scale) * f; H = (H * win->scale) * f; @@ -404,4 +405,7 @@ void Fl_Wayland_Gl_Window_Driver::gl_start() { glClear(GL_COLOR_BUFFER_BIT); } + +FL_EXPORT EGLContext fl_wl_glcontext(GLContext rc) { return (EGLContext)rc; } + #endif // HAVE_GL diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx index 78586dc59..986d25ddf 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx @@ -149,8 +149,9 @@ void Fl_Wayland_Graphics_Driver::set_color(Fl_Color i, unsigned c) { } -void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) { +void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen src, int srcx, int srcy) { // draw portion srcx,srcy,w,h of osrc to position x,y (top-left) of the graphics driver's surface + struct fl_wld_buffer *osrc = (struct fl_wld_buffer *)src; int height = osrc->data_size / osrc->stride; cairo_matrix_t matrix; cairo_get_matrix(cairo_, &matrix); diff --git a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx index 1638cf0d2..4f64434d8 100644 --- a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx @@ -33,12 +33,13 @@ Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, i w = int(w*d); h = int(h*d); } - offscreen = (struct fl_wld_buffer*)calloc(1, sizeof(struct fl_wld_buffer)); - offscreen->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w); - offscreen->data_size = offscreen->stride * h; - offscreen->draw_buffer = (uchar*)malloc(offscreen->data_size); - offscreen->width = w; - Fl_Wayland_Graphics_Driver::cairo_init(offscreen, w, h, offscreen->stride, CAIRO_FORMAT_RGB24); + struct fl_wld_buffer *off_ = (struct fl_wld_buffer*)calloc(1, sizeof(struct fl_wld_buffer)); + off_->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w); + off_->data_size = off_->stride * h; + off_->draw_buffer = (uchar*)malloc(off_->data_size); + off_->width = w; + offscreen = (Fl_Offscreen)off_; + Fl_Wayland_Graphics_Driver::cairo_init(off_, w, h, off_->stride, CAIRO_FORMAT_RGB24); } driver(new Fl_Wayland_Graphics_Driver()); if (d != 1 && high_res) driver()->scale(d); @@ -47,24 +48,24 @@ Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, i Fl_Wayland_Image_Surface_Driver::~Fl_Wayland_Image_Surface_Driver() { if (offscreen && !external_offscreen) { - cairo_destroy(offscreen->cairo_); - free(offscreen->draw_buffer); - free(offscreen); + cairo_destroy(((struct fl_wld_buffer *)offscreen)->cairo_); + free(((struct fl_wld_buffer *)offscreen)->draw_buffer); + free((struct fl_wld_buffer *)offscreen); } delete driver(); } void Fl_Wayland_Image_Surface_Driver::set_current() { Fl_Surface_Device::set_current(); - ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer(offscreen); + ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer((struct fl_wld_buffer*)offscreen); pre_window = Fl_Wayland_Window_Driver::wld_window; - fl_window = Fl_Wayland_Window_Driver::wld_window = NULL; + Fl_Wayland_Window_Driver::wld_window = NULL; } void Fl_Wayland_Image_Surface_Driver::end_current() { - cairo_surface_t *surf = cairo_get_target(offscreen->cairo_); + cairo_surface_t *surf = cairo_get_target(((struct fl_wld_buffer *)offscreen)->cairo_); cairo_surface_flush(surf); - fl_window = Fl_Wayland_Window_Driver::wld_window = pre_window; + Fl_Wayland_Window_Driver::wld_window = pre_window; } void Fl_Wayland_Image_Surface_Driver::translate(int x, int y) { @@ -77,20 +78,20 @@ void Fl_Wayland_Image_Surface_Driver::untranslate() { Fl_RGB_Image* Fl_Wayland_Image_Surface_Driver::image() { // Convert depth-4 image in draw_buffer to a depth-3 image while exchanging R and B colors - int height = offscreen->data_size / offscreen->stride; - uchar *rgb = new uchar[offscreen->width * height * 3]; + int height = ((struct fl_wld_buffer *)offscreen)->data_size / ((struct fl_wld_buffer *)offscreen)->stride; + uchar *rgb = new uchar[((struct fl_wld_buffer *)offscreen)->width * height * 3]; uchar *p = rgb; uchar *q; for (int j = 0; j < height; j++) { - q = offscreen->draw_buffer + j*offscreen->stride; - for (int i = 0; i < offscreen->width; i++) { // exchange R and B colors, transmit G + q = ((struct fl_wld_buffer *)offscreen)->draw_buffer + j*((struct fl_wld_buffer *)offscreen)->stride; + for (int i = 0; i < ((struct fl_wld_buffer *)offscreen)->width; i++) { // exchange R and B colors, transmit G *p = *(q+2); *(p+1) = *(q+1); *(p+2) = *q; p += 3; q += 4; } } - Fl_RGB_Image *image = new Fl_RGB_Image(rgb, offscreen->width, height, 3); + Fl_RGB_Image *image = new Fl_RGB_Image(rgb, ((struct fl_wld_buffer *)offscreen)->width, height, 3); image->alloc_array = 1; return image; } diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H index 196f07d5e..a7a3f9512 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H @@ -64,6 +64,10 @@ class Fl_Wayland_Screen_Driver : public Fl_Screen_Driver static bool insertion_point_location_is_valid; public: static struct wl_display *wl_display; + // use it to make sure the Wayland leg was selected and fl_open_display() has run + static struct wl_registry *wl_registry; + // true when an app is forbidden to use its Wayland leg + static bool wld_disabled; static void insertion_point_location(int x, int y, int height); static bool insertion_point_location(int *px, int *py, int *pwidth, int *pheight); int get_mouse_unscaled(int &xx, int &yy); diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx index 372d08b32..821bdd56a 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx @@ -227,13 +227,16 @@ static inline void checkdouble() { struct wl_display *Fl_Wayland_Screen_Driver::wl_display = NULL; +struct wl_registry *Fl_Wayland_Screen_Driver::wl_registry = NULL; +bool Fl_Wayland_Screen_Driver::wld_disabled = false; + Fl_Window *Fl_Wayland_Screen_Driver::surface_to_window(struct wl_surface *surface) { if (surface) { Fl_X *xp = Fl_X::first; while (xp) { - if (xp->xid->wl_surface == surface) return xp->w; + if (((struct wld_window*)xp->xid)->wl_surface == surface) return xp->w; xp = xp->next; } } @@ -335,9 +338,9 @@ static void pointer_button(void *data, win = win->top_window(); wld_event_time = time; if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED && seat->pointer_focus == NULL && - fl_xid(win)->kind == Fl_Wayland_Window_Driver::DECORATED) { + (fl_wl_xid(win))->kind == Fl_Wayland_Window_Driver::DECORATED) { // click on titlebar - libdecor_frame_move(fl_xid(win)->frame, seat->wl_seat, serial); + libdecor_frame_move(fl_wl_xid(win)->frame, seat->wl_seat, serial); return; } int b = 0; @@ -907,7 +910,7 @@ static void output_done(void *data, struct wl_output *wl_output) //fprintf(stderr, "output_done output=%p\n",output); Fl_X *xp = Fl_X::first; while (xp) { // all mapped windows - struct wld_window *win = xp->xid; + struct wld_window *win = (struct wld_window*)xp->xid; wl_list_for_each(window_output, &(win->outputs), link) { // all Fl_Wayland_Window_Driver::window_output for this window if (window_output->output == output) { Fl_Wayland_Window_Driver *win_driver = Fl_Wayland_Window_Driver::driver(win->fl_win); @@ -1041,7 +1044,7 @@ static void registry_handle_global_remove(void *data, struct wl_registry *regist if (output->id == name) { // the screen being removed Fl_X *xp = Fl_X::first; while (xp) { // all mapped windows - struct wld_window *win = xp->xid; + struct wld_window *win = (struct wld_window*)xp->xid; wl_list_for_each_safe(window_output, tmp, &(win->outputs), link) { // all Fl_Wayland_Window_Driver::window_output for this window if (window_output->output == output) { wl_list_remove(&window_output->link); @@ -1086,16 +1089,16 @@ Fl_Wayland_Screen_Driver::Fl_Wayland_Screen_Driver() : Fl_Screen_Driver() { } void Fl_Wayland_Screen_Driver::open_display_platform() { - struct wl_registry *wl_registry; - static bool beenHereDoneThat = false; if (beenHereDoneThat) return; beenHereDoneThat = true; - wl_display = wl_display_connect(NULL); if (!wl_display) { - Fl::fatal("No Wayland connection\n"); + wl_display = wl_display_connect(NULL); + if (!wl_display) { + Fl::fatal("No Wayland connection\n"); + } } wl_list_init(&seats); wl_list_init(&outputs); @@ -1121,6 +1124,7 @@ void Fl_Wayland_Screen_Driver::close_display() { Fl::remove_fd(wl_display_get_fd(Fl_Wayland_Screen_Driver::wl_display)); wl_display_disconnect(Fl_Wayland_Screen_Driver::wl_display); Fl_Wayland_Screen_Driver::wl_display = NULL; + Fl_Wayland_Screen_Driver::wl_registry = NULL; } @@ -1141,7 +1145,7 @@ void Fl_Wayland_Screen_Driver::init_workarea() int Fl_Wayland_Screen_Driver::x() { - if (!Fl_Wayland_Screen_Driver::wl_display) open_display(); + if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl_Wayland_Screen_Driver::output *output; wl_list_for_each(output, &outputs, link) { break; @@ -1150,7 +1154,7 @@ int Fl_Wayland_Screen_Driver::x() { } int Fl_Wayland_Screen_Driver::y() { - if (!Fl_Wayland_Screen_Driver::wl_display) open_display(); + if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl_Wayland_Screen_Driver::output *output; wl_list_for_each(output, &outputs, link) { break; @@ -1159,7 +1163,7 @@ int Fl_Wayland_Screen_Driver::y() { } int Fl_Wayland_Screen_Driver::w() { - if (!Fl_Wayland_Screen_Driver::wl_display) open_display(); + if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl_Wayland_Screen_Driver::output *output; wl_list_for_each(output, &outputs, link) { break; @@ -1168,7 +1172,7 @@ int Fl_Wayland_Screen_Driver::w() { } int Fl_Wayland_Screen_Driver::h() { - if (!Fl_Wayland_Screen_Driver::wl_display) open_display(); + if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl_Wayland_Screen_Driver::output *output; wl_list_for_each(output, &outputs, link) { break; @@ -1178,7 +1182,7 @@ int Fl_Wayland_Screen_Driver::h() { void Fl_Wayland_Screen_Driver::init() { - if (!Fl_Wayland_Screen_Driver::wl_display) open_display(); + if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); } @@ -1315,8 +1319,8 @@ const char *Fl_Wayland_Screen_Driver::get_system_scheme() Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, bool ignore, bool *p_ignore) { - Window xid = win ? fl_xid(win) : NULL; - struct fl_wld_buffer *buffer = win ? xid->buffer : (Fl_Offscreen)Fl_Surface_Device::surface()->driver()->gc(); + struct wld_window* xid = win ? fl_wl_xid(win) : NULL; + struct fl_wld_buffer *buffer = win ? xid->buffer : (struct fl_wld_buffer *)Fl_Surface_Device::surface()->driver()->gc(); float s = win ? xid->scale * scale(win->screen_num()) : Fl_Surface_Device::surface()->driver()->scale(); int Xs, Ys, ws, hs; @@ -1346,8 +1350,9 @@ Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w, } -void Fl_Wayland_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &height) +void Fl_Wayland_Screen_Driver::offscreen_size(Fl_Offscreen off_, int &width, int &height) { + struct fl_wld_buffer *off = (struct fl_wld_buffer *)off_; width = off->width; height = off->data_size / off->stride; } @@ -1457,3 +1462,8 @@ void Fl_Wayland_Screen_Driver::reset_spot() { Fl_Wayland_Screen_Driver::next_marked_length = 0; Fl_Wayland_Screen_Driver::insertion_point_location_is_valid = false; } + + +struct wl_display *fl_wl_display() { + return Fl_Wayland_Screen_Driver::wl_display; +} diff --git a/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx index a54e2ac5f..4b26a17ea 100644 --- a/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx @@ -18,6 +18,7 @@ #include "Fl_Wayland_System_Driver.H" #include #include "Fl_Wayland_Window_Driver.H" +#include "Fl_Wayland_Screen_Driver.H" #include #include "../../../libdecor/src/libdecor.h" @@ -55,7 +56,7 @@ void *Fl_Wayland_System_Driver::control_maximize_button(void *data) { Fl_Window *win = Fl::first_window(); while (win) { if (!win->parent() && win->border() && - !(Fl_X::i(win)->xid->state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ) { + !( ((struct wld_window*)Fl_X::i(win)->xid)->state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ) { win_dims *dim = new win_dims; dim->tracker = new Fl_Widget_Tracker(win); Fl_Window_Driver *dr = Fl_Window_Driver::driver(win); diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 38230b3db..96985c10b 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -49,7 +49,7 @@ extern "C" { #define fl_max(a,b) ((a) > (b) ? (a) : (b)) -Window fl_window; + struct wld_window *Fl_Wayland_Window_Driver::wld_window = NULL; @@ -112,7 +112,7 @@ void Fl_Wayland_Window_Driver::decorated_win_size(int &w, int &h) h = win->h(); if (!win->shown() || win->parent() || !win->border() || !win->visible()) return; int X, titlebar_height; - libdecor_frame_translate_coordinate(fl_xid(win)->frame, 0, 0, &X, &titlebar_height); + libdecor_frame_translate_coordinate(fl_wl_xid(win)->frame, 0, 0, &X, &titlebar_height); //printf("titlebar_height=%d\n",titlebar_height); h = win->h() + ceil(titlebar_height / Fl::screen_scale(win->screen_num())); } @@ -135,7 +135,7 @@ int Fl_Wayland_Window_Driver::decorated_w() } struct xdg_toplevel *Fl_Wayland_Window_Driver::xdg_toplevel() { - Window w = fl_xid(pWindow); + struct wld_window * w = fl_wl_xid(pWindow); struct xdg_toplevel *top = NULL; if (w->kind == DECORATED) top = libdecor_frame_get_xdg_toplevel(w->frame); else if (w->kind == UNFRAMED) top = w->xdg_toplevel; @@ -144,10 +144,10 @@ struct xdg_toplevel *Fl_Wayland_Window_Driver::xdg_toplevel() { void Fl_Wayland_Window_Driver::take_focus() { - Window w = fl_xid(pWindow); + struct wld_window *w = fl_wl_xid(pWindow); if (w) { Fl_Window *old_first = Fl::first_window(); - Window first_xid = (old_first ? fl_xid(old_first->top_window()) : NULL); + struct wld_window *first_xid = (old_first ? fl_wl_xid(old_first->top_window()) : NULL); if (first_xid && first_xid != w && xdg_toplevel()) { // this will move the target window to the front Fl_Wayland_Window_Driver *top_dr = Fl_Wayland_Window_Driver::driver(old_first->top_window()); @@ -157,7 +157,7 @@ void Fl_Wayland_Window_Driver::take_focus() xdg_toplevel_set_parent(xdg_toplevel(), NULL); } // this sets the first window - fl_find(w); + fl_wl_find(w); } } @@ -185,7 +185,7 @@ void Fl_Wayland_Window_Driver::flush_overlay() fl_copy_offscreen(0, 0, oWindow->w(), oWindow->h(), other_xid, 0, 0); } if (overlay() == oWindow) oWindow->draw_overlay(); - Window xid = fl_xid(pWindow); + struct wld_window * xid = fl_wl_xid(pWindow); wl_surface_damage_buffer(xid->wl_surface, 0, 0, pWindow->w() * xid->scale, pWindow->h() * xid->scale); } @@ -295,7 +295,7 @@ void Fl_Wayland_Window_Driver::capture_titlebar_and_borders(Fl_RGB_Image*& top, top = left = bottom = right = NULL; if (pWindow->decorated_h() == h()) return; int htop = pWindow->decorated_h() - pWindow->h(); - struct wld_window *wwin = fl_xid(pWindow); + struct wld_window *wwin = fl_wl_xid(pWindow); int width, height, stride; uchar *cairo_data = fl_libdecor_titlebar_buffer(wwin->frame, &width, &height, &stride); if (!cairo_data) return; @@ -342,7 +342,7 @@ void Fl_Wayland_Window_Driver::make_current() { Fl::fatal(err_message); } - struct wld_window *window = fl_xid(pWindow); + struct wld_window *window = fl_wl_xid(pWindow); if (window->buffer) { ((Fl_Cairo_Graphics_Driver*)fl_graphics_driver)->needs_commit_tag( &window->buffer->draw_buffer_needs_commit); @@ -355,7 +355,7 @@ void Fl_Wayland_Window_Driver::make_current() { } fl_graphics_driver->clip_region(0); - fl_window = Fl_Wayland_Window_Driver::wld_window = window; + Fl_Wayland_Window_Driver::wld_window = window; float scale = Fl::screen_scale(pWindow->screen_num()) * window->scale; if (!window->buffer) { window->buffer = Fl_Wayland_Graphics_Driver::create_shm_buffer( @@ -385,11 +385,11 @@ void Fl_Wayland_Window_Driver::flush() { if (scale != fl_graphics_driver->scale() || W != pWindow->w() || H != pWindow->h()) gl_plugin()->invalidate(pWindow); return; } - struct wld_window *window = fl_xid(pWindow); + struct wld_window *window = fl_wl_xid(pWindow); if (!window || !window->configured_width) return; Fl_X *i = Fl_X::i(pWindow); - Fl_Region r = i->region; + struct flCairoRegion* r = (struct flCairoRegion*)i->region; float f = Fl::screen_scale(pWindow->screen_num()); if (r && window->buffer) { for (int i = 0; i < r->count; i++) { @@ -440,7 +440,7 @@ void Fl_Wayland_Window_Driver::hide() { ip->region = 0; } screen_num_ = -1; - struct wld_window *wld_win = ip->xid; + struct wld_window *wld_win = (struct wld_window*)ip->xid; if (wld_win) { // this test makes sure ip->xid has not been destroyed already Fl_Wayland_Graphics_Driver::buffer_release(wld_win); //fprintf(stderr, "Before hide: sub=%p frame=%p xdg=%p top=%p pop=%p surf=%p\n", wld_win->subsurface, wld_win->frame, wld_win->xdg_surface, wld_win->xdg_toplevel, wld_win->xdg_popup, wld_win->wl_surface); @@ -479,7 +479,7 @@ void Fl_Wayland_Window_Driver::hide() { } free(wld_win); if (pWindow->as_gl_window() && in_flush) { - ip->xid = NULL; + ip->xid = 0; ip->next = NULL; // to end the loop in calling Fl::flush() Fl::add_timeout(.01, (Fl_Timeout_Handler)delayed_delete_Fl_X, ip); } else { @@ -490,9 +490,9 @@ void Fl_Wayland_Window_Driver::hide() { void Fl_Wayland_Window_Driver::map() { Fl_X* ip = Fl_X::i(pWindow); - struct wld_window *wl_win = ip->xid; + struct wld_window *wl_win = (struct wld_window*)ip->xid; if (wl_win->kind == SUBWINDOW && !wl_win->subsurface) { - struct wld_window *parent = fl_xid(pWindow->window()); + struct wld_window *parent = fl_wl_xid(pWindow->window()); if (parent) { Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); wl_win->subsurface = wl_subcompositor_get_subsurface(scr_driver->wl_subcompositor, wl_win->wl_surface, parent->wl_surface); @@ -512,7 +512,7 @@ void Fl_Wayland_Window_Driver::map() { void Fl_Wayland_Window_Driver::unmap() { Fl_X* ip = Fl_X::i(pWindow); - struct wld_window *wl_win = ip->xid; + struct wld_window *wl_win = (struct wld_window*)ip->xid; if (wl_win->kind == SUBWINDOW && wl_win->wl_surface) { wl_surface_attach(wl_win->wl_surface, NULL, 0, 0); Fl_Wayland_Graphics_Driver::buffer_release(wl_win); @@ -525,7 +525,7 @@ void Fl_Wayland_Window_Driver::unmap() { void Fl_Wayland_Window_Driver::size_range() { if (shown()) { Fl_X* ip = Fl_X::i(pWindow); - struct wld_window *wl_win = ip->xid; + struct wld_window *wl_win = (struct wld_window*)ip->xid; float f = Fl::screen_scale(pWindow->screen_num()); if (wl_win->kind == DECORATED && wl_win->frame) { int X,Y,W,H; @@ -553,7 +553,7 @@ void Fl_Wayland_Window_Driver::size_range() { void Fl_Wayland_Window_Driver::iconize() { Fl_X* ip = Fl_X::i(pWindow); - struct wld_window *wl_win = ip->xid; + struct wld_window *wl_win = (struct wld_window*)ip->xid; if (wl_win->kind == DECORATED) { libdecor_frame_set_minimized(wl_win->frame); Fl::handle(FL_HIDE, pWindow); @@ -577,7 +577,7 @@ void Fl_Wayland_Window_Driver::decoration_sizes(int *top, int *left, int *right int Fl_Wayland_Window_Driver::scroll(int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, void (*draw_area)(void*, int,int,int,int), void* data) { - Window xid = fl_xid(pWindow); + struct wld_window * xid = fl_wl_xid(pWindow); struct fl_wld_buffer *buffer = xid->buffer; float s = xid->scale * fl_graphics_driver->scale(); if (s != 1) { @@ -781,7 +781,7 @@ static void handle_configure(struct libdecor_frame *frame, void Fl_Wayland_Window_Driver::wait_for_expose() { Fl_Window_Driver::wait_for_expose(); - Window xid = fl_xid(pWindow); + struct wld_window * xid = fl_wl_xid(pWindow); if (pWindow->fullscreen_active()) { if (xid->kind == DECORATED) { while (!(xid->state & LIBDECOR_WINDOW_STATE_FULLSCREEN) || !(xid->state & LIBDECOR_WINDOW_STATE_ACTIVE)) { @@ -897,7 +897,7 @@ static void popup_done(void *data, struct xdg_popup *xdg_popup) { #if USE_GRAB_POPUP if (mem_grabbing_popup == xdg_popup) { Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); - libdecor_frame_popup_ungrab(fl_xid(mem_parent)->frame, scr_driver->get_seat_name()); + libdecor_frame_popup_ungrab(fl_wl_xid(mem_parent)->frame, scr_driver->get_seat_name()); mem_grabbing_popup = NULL; mem_parent = NULL; } @@ -1003,7 +1003,7 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow() if (!target) target = Fl::first_window(); Fl_Window *parent_win = target->top_window(); while (parent_win && parent_win->menu_window()) parent_win = Fl::next_window(parent_win); - Window parent_xid = fl_xid(parent_win); + struct wld_window * parent_xid = fl_wl_xid(parent_win); struct xdg_surface *parent_xdg = parent_xid->xdg_surface; float f = Fl::screen_scale(parent_win->screen_num()); //fprintf(stderr, "menu parent_win=%p pos:%dx%d size:%dx%d\n", parent_win, pWindow->x(), pWindow->y(), pWindow->w(), pWindow->h()); @@ -1029,7 +1029,8 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow() } else if ( pWindow->border() && !pWindow->parent() ) { // a decorated window new_window->kind = DECORATED; - if (!scr_driver->libdecor_context) scr_driver->libdecor_context = libdecor_new(Fl_Wayland_Screen_Driver::wl_display, &libdecor_iface); + if (!scr_driver->libdecor_context) + scr_driver->libdecor_context = libdecor_new(Fl_Wayland_Screen_Driver::wl_display, &libdecor_iface); new_window->frame = libdecor_decorate(scr_driver->libdecor_context, new_window->wl_surface, &libdecor_frame_iface, new_window); //fprintf(stderr, "makeWindow: libdecor_decorate=%p pos:%dx%d\n", new_window->frame, pWindow->x(), pWindow->y()); @@ -1046,7 +1047,7 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow() } else if (pWindow->parent()) { // for subwindows (GL or non-GL) new_window->kind = SUBWINDOW; - struct wld_window *parent = fl_xid(pWindow->window()); + struct wld_window *parent = fl_wl_xid(pWindow->window()); new_window->subsurface = wl_subcompositor_get_subsurface(scr_driver->wl_subcompositor, new_window->wl_surface, parent->wl_surface); //fprintf(stderr, "makeWindow: subsurface=%p\n", new_window->subsurface); float f = Fl::screen_scale(pWindow->top_window()->screen_num()); @@ -1073,9 +1074,9 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow() } Fl_Window *old_first = Fl::first_window(); - Window first_xid = (old_first ? fl_xid(old_first) : NULL); + struct wld_window * first_xid = (old_first ? fl_wl_xid(old_first) : NULL); Fl_X *xp = new Fl_X; - xp->xid = new_window; + xp->xid = (fl_uintptr_t)new_window; other_xid = 0; xp->w = pWindow; i(xp); @@ -1244,7 +1245,7 @@ int Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor c) { void Fl_Wayland_Window_Driver::update_scale() { - struct wld_window *window = fl_xid(pWindow); + struct wld_window *window = fl_wl_xid(pWindow); int scale = 0; Fl_Wayland_Window_Driver::window_output *window_output; @@ -1265,7 +1266,7 @@ void Fl_Wayland_Window_Driver::update_scale() void Fl_Wayland_Window_Driver::use_border() { if (!shown() || pWindow->parent()) return; pWindow->wait_for_expose(); // useful for border(0) just after show() - struct libdecor_frame *frame = fl_xid(pWindow)->frame; + struct libdecor_frame *frame = fl_wl_xid(pWindow)->frame; if (frame && Fl_Wayland_Screen_Driver::compositor != Fl_Wayland_Screen_Driver::KDE) { libdecor_frame_set_visibility(frame, pWindow->border()); pWindow->redraw(); @@ -1310,10 +1311,10 @@ void Fl_Wayland_Window_Driver::fullscreen_off(int X, int Y, int W, int H) { void Fl_Wayland_Window_Driver::label(const char *name, const char *iname) { - if (shown() && !parent() && fl_xid(pWindow)->kind == DECORATED) { + if (shown() && !parent() && fl_wl_xid(pWindow)->kind == DECORATED) { if (!name) name = ""; if (!iname) iname = fl_filename_name(name); - libdecor_frame_set_title(fl_xid(pWindow)->frame, name); + libdecor_frame_set_title(fl_wl_xid(pWindow)->frame, name); } } @@ -1322,7 +1323,7 @@ int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int // build a new wl_cursor and its image struct wl_cursor *new_cursor = (struct wl_cursor*)malloc(sizeof(struct wl_cursor)); struct cursor_image *new_image = (struct cursor_image*)calloc(1, sizeof(struct cursor_image)); - int scale = fl_xid(pWindow)->scale; + int scale = fl_wl_xid(pWindow)->scale; new_image->image.width = rgb->w() * scale; new_image->image.height = rgb->h() * scale; new_image->image.hotspot_x = hotx * scale; @@ -1338,7 +1339,7 @@ int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int new_cursor->images[0] = (struct wl_cursor_image*)new_image; new_cursor->name = strdup("custom cursor"); // draw the rgb image to the cursor's drawing buffer - Fl_Image_Surface *img_surf = new Fl_Image_Surface(new_image->image.width, new_image->image.height, 0, offscreen); + Fl_Image_Surface *img_surf = new Fl_Image_Surface(new_image->image.width, new_image->image.height, 0, (Fl_Offscreen)offscreen); Fl_Surface_Device::push_current(img_surf); Fl_Wayland_Graphics_Driver *driver = (Fl_Wayland_Graphics_Driver*)img_surf->driver(); cairo_scale(driver->cr(), scale, scale); @@ -1361,7 +1362,7 @@ int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int // This is only to fix a bug in libdecor where what libdecor_frame_set_min_content_size() // does is often destroyed by libdecor-cairo. static void delayed_minsize(Fl_Window *win) { - struct wld_window *wl_win = fl_xid(win); + struct wld_window *wl_win = fl_wl_xid(win); Fl_Window_Driver *driver = Fl_Window_Driver::driver(win); if (wl_win->kind == Fl_Wayland_Window_Driver::DECORATED) { float f = Fl::screen_scale(win->screen_num()); @@ -1377,7 +1378,7 @@ static void delayed_minsize(Fl_Window *win) { void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) { - struct wld_window *fl_win = fl_xid(pWindow); + struct wld_window *fl_win = fl_wl_xid(pWindow); if (fl_win && fl_win->kind == DECORATED && !xdg_toplevel()) { pWindow->wait_for_expose(); } @@ -1448,7 +1449,7 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) { } void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) { - Window xid_menu = fl_xid(pWindow); + struct wld_window * xid_menu = fl_wl_xid(pWindow); if (y == pWindow->y() && y >= 0) return; int true_y = y; int y_offset = 0; @@ -1468,7 +1469,7 @@ void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) { xid_menu->xdg_surface = xdg_wm_base_get_xdg_surface(scr_driver->xdg_wm_base, xid_menu->wl_surface); xdg_surface_add_listener(xid_menu->xdg_surface, &xdg_surface_listener, xid_menu); struct xdg_positioner *positioner = xdg_wm_base_create_positioner(scr_driver->xdg_wm_base); - Window parent_xid = fl_xid(Fl_Window_Driver::menu_parent()); + struct wld_window * parent_xid = fl_wl_xid(Fl_Window_Driver::menu_parent()); float f = Fl::screen_scale(Fl_Window_Driver::menu_parent()->screen_num()); int popup_x = x * f, popup_y = y * f; if (parent_xid->kind == DECORATED) @@ -1504,7 +1505,7 @@ void Fl_Wayland_Window_Driver::menu_window_area(int &X, int &Y, int &W, int &H, } -struct wl_surface *fl_wl_surface(Window xid) { +FL_EXPORT struct wl_surface *fl_wl_surface(struct wld_window *xid) { return xid->wl_surface; } @@ -1514,8 +1515,13 @@ cairo_t *fl_wl_cairo() { } -struct wl_display *fl_wl_display() { - return Fl_Wayland_Screen_Driver::wl_display; +Fl_Window *fl_wl_find(struct wld_window *xid) { + return Fl_Window_Driver::find((fl_uintptr_t)xid); +} + + +struct wld_window *fl_wl_xid(const Fl_Window *win) { + return (struct wld_window *)Fl_Window_Driver::xid(win); } diff --git a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx index 07bcd3ed4..2dca84924 100644 --- a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx +++ b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx @@ -34,7 +34,6 @@ //////////////////////////////////////////////////////////////// // Code used for copy and paste and DnD into the program: -//static Window fl_dnd_source_window; static char *fl_selection_buffer[2]; static int fl_selection_length[2]; @@ -99,7 +98,7 @@ static void data_source_handle_cancelled(void *data, struct wl_data_source *sour wl_data_source_destroy(source); doing_dnd = false; if (dnd_icon) { - Fl_Offscreen off = (Fl_Offscreen)wl_surface_get_user_data(dnd_icon); + struct fl_wld_buffer * off = (struct fl_wld_buffer *)wl_surface_get_user_data(dnd_icon); struct wld_window fake_window; fake_window.buffer = off; Fl_Wayland_Graphics_Driver::buffer_release(&fake_window); @@ -190,9 +189,9 @@ static Fl_Offscreen offscreen_from_text(const char *text, int scale) { if (width > 300*scale) width = 300*scale; height = nl * fl_height() + 3; width += 6; - Fl_Offscreen off = Fl_Wayland_Graphics_Driver::create_shm_buffer(width, height); + struct fl_wld_buffer * off = Fl_Wayland_Graphics_Driver::create_shm_buffer(width, height); memset(off->draw_buffer, 0, off->data_size); - Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 0, off); + Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 0, (Fl_Offscreen)off); Fl_Surface_Device::push_current(surf); p = text; fl_font(FL_HELVETICA, 10 * scale); @@ -213,7 +212,7 @@ static Fl_Offscreen offscreen_from_text(const char *text, int scale) { delete surf; cairo_surface_flush( cairo_get_target(off->cairo_) ); memcpy(off->data, off->draw_buffer, off->data_size); - return off; + return (Fl_Offscreen)off; } @@ -226,13 +225,13 @@ int Fl_Wayland_Screen_Driver::dnd(int use_selection) { wl_data_source_add_listener(source, &data_source_listener, (void*)0); wl_data_source_offer(source, wld_plain_text_clipboard); wl_data_source_set_actions(source, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY); - Fl_Offscreen off = NULL; + struct fl_wld_buffer * off = NULL; int s = 1; if (use_selection) { // use the text as dragging icon Fl_Widget *current = Fl::pushed() ? Fl::pushed() : Fl::first_window(); - s = fl_xid(current->top_window())->scale; - off = offscreen_from_text(fl_selection_buffer[0], s); + s = fl_wl_xid(current->top_window())->scale; + off = (struct fl_wld_buffer *)offscreen_from_text(fl_selection_buffer[0], s); dnd_icon = wl_compositor_create_surface(scr_driver->wl_compositor); } else dnd_icon = NULL; doing_dnd = true; @@ -571,7 +570,7 @@ void Fl_Wayland_Screen_Driver::paste(Fl_Widget &receiver, int clipboard, const c receiver.handle(FL_PASTE); } else if (type == Fl::clipboard_image && clipboard_contains(Fl::clipboard_image)) { if (get_clipboard_image()) return; - Window xid = fl_xid(receiver.top_window()); + struct wld_window * xid = fl_wl_xid(receiver.top_window()); if (xid && xid->scale > 1) { Fl_RGB_Image *rgb = (Fl_RGB_Image*)Fl::e_clipboard_data; rgb->scale(rgb->data_w() / xid->scale, rgb->data_h() / xid->scale); diff --git a/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx b/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx index 5a2a78bee..f80ee67ba 100644 --- a/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx +++ b/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx @@ -16,9 +16,12 @@ #include "Fl_Wayland_Gl_Window_Driver.H" +#include "Fl_Wayland_Screen_Driver.H" +#include "../X11/Fl_X11_Gl_Window_Driver.H" Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w) { - return new Fl_Wayland_Gl_Window_Driver(w); + if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Gl_Window_Driver(w); + return new Fl_X11_Gl_Window_Driver(w); } diff --git a/src/drivers/Wayland/fl_wayland_platform_init.cxx b/src/drivers/Wayland/fl_wayland_platform_init.cxx index 4500a0f45..8c81ab331 100644 --- a/src/drivers/Wayland/fl_wayland_platform_init.cxx +++ b/src/drivers/Wayland/fl_wayland_platform_init.cxx @@ -22,10 +22,61 @@ #include "Fl_Wayland_Window_Driver.H" #include "Fl_Wayland_Image_Surface_Driver.H" +#include "../Xlib/Fl_Xlib_Copy_Surface_Driver.H" +#include +#include "../Cairo/Fl_Display_Cairo_Graphics_Driver.H" +#include "../X11/Fl_X11_Screen_Driver.H" +#include "../X11/Fl_X11_System_Driver.H" +#include "../X11/Fl_X11_Window_Driver.H" +#include "../Xlib/Fl_Xlib_Image_Surface_Driver.H" + +#include +#include +#include + + +void fl_disable_wayland() { + if (Fl_Wayland_Screen_Driver::wl_display) { + wl_display_disconnect(Fl_Wayland_Screen_Driver::wl_display); + Fl_Wayland_Screen_Driver::wl_display = NULL; + delete Fl_Screen_Driver::system_driver; + Fl_Screen_Driver::system_driver = NULL; + } + Fl_Wayland_Screen_Driver::wld_disabled = true; + Fl::system_driver(); +} + -Fl_Copy_Surface_Driver *Fl_Copy_Surface_Driver::newCopySurfaceDriver(int w, int h) +Fl_System_Driver *Fl_System_Driver::newSystemDriver() { - return new Fl_Wayland_Copy_Surface_Driver(w, h); + const char *backend = ::getenv("FLTK_BACKEND"); + // fprintf(stderr, "FLTK_BACKEND='%s' XDG_RUNTIME_DIR='%s'\n",backend ? backend : "", xdg ? xdg : ""); + if (backend && strcmp(backend, "wayland") == 0) { + Fl_Wayland_Screen_Driver::wl_display = wl_display_connect(NULL); + if (!Fl_Wayland_Screen_Driver::wl_display) { + fprintf(stderr, "Error: no Wayland connection available, FLTK_BACKEND = '%s'\n", backend); + exit(1); + } + return new Fl_Wayland_System_Driver(); + } + else if (backend && strcmp(backend, "x11") == 0) { + return new Fl_X11_System_Driver(); + } + else if (!backend) { + if (!Fl_Wayland_Screen_Driver::wld_disabled && ::getenv("XDG_RUNTIME_DIR")) { + // env var XDG_RUNTIME_DIR is necessary for wayland + // is a Wayland connection available ? + Fl_Wayland_Screen_Driver::wl_display = wl_display_connect(NULL); + if (Fl_Wayland_Screen_Driver::wl_display) { // Yes, use Wayland drivers + // puts("using wayland"); + return new Fl_Wayland_System_Driver(); + } + } + return new Fl_X11_System_Driver(); + } + fprintf(stderr, "Error: unexpected value of FLTK_BACKEND: '%s'\n", backend); + exit(1); + return NULL; } @@ -52,32 +103,43 @@ static Fl_Fontdesc built_in_table[] = { // Pango font names FL_EXPORT Fl_Fontdesc *fl_fonts = built_in_table; -Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver() -{ - fl_graphics_driver = new Fl_Wayland_Graphics_Driver(); +Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver() { + if (Fl_Wayland_Screen_Driver::wl_display) { + fl_graphics_driver = new Fl_Wayland_Graphics_Driver(); +puts("using Fl_Wayland_Graphics_Driver"); + } else { + fl_graphics_driver = new Fl_Display_Cairo_Graphics_Driver(); +puts("using Fl_Display_Cairo_Graphics_Driver"); + } return fl_graphics_driver; } -Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver() -{ - return new Fl_Wayland_Screen_Driver(); +Fl_Copy_Surface_Driver *Fl_Copy_Surface_Driver::newCopySurfaceDriver(int w, int h) { + if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Copy_Surface_Driver(w, h); + return new Fl_Xlib_Copy_Surface_Driver(w, h); } -Fl_System_Driver *Fl_System_Driver::newSystemDriver() -{ - return new Fl_Wayland_System_Driver(); +Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver() { + if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Screen_Driver(); + + Fl_X11_Screen_Driver *d = new Fl_X11_Screen_Driver(); + for (int i = 0; i < MAX_SCREENS; i++) d->screens[i].scale = 1; + d->current_xft_dpi = 0.; // means the value of the Xft.dpi resource is still unknown + return d; } Fl_Window_Driver *Fl_Window_Driver::newWindowDriver(Fl_Window *w) { - return new Fl_Wayland_Window_Driver(w); + if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Window_Driver(w); + return new Fl_X11_Window_Driver(w); } Fl_Image_Surface_Driver *Fl_Image_Surface_Driver::newImageSurfaceDriver(int w, int h, int high_res, Fl_Offscreen off) { - return new Fl_Wayland_Image_Surface_Driver(w, h, high_res, off); + if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Image_Surface_Driver(w, h, high_res, off); + return new Fl_Xlib_Image_Surface_Driver(w, h, high_res, off); } diff --git a/src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx index cd6e98646..7952dfdc1 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx @@ -1,7 +1,7 @@ // // Class Fl_WinAPI_Gl_Window_Driver for the Fast Light Tool Kit (FLTK). // -// Copyright 2021 by Bill Spitzak and others. +// Copyright 2021-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 @@ -129,8 +129,8 @@ GLContext Fl_WinAPI_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_X* i = Fl_X::i(window); HDC hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc; if (!hdc) { - hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc = GetDCEx(i->xid, 0, DCX_CACHE); - fl_save_dc(i->xid, hdc); + hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc = GetDCEx((HWND)i->xid, 0, DCX_CACHE); + fl_save_dc((HWND)i->xid, hdc); SetPixelFormat(hdc, ((Fl_WinAPI_Gl_Choice*)g)->pixelformat, (PIXELFORMATDESCRIPTOR*)(&((Fl_WinAPI_Gl_Choice*)g)->pfd)); # if USE_COLORMAP if (fl_palette) SelectPalette(hdc, fl_palette, FALSE); @@ -139,7 +139,7 @@ GLContext Fl_WinAPI_Gl_Window_Driver::create_gl_context(Fl_Window* window, const GLContext context = layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc); if (context) { if (context_list && nContext) - wglShareLists(context_list[0], context); + wglShareLists((HGLRC)context_list[0], (HGLRC)context); add_context(context); } return context; @@ -150,7 +150,7 @@ void Fl_WinAPI_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) if (context != cached_context || w != cached_window) { cached_context = context; cached_window = w; - wglMakeCurrent(Fl_WinAPI_Window_Driver::driver(w)->private_dc, context); + wglMakeCurrent(Fl_WinAPI_Window_Driver::driver(w)->private_dc, (HGLRC)context); } } @@ -160,7 +160,7 @@ void Fl_WinAPI_Gl_Window_Driver::delete_gl_context(GLContext context) { cached_window = 0; wglMakeCurrent(0, 0); } - wglDeleteContext(context); + wglDeleteContext((HGLRC)context); del_context(context); } @@ -368,4 +368,6 @@ void Fl_WinAPI_Gl_Window_Driver::get_list(Fl_Font_Descriptor *fd, int r) { } +FL_EXPORT HGLRC fl_win32_glcontext(GLContext rc) { return (HGLRC)rc; } + #endif // HAVE_GL diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx index be9dac6bd..92f34b9ce 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx @@ -450,7 +450,7 @@ Fl_RGB_Image *Fl_WinAPI_Screen_Driver::read_win_rectangle_unscaled(int X, int Y, void Fl_WinAPI_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &height) { BITMAP bitmap; - if ( GetObject(off, sizeof(BITMAP), &bitmap) ) { + if ( GetObject((HBITMAP)off, sizeof(BITMAP), &bitmap) ) { width = bitmap.bmWidth; height = bitmap.bmHeight; } diff --git a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx index 459143dad..5f8c40d8d 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx @@ -317,7 +317,7 @@ void Fl_WinAPI_Window_Driver::flush_double() for an Fl_Double_Window. */ HDC sgc = fl_gc; - fl_gc = fl_makeDC(other_xid); + fl_gc = fl_makeDC((HBITMAP)other_xid); int savedc = SaveDC(fl_gc); fl_graphics_driver->gc(fl_gc); fl_graphics_driver->restore_clip(); // duplicate clip region into new gc @@ -462,7 +462,7 @@ void Fl_WinAPI_Window_Driver::hide() { int count = 0; Fl_Window *win, **doit = NULL; for (win = Fl::first_window(); win && ip; win = Fl::next_window(win)) { - if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == ip->xid) { + if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == (HWND)ip->xid) { count++; } } @@ -470,7 +470,7 @@ void Fl_WinAPI_Window_Driver::hide() { doit = new Fl_Window*[count]; count = 0; for (win = Fl::first_window(); win && ip; win = Fl::next_window(win)) { - if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == ip->xid) { + if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == (HWND)ip->xid) { doit[count++] = win; } } @@ -485,14 +485,14 @@ void Fl_WinAPI_Window_Driver::hide() { // icons(NULL, 0); // free_icons() is called by the Fl_Window destructor // this little trick keeps the current clipboard alive, even if we are about // to destroy the window that owns the selection. - if (GetClipboardOwner()==ip->xid) + if (GetClipboardOwner() == (HWND)ip->xid) fl_update_clipboard(); // Make sure we unlink this window from the clipboard chain - fl_clipboard_notify_retarget(ip->xid); + fl_clipboard_notify_retarget((HWND)ip->xid); // Send a message to myself so that I'll get out of the event loop... - PostMessage(ip->xid, WM_APP, 0, 0); - if (private_dc) fl_release_dc(ip->xid, private_dc); - if (ip->xid == fl_window && fl_graphics_driver->gc()) { + PostMessage((HWND)ip->xid, WM_APP, 0, 0); + if (private_dc) fl_release_dc((HWND)ip->xid, private_dc); + if ((HWND)ip->xid == fl_window && fl_graphics_driver->gc()) { fl_release_dc(fl_window, (HDC)fl_graphics_driver->gc()); fl_window = (HWND)-1; fl_graphics_driver->gc(0); @@ -505,11 +505,11 @@ void Fl_WinAPI_Window_Driver::hide() { // this little trickery seems to avoid the popup window stacking problem HWND p = GetForegroundWindow(); - if (p==GetParent(ip->xid)) { - ShowWindow(ip->xid, SW_HIDE); + if (p==GetParent((HWND)ip->xid)) { + ShowWindow((HWND)ip->xid, SW_HIDE); ShowWindow(p, SW_SHOWNA); } - DestroyWindow(ip->xid); + DestroyWindow((HWND)ip->xid); // end of fix for STR#3079 if (count) { int ii; @@ -541,7 +541,7 @@ void Fl_WinAPI_Window_Driver::unmap() { #if !defined(FL_DOXYGEN) // FIXME - silence Doxygen warning void Fl_WinAPI_Window_Driver::make_fullscreen(int X, int Y, int W, int H) { - Window xid = fl_xid(pWindow); + HWND xid = fl_xid(pWindow); int top, bottom, left, right; int sx, sy, sw, sh; @@ -589,7 +589,7 @@ void Fl_WinAPI_Window_Driver::fullscreen_off(int X, int Y, int W, int H) { // Remove the xid temporarily so that Fl_WinAPI_Window_Driver::fake_X_wm() behaves like it // does in Fl_WinAPI_Window_Driver::makeWindow(). HWND xid = fl_xid(pWindow); - Fl_X::i(pWindow)->xid = NULL; + Fl_X::i(pWindow)->xid = 0; int wx, wy, bt, bx, by; switch (fake_X_wm(wx, wy, bt, bx, by)) { case 0: @@ -603,7 +603,7 @@ void Fl_WinAPI_Window_Driver::fullscreen_off(int X, int Y, int W, int H) { } break; } - Fl_X::i(pWindow)->xid = xid; + Fl_X::i(pWindow)->xid = (fl_uintptr_t)xid; // compute window position and size in scaled units float s = Fl::screen_driver()->scale(screen_num()); int scaledX = int(ceil(X*s)), scaledY= int(ceil(Y*s)), scaledW = int(ceil(W*s)), scaledH = int(ceil(H*s)); @@ -712,3 +712,13 @@ void Fl_WinAPI_Window_Driver::resize_after_screen_change(void *data) { const Fl_Image* Fl_WinAPI_Window_Driver::shape() { return shape_data_ ? shape_data_->shape_ : NULL; } + + +HWND fl_win32_xid(const Fl_Window *win) { + return (HWND)Fl_Window_Driver::xid(win); +} + + +Fl_Window *fl_win32_find(HWND xid) { + return Fl_Window_Driver::find((fl_uintptr_t)xid); +} diff --git a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx index 9a092756a..b85aadd39 100644 --- a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx @@ -1,7 +1,7 @@ // // Class Fl_X11_Gl_Window_Driver for the Fast Light Tool Kit (FLTK). // -// Copyright 2021 by Bill Spitzak and others. +// Copyright 2021-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 @@ -21,8 +21,6 @@ #include "../../Fl_Screen_Driver.H" #include "../../Fl_Window_Driver.H" #include "Fl_X11_Gl_Window_Driver.H" -#include "../Xlib/Fl_Font.H" -#include "../Xlib/Fl_Xlib_Graphics_Driver.H" # include # if ! defined(GLX_VERSION_1_3) # typedef void *GLXFBConfig; @@ -61,7 +59,7 @@ void Fl_X11_Gl_Window_Driver::gl_bitmap_font(Fl_Font_Descriptor *fl_fontsize) { * is not working on this platform. This code might not reliably render glyphs * from higher codepoints. */ if (!fl_fontsize->listbase) { -#if USE_XFT +#if USE_XFT && !FLTK_USE_CAIRO /* Ideally, for XFT, we need a glXUseXftFont implementation here... But we * do not have such a thing. Instead, we try to find a legacy Xlib font that * matches the current XFT font and use that. @@ -288,7 +286,7 @@ GLContext Fl_X11_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl XSetErrorHandler(oldHandler); } if (!ctx) { // use OpenGL 1-style context creation - ctx = glXCreateContext(fl_display, ((Fl_X11_Gl_Choice*)g)->vis, shared_ctx, true); + ctx = glXCreateContext(fl_display, ((Fl_X11_Gl_Choice*)g)->vis, (GLXContext)shared_ctx, true); } if (ctx) add_context(ctx); @@ -299,7 +297,7 @@ GLContext Fl_X11_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl GLContext Fl_X11_Gl_Window_Driver::create_gl_context(XVisualInfo *vis) { GLContext shared_ctx = 0; if (context_list && nContext) shared_ctx = context_list[0]; - GLContext context = glXCreateContext(fl_display, vis, shared_ctx, 1); + GLContext context = glXCreateContext(fl_display, vis, (GLXContext)shared_ctx, 1); if (context) add_context(context); return context; @@ -309,7 +307,7 @@ void Fl_X11_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) { if (context != cached_context || w != cached_window) { cached_context = context; cached_window = w; - glXMakeCurrent(fl_display, fl_xid(w), context); + glXMakeCurrent(fl_display, fl_xid(w), (GLXContext)context); } } @@ -319,7 +317,7 @@ void Fl_X11_Gl_Window_Driver::delete_gl_context(GLContext context) { cached_window = 0; glXMakeCurrent(fl_display, 0, 0); } - glXDestroyContext(fl_display, context); + glXDestroyContext(fl_display, (GLXContext)context); del_context(context); } @@ -394,4 +392,8 @@ void Fl_X11_Gl_Window_Driver::gl_start() { glXWaitX(); } + +FL_EXPORT GLXContext fl_x11_glcontext(GLContext rc) { return (GLXContext)rc; } + + #endif // HAVE_GL diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx index b8fdd20c1..87a91636c 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx @@ -17,11 +17,9 @@ #include #include "Fl_X11_Screen_Driver.H" -#include "../Xlib/Fl_Font.H" #include "Fl_X11_Window_Driver.H" #include "Fl_X11_System_Driver.H" #include "../Posix/Fl_Posix_System_Driver.H" -#include "../Xlib/Fl_Xlib_Graphics_Driver.H" #include #include #include @@ -986,7 +984,7 @@ void Fl_X11_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &hei int px, py; unsigned w, h, b, d; Window root; - XGetGeometry(fl_display, off, &root, &px, &py, &w, &h, &b, &d); + XGetGeometry(fl_display, (Pixmap)off, &root, &px, &py, &w, &h, &b, &d); width = (int)w; height = (int)h; } diff --git a/src/drivers/X11/Fl_X11_Window_Driver.H b/src/drivers/X11/Fl_X11_Window_Driver.H index 84b11ad16..13c1cf900 100644 --- a/src/drivers/X11/Fl_X11_Window_Driver.H +++ b/src/drivers/X11/Fl_X11_Window_Driver.H @@ -26,6 +26,11 @@ #include "../../Fl_Window_Driver.H" #include #include // for Cursor + +#if FLTK_USE_CAIRO +typedef struct _cairo cairo_t; +#endif // FLTK_USE_CAIRO + class Fl_Bitmap; /* @@ -71,6 +76,9 @@ private: int screen_num_; void screen_num(int n) { screen_num_ = n; } #endif // USE_XFT +#if FLTK_USE_CAIRO + cairo_t *cairo_; +#endif // FLTK_USE_CAIRO void decorated_win_size(int &w, int &h); void combine_mask(); void shape_bitmap_(Fl_Image* b); diff --git a/src/drivers/X11/Fl_X11_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Window_Driver.cxx index ed9dd8fcb..a5302904f 100644 --- a/src/drivers/X11/Fl_X11_Window_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Window_Driver.cxx @@ -18,9 +18,13 @@ #include #include "Fl_X11_Window_Driver.H" #include "Fl_X11_Screen_Driver.H" -#include "../Xlib/Fl_Xlib_Graphics_Driver.H" +#if FLTK_USE_CAIRO +# include +# include "../Cairo/Fl_Display_Cairo_Graphics_Driver.H" +#else +# include "../Xlib/Fl_Xlib_Graphics_Driver.H" +#endif // FLTK_USE_CAIRO -#include "../../Fl_Screen_Driver.H" #include #include #include @@ -53,6 +57,9 @@ Fl_X11_Window_Driver::Fl_X11_Window_Driver(Fl_Window *win) #if USE_XFT screen_num_ = -1; #endif +#if FLTK_USE_CAIRO + cairo_ = NULL; +#endif } @@ -151,9 +158,17 @@ void Fl_X11_Window_Driver::flush_double(int erase_overlay) pWindow->make_current(); // make sure fl_gc is non-zero Fl_X *i = Fl_X::i(pWindow); if (!other_xid) { - other_xid = fl_create_offscreen(w(), h()); + other_xid = fl_create_offscreen(w(), h()); +#if FLTK_USE_CAIRO + fl_begin_offscreen(other_xid); + cairo_ = ((Fl_Cairo_Graphics_Driver*)fl_graphics_driver)->cr(); + fl_end_offscreen(); +#endif pWindow->clear_damage(FL_DAMAGE_ALL); } +#if FLTK_USE_CAIRO + ((Fl_Display_Cairo_Graphics_Driver*)fl_graphics_driver)->set_cairo(cairo_); +#endif if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) { fl_clip_region(i->region); i->region = 0; fl_window = other_xid; @@ -176,8 +191,21 @@ void Fl_X11_Window_Driver::flush_overlay() int erase_overlay = (pWindow->damage()&FL_DAMAGE_OVERLAY) | (overlay() == pWindow); pWindow->clear_damage((uchar)(pWindow->damage()&~FL_DAMAGE_OVERLAY)); flush_double(erase_overlay); - Fl_Overlay_Window *oWindow = pWindow->as_overlay_window(); - if (overlay() == oWindow) oWindow->draw_overlay(); + if (overlay() == pWindow) { +#if FLTK_USE_CAIRO + float scale = fl_graphics_driver->scale(); + int W = pWindow->w() * scale, H = pWindow->h() * scale; + cairo_surface_t *s = cairo_xlib_surface_create(fl_display, Fl_X::i(pWindow)->xid, fl_visual->visual, W, H); + cairo_t *overlay_cairo = cairo_create(s); + cairo_surface_destroy(s); + cairo_save(overlay_cairo); + ((Fl_Display_Cairo_Graphics_Driver*)fl_graphics_driver)->set_cairo(overlay_cairo); +#endif + pWindow->as_overlay_window()->draw_overlay(); +#if FLTK_USE_CAIRO + cairo_destroy(overlay_cairo); +#endif + } } @@ -373,7 +401,21 @@ void Fl_X11_Window_Driver::make_current() { } fl_window = fl_xid(pWindow); fl_graphics_driver->clip_region(0); -#if USE_XFT + +#if FLTK_USE_CAIRO + float scale = Fl::screen_scale(screen_num()); // get the screen scaling factor + if (!pWindow->as_double_window()) { + if (!cairo_) { + int W = pWindow->w() * scale, H = pWindow->h() * scale; + cairo_surface_t *s = cairo_xlib_surface_create(fl_display, fl_window, fl_visual->visual, W, H); + cairo_ = cairo_create(s); + cairo_surface_destroy(s); + cairo_save(cairo_); + } + ((Fl_Display_Cairo_Graphics_Driver*)fl_graphics_driver)->set_cairo(cairo_); + } + fl_graphics_driver->scale(scale); +#elif USE_XFT ((Fl_Xlib_Graphics_Driver*)fl_graphics_driver)->scale(Fl::screen_driver()->scale(screen_num())); #endif @@ -388,9 +430,15 @@ void Fl_X11_Window_Driver::hide() { Fl_X* ip = Fl_X::i(pWindow); if (hide_common()) return; if (ip->region) Fl_Graphics_Driver::default_driver().XDestroyRegion(ip->region); -# if USE_XFT +# if USE_XFT && ! FLTK_USE_CAIRO Fl_Xlib_Graphics_Driver::destroy_xft_draw(ip->xid); screen_num_ = -1; +# endif +# if FLTK_USE_CAIRO + if (cairo_ && !pWindow->as_double_window()) { + cairo_destroy(cairo_); + cairo_ = NULL; + } # endif // this test makes sure ip->xid has not been destroyed already if (ip->xid) XDestroyWindow(fl_display, ip->xid); @@ -504,6 +552,15 @@ const Fl_Image* Fl_X11_Window_Driver::shape() { return shape_data_ ? shape_data_->shape_ : NULL; } +Fl_Window *fl_x11_find(Window xid) { + return Fl_Window_Driver::find((fl_uintptr_t)xid); +} + +Window fl_x11_xid(const Fl_Window *win) { + return (Window)Fl_Window_Driver::xid(win); +} + + #if USE_XFT Fl_X11_Window_Driver::type_for_resize_window_between_screens Fl_X11_Window_Driver::data_for_resize_window_between_screens_ = {0, false}; diff --git a/src/drivers/X11/fl_X11_platform_init.cxx b/src/drivers/X11/fl_X11_platform_init.cxx index 3bcf21370..b26dfa444 100644 --- a/src/drivers/X11/fl_X11_platform_init.cxx +++ b/src/drivers/X11/fl_X11_platform_init.cxx @@ -14,9 +14,14 @@ // https://www.fltk.org/bugs.php // +#include #include #include "../Xlib/Fl_Xlib_Copy_Surface_Driver.H" -#include "../Xlib/Fl_Xlib_Graphics_Driver.H" +#if FLTK_USE_CAIRO +# include "../Cairo/Fl_Display_Cairo_Graphics_Driver.H" +#else +# include "../Xlib/Fl_Xlib_Graphics_Driver.H" +#endif #include "Fl_X11_Screen_Driver.H" #include "Fl_X11_System_Driver.H" #include "Fl_X11_Window_Driver.H" @@ -127,7 +132,11 @@ FL_EXPORT Fl_Fontdesc* fl_fonts = (Fl_Fontdesc*)built_in_table; Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver() { +#if FLTK_USE_CAIRO + return new Fl_Display_Cairo_Graphics_Driver(); +#else return new Fl_Xlib_Graphics_Driver(); +#endif } diff --git a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H index a0b0db171..e67447b4d 100644 --- a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H +++ b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H @@ -19,6 +19,9 @@ #include #include +#if FLTK_USE_CAIRO +# include +#endif // FLTK_USE_CAIRO class Fl_Xlib_Copy_Surface_Driver : public Fl_Copy_Surface_Driver { friend class Fl_Copy_Surface_Driver; @@ -31,6 +34,9 @@ protected: void set_current(); void translate(int x, int y); void untranslate(); +#if FLTK_USE_CAIRO + cairo_t *cairo_; +#endif }; #endif // FL_XLIB_COPY_SURFACE_DRIVER_H diff --git a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx index f87ae55a2..e4bbe29ef 100644 --- a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx @@ -19,16 +19,35 @@ #include #include #include -#include "Fl_Xlib_Graphics_Driver.H" #include "../X11/Fl_X11_Screen_Driver.H" +#if FLTK_USE_CAIRO +# include +# include "../Cairo/Fl_Display_Cairo_Graphics_Driver.H" +# include +#else +# include "Fl_Xlib_Graphics_Driver.H" +#endif // FLTK_USE_CAIRO + Fl_Xlib_Copy_Surface_Driver::Fl_Xlib_Copy_Surface_Driver(int w, int h) : Fl_Copy_Surface_Driver(w, h) { +#if FLTK_USE_CAIRO + driver(new Fl_Display_Cairo_Graphics_Driver()); +#else driver(new Fl_Xlib_Graphics_Driver()); +#endif float s = Fl_Graphics_Driver::default_driver().scale(); - ((Fl_Xlib_Graphics_Driver*)driver())->scale(s); + driver()->scale(s); oldwindow = fl_window; xid = fl_create_offscreen(w,h); +#if FLTK_USE_CAIRO + cairo_surface_t *surf = cairo_xlib_surface_create(fl_display, xid, 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_Display_Cairo_Graphics_Driver*)driver())->set_cairo(cairo_); +#endif driver()->push_no_clip(); fl_window = xid; driver()->color(FL_WHITE); @@ -47,6 +66,9 @@ Fl_Xlib_Copy_Surface_Driver::~Fl_Xlib_Copy_Surface_Driver() { Fl_X11_Screen_Driver::copy_image(rgb->array, rgb->w(), rgb->h(), 1); delete rgb; fl_delete_offscreen(xid); +#if FLTK_USE_CAIRO + cairo_destroy(cairo_); +#endif delete driver(); } @@ -55,6 +77,9 @@ void Fl_Xlib_Copy_Surface_Driver::set_current() { Fl_Surface_Device::set_current(); oldwindow = fl_window; fl_window = xid; +#if FLTK_USE_CAIRO + ((Fl_Display_Cairo_Graphics_Driver*)driver())->set_cairo(cairo_); +#endif } void Fl_Xlib_Copy_Surface_Driver::end_current() { @@ -63,10 +88,20 @@ void Fl_Xlib_Copy_Surface_Driver::end_current() { } void Fl_Xlib_Copy_Surface_Driver::translate(int x, int y) { +#if FLTK_USE_CAIRO + cairo_save(cairo_); + cairo_translate(cairo_, x, y); +#else ((Fl_Xlib_Graphics_Driver*)driver())->translate_all(x, y); +#endif + } void Fl_Xlib_Copy_Surface_Driver::untranslate() { +#if FLTK_USE_CAIRO + cairo_restore(cairo_); +#else ((Fl_Xlib_Graphics_Driver*)driver())->untranslate_all(); +#endif } diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H index 5440b53bd..cf2fcac58 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H @@ -76,7 +76,7 @@ protected: #endif virtual int height_unscaled(); virtual int descent_unscaled(); - virtual Region scale_clip(float f); + virtual Fl_Region scale_clip(float f); #if USE_XFT void drawUCS4(const void *str, int n, int x, int y); #endif diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx index 13a67f428..4c7b64a4c 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx @@ -38,6 +38,8 @@ int Fl_Xlib_Graphics_Driver::fl_overlay = 0; */ GC fl_gc = 0; +GC fl_x11_gc() { return fl_gc; } + Fl_Xlib_Graphics_Driver::Fl_Xlib_Graphics_Driver(void) { mask_bitmap_ = NULL; short_point = NULL; @@ -71,14 +73,14 @@ void Fl_Xlib_Graphics_Driver::scale(float f) { } void Fl_Xlib_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_, srcx*scale(), srcy*scale(), w*scale(), h*scale(), (x+offset_x_)*scale(), (y+offset_y_)*scale()); + XCopyArea(fl_display, (Pixmap)pixmap, fl_window, gc_, srcx*scale(), srcy*scale(), w*scale(), h*scale(), (x+offset_x_)*scale(), (y+offset_y_)*scale()); } void Fl_Xlib_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { XRectangle R; R.x = X; R.y = Y; R.width = W; R.height = H; - XUnionRectWithRegion(&R, r, r); + XUnionRectWithRegion(&R, (Region)r, (Region)r); } void Fl_Xlib_Graphics_Driver::transformed_vertex0(float fx, float fy) { @@ -144,8 +146,8 @@ void Fl_Xlib_Graphics_Driver::font_name(int num, const char *name) { } -Region Fl_Xlib_Graphics_Driver::scale_clip(float f) { - Region r = rstack[rstackptr]; +Fl_Region Fl_Xlib_Graphics_Driver::scale_clip(float f) { + Region r = (Region)rstack[rstackptr]; if (r == 0 || (f == 1 && offset_x_ == 0 && offset_y_ == 0) ) return 0; Region r2 = XCreateRegion(); for (int i = 0; i < r->numRects; i++) { @@ -153,7 +155,7 @@ Region Fl_Xlib_Graphics_Driver::scale_clip(float f) { int y = floor(r->rects[i].y1 + offset_y_, f); int w = floor((r->rects[i].x2 + offset_x_) , f) - x; int h = floor((r->rects[i].y2 + offset_y_) , f) - y; - Region R = XRectangleRegion(x, y, w, h); + Region R = (Region)XRectangleRegion(x, y, w, h); XUnionRegion(R, r2, r2); ::XDestroyRegion(R); } diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx index 17711883e..3a4817b7f 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx @@ -720,7 +720,7 @@ void Fl_Xlib_Graphics_Driver::draw_unscaled(const char *str, int n, int x, int y else //if (draw_window != fl_window) XftDrawChange(draw_, draw_window = fl_window); - Region region = fl_clip_region(); + Region region = (Region)fl_clip_region(); if (!(region && XEmptyRegion(region))) { XftDrawSetClip(draw_, region); @@ -756,7 +756,7 @@ void Fl_Xlib_Graphics_Driver::drawUCS4(const void *str, int n, int x, int y) { else //if (draw_window != fl_window) XftDrawChange(draw_, draw_window = fl_window); - Region region = fl_clip_region(); + Region region = (Region)fl_clip_region(); if (region && XEmptyRegion(region)) return; XftDrawSetClip(draw_, region); @@ -1192,7 +1192,7 @@ static void fl_pango_layout_get_pixel_extents(PangoLayout *layout, int &dx, int void Fl_Xlib_Graphics_Driver::do_draw(int from_right, const char *str, int n, int x, int y) { if (!fl_display || n == 0) return; - Region region = clip_region(); + Region region = (Region)clip_region(); if (region && XEmptyRegion(region)) return; if (!playout_) context(); diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx index d57e5b031..ba098c309 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx @@ -718,8 +718,8 @@ void Fl_Xlib_Graphics_Driver::cache(Fl_RGB_Image *img) { if (depth == 1 || depth == 3) { surface = new Fl_Image_Surface(img->data_w(), img->data_h()); } else if (fl_can_do_alpha_blending()) { - Fl_Offscreen pixmap = XCreatePixmap(fl_display, RootWindow(fl_display, fl_screen), img->data_w(), img->data_h(), 32); - surface = new Fl_Image_Surface(img->data_w(), img->data_h(), 0, pixmap); + Pixmap pixmap = XCreatePixmap(fl_display, RootWindow(fl_display, fl_screen), img->data_w(), img->data_h(), 32); + surface = new Fl_Image_Surface(img->data_w(), img->data_h(), 0, (Fl_Offscreen)pixmap); depth |= FL_IMAGE_WITH_ALPHA; } else { *Fl_Graphics_Driver::id(img) = 0; @@ -806,14 +806,14 @@ int Fl_Xlib_Graphics_Driver::scale_and_render_pixmap(Fl_Offscreen pixmap, int de static XRenderPictFormat *fmt24 = XRenderFindStandardFormat(fl_display, PictStandardRGB24); static XRenderPictFormat *fmt32 = XRenderFindStandardFormat(fl_display, PictStandardARGB32); static XRenderPictFormat *dstfmt = XRenderFindVisualFormat(fl_display, fl_visual->visual); - Picture src = XRenderCreatePicture(fl_display, pixmap, has_alpha ?fmt32:fmt24, 0, &srcattr); + Picture src = XRenderCreatePicture(fl_display, (Pixmap)pixmap, has_alpha ?fmt32:fmt24, 0, &srcattr); Picture dst = XRenderCreatePicture(fl_display, fl_window, dstfmt, 0, &srcattr); if (!src || !dst) { fprintf(stderr, "Failed to create Render pictures (%lu %lu)\n", src, dst); return 0; } Fl_Region r = scale_clip(scale()); - const Fl_Region clipr = clip_region(); + const Region clipr = (Region)clip_region(); if (clipr) XRenderSetPictureClipRegion(fl_display, dst, clipr); unscale_clip(r); @@ -849,7 +849,7 @@ int Fl_Xlib_Graphics_Driver::scale_and_render_pixmap(Fl_Offscreen pixmap, int de void Fl_Xlib_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_uintptr_t &mask_) { if (id_) { - XFreePixmap(fl_display, (Fl_Offscreen)id_); + XFreePixmap(fl_display, (Pixmap)id_); id_ = 0; } } @@ -882,8 +882,8 @@ void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, in // be done in a single Xlib call for a multi-rectangle clip region. Thus, we // process each rectangle of the intersection between the clip region and XYWH. // See also STR #3206. - Region r = XRectangleRegion(X,Y,W,H); - XIntersectRegion(r, clip_region(), r); + Region r = (Region)XRectangleRegion(X,Y,W,H); + XIntersectRegion(r, (Region)clip_region(), r); int X1, Y1, W1, H1; for (int i = 0; i < r->numRects; i++) { X1 = r->rects[i].x1; @@ -929,5 +929,5 @@ void Fl_Xlib_Graphics_Driver::cache(Fl_Pixmap *pxm) { } void Fl_Xlib_Graphics_Driver::uncache_pixmap(fl_uintptr_t offscreen) { - XFreePixmap(fl_display, (Fl_Offscreen)offscreen); + XFreePixmap(fl_display, (Pixmap)offscreen); } diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx index a72fe9d8b..ea24eba34 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx @@ -194,7 +194,7 @@ int Fl_Xlib_Graphics_Driver::clip_rect(int &x, int &y, int &w, int &h) { Fl_Region Fl_Xlib_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { XRectangle R; - Fl_Region r = XCreateRegion(); // create an empty region + Region r = XCreateRegion(); // create an empty region if (clip_rect(x, y, w, h)) // outside valid coordinate space return r; // empty region R.x = x; R.y = y; R.width = w; R.height = h; @@ -203,7 +203,7 @@ Fl_Region Fl_Xlib_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) } void Fl_Xlib_Graphics_Driver::XDestroyRegion(Fl_Region r) { - ::XDestroyRegion(r); + ::XDestroyRegion((Region)r); } // --- line and polygon drawing @@ -312,12 +312,12 @@ void Fl_Xlib_Graphics_Driver::draw_clipped_line(int x1, int y1, int x2, int y2) // --- clipping void Fl_Xlib_Graphics_Driver::push_clip(int x, int y, int w, int h) { - Fl_Region r; + Region r; if (w > 0 && h > 0) { - r = XRectangleRegion(x, y, w, h); // does X coordinate clipping - Fl_Region current = rstack[rstackptr]; + r = (Region)XRectangleRegion(x, y, w, h); // does X coordinate clipping + Region current = (Region)rstack[rstackptr]; if (current) { - Fl_Region temp = XCreateRegion(); + Region temp = XCreateRegion(); XIntersectRegion(current, r, temp); XDestroyRegion(r); r = temp; @@ -337,7 +337,7 @@ int Fl_Xlib_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y W = H = 0; return 2; } - Fl_Region r = rstack[rstackptr]; + Region r = (Region)rstack[rstackptr]; if (!r) { // no clipping region if (X != x || Y != y || W != w || H != h) // pre-clipped return 1; // partially outside, region differs @@ -352,8 +352,8 @@ int Fl_Xlib_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y default: // partial: break; } - Fl_Region rr = XRectangleRegion(X, Y, W, H); - Fl_Region temp = XCreateRegion(); + Region rr = (Region)XRectangleRegion(X, Y, W, H); + Region temp = XCreateRegion(); XIntersectRegion(r, rr, temp); XRectangle rect; XClipBox(temp, &rect); @@ -365,7 +365,7 @@ int Fl_Xlib_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y int Fl_Xlib_Graphics_Driver::not_clipped(int x, int y, int w, int h) { if (x+w <= 0 || y+h <= 0) return 0; - Fl_Region r = rstack[rstackptr]; + Region r = (Region)rstack[rstackptr]; if (!r) return 1; // get rid of coordinates outside the 16-bit range the X calls take. if (clip_rect(x,y,w,h)) return 0; // clipped @@ -375,10 +375,10 @@ int Fl_Xlib_Graphics_Driver::not_clipped(int x, int y, int w, int h) { void Fl_Xlib_Graphics_Driver::restore_clip() { fl_clip_state_number++; if (gc_) { - Region r = rstack[rstackptr]; + Region r = (Region)rstack[rstackptr]; if (r) { - Region r2 = scale_clip(scale()); - XSetRegion(fl_display, gc_, rstack[rstackptr]); + Region r2 = (Region)scale_clip(scale()); + XSetRegion(fl_display, gc_, (Region)rstack[rstackptr]); unscale_clip(r2); } else XSetClipMask(fl_display, gc_, 0); diff --git a/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H b/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H index b7cb48010..3f8ecda7f 100644 --- a/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H +++ b/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H @@ -18,6 +18,9 @@ #define FL_XLIB_IMAGE_SURFACE_DRIVER_H #include +#if FLTK_USE_CAIRO +# include +#endif // FLTK_USE_CAIRO class Fl_Xlib_Image_Surface_Driver : public Fl_Image_Surface_Driver { virtual void end_current(); @@ -29,6 +32,9 @@ public: void translate(int x, int y); void untranslate(); Fl_RGB_Image *image(); +#if FLTK_USE_CAIRO + cairo_t *cairo_; +#endif }; #endif // FL_XLIB_IMAGE_SURFACE_DRIVER_H diff --git a/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx index e1a33c746..240ced649 100644 --- a/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx @@ -14,28 +14,47 @@ // https://www.fltk.org/bugs.php // -#include "Fl_Xlib_Graphics_Driver.H" +#include #include "Fl_Xlib_Image_Surface_Driver.H" #include "../../Fl_Screen_Driver.H" +#if FLTK_USE_CAIRO +# include +# include "../Cairo/Fl_Display_Cairo_Graphics_Driver.H" +#else +# include "Fl_Xlib_Graphics_Driver.H" +#endif // FLTK_USE_CAIRO + Fl_Xlib_Image_Surface_Driver::Fl_Xlib_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(); - d = fl_graphics_driver->scale(); + d = Fl_Graphics_Driver::default_driver().scale(); if (d != 1 && high_res) { w = int(w*d); h = int(h*d); } - offscreen = XCreatePixmap(fl_display, RootWindow(fl_display, fl_screen), w, h, fl_visual->depth); + offscreen = (Fl_Offscreen)XCreatePixmap(fl_display, RootWindow(fl_display, fl_screen), w, h, fl_visual->depth); } +#if FLTK_USE_CAIRO + driver(new Fl_Display_Cairo_Graphics_Driver()); + cairo_surface_t *s = cairo_xlib_surface_create(fl_display, offscreen, fl_visual->visual, w, h); + cairo_ = cairo_create(s); + cairo_surface_destroy(s); + cairo_save(cairo_); + ((Fl_Display_Cairo_Graphics_Driver*)driver())->set_cairo(cairo_); +#else driver(new Fl_Xlib_Graphics_Driver()); - if (d != 1 && high_res) ((Fl_Xlib_Graphics_Driver*)driver())->scale(d); +#endif + if (d != 1 && high_res) driver()->scale(d); } Fl_Xlib_Image_Surface_Driver::~Fl_Xlib_Image_Surface_Driver() { - if (offscreen && !external_offscreen) XFreePixmap(fl_display, offscreen); +#if FLTK_USE_CAIRO + cairo_destroy(cairo_); +#endif + if (offscreen && !external_offscreen) XFreePixmap(fl_display, (Pixmap)offscreen); delete driver(); } @@ -43,14 +62,26 @@ void Fl_Xlib_Image_Surface_Driver::set_current() { Fl_Surface_Device::set_current(); pre_window = fl_window; fl_window = offscreen; +#if FLTK_USE_CAIRO + ((Fl_Display_Cairo_Graphics_Driver*)driver())->set_cairo(cairo_); +#endif } void Fl_Xlib_Image_Surface_Driver::translate(int x, int y) { +#if FLTK_USE_CAIRO + cairo_save(cairo_); + cairo_translate(cairo_, x, y); +#else ((Fl_Xlib_Graphics_Driver*)driver())->translate_all(x, y); +#endif } void Fl_Xlib_Image_Surface_Driver::untranslate() { +#if FLTK_USE_CAIRO + cairo_restore(cairo_); +#else ((Fl_Xlib_Graphics_Driver*)driver())->untranslate_all(); +#endif } Fl_RGB_Image* Fl_Xlib_Image_Surface_Driver::image() -- cgit v1.2.3