diff --git a/CMake/options.cmake b/CMake/options.cmake index ae77c7c460..e91d1c828c 100644 --- a/CMake/options.cmake +++ b/CMake/options.cmake @@ -197,12 +197,20 @@ if (UNIX) option (OPTION_USE_WAYLAND "use Wayland" OFF) if (OPTION_USE_WAYLAND) set (FLTK_USE_WAYLAND 1) + set (FLTK_USE_X11 1) # to build a hybrid Wayland/X11 library + unset (OPTION_USE_CAIRO CACHE) + set (OPTION_USE_CAIRO TRUE CACHE BOOL "all drawing to X11 windows uses Cairo") option (OPTION_USE_SYSTEM_LIBDECOR "use libdecor from the system" OFF) unset (OPTION_USE_XRENDER CACHE) unset (OPTION_USE_XINERAMA CACHE) unset (OPTION_USE_XFT CACHE) unset (OPTION_USE_XCURSOR CACHE) unset (OPTION_USE_XFIXES CACHE) + set (HAVE_XFIXES 1) + set (HAVE_XRENDER 1) + set (USE_XFT 1) + set (HAVE_XCURSOR 1) + set (HAVE_XINERAMA 1) unset (OPTION_USE_PANGO CACHE) set (OPTION_USE_PANGO TRUE CACHE BOOL "use lib Pango") if (OPTION_USE_SYSTEM_LIBDECOR) @@ -211,6 +219,9 @@ if (UNIX) set (OPTION_USE_SYSTEM_LIBDECOR OFF) endif (NOT SYSTEM_LIBDECOR_FOUND) endif (OPTION_USE_SYSTEM_LIBDECOR) + + option (OPTION_ALLOW_GTK_PLUGIN "Allow to use libdecor's GTK plugin" ON) + endif (OPTION_USE_WAYLAND) endif (UNIX) @@ -311,7 +322,7 @@ endif (OPTION_BUILD_HTML_DOCUMENTATION OR OPTION_BUILD_PDF_DOCUMENTATION) # Include optional Cairo support ####################################################################### -option (OPTION_CAIRO "use lib Cairo" OFF) +option (OPTION_CAIRO "add support for Fl_Cairo_Window" OFF) option (OPTION_CAIROEXT "use FLTK code instrumentation for Cairo extended use" OFF ) @@ -556,8 +567,17 @@ endif (OPTION_USE_XCURSOR) if (X11_Xft_FOUND) option (OPTION_USE_XFT "use lib Xft" ON) option (OPTION_USE_PANGO "use lib Pango" OFF) + if (NOT OPTION_USE_WAYLAND) + option (OPTION_USE_CAIRO "all drawing to X11 windows uses Cairo" OFF) + endif (NOT OPTION_USE_WAYLAND) endif (X11_Xft_FOUND) +# test option compatibility: Cairo for Xlib requires Pango +if (OPTION_USE_CAIRO) + unset (OPTION_USE_PANGO CACHE) + set (OPTION_USE_PANGO TRUE CACHE BOOL "use lib Pango") +endif (OPTION_USE_CAIRO) + # test option compatibility: Pango requires Xft if (OPTION_USE_PANGO AND NOT OPTION_USE_WAYLAND) if (NOT X11_Xft_FOUND) @@ -654,14 +674,30 @@ if ((X11_Xft_FOUND OR OPTION_USE_WAYLAND) AND OPTION_USE_PANGO) endif (HAVE_LIB_PANGO AND HAVE_LIB_PANGOXFT AND HAVE_LIB_GOBJECT) endif (PANGOXFT_FOUND AND PANGOCAIRO_FOUND AND CAIRO_FOUND) + if (USE_PANGO AND (OPTION_USE_CAIRO OR OPTION_USE_WAYLAND)) + set (FLTK_USE_CAIRO 1) + # fl_debug_var (FLTK_USE_CAIRO) + endif (USE_PANGO AND (OPTION_USE_CAIRO OR OPTION_USE_WAYLAND)) + endif ((X11_Xft_FOUND OR OPTION_USE_WAYLAND) AND OPTION_USE_PANGO) if (OPTION_USE_WAYLAND AND NOT OPTION_USE_SYSTEM_LIBDECOR) - pkg_check_modules(GTK gtk+-3.0) - # set (GTK_FOUND 0) # use this to get cairo titlebars rather than GTK - if (GTK_FOUND) - include_directories (${GTK_INCLUDE_DIRS}) - endif (GTK_FOUND) + + # Note: Disable OPTION_ALLOW_GTK_PLUGIN to get cairo titlebars rather than GTK + # FIXME: This needs to be redesigned! Forcing GTK_FOUND to 0 (NO) is a bad + # FIXME: idea because there could be unwanted side effects. AlbrechtS + if (OPTION_ALLOW_GTK_PLUGIN) + pkg_check_modules(GTK gtk+-3.0) + if (GTK_FOUND) + include_directories (${GTK_INCLUDE_DIRS}) + endif (GTK_FOUND) + else () + if (GTK_FOUND) + message (STATUS "*** FIXME: Disable GTK plugin by forcing GTK_FOUND to 0 ***") + set (GTK_FOUND 0) + endif (GTK_FOUND) + endif (OPTION_ALLOW_GTK_PLUGIN) + endif (OPTION_USE_WAYLAND AND NOT OPTION_USE_SYSTEM_LIBDECOR) if (OPTION_USE_XFT) diff --git a/CMakeLists.txt b/CMakeLists.txt index c871386e7a..9fb8cac435 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -241,30 +241,36 @@ endif () if (UNIX) if (OPTION_USE_WAYLAND) - message (STATUS "Use Wayland: Yes") + message (STATUS "Use Wayland: Yes (when available at run-time)") else () - message (STATUS "Use Wayland: No") + message (STATUS "Use Wayland: No (therefore, X11 is used)") + endif () + + if (FLTK_USE_CAIRO) + message (STATUS "All drawing uses Cairo: Yes") + else () + message (STATUS "All drawing uses Cairo: No") endif () if (USE_PANGO) - message (STATUS "Use Pango: Yes") + message (STATUS "Use Pango: Yes") else (USE_PANGO) - message (STATUS "Use Pango: No") + message (STATUS "Use Pango: No") if (USE_XFT) - message (STATUS "Use Xft: Yes") + message (STATUS "Use Xft: Yes") else () - message (STATUS "Use Xft: No") + message (STATUS "Use Xft: No") endif (USE_XFT) endif (USE_PANGO) endif (UNIX) if (FLTK_HAVE_CAIROEXT) - message (STATUS "Cairo support: Yes (extended)") + message (STATUS "Fl_Cairo_Window support: Yes (extended)") elseif (FLTK_HAVE_CAIRO) - message (STATUS "Cairo support: Yes (standard)") + message (STATUS "Fl_Cairo_Window support: Yes (standard)") else () - message (STATUS "Cairo support: No") + message (STATUS "Fl_Cairo_Window support: No") endif () message ("") diff --git a/FL/Fl_Cairo_Window.H b/FL/Fl_Cairo_Window.H index 86f25c9865..1111097c54 100644 --- a/FL/Fl_Cairo_Window.H +++ b/FL/Fl_Cairo_Window.H @@ -74,7 +74,7 @@ \see examples/cairo-draw-x.cxx \see test/cairo_test.cxx - + \note Class Fl_Cairo_Window requires the FLTK library to have been built with CMake option OPTION_CAIRO or configure --enable-cairo. diff --git a/FL/Fl_Device.H b/FL/Fl_Device.H index 93b3836a90..757aa6581f 100644 --- a/FL/Fl_Device.H +++ b/FL/Fl_Device.H @@ -28,6 +28,7 @@ class Fl_Graphics_Driver; class Fl_RGB_Image; class Fl_Widget; +class Fl_Image_Surface; /** A drawing surface that's susceptible to receive graphical output. @@ -91,6 +92,7 @@ public: } /** \brief The destructor. */ virtual ~Fl_Surface_Device(); + virtual Fl_Image_Surface *as_image_surface(); static void push_current(Fl_Surface_Device *new_current); static Fl_Surface_Device *pop_current(); }; diff --git a/FL/Fl_Gl_Window.H b/FL/Fl_Gl_Window.H index ec9179bfb2..9143d0a301 100644 --- a/FL/Fl_Gl_Window.H +++ b/FL/Fl_Gl_Window.H @@ -187,8 +187,9 @@ public: and may be followed by adequate attribute values. */ int mode(const int *a) {return mode(0, a);} - /** Returns a pointer to the GLContext that this window is using. - \see void context(GLContext c, int destroy_flag) */ + /** Returns a pointer to the window's OpenGL rendering context. + \see void context(GLContext c, int destroy_flag) + */ GLContext context() const {return context_;} void context(GLContext, int destroy_flag = 0); void make_current(); diff --git a/FL/Fl_Image_Surface.H b/FL/Fl_Image_Surface.H index a22d1d97d9..b09d7d4d31 100644 --- a/FL/Fl_Image_Surface.H +++ b/FL/Fl_Image_Surface.H @@ -82,6 +82,7 @@ public: int printable_rect(int *w, int *h); Fl_Offscreen offscreen(); void rescale(); + Fl_Image_Surface *as_image_surface(); }; @@ -98,6 +99,8 @@ public: */ class Fl_Image_Surface_Driver : public Fl_Widget_Surface { friend class Fl_Image_Surface; +private: + Fl_Image_Surface *image_surface_; protected: int width; int height; @@ -110,6 +113,7 @@ protected: virtual void untranslate() = 0; int printable_rect(int *w, int *h); virtual Fl_RGB_Image *image() = 0; + virtual Fl_Image_Surface *as_image_surface(); /** Each platform implements this function its own way. It returns an object implementing all virtual functions of class Fl_Image_Surface_Driver for the plaform. diff --git a/FL/mac.H b/FL/mac.H index 0b5d32a349..c1748abceb 100644 --- a/FL/mac.H +++ b/FL/mac.H @@ -23,6 +23,13 @@ # error "Never use directly; include instead." #endif // !FL_PLATFORM_H +#ifdef __OBJC__ + @class NSOpenGLContext; +#elif defined(__cplusplus) + class NSOpenGLContext; +#endif /* __OBJC__ */ +extern NSOpenGLContext *fl_mac_glcontext(GLContext rc); + #ifdef __OBJC__ @class FLWindow; // a subclass of the NSWindow Cocoa class typedef FLWindow *Window; @@ -125,6 +132,12 @@ extern CGContextRef fl_gc; */ void fl_mac_set_about(Fl_Callback *cb, void *user_data, int shortcut = 0); +/** Returns the macOS-specific graphics context for the current window */ +extern CGContextRef fl_mac_gc(); +/** Returns the macOS-specific window reference corresponding to the given Fl_Window object */ +extern FLWindow *fl_mac_xid(const Fl_Window *win); +/** Returns the Fl_Window corresponding to the given macOS-specific window reference */ +extern Fl_Window *fl_mac_find(FLWindow *); /** The version number of the running Mac OS X (e.g., 100604 for 10.6.4, 101300 for 10.13). FLTK initializes this global variable before main() begins running. If diff --git a/FL/platform.H b/FL/platform.H index 1ff9cd48c8..834a323926 100644 --- a/FL/platform.H +++ b/FL/platform.H @@ -51,7 +51,7 @@ class Fl_Window; class FL_EXPORT Fl_X { public: - Window xid; + fl_uintptr_t xid; Fl_Window* w; Fl_Region region; Fl_X *next; @@ -64,7 +64,7 @@ public: # endif }; -inline Window fl_xid(const Fl_Window* w) { Fl_X *xTemp = Fl_X::i(w); return xTemp ? xTemp->xid : 0; } +inline Window fl_xid(const Fl_Window* w) { Fl_X *xTemp = Fl_X::i(w); return xTemp ? (Window)xTemp->xid : 0; } #else extern FL_EXPORT Window fl_xid_(const Fl_Window* w); # define fl_xid(w) fl_xid_(w) diff --git a/FL/platform_types.h b/FL/platform_types.h index f831b8b222..b55544d4ce 100644 --- a/FL/platform_types.h +++ b/FL/platform_types.h @@ -32,15 +32,40 @@ typedef opaque fl_intptr_t; A variable of type fl_uintptr_t can also store an unsigned long int value. */ typedef opaque fl_uintptr_t; -typedef opaque Fl_Offscreen; /**< an offscreen drawing buffer */ -typedef opaque Fl_Region; /**< a region made of several rectangles */ +/** + Platform-specific value representing an offscreen drawing buffer. + \note This value can be safely cast to these types on each platform: + \li X11: Pixmap + \li Wayland: struct fl_wld_buffer * + \li Windows: HBITMAP + \li macOS: CGContextRef + */ +typedef opaque Fl_Offscreen; + +/** + Pointer to a platform-specific structure representing a collection of rectangles. + \note This pointer can be safely cast to these types on each platform: + \li X11: Region as defined by X11 + \li Wayland: struct flCairoRegion * + \li Windows: HRGN + \li macOS: struct flCocoaRegion * + */ +typedef struct opaque *Fl_Region; typedef opaque FL_SOCKET; /**< socket or file descriptor */ -typedef opaque GLContext; /**< an OpenGL graphics context, into which all OpenGL calls are rendered */ +/** + Pointer to a platform-specific structure representing the window's OpenGL rendering context. + \note This pointer can be safely cast to these types on each platform: + \li X11: GLXContext + \li Wayland: EGLContext + \li Windows: HGLRC + \li macOS: NSOpenGLContext * + */ +typedef struct opaque *GLContext; # define FL_COMMAND opaque /**< An alias for FL_CTRL on Windows and X11, or FL_META on MacOS X */ # define FL_CONTROL opaque /**< An alias for FL_META on Windows and X11, or FL_CTRL on MacOS X */ -#else +#else /* FL_DOXYGEN */ #ifndef FL_PLATFORM_TYPES_H #define FL_PLATFORM_TYPES_H @@ -49,8 +74,7 @@ typedef opaque GLContext; /**< an OpenGL graphics context, into which all OpenGL /* Platform-dependent types are defined here. These types must be defined by any platform: - Fl_Offscreen, Fl_Region, FL_SOCKET, GLContext, struct dirent, struct stat, - fl_intptr_t, fl_uintptr_t + FL_SOCKET, struct dirent, fl_intptr_t, fl_uintptr_t NOTE: *FIXME* AlbrechtS 13 Apr 2016 (concerning FL_SOCKET) ---------------------------------------------------------- @@ -78,65 +102,29 @@ typedef unsigned long fl_uintptr_t; #endif /* _WIN64 */ +typedef void *GLContext; +typedef void *Fl_Region; +typedef fl_uintptr_t Fl_Offscreen; + +/* Allows all hybrid combinations except WIN32 + X11 with MSVC */ +#if defined(_WIN32) && !defined(__MINGW32__) + struct dirent {char d_name[1];}; +#else +# include +#endif -#ifdef __APPLE__ -typedef struct CGContext* Fl_Offscreen; -typedef struct flCocoaRegion* Fl_Region; -typedef int FL_SOCKET; -#ifdef __OBJC__ - @class NSOpenGLContext; - typedef NSOpenGLContext* GLContext; -#elif defined(__cplusplus) - typedef class NSOpenGLContext* GLContext; -#endif /* __OBJC__ */ - -#include -#include -# define FL_COMMAND FL_META -# define FL_CONTROL FL_CTRL - -#elif defined(_WIN32) -typedef struct HBITMAP__ *HBITMAP; -typedef HBITMAP Fl_Offscreen; -typedef struct HRGN__ *Fl_Region; # if defined(_WIN64) && defined(_MSC_VER) typedef unsigned __int64 FL_SOCKET; /* *FIXME* - FL_SOCKET (see above) */ # else typedef int FL_SOCKET; # endif -typedef struct HGLRC__ *GLContext; -#ifdef __MINGW32__ -# include -#else - struct dirent {char d_name[1];}; -#endif - -#elif defined(FLTK_USE_WAYLAND) -typedef struct fl_wld_buffer *Fl_Offscreen; /**< an offscreen drawing buffer */ -typedef struct flCairoRegion* Fl_Region; -typedef int FL_SOCKET; /**< socket or file descriptor */ -typedef void *EGLContext; -typedef EGLContext GLContext; -#include -#include - -#elif defined(FLTK_USE_X11) -typedef unsigned long Fl_Offscreen; -typedef struct _XRegion *Fl_Region; -typedef int FL_SOCKET; -typedef struct __GLXcontextRec *GLContext; -#include -#include - -#endif /* __APPLE__ */ - - -#ifndef __APPLE__ -# define FL_COMMAND FL_CTRL /**< An alias for FL_CTRL on Windows and X11, or FL_META on MacOS X */ -# define FL_CONTROL FL_META /**< An alias for FL_META on Windows and X11, or FL_CTRL on MacOS X */ -#endif +#include +extern FL_EXPORT int fl_command_modifier(); +extern FL_EXPORT int fl_control_modifier(); +# define FL_COMMAND fl_command_modifier() +# define FL_CONTROL fl_control_modifier() #endif /* FL_PLATFORM_TYPES_H */ -#endif // FL_DOXYGEN +#endif /* FL_DOXYGEN */ diff --git a/FL/wayland.H b/FL/wayland.H index bd5f8a8121..66b6331824 100644 --- a/FL/wayland.H +++ b/FL/wayland.H @@ -1,7 +1,7 @@ // -// Wayland platform header file for the Fast Light Tool Kit (FLTK). +// Wayland/X11 hybrid platform header file for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2021 by Bill Spitzak and others. +// Copyright 1998-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -18,16 +18,35 @@ # error "Never use directly; include instead." #endif // !FL_PLATFORM_H -typedef struct wld_window *Window; +/** \file + Definitions of functions specific to the Wayland platform. +*/ -struct flCairoRegion { - int count; - struct _cairo_rectangle *rects; -}; // a region is the union of a series of rectangles +// *********** for Wayland component *********** -#include typedef struct _cairo cairo_t; -FL_EXPORT struct wl_display *fl_wl_display(); -FL_EXPORT struct wl_surface *fl_wl_surface(Window xid); -FL_EXPORT cairo_t *fl_wl_cairo(); +/** Returns the Wayland display in use */ +extern FL_EXPORT struct wl_display *fl_wl_display(); +/** Returns the wl_surface associated to a shown window */ +extern FL_EXPORT struct wl_surface *fl_wl_surface(struct wld_window *xid); +/** Returns a platform-specific reference associated to a shown window */ +extern FL_EXPORT struct wld_window *fl_wl_xid(const Fl_Window *win); +/** Returns the Fl_Window corresponding to a given the platform-specific window reference */ +extern FL_EXPORT Fl_Window *fl_wl_find(struct wld_window *); +/** Returns the cairo context associated to the current window*/ +extern FL_EXPORT cairo_t *fl_wl_cairo(); +typedef void *EGLContext; +/** Returns the EGLContext corresponding to the given GLContext */ +extern FL_EXPORT EGLContext fl_wl_glcontext(GLContext rc); +/** Prevent the FLTK library from using its wayland backend. + Call this early in your main(), before fl_open_display() runs. */ +extern FL_EXPORT void fl_disable_wayland(); + + +#ifndef FL_DOXYGEN + +// *********** for X11 component *********** +# include "x11.H" + +#endif // FL_DOXYGEN diff --git a/FL/win32.H b/FL/win32.H index 8ff136cb35..d7bfd5c18c 100644 --- a/FL/win32.H +++ b/FL/win32.H @@ -18,7 +18,25 @@ // include this file if _WIN32 is defined. This is to encourage // portability of even the system-specific code... -#ifndef FL_DOXYGEN +#ifdef FL_DOXYGEN + +/** \file + Definitions of functions specific to the Windows platform. +*/ + +/** Returns the Windows-specific window reference corresponding to the given Fl_Window object */ +extern HWND fl_win32_xid(const Fl_Window *win); +/** Returns the Fl_Window corresponding to the given Windows-specific window reference */ +extern Fl_Window *fl_win32_find(HWND); +/** Returns the Windows-specific GL rendering context corresponding to the given GLContext */ +extern HGLRC fl_win32_glcontext(GLContext rc); +/** Returns the Windows-specific graphics context for the current window */ +extern HDC fl_win32_gc(); +/** Returns the Windows-specific display in use */ +extern HINSTANCE fl_win32_display(); + +#else + #ifndef FL_PLATFORM_H # error "Never use directly; include instead." #endif // !FL_PLATFORM_H @@ -26,6 +44,11 @@ #include typedef HWND Window; +typedef struct HGLRC__ *HGLRC; +extern FL_EXPORT HGLRC fl_win32_glcontext(GLContext rc); +extern FL_EXPORT HWND fl_win32_xid(const Fl_Window *win); +extern FL_EXPORT Fl_Window *fl_win32_find(HWND); + // this part is included only when compiling the FLTK library or if requested explicitly #if defined(FL_LIBRARY) || defined(FL_INTERNALS) @@ -60,7 +83,9 @@ FL_EXPORT HBRUSH fl_brush(); // allocates a brush if necessary FL_EXPORT HBRUSH fl_brush_action(int); // now does the real work extern FL_EXPORT HINSTANCE fl_display; +extern FL_EXPORT HINSTANCE fl_win32_display(); extern FL_EXPORT HDC fl_gc; +extern FL_EXPORT HDC fl_win32_gc(); extern FL_EXPORT MSG fl_msg; extern FL_EXPORT HDC fl_GetDC(Window); extern FL_EXPORT HDC fl_makeDC(HBITMAP); diff --git a/FL/x11.H b/FL/x11.H index 1168701662..56ca43b08e 100644 --- a/FL/x11.H +++ b/FL/x11.H @@ -18,7 +18,22 @@ // include this file if FLTK_USE_X11 is defined. This is to encourage // portability of even the system-specific code... -#ifndef FL_DOXYGEN +#ifdef FL_DOXYGEN + +/** \file + Definitions of functions specific to the X11 platform. +*/ + +/** Returns the X11 Display in use */ +extern Display *fl_x11_display(); +/** Returns the Window reference for the given Fl_Window, or zero if not \c shown(). */ +extern Window fl_x11_xid(const Fl_Window *win); +/** Returns the Fl_Window corresponding to the given Window reference. */ +extern Fl_Window *fl_x11_find(Window xid); +/** Returns the X11-specific currently active graphics context. */ +extern GC fl_x11_gc(); + +#else // ! FL_DOXYGEN #ifndef FL_PLATFORM_H # error "Never use directly; include instead." @@ -36,14 +51,21 @@ #endif #include +typedef struct __GLXcontextRec *GLXContext; +extern GLXContext fl_x11_glcontext(GLContext rc); + // constant info about the X server connection: extern FL_EXPORT Display *fl_display; +extern FL_EXPORT Display *fl_x11_display(); +extern FL_EXPORT Window fl_x11_xid(const Fl_Window *win); +extern FL_EXPORT Fl_Window *fl_x11_find(Window); extern FL_EXPORT int fl_screen; extern FL_EXPORT XVisualInfo *fl_visual; extern FL_EXPORT Colormap fl_colormap; // drawing functions: extern FL_EXPORT GC fl_gc; +extern FL_EXPORT GC fl_x11_gc(); FL_EXPORT ulong fl_xpixel(Fl_Color i); FL_EXPORT ulong fl_xpixel(uchar r, uchar g, uchar b); diff --git a/README.CMake.txt b/README.CMake.txt index b3d089be52..d97b491cd9 100644 --- a/README.CMake.txt +++ b/README.CMake.txt @@ -126,7 +126,8 @@ FLTK_BUILD_EXAMPLES - default OFF Builds the example programs in the 'examples' directory. OPTION_CAIRO - default OFF - Enables libcairo support - see README.Cairo.txt. + Enables support of class Fl_Cairo_Window (all platforms, requires the + Cairo library) - see README.Cairo.txt. OPTION_CAIROEXT - default OFF Enables extended libcairo support - see README.Cairo.txt. @@ -148,7 +149,7 @@ OPTION_USE_SYSTEM_ZLIB - default ON any of these options to OFF, then the built in library will be used. OPTION_USE_SVG - default ON - FLTK has a built in SVG library and can create (write) SVG image files. + FLTK has a built-in SVG library and can create (write) SVG image files. Turning this option off disables SVG (read and write) support. OPTION_USE_XINERAMA - default ON @@ -158,14 +159,21 @@ OPTION_USE_XRENDER - default ON These are X11 extended libraries. These libs are used if found on the build system unless the respective option is turned off. +OPTION_USE_CAIRO - default OFF + Makes all drawing operations use the Cairo library (rather than Xlib) + producing antialiased graphics (X11 platform, implies OPTION_USE_PANGO). + OPTION_USE_PANGO - default OFF Enables use of the Pango library for drawing text. Pango supports all unicode-defined scripts with limited support of right-to-left scripts. This option makes sense only under X11, and also requires Xft. OPTION_USE_WAYLAND - default OFF - Enables use of the Wayland system for all window operations. - This option requires a Wayland-equipped system, i.e., Linux or FreeBSD. + Enables the use of Wayland for all window operations, of Cairo for all + graphics and of Pango for text drawing (Linux only). Resulting FLTK + apps use Wayland when a Wayland compositor is available at run-time, + and use X11 for their window operations otherwise, but keep using + Cairo and Pango - see README.Wayland.txt. OPTION_ABI_VERSION - default EMPTY Use a numeric value corresponding to the FLTK ABI version you want to @@ -182,6 +190,9 @@ OPTION_PRINT_SUPPORT - default ON is somewhat smaller. This option makes sense only on the Unix/Linux platform or when OPTION_APPLE_X11 is ON. +OPTION_USE_GDIPLUS - default ON + Makes FLTK use GDI+ to draw oblique lines and curves resulting in + antialiased graphics (Windows platform only). Documentation options: these options are only available if `doxygen' is installed and found by CMake. PDF related options require also `latex'. diff --git a/README.Cairo.txt b/README.Cairo.txt index b2bfba0e71..6d70e9213b 100644 --- a/README.Cairo.txt +++ b/README.Cairo.txt @@ -61,11 +61,19 @@ variable OPTION_CAIRO:BOOL=ON is set. transparently a Cairo context to your custom Fl_Window derived class. This function is intended to be used in your overloaded draw() method. -(3) Adding an optional Cairo autolink context mode support which permits +(3) FLTK instrumentation for cairo extended use : + Adding an optional Cairo autolink context mode support which permits complete and automatic synchronization of OS dependent graphical context and Cairo contexts, thus furthering a valid Cairo context anytime, in any current window. + Usage : + - Call Fl::cairo_autolink_context(true); before windows are shown. + - In an overridden widget draw method, do + cairo_t *cc = Fl::cairo_cc(); + and obtain the cairo context value adequate to draw with cairo to + the current window. + This feature should be only necessary in the following cases: - Intensive and almost systematic use of Cairo in an FLTK application - Creation of a new Cairo based scheme for FLTK diff --git a/README.Wayland.txt b/README.Wayland.txt index 840f372131..01b7ba1ada 100644 --- a/README.Wayland.txt +++ b/README.Wayland.txt @@ -9,12 +9,17 @@ CONTENTS 2 WAYLAND SUPPORT FOR FLTK 2.1 Configuration - 2.2 Known limitations + 2.2 Known Limitations - 3 PLATFORM SPECIFIC NOTES - 3.1 Debian and Derivatives (like Ubuntu) - 3.2 Fedora - 3.3 FreeBSD + 3 PREPARING PLATFORM-SPECIFIC CODE FOR THE WAYLAND PLATFORM + 3.1 Handling X11-specific source code + 3.2 Handling X11- and Wayland-specific source code in the same app + 3.3 Forcing an app to always use the X11 mechanism + + 4 PLATFORM SPECIFIC NOTES + 4.1 Debian and Derivatives (like Ubuntu) + 4.2 Fedora + 4.3 FreeBSD 1 INTRODUCTION @@ -33,36 +38,49 @@ CJK text-input methods, as well as dead and compose keys are supported. 2 WAYLAND SUPPORT FOR FLTK ========================== -It is possible to have your FLTK application do all its windowing and drawing -through the Wayland protocol on Linux or FreeBSD systems. -All graphics is done via Cairo or EGL. All text-drawing is done via Pango. +On Linux and FreeBSD systems, and provided a Wayland compositor is available at run-time, +it is possible to have your FLTK application do all its windowing through the +Wayland protocol, all its graphics with Cairo or EGL, and all text-drawing with +Pango. If no Wayland compositor is available at run-time, FLTK falls back to +using X11 or OpenGL for its windowing. Cairo and Pango remain used for graphics +and text, respectively. + +Environment variable FLTK_BACKEND can be used to control whether Wayland or +X11 is used at run time as follows: +- if FLTK_BACKEND is not defined, Wayland is used when possible, otherwise + X11 is used; +- if FLTK_BACKEND equals "wayland", the library stops with error if no + Wayland compositor is available; +- if FLTK_BACKEND equals "x11", the library uses X11 even if a Wayland + compositor is available; +- if FLTK_BACKEND has another value, the library stops with error. 2.1 Configuration ---------------- +------------------ * Configure-based build can be performed as follows: Once after "git clone", create the configure file : - autoconf -f + autoconf -f Prepare build with : - ./configure --enable-wayland [--enable-shared] + ./configure --enable-wayland [--enable-shared] Build with : - make + make * CMake-based build can be performed as follows: -cmake -S -B -DCMAKE_BUILD_TYPE=Release -DOPTION_USE_WAYLAND=1 + cmake -S -B -DCMAKE_BUILD_TYPE=Release -DOPTION_USE_WAYLAND=1 -cd ; make + cd ; make -The FLTK wayland platform uses a library called libdecor which handles window decorations +The FLTK Wayland platform uses a library called libdecor which handles window decorations (i.e., titlebars, shade). Libdecor is bundled in the FLTK source code and FLTK uses by default this form of libdecor. Optionally, OPTION_USE_SYSTEM_LIBDECOR can be turned on to have FLTK use the system's version of libdecor which is available on recent Linux distributions (e.g., -Debian bookworm or more recent in packages libdecor-0-0 and libdecor-0-plugin-1-cairo). +Debian Bookworm or more recent in packages libdecor-0-0 and libdecor-0-plugin-1-cairo). - 2.2 Known limitations -------------------------------- + 2.2 Known Limitations +---------------------- * A deliberate design trait of Wayland makes application windows ignorant of their exact placement on screen. It's possible, though, to position a popup window relatively to @@ -86,41 +104,72 @@ tested in that situation. * Text input methods have been tested without any understanding of the writing systems, so feedback on this subject would be helpful. -* While platform-independent source code prepared for FLTK 1.3 is expected to be compatible -with FLTK 1.4 and the Wayland platform, X11-specific code will not compile. In particular, -the common FLTK 1.3 construct : + +3 PREPARING PLATFORM-SPECIFIC CODE FOR THE WAYLAND PLATFORM +=========================================================== + +While platform-independent source code prepared for FLTK 1.3 is expected +to be compatible with no change with FLTK 1.4 and the Wayland platform, +platform-specific code may require some attention. + +3.1 Handling X11-specific source code +------------------------------------- + +If an FLTK 1.4 application contains X11-specific code, execution of this code +in the context of an active Wayland session can produce malfunctions or program crashes. +To ensure that X11-specific code gets called only when an X11 connection is active, +check that function fl_x11_display() returns non-NULL before using any X11-specific +function or variable. + +3.2 Handling X11- and Wayland-specific source code in the same app +------------------------------------------------------------------ + +The recommended way to prepare and use platform-specific code that would contain +both X11-specific and Wayland-specific parts is as follows : + +a) Organize platform-specific code as follows : + + #include + #ifdef __APPLE__ *** macOS-specific code *** #elif defined(_WIN32) *** Windows-specific code *** #else - *** X11-specific code *** - #endif -will choke at compile time because it exposes X11-specific code to the non-X11, Wayland -environment. This should be written instead : - #include + *** X11-specific code *** - #ifdef __APPLE__ - *** macOS-specific code *** - #elif defined(_WIN32) - *** Windows-specific code *** - #elif defined(FLTK_USE_X11) - *** X11-specific code *** + *** Wayland-specific code *** #endif -Moreover, the new FLTK_USE_WAYLAND preprocessor variable is available to bracket -Wayland-specific source code. +b) Make sure to use distinct names for global variables and functions +in the X11- and the Wayland-specific sections. -3 PLATFORM SPECIFIC NOTES +c) Check that function fl_x11_display() returns non-NULL before using any X11-specific +function or variable, and that fl_wl_display() returns non-NULL before using any +Wayland-specific function or variable. Make sure that fl_open_display() was called +directly or indirectly before using any such symbol. + +3.3 Forcing an app to always use the X11 mechanism +-------------------------------------------------- + +Alternatively, it's possible to force an FLTK app to use X11 in all +situations by calling function fl_disable_wayland() early in main(), before +fl_open_display() runs. FLTK source code and also platform-specific +code conceived for FLTK 1.3 should run under 1.4 with that single change only. + + +4 PLATFORM SPECIFIC NOTES ========================= The following are notes about building FLTK for the Wayland platform -on the various supported Linux distributions. +on the various supported Linux distributions/OS. + +4.1 Debian and Derivatives (like Ubuntu) +---------------------------------------- - 3.1 Debian and Derivatives (like Ubuntu) - ---------------------------------------- Under Debian, the Wayland platform requires version 11 (a.k.a. Bullseye) or more recent. -Under Ubuntu, the Wayland platform is known to work with version 20.04 (focal fossa) or more recent. +Under Ubuntu, the Wayland platform is known to work with version 20.04 (focal fossa) or +more recent. These packages are necessary to build the FLTK library, in addition to those present in a basic Debian/Ubuntu distribution : @@ -148,8 +197,8 @@ These packages allow to run FLTK apps under the KDE/Plasma-Wayland desktop: - plasma-workspace-wayland - 3.2 Fedora - ---------- +4.2 Fedora +---------- The Wayland platform is known to work with Fedora version 35. @@ -172,8 +221,8 @@ in a Fedora 35 Workstation distribution : Package installation command: sudo yum install - 3.3 FreeBSD - ----------- +4.3 FreeBSD +----------- The Wayland platform is known to work with FreeBSD version 13.1 and the sway compositor. diff --git a/cairo/Fl_Cairo.cxx b/cairo/Fl_Cairo.cxx index dbbf2e55f7..4833bb3952 100644 --- a/cairo/Fl_Cairo.cxx +++ b/cairo/Fl_Cairo.cxx @@ -21,17 +21,18 @@ #include // Cairo is currently supported for the following platforms: -// Win32, Apple Quartz, X11 +// Win32, Apple Quartz, X11, Wayland -#if defined(FLTK_USE_X11) // X11 -# include -#elif defined(_WIN32) // Windows +#if defined(_WIN32) // Windows # include #elif defined(__APPLE__) // macOS # include -#elif defined(FLTK_USE_WAYLAND) +#elif defined(FLTK_USE_WAYLAND) // Wayland or hybrid # include "../src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H" # include "../src/drivers/Wayland/Fl_Wayland_Window_Driver.H" +# include +#elif defined(FLTK_USE_X11) // X11 +# include #else # error Cairo is not supported on this platform. #endif @@ -73,11 +74,14 @@ cairo_t * Fl::cairo_make_current(Fl_Window* wi) { if (!wi) return NULL; // Precondition cairo_t * cairo_ctxt; #if defined(FLTK_USE_WAYLAND) - Window xid = fl_xid(wi); - if (!xid->buffer) return NULL; // this may happen with GL windows - cairo_ctxt = xid->buffer->cairo_; - cairo_state_.cc(cairo_ctxt, false); -#else // !FLTK_USE_WAYLAND + if (fl_wl_display()) { // true means using wayland backend + struct wld_window *xid = fl_wl_xid(wi); + if (!xid->buffer) return NULL; // this may happen with GL windows + cairo_ctxt = xid->buffer->cairo_; + cairo_state_.cc(cairo_ctxt, false); + return cairo_ctxt; + } +#endif if (fl_gc==0) { // means remove current cc Fl::cairo_cc(0); // destroy any previous cc cairo_state_.window(0); @@ -102,11 +106,9 @@ cairo_t * Fl::cairo_make_current(Fl_Window* wi) { #ifndef __APPLE__ cairo_scale(cairo_ctxt, scale, scale); #endif -#endif // FLTK_USE_WAYLAND return cairo_ctxt; } -#if !defined(FLTK_USE_WAYLAND) /* Creates transparently a cairo_surface_t object. gc is an HDC context in Windows, a CGContext* in Quartz, and @@ -194,7 +196,6 @@ cairo_t * Fl::cairo_make_current(void *gc, int W, int H) { return c; } -#endif // !FLTK_USE_WAYLAND #else // just don't leave the libfltk_cairo lib empty to avoid warnings diff --git a/configure.ac b/configure.ac index 9826102128..3a2240ccfa 100644 --- a/configure.ac +++ b/configure.ac @@ -85,7 +85,7 @@ AC_SUBST(OPTIM) dnl Other options -AC_ARG_ENABLE([cairo], AS_HELP_STRING([--enable-cairo], [use Cairo library])) +AC_ARG_ENABLE([cairo], AS_HELP_STRING([--enable-cairo], [add support for Fl_Cairo_Window])) AC_ARG_ENABLE([cairoext], AS_HELP_STRING([--enable-cairoext], [use FLTK code instrumentation for cairo extended use])) AC_ARG_ENABLE([cp936], AS_HELP_STRING([--enable-cp936], [turn on CP936])) @@ -112,6 +112,8 @@ AC_ARG_ENABLE([pango], AS_HELP_STRING([--enable-pango], [turn on Pango support]) AC_ARG_ENABLE([wayland], AS_HELP_STRING([--enable-wayland], [turn on Wayland support])) +AC_ARG_ENABLE([usecairo], AS_HELP_STRING([--enable-usecairo], [all drawing to X11 windows uses Cairo])) + AC_ARG_ENABLE([print], AS_HELP_STRING([--disable-print], [turn off print support (X11)])) AS_IF([test x$enable_print = xno], [ AC_DEFINE([FL_NO_PRINT_SUPPORT], [Disable X11 print support?]) @@ -984,13 +986,18 @@ AS_CASE([$host_os_gui], [cygwin* | mingw*], [ AC_MSG_WARN([--enable-wayland: please install pkg-config.]) AC_MSG_ERROR([Aborting.]) ]) + + dnl Turn option usecairo ON + AC_DEFINE([FLTK_USE_CAIRO]) + AC_MSG_NOTICE([Turning on the usecairo option]) BUILD="WAYLAND" AC_DEFINE([FLTK_USE_WAYLAND]) + AC_DEFINE([FLTK_USE_X11]) # to build a hybrid Wayland/X11 library CFLAGS="$CFLAGS -DUSE_SYSTEM_LIBDECOR=0" CXXFLAGS="$CXXFLAGS -DUSE_SYSTEM_LIBDECOR=0" - graphics="Wayland" - LIBS="$LIBS $($PKGCONFIG --libs wayland-cursor) $($PKGCONFIG --libs wayland-client) $($PKGCONFIG --libs xkbcommon)" + graphics="Wayland or X11 with cairo" + LIBS="$LIBS $($PKGCONFIG --libs wayland-cursor) $($PKGCONFIG --libs wayland-client) $($PKGCONFIG --libs xkbcommon) $($PKGCONFIG --libs pangoxft) $($PKGCONFIG --libs x11)" LIBS="$LIBS $($PKGCONFIG --libs dbus-1) -ldl" CXXFLAGS="$CXXFLAGS -I../libdecor/src" DSOFLAGS="$LIBS $DSOFLAGS" @@ -1174,6 +1181,15 @@ AS_CASE([$host_os_gui], [cygwin* | mingw*], [ ]) ]) + dnl Option usecairo + AS_IF([test x$enable_usecairo = xyes], [ + enable_pango=yes + BUILD="CAIRO" + AC_DEFINE([FLTK_USE_CAIRO]) + AC_MSG_NOTICE([Processing usecairo option]) + ] + ) + dnl test if Pango is asked but xft was not found AS_IF([test x$enable_pango = xyes -a x$xft_found = xno], [ AC_MSG_WARN([could not find the Xft headers and/or libraries required for Pango.]) @@ -1609,6 +1625,9 @@ AS_CASE([$host_os_gui], [cygwin* | mingw*], [ AS_IF([test x$xrender_found = xyes], [ graphics="$graphics + Xrender" ]) + AS_IF([test x$enable_usecairo = xyes], [ + graphics="$graphics + Cairo" + ]) AS_IF([test x$pango_found = xyes], [ graphics="$graphics + Pango" ]) diff --git a/documentation/src/intro.dox b/documentation/src/intro.dox index 89ac09ac83..7b827fd80c 100644 --- a/documentation/src/intro.dox +++ b/documentation/src/intro.dox @@ -143,7 +143,13 @@ the toolkit, which was already in use by several people, Bill came up with "FLTK", including a bogus excuse that it stands for "The Fast Light Toolkit". -\section intro_unix Building and Installing FLTK Under UNIX and Apple macOS +\section intro_cmake Building and Installing FLTK with CMake + +Starting with version 1.4, the recommended FLTK building system +is CMake. See file README.CMake of the FLTK source tree for all information. +It's also possible to use \p configure and \p make as follows to build and install FLTK. + +\section intro_unix Building and Installing FLTK Under UNIX and macOS with make In most cases you can just type "make". This will run configure with the default of no options and then compile everything. @@ -196,6 +202,9 @@ Enable debugging code & symbols \par --disable-gl Disable OpenGL support +\par --disable-svg +Disable support of reading and writing of Support Vector Graphics (.svg) files. + \par --disable-print Disable print support for an X11 platform @@ -205,22 +214,39 @@ Enable generation of shared libraries \par --enable-threads Enable multithreading support -\par --enable-xdbe -Enable the X double-buffer extension +\par --enable-wayland +Enable the use of Wayland for all window operations, of Cairo for all graphics +and of Pango for text drawing (Linux and FreeBSD only). Resulting FLTK apps +use Wayland if a Wayland compositor is available at run-time, and use +the equivalent of "--enable-x11 --enable-usecairo" otherwise. + +\par --disable-xft +Disables the Xft library, resulting in non anti-aliased fonts (X11 platform). -\par --enable-xft -Enable the Xft library for anti-aliased fonts under X11 +\par --enable-usecairo +All drawing operations use the Cairo library (rather than Xlib) producing +antialiased graphics (X11 platform, implies --enable-pango). \par --enable-pango -Enable the pango library for drawing any text in any script under X11. +Enable the Pango library for drawing any text in any script with any font under X11. \par --enable-x11 +This is the default under Unix and Linux. When targeting cygwin, build with X11 GUI instead of windows GDI. Also applicable to macOS platforms supplemented with XQuartz. \par --enable-wayland Enable use of the Wayland system for window handling. +\par --enable-cairo +Enable support of class Fl_Cairo_Window (all platforms, requires the Cairo library). + +\par --enable-cairoext +Enable the FLTK instrumentation for cairo extended use (requires --enable-cairo). + +\par --disable-gdiplus +Don't use GDI+ when drawing curves and oblique lines (Windows platform). + \par --enable-cp936 Under X11, enable use of the GB2312 locale diff --git a/documentation/src/osissues.dox b/documentation/src/osissues.dox index 999fced254..32328847bb 100644 --- a/documentation/src/osissues.dox +++ b/documentation/src/osissues.dox @@ -88,6 +88,8 @@ Window fl_xid(const Fl_Window *) \par Returns the XID for a window, or zero if not \c shown(). +\deprecated Kept for compatibility with FLTK versions before 1.4. +Use preferentially fl_x11_xid(const Fl_Window *) with versions 1.4 and above. Fl_Window *fl_find(ulong xid) @@ -96,6 +98,8 @@ Returns the Fl_Window that corresponds to the given XID, or \c NULL if not found. This function uses a cache so it is slightly faster than iterating through the windows yourself. +\deprecated Kept for compatibility with FLTK versions before 1.4. +Use preferentially fl_x11_find(Window) with versions 1.4 and above. int fl_handle(const XEvent &) @@ -124,9 +128,11 @@ The following global variables are set before Fl_Widget::draw() is called, or by Fl_Window::make_current(): \code -extern Display *fl_display; +extern Display *fl_display; // for compatibility with previous FLTK versions +extern Display *fl_x11_display(); // preferred access starting with FLTK 1.4 extern Window fl_window; -extern GC fl_gc; +extern GC fl_gc; // for compatibility with previous FLTK versions +extern GC fl_x11_gc(); // preferred access starting with FLTK 1.4 extern int fl_screen; extern XVisualInfo *fl_visual; extern Colormap fl_colormap; @@ -559,9 +565,11 @@ called, FLTK stores all the extra arguments you need to make a proper GDI call in some global variables: \code -extern HINSTANCE fl_display; +extern HINSTANCE fl_display; // for compatibility with previous FLTK versions +extern HINSTANCE fl_win32_display(); // preferred access starting with FLTK 1.4 extern HWND fl_window; -extern HDC fl_gc; +extern HDC fl_gc; // for compatibility with previous FLTK versions +extern HDC fl_win32_gc(); // preferred access starting with FLTK 1.4 COLORREF fl_RGB(); HPEN fl_pen(); HBRUSH fl_brush(); @@ -931,17 +939,8 @@ FLTK uses UTF-8-encoded UNIX-style filenames and paths. \section osissues_wayland The Wayland Interface -Wayland-specific source code can be organized as follows to be distinguished -from X11-specific source code : -\code -#include // defines FLTK_USE_WAYLAND or FLTK_USE_X11 as appropriate - -#if defined(FLTK_USE_WAYLAND) -… Wayland-specific source code … -#elif defined(FLTK_USE_X11) -… X11-specific source code … -#endif -\endcode +See file README.Wayland.txt for details about how to organize platform-specific +source code for the Wayland platform. extern struct wl_display *fl_wl_display(); \par @@ -950,16 +949,16 @@ struct wl_display representing the connection between the application and Waylan For example, \c wl_display_get_fd(fl_wl_display()) gives the file descriptor one can use to communicate with the Wayland compositor according to the Wayland protocol. -Window fl_xid(const Fl_Window *) +struct wld_window *fl_wl_xid(const Fl_Window *) \par Returns a pointer to an FLTK-defined structure holding Wayland-related data created when a window gets show()'n, or NULL if not show()'n. -Fl_Window *fl_find(Window wld_win) +Fl_Window *fl_wl_find(struct wld_window * wld_win) \par Returns the Fl_Window that corresponds to the given Window, or NULL if not found. -struct wl_surface *fl_wl_surface(Window wld_win) +struct wl_surface *fl_wl_surface(struct wld_window *wld_win) \par Returns a pointer to the struct wl_surface corresponding to a show()'n top-level window or subwindow. diff --git a/fl_config.cmake.in b/fl_config.cmake.in index c0505e03a9..0acc7a8ff9 100644 --- a/fl_config.cmake.in +++ b/fl_config.cmake.in @@ -56,6 +56,16 @@ #cmakedefine FLTK_USE_X11 1 +/* + * FLTK_USE_CAIRO + * + * Do we use Cairo to draw to the display? + * + */ + +#cmakedefine FLTK_USE_CAIRO 1 + + /* * FLTK_USE_WAYLAND * diff --git a/fl_config.in b/fl_config.in index af4fd3530a..992c3cd61c 100644 --- a/fl_config.in +++ b/fl_config.in @@ -55,6 +55,16 @@ #undef FLTK_USE_X11 +/* + * FLTK_USE_CAIRO + * + * Do we use Cairo to draw to the display? + * + */ + +#undef FLTK_USE_CAIRO + + /* * FLTK_USE_WAYLAND * diff --git a/fluid/Makefile b/fluid/Makefile index 3252abc668..f8423ce5de 100644 --- a/fluid/Makefile +++ b/fluid/Makefile @@ -48,6 +48,7 @@ CPPFILES_WIN = ExternalCodeEditor_WIN32.cxx CPPFILES_OSX = ExternalCodeEditor_UNIX.cxx CPPFILES_X11 = ExternalCodeEditor_UNIX.cxx CPPFILES_XFT = ExternalCodeEditor_UNIX.cxx +CPPFILES_CAIRO = ExternalCodeEditor_UNIX.cxx CPPFILES_WAYLAND = ExternalCodeEditor_UNIX.cxx CPPFILES += $(CPPFILES_$(BUILD)) diff --git a/makeinclude.in b/makeinclude.in index 8df8eb2a21..78637eaf43 100644 --- a/makeinclude.in +++ b/makeinclude.in @@ -24,7 +24,7 @@ FL_ABI_VERSION = @FL_ABI_VERSION@ FLTK_VERSION = @FLTK_VERSION@ -# FLTK configuration options: BUILD = { WIN | OSX | X11 | XFT | WAYLAND } +# FLTK configuration options: BUILD = { WIN | OSX | X11 | XFT | CAIROXLIB | WAYLAND } BUILD = @BUILD@ UNAME = @UNAME@ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 63b5b83992..a9bc917101 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -191,7 +191,7 @@ endif (FLTK_USE_X11 AND NOT OPTION_PRINT_SUPPORT) set (DRIVER_FILES) -if (FLTK_USE_X11) +if (FLTK_USE_X11 AND NOT OPTION_USE_WAYLAND) # X11 (including APPLE with X11) @@ -202,13 +202,6 @@ if (FLTK_USE_X11) drivers/Posix/Fl_Posix_System_Driver.cxx drivers/Unix/Fl_Unix_System_Driver.cxx drivers/X11/Fl_X11_System_Driver.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx drivers/X11/fl_X11_platform_init.cxx @@ -223,29 +216,56 @@ if (FLTK_USE_X11) set (DRIVER_FILES ${DRIVER_FILES} Fl_Native_File_Chooser_Kdialog.cxx) endif (OPTION_USE_KDIALOG) - if (USE_XFT) + if (FLTK_USE_CAIRO) set (DRIVER_FILES ${DRIVER_FILES} - drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx + drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx ) - if (USE_PANGO) - set (DRIVER_FILES ${DRIVER_FILES} drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx) - endif (USE_PANGO) else () + if (USE_XFT) + set (DRIVER_FILES ${DRIVER_FILES} + drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx + ) + if (USE_PANGO) + set (DRIVER_FILES ${DRIVER_FILES} drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx) + endif (USE_PANGO) + else () + set (DRIVER_FILES ${DRIVER_FILES} + drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx + ) + endif (USE_XFT) set (DRIVER_FILES ${DRIVER_FILES} - drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx ) - endif (USE_XFT) + endif (FLTK_USE_CAIRO) set (DRIVER_HEADER_FILES drivers/Posix/Fl_Posix_System_Driver.H drivers/X11/Fl_X11_Screen_Driver.H drivers/X11/Fl_X11_Window_Driver.H drivers/X11/Fl_X11_System_Driver.H + drivers/Xlib/Fl_Xlib_Graphics_Driver.H drivers/Xlib/Fl_Font.H drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H drivers/Unix/Fl_Unix_System_Driver.H ) + if (FLTK_USE_CAIRO) + set (DRIVER_HEADER_FILES ${DRIVER_HEADER_FILES} + drivers/Cairo/Fl_Cairo_Graphics_Driver.H + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H + ) + elseif (USE_PANGO) + set (DRIVER_HEADER_FILES ${DRIVER_HEADER_FILES} + drivers/Cairo/Fl_Cairo_Graphics_Driver.H + ) + endif (FLTK_USE_CAIRO) elseif (OPTION_USE_WAYLAND) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_BINARY_DIR}") @@ -262,9 +282,18 @@ elseif (OPTION_USE_WAYLAND) drivers/Wayland/fl_wayland_clipboard_dnd.cxx drivers/Wayland/fl_wayland_platform_init.cxx drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx Fl_Native_File_Chooser_FLTK.cxx Fl_Native_File_Chooser_GTK.cxx Fl_Native_File_Chooser_Kdialog.cxx + drivers/X11/Fl_X11_Screen_Driver.cxx + drivers/X11/Fl_X11_Window_Driver.cxx + drivers/X11/Fl_X11_System_Driver.cxx + drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx + drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx + Fl_x.cxx + fl_dnd_x.cxx + Fl_get_key.cxx ) set (DRIVER_HEADER_FILES drivers/Posix/Fl_Posix_System_Driver.H @@ -272,6 +301,8 @@ elseif (OPTION_USE_WAYLAND) drivers/Wayland/Fl_Wayland_Screen_Driver.H drivers/Wayland/Fl_Wayland_Window_Driver.H drivers/Wayland/Fl_Wayland_Graphics_Driver.H + drivers/Cairo/Fl_Cairo_Graphics_Driver.H + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.H drivers/Wayland/Fl_Wayland_Image_Surface_Driver.H drivers/Unix/Fl_Unix_System_Driver.H @@ -346,7 +377,7 @@ else () drivers/GDI/Fl_GDI_Image_Surface_Driver.H ) -endif (FLTK_USE_X11) +endif (FLTK_USE_X11 AND NOT OPTION_USE_WAYLAND) source_group("Header Files" FILES ${HEADER_FILES}) source_group("Driver Source Files" FILES ${DRIVER_FILES}) @@ -392,19 +423,22 @@ set (GL_DRIVER_FILES drivers/OpenGL/Fl_OpenGL_Graphics_Driver_rect.cxx drivers/OpenGL/Fl_OpenGL_Graphics_Driver_vertex.cxx ) -if (FLTK_USE_X11) +if (OPTION_USE_WAYLAND) + set (GL_DRIVER_FILES ${GL_DRIVER_FILES} + drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx + drivers/X11/Fl_X11_Gl_Window_Driver.cxx + drivers/Wayland/fl_wayland_gl_platform_init.cxx) + set (GL_DRIVER_HEADER_FILES drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H drivers/X11/Fl_X11_Gl_Window_Driver.H) +elseif (FLTK_USE_X11) set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/X11/Fl_X11_Gl_Window_Driver.cxx drivers/X11/fl_X11_gl_platform_init.cxx) set (GL_DRIVER_HEADER_FILES drivers/X11/Fl_X11_Gl_Window_Driver.H) -elseif (OPTION_USE_WAYLAND) - set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx drivers/Wayland/fl_wayland_gl_platform_init.cxx) - set (GL_DRIVER_HEADER_FILES drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H) elseif (APPLE) set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx drivers/Cocoa/fl_macOS_gl_platform_init.cxx) set (GL_DRIVER_HEADER_FILES drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H) elseif (WIN32) set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx drivers/WinAPI/fl_WinAPI_gl_platform_init.cxx) set (GL_DRIVER_HEADER_FILES drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.H) -endif (FLTK_USE_X11) +endif (OPTION_USE_WAYLAND) set (GL_DRIVER_HEADER_FILES ${GL_DRIVER_FILES} drivers/OpenGL/Fl_OpenGL_Display_Device.H @@ -621,7 +655,7 @@ if (OPTION_USE_WAYLAND) if (OPTION_USE_SYSTEM_LIBDECOR) list (APPEND OPTIONAL_LIBS "-ldecor-0") endif (OPTION_USE_SYSTEM_LIBDECOR) - list (APPEND OPTIONAL_LIBS "-lwayland-cursor -lwayland-client -lxkbcommon -ldl -ldbus-1") + list (APPEND OPTIONAL_LIBS "-lwayland-cursor -lwayland-client -lxkbcommon -ldl -ldbus-1 -lXcursor -lXrender -lXinerama -lXfixes -lXft -lXext -lX11") if (GTK_FOUND) list (APPEND OPTIONAL_LIBS ${GTK_LDFLAGS} ) endif (GTK_FOUND) diff --git a/src/Fl.cxx b/src/Fl.cxx index bac2ffa338..7b7cb2b7e6 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -99,8 +99,10 @@ Fl_Screen_Driver *Fl::screen_driver() /** Returns a pointer to the unique Fl_System_Driver object of the platform */ Fl_System_Driver *Fl::system_driver() { - static Fl_System_Driver* system_driver_ = Fl_System_Driver::newSystemDriver(); - return system_driver_; + if (!Fl_Screen_Driver::system_driver) { + Fl_Screen_Driver::system_driver = Fl_System_Driver::newSystemDriver(); + } + return Fl_Screen_Driver::system_driver; } // @@ -578,21 +580,15 @@ int Fl::program_should_quit_ = 0; Fl_X* Fl_X::first; #endif +/** Returns the Fl_Window that corresponds to the given window reference, + or \c NULL if not found. + \deprecated Kept in the X11, Windows, and macOS platforms for compatibility + with FLTK versions before 1.4. + Please use fl_x11_find(Window), fl_wl_find(struct wld_window*), + fl_win32_find(HWND) or fl_mac_find(FLWindow*) with FLTK 1.4.0 and above. +*/ Fl_Window* fl_find(Window xid) { - Fl_X *window; - for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next) { - if (window->xid == xid) { - if (window != Fl_X::first && !Fl::modal()) { - // make this window be first to speed up searches - // this is not done if modal is true to avoid messing up modal stack - *pp = window->next; - window->next = Fl_X::first; - Fl_X::first = window; - } - return window->w; - } - } - return 0; + return Fl_Window_Driver::find((fl_uintptr_t)xid); } /** @@ -630,7 +626,7 @@ Fl_Window* Fl::next_window(const Fl_Window* window) { */ void Fl::first_window(Fl_Window* window) { if (!window || !window->shown()) return; - fl_find( Fl_X::i(window)->xid ); + Fl_Window_Driver::find( Fl_X::i(window)->xid ); } /** @@ -2021,7 +2017,7 @@ void fl_close_display() FL_EXPORT Window fl_xid_(const Fl_Window *w) { Fl_X *temp = Fl_X::i(w); - return temp ? temp->xid : 0; + return temp ? (Window)temp->xid : 0; } /** \addtogroup group_macosx \{ */ diff --git a/src/Fl_Color_Chooser.cxx b/src/Fl_Color_Chooser.cxx index 9111dba7e4..643ba4f3c0 100644 --- a/src/Fl_Color_Chooser.cxx +++ b/src/Fl_Color_Chooser.cxx @@ -506,7 +506,7 @@ static int copy_rgb(double r, double g, double b) { int Fl_Color_Chooser::handle(int e) { - unsigned int mods = Fl::event_state() & (FL_META | FL_CTRL | FL_ALT); + int mods = Fl::event_state() & (FL_META | FL_CTRL | FL_ALT); unsigned int shift = Fl::event_state() & FL_SHIFT; switch (e) { diff --git a/src/Fl_Device.cxx b/src/Fl_Device.cxx index c4f1dec362..d5e1b27c4b 100644 --- a/src/Fl_Device.cxx +++ b/src/Fl_Device.cxx @@ -97,6 +97,10 @@ Fl_Surface_Device::~Fl_Surface_Device() if (surface_ == this) surface_ = NULL; } +/** Returns non-NULL if this surface is an Fl_Image_Surface object + \version 1.4.0 + */ +Fl_Image_Surface *Fl_Surface_Device::as_image_surface() { return NULL; } /** A constructor that sets the graphics driver used by the display */ Fl_Display_Device::Fl_Display_Device(Fl_Graphics_Driver *graphics_driver) : Fl_Surface_Device(graphics_driver) { diff --git a/src/Fl_File_Chooser2.cxx b/src/Fl_File_Chooser2.cxx index ca17df1246..e0192bfa18 100644 --- a/src/Fl_File_Chooser2.cxx +++ b/src/Fl_File_Chooser2.cxx @@ -360,6 +360,7 @@ #include #include "flstring.h" #include +#include // // File chooser label strings and sort function... diff --git a/src/Fl_Image_Surface.cxx b/src/Fl_Image_Surface.cxx index e2870e5787..1a5f5ec313 100644 --- a/src/Fl_Image_Surface.cxx +++ b/src/Fl_Image_Surface.cxx @@ -37,6 +37,7 @@ */ Fl_Image_Surface::Fl_Image_Surface(int w, int h, int high_res, Fl_Offscreen off) : Fl_Widget_Surface(NULL) { platform_surface = Fl_Image_Surface_Driver::newImageSurfaceDriver(w, h, high_res, off); + platform_surface->image_surface_ = this; if (platform_surface) driver(platform_surface->driver()); } @@ -88,6 +89,10 @@ int Fl_Image_Surface_Driver::printable_rect(int *w, int *h) { *w = width; *h = height; return 0; } + +Fl_Image_Surface *Fl_Image_Surface_Driver::as_image_surface() { + return image_surface_; +} /** \} \endcond @@ -149,6 +154,12 @@ void Fl_Image_Surface::rescale() { delete rgb; } + +Fl_Image_Surface *Fl_Image_Surface::as_image_surface() { + return this; +} + + // implementation of the fl_XXX_offscreen() functions static Fl_Image_Surface **offscreen_api_surface = NULL; diff --git a/src/Fl_Input.cxx b/src/Fl_Input.cxx index 880b7c676d..bc94a8897e 100644 --- a/src/Fl_Input.cxx +++ b/src/Fl_Input.cxx @@ -374,7 +374,7 @@ int Fl_Input::handle_key() { return 1; } - unsigned int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT); + int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT); unsigned int shift = Fl::event_state() & FL_SHIFT; unsigned int multiline = (input_type() == FL_MULTILINE_INPUT) ? 1 : 0; // diff --git a/src/Fl_Message.cxx b/src/Fl_Message.cxx index 7047fbf233..246835d6cf 100644 --- a/src/Fl_Message.cxx +++ b/src/Fl_Message.cxx @@ -548,7 +548,7 @@ void Fl_Message::icon_label(const char *str) { // handle ctrl-c (command-c on macOS) to copy message text int Fl_Message_Box::handle(int e) { - unsigned int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT); + int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT); switch (e) { case FL_KEYBOARD: case FL_SHORTCUT: diff --git a/src/Fl_Native_File_Chooser_FLTK.cxx b/src/Fl_Native_File_Chooser_FLTK.cxx index 144ca950df..178ce1bafc 100644 --- a/src/Fl_Native_File_Chooser_FLTK.cxx +++ b/src/Fl_Native_File_Chooser_FLTK.cxx @@ -24,8 +24,8 @@ #include #include #include -#include "Fl_System_Driver.H" // for struct stat #include +#include diff --git a/src/Fl_Screen_Driver.H b/src/Fl_Screen_Driver.H index 135a7bf5f5..3047aedc5f 100644 --- a/src/Fl_Screen_Driver.H +++ b/src/Fl_Screen_Driver.H @@ -43,6 +43,7 @@ class Fl_Window; class Fl_RGB_Image; class Fl_Group; class Fl_Input; +class Fl_System_Driver; /** A base class describing the interface between FLTK and screen-related operations. @@ -68,6 +69,7 @@ public: static char bg_set; static char bg2_set; static char fg_set; + static Fl_System_Driver *system_driver; virtual float scale(int) { return 1; } virtual void scale(int /*n*/, float /*f*/) {} diff --git a/src/Fl_Screen_Driver.cxx b/src/Fl_Screen_Driver.cxx index 22008dae22..3f0d1b4f8b 100644 --- a/src/Fl_Screen_Driver.cxx +++ b/src/Fl_Screen_Driver.cxx @@ -34,6 +34,7 @@ char Fl_Screen_Driver::bg_set = 0; char Fl_Screen_Driver::bg2_set = 0; char Fl_Screen_Driver::fg_set = 0; +Fl_System_Driver *Fl_Screen_Driver::system_driver = NULL; int Fl_Screen_Driver::keyboard_screen_scaling = 1; diff --git a/src/Fl_System_Driver.H b/src/Fl_System_Driver.H index e8930486ee..0abab55df0 100644 --- a/src/Fl_System_Driver.H +++ b/src/Fl_System_Driver.H @@ -84,6 +84,8 @@ public: static const int fl_YValue; static const int fl_XNegative; static const int fl_YNegative; + static int command_key; + static int control_key; // implement if the system adds unwanted program argument(s) virtual int single_arg(const char *) { return 0; } diff --git a/src/Fl_System_Driver.cxx b/src/Fl_System_Driver.cxx index ee5e990ced..44b47bc7c5 100644 --- a/src/Fl_System_Driver.cxx +++ b/src/Fl_System_Driver.cxx @@ -83,11 +83,30 @@ static Fl_System_Driver::Keyname default_key_table[] = { {FL_Delete, "Delete"} }; + +int Fl_System_Driver::command_key = 0; +int Fl_System_Driver::control_key = 0; + + +int fl_command_modifier() { + if (!Fl_System_Driver::command_key) Fl::system_driver(); + return Fl_System_Driver::command_key; +} + + +int fl_control_modifier() { + if (!Fl_System_Driver::control_key) Fl::system_driver(); + return Fl_System_Driver::control_key; +} + + Fl_System_Driver::Fl_System_Driver() { // initialize default key table (used in fl_shortcut.cxx) key_table = default_key_table; key_table_size = sizeof(default_key_table)/sizeof(*default_key_table); + command_key = FL_CTRL; + control_key = FL_META; } Fl_System_Driver::~Fl_System_Driver() diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx index 56f672f44b..2d589f4957 100644 --- a/src/Fl_Window.cxx +++ b/src/Fl_Window.cxx @@ -879,6 +879,8 @@ const Fl_Image* Fl_Window::shape() {return pWindowDriver->shape();} bool Fl_Window::is_a_rescale() {return Fl_Window_Driver::is_a_rescale_;} /** Returns a platform-specific identification of a shown window, or 0 if not shown. + \note This identification may differ from the platform-specific reference of an + Fl_Window object used by functions fl_x11_xid(), fl_mac_xid(), fl_x11_find(), and fl_mac_find(). \li X11 platform: the window's XID. \li macOS platform: The window number of the window’s window device. \li other platforms: 0. diff --git a/src/Fl_Window_Driver.H b/src/Fl_Window_Driver.H index 24878e71de..03333c958b 100644 --- a/src/Fl_Window_Driver.H +++ b/src/Fl_Window_Driver.H @@ -61,6 +61,8 @@ public: Fl_Window_Driver(Fl_Window *); virtual ~Fl_Window_Driver(); static Fl_Window_Driver *newWindowDriver(Fl_Window *); + static fl_uintptr_t xid(const Fl_Window *win); + static Fl_Window *find(fl_uintptr_t xid); int wait_for_expose_value; Fl_Offscreen other_xid; // offscreen bitmap (overlay and double-buffered windows) virtual int screen_num(); diff --git a/src/Fl_Window_Driver.cxx b/src/Fl_Window_Driver.cxx index 23c66be7fd..a9faa32119 100644 --- a/src/Fl_Window_Driver.cxx +++ b/src/Fl_Window_Driver.cxx @@ -258,6 +258,32 @@ void Fl_Window_Driver::menu_window_area(int &X, int &Y, int &W, int &H, int nscr scr_driver->screen_work_area(X, Y, W, H, nscreen); } +/** Returns the platform-specific reference of the given window, or NULL if that window isn't shown. + \version 1.4.0 */ +fl_uintptr_t Fl_Window_Driver::xid(const Fl_Window *win) { + Fl_X *flx = win->i; + return flx ? flx->xid : 0; +} + +/** Returns a pointer to the Fl_Window corresponding to the platform-specific reference \p xid of a shown window. + \version 1.4.0 */ +Fl_Window *Fl_Window_Driver::find(fl_uintptr_t xid) { + Fl_X *window; + for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next) { + if (window->xid == xid) { + if (window != Fl_X::first && !Fl::modal()) { + // make this window be first to speed up searches + // this is not done if modal is true to avoid messing up modal stack + *pp = window->next; + window->next = Fl_X::first; + Fl_X::first = window; + } + return window->w; + } + } + return 0; +} + /** \} \endcond diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 05a748b8e3..663fd29564 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -81,7 +81,7 @@ // public variables void *fl_capture = 0; // (NSWindow*) we need this to compensate for a missing(?) mouse capture -Window fl_window; +FLWindow *fl_window; // forward declarations of variables in this file static int main_screen_height; // height of menubar-containing screen used to convert between Cocoa and FLTK global screen coordinates @@ -803,7 +803,7 @@ static NSInteger max_normal_window_level(void) for (x = Fl_X::first;x;x = x->next) { NSInteger level; - FLWindow *cw = x->xid; + FLWindow *cw = (FLWindow*)x->xid; Fl_Window *win = x->w; if (!win || !cw || ![cw isVisible]) continue; @@ -868,7 +868,7 @@ static void fixup_window_levels(void) prev_non_modal = NULL; for (x = Fl_X::first;x;x = x->next) { - FLWindow *cw = x->xid; + FLWindow *cw = (FLWindow*)x->xid; Fl_Window *win = x->w; if (!win || !cw || ![cw isVisible]) continue; @@ -1513,7 +1513,7 @@ - (void)applicationWillResignActive:(NSNotification *)notify FLWindow *top = 0; // sort in all regular windows for (x = Fl_X::first;x;x = x->next) { - FLWindow *cw = x->xid; + FLWindow *cw = (FLWindow*)x->xid; Fl_Window *win = x->w; if (win && cw) { if (win->modal()) { @@ -1525,7 +1525,7 @@ - (void)applicationWillResignActive:(NSNotification *)notify } // now sort in all modals for (x = Fl_X::first;x;x = x->next) { - FLWindow *cw = x->xid; + FLWindow *cw = (FLWindow*)x->xid; Fl_Window *win = x->w; if (win && cw && [cw isVisible]) { if (win->modal()) { @@ -1536,7 +1536,7 @@ - (void)applicationWillResignActive:(NSNotification *)notify } // finally all non-modals for (x = Fl_X::first;x;x = x->next) { - FLWindow *cw = x->xid; + FLWindow *cw = (FLWindow*)x->xid; Fl_Window *win = x->w; if (win && cw && [cw isVisible]) { if (win->non_modal()) { @@ -1600,8 +1600,8 @@ - (void)applicationDidUnhide:(NSNotification *)notify { // before 10.5, subwindows are lost when application is unhidden fl_lock_function(); for (Fl_X *x = Fl_X::first; x; x = x->next) { - if (![x->xid parentWindow]) { - orderfront_subwindows(x->xid); + if (![(FLWindow*)x->xid parentWindow]) { + orderfront_subwindows((FLWindow*)x->xid); } } fl_unlock_function(); @@ -3103,7 +3103,7 @@ - (void)draggingSession:(NSDraggingSession *)session [cw setOpaque:NO]; // shaped windows must be non opaque [cw setBackgroundColor:[NSColor clearColor]]; // and with transparent background color } - x->xid = cw; + x->xid = (fl_uintptr_t)cw; x->w = w; i(x); wait_for_expose_value = 1; @@ -3444,7 +3444,7 @@ static void restore_window_title_and_icon(Fl_Window *pWindow, NSImage *icon) { q_release_context(); Fl_X *i = Fl_X::i(pWindow); //NSLog(@"region-count=%d damage=%u",i->region?i->region->count:0, pWindow->damage()); - fl_window = i->xid; + fl_window = (FLWindow*)i->xid; ((Fl_Quartz_Graphics_Driver&)Fl_Graphics_Driver::default_driver()).high_resolution( mapped_to_retina() ); if (pWindow->as_overlay_window() && other_xid && changed_resolution()) { @@ -3766,7 +3766,7 @@ static int get_plain_text_from_clipboard(int clipboard) void Fl_Cocoa_Window_Driver::map() { - Window xid = fl_xid(pWindow); + FLWindow *xid = fl_xid(pWindow); if (pWindow && xid && ![xid parentWindow]) { // 10.2 // after a subwindow has been unmapped, it has lost its parent window and its frame may be wrong [xid setSubwindowFrame]; @@ -3779,7 +3779,7 @@ static int get_plain_text_from_clipboard(int clipboard) void Fl_Cocoa_Window_Driver::unmap() { - Window xid = fl_xid(pWindow); + FLWindow *xid = fl_xid(pWindow); if (pWindow && xid) { if (parent()) [[xid parentWindow] removeChildWindow:xid]; // necessary with at least 10.5 [xid orderOut:nil]; diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index 6480aabd4f..da4dddcd77 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -636,7 +636,7 @@ void Fl_WinAPI_Screen_Driver::enable_im() { Fl_X *i = Fl_X::first; while (i) { - flImmAssociateContextEx(i->xid, 0, IACE_DEFAULT); + flImmAssociateContextEx((HWND)i->xid, 0, IACE_DEFAULT); i = i->next; } @@ -648,7 +648,7 @@ void Fl_WinAPI_Screen_Driver::disable_im() { Fl_X *i = Fl_X::first; while (i) { - flImmAssociateContextEx(i->xid, 0, 0); + flImmAssociateContextEx((HWND)i->xid, 0, 0); i = i->next; } @@ -1288,7 +1288,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar break; case WM_PAINT: { - Fl_Region R, R2; + HRGN R, R2; Fl_X *i = Fl_X::i(window); Fl_Window_Driver::driver(window)->wait_for_expose_value = 0; char redraw_whole_window = false; @@ -1307,7 +1307,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar } // convert i->region in FLTK units to R2 in drawing units - R2 = Fl_GDI_Graphics_Driver::scale_region(i->region, scale, NULL); + R2 = Fl_GDI_Graphics_Driver::scale_region((HRGN)i->region, scale, NULL); RECT r_box; if (scale != 1 && GetRgnBox(R, &r_box) != NULLREGION) { @@ -1316,10 +1316,10 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar r_box.right = LONG(r_box.right / scale); r_box.top = LONG(r_box.top / scale); r_box.bottom = LONG(r_box.bottom / scale); - Fl_Region R3 = CreateRectRgn(r_box.left, r_box.top, r_box.right + 1, r_box.bottom + 1); + HRGN R3 = CreateRectRgn(r_box.left, r_box.top, r_box.right + 1, r_box.bottom + 1); if (!i->region) i->region = R3; else { - CombineRgn(i->region, i->region, R3, RGN_OR); + CombineRgn((HRGN)i->region, (HRGN)i->region, R3, RGN_OR); DeleteObject(R3); } } @@ -2185,7 +2185,7 @@ Fl_X *Fl_WinAPI_Window_Driver::makeWindow() { wlen = fl_utf8toUtf16(w->label(), (unsigned)l, (unsigned short *)lab, wlen); lab[wlen] = 0; } - x->xid = CreateWindowExW(styleEx, + x->xid = (fl_uintptr_t)CreateWindowExW(styleEx, class_namew, lab, style, xp, yp, wp, hp, parent, @@ -2208,14 +2208,14 @@ Fl_X *Fl_WinAPI_Window_Driver::makeWindow() { for x and y. We can then use GetWindowRect to determine which monitor the window was placed on. */ RECT rect; - GetWindowRect(x->xid, &rect); + GetWindowRect((HWND)x->xid, &rect); make_fullscreen(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); } // Setup clipboard monitor target if there are registered handlers and // no window is targeted. if (!fl_clipboard_notify_empty() && clipboard_wnd == NULL) - fl_clipboard_notify_target(x->xid); + fl_clipboard_notify_target((HWND)x->xid); wait_for_expose_value = 1; if (show_iconic()) { @@ -2239,14 +2239,14 @@ Fl_X *Fl_WinAPI_Window_Driver::makeWindow() { // If we've captured the mouse, we dont want to activate any // other windows from the code, or we lose the capture. - ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE : + ShowWindow((HWND)x->xid, !showit ? SW_SHOWMINNOACTIVE : (Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL); // Register all windows for potential drag'n'drop operations - RegisterDragDrop(x->xid, flIDropTarget); + RegisterDragDrop((HWND)x->xid, flIDropTarget); if (!im_enabled) - flImmAssociateContextEx(x->xid, 0, 0); + flImmAssociateContextEx((HWND)x->xid, 0, 0); return x; } @@ -2256,6 +2256,8 @@ Fl_X *Fl_WinAPI_Window_Driver::makeWindow() { HINSTANCE fl_display = GetModuleHandle(NULL); +HINSTANCE fl_win32_display() { return fl_display; } + void Fl_WinAPI_Window_Driver::set_minmax(LPMINMAXINFO minmax) { int td, wd, hd, dummy_x, dummy_y; @@ -2632,10 +2634,10 @@ void Fl_WinAPI_Window_Driver::show() { } else { // Once again, we would lose the capture if we activated the window. Fl_X *i = Fl_X::i(pWindow); - if (IsIconic(i->xid)) - OpenIcon(i->xid); + if (IsIconic((HWND)i->xid)) + OpenIcon((HWND)i->xid); if (!fl_capture) - BringWindowToTop(i->xid); + BringWindowToTop((HWND)i->xid); // ShowWindow(i->xid,fl_capture?SW_SHOWNOACTIVATE:SW_RESTORE); } } diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index d29bf82c59..b189dc470a 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -41,7 +41,11 @@ # include "drivers/X11/Fl_X11_Screen_Driver.H" # include "drivers/X11/Fl_X11_Window_Driver.H" # include "drivers/X11/Fl_X11_System_Driver.H" +#if FLTK_USE_CAIRO +# include "drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H" +#else # include "drivers/Xlib/Fl_Xlib_Graphics_Driver.H" +#endif # include "print_button.h" # include # include @@ -53,6 +57,11 @@ # include # include "Xutf8.h" +#if FLTK_USE_CAIRO +# include +# include +#endif // FLTK_USE_CAIRO + #define USE_XRANDR (HAVE_DLSYM && HAVE_DLFCN_H) // means attempt to dynamically load libXrandr.so #if USE_XRANDR #include @@ -149,6 +158,7 @@ static void convert_crlf(unsigned char *string, long& len) { //////////////////////////////////////////////////////////////// Display *fl_display; +Display *fl_x11_display() { return fl_display; } Window fl_message_window = 0; int fl_screen; XVisualInfo *fl_visual; @@ -2117,7 +2127,15 @@ void Fl_X11_Window_Driver::resize(int X,int Y,int W,int H) { else if (!is_a_resize && !is_a_move) return; if (is_a_resize) { pWindow->Fl_Group::resize(X,Y,W,H); - if (shown()) {pWindow->redraw();} + if (shown()) { +#if FLTK_USE_CAIRO + if (!pWindow->as_gl_window() && cairo_) { + float s = Fl::screen_driver()->scale(screen_num()); + cairo_xlib_surface_set_size(cairo_get_target(cairo_), (W>0 ? int(W*s) : 1), (H>0 ? int(H*s) : 1)); + } +#endif + pWindow->redraw(); + } } else { x(X); y(Y); if (Fl_X11_Screen_Driver::xim_win && Fl::focus()) { @@ -2202,6 +2220,7 @@ static int xrender_supported() { } #endif +#if ! FLTK_USE_CAIRO char Fl_Xlib_Graphics_Driver::can_do_alpha_blending() { #if HAVE_XRENDER static char result = (char)xrender_supported(); @@ -2210,6 +2229,7 @@ char Fl_Xlib_Graphics_Driver::can_do_alpha_blending() { return 0; #endif } +#endif extern Fl_Window *fl_xfocus; diff --git a/src/Makefile b/src/Makefile index 94aaf0b96a..8be30e3cf2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -207,9 +207,11 @@ GLCPPFILES_OSX = drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx \ GLCPPFILES_X11 = drivers/X11/Fl_X11_Gl_Window_Driver.cxx \ drivers/X11/fl_X11_gl_platform_init.cxx GLCPPFILES_XFT = $(GLCPPFILES_X11) +GLCPPFILES_CAIRO = $(GLCPPFILES_X11) GLCPPFILES_WIN = drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx \ drivers/WinAPI/fl_WinAPI_gl_platform_init.cxx GLCPPFILES_WAYLAND = drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx \ + drivers/X11/Fl_X11_Gl_Window_Driver.cxx \ drivers/Wayland/fl_wayland_gl_platform_init.cxx GLCPPFILES += $(GLCPPFILES_$(BUILD)) @@ -258,13 +260,6 @@ QUARTZCPPFILES = \ # These C++ files are used under condition: BUILD_X11 XLIBCPPFILES = \ - drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx \ drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx \ drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx \ drivers/X11/Fl_X11_Window_Driver.cxx \ @@ -280,7 +275,21 @@ XLIBCPPFILES = \ Fl_Native_File_Chooser_GTK.cxx\ Fl_Native_File_Chooser_Kdialog.cxx \ Fl_get_key.cxx - + +# These graphics driver files are used under condition: BUILD_CAIRO +CAIROGDFILES = \ + drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx \ + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx + +# These graphics driver files are used under condition: BUILD_X11 AND BUILD_XFT +XLIBGDFILES = drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx + # These C++ files are used under condition: BUILD_WAYLAND WLCPPFILES = \ drivers/Posix/Fl_Posix_Printer_Driver.cxx \ @@ -296,7 +305,16 @@ WLCPPFILES = \ drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx \ drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx \ drivers/Wayland/fl_wayland_platform_init.cxx \ - drivers/Wayland/fl_wayland_clipboard_dnd.cxx + drivers/Wayland/fl_wayland_clipboard_dnd.cxx \ + drivers/X11/Fl_X11_Screen_Driver.cxx \ + drivers/X11/Fl_X11_Window_Driver.cxx \ + drivers/X11/Fl_X11_System_Driver.cxx \ + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx \ + drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx \ + drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx \ + Fl_x.cxx \ + fl_dnd_x.cxx \ + Fl_get_key.cxx # fl_dnd_x.cxx Fl_Native_File_Chooser_GTK.cxx @@ -364,7 +382,7 @@ FLTKFLAGS = -DFL_LIBRARY include ../makeinclude # makeinclude has set this variable: -# BUILD = {WIN|X11|XFT|OSX|WAYLAND} +# BUILD = {WIN|X11|XFT|CAIRO|OSX|WAYLAND} MMFILES_OSX = $(OBJCPPFILES) MMFILES = $(MMFILES_$(BUILD)) @@ -372,8 +390,9 @@ MMFILES = $(MMFILES_$(BUILD)) CPPFILES += $(PSCPPFILES) CPPFILES_OSX = $(QUARTZCPPFILES) -CPPFILES_XFT = $(XLIBCPPFILES) $(XLIBXFTFILES) -CPPFILES_X11 = $(XLIBCPPFILES) $(XLIBFONTFILES) +CPPFILES_XFT = $(XLIBCPPFILES) $(XLIBGDFILES) $(XLIBXFTFILES) +CPPFILES_X11 = $(XLIBCPPFILES) $(XLIBGDFILES) $(XLIBFONTFILES) +CPPFILES_CAIRO = $(XLIBCPPFILES) $(CAIROGDFILES) CPPFILES_WAYLAND = $(WLCPPFILES) $(WLXFTFILES) @@ -383,6 +402,7 @@ CPPFILES += $(CPPFILES_$(BUILD)) CFILES_X11 = $(XLIBCFILES) $(XLIBXCFILES) +CFILES_CAIRO = $(XLIBCFILES) CFILES_XFT = $(XLIBCFILES) CFILES_WAYLAND = $(WLCFILES) 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 0000000000..76986af9ae --- /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 0000000000..02df902d8f --- /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 6491332e3e..d1ed8df1e3 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 fd278cf757..c587caf37a 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm +++ b/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm @@ -347,7 +347,7 @@ - (void)printPanelDidEnd:(NSPrintPanel *)printPanel returnCode:(NSInteger)return 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 01c3b0f954..33b0392c49 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 b7f213da0c..019e2b7f51 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 0c8015dbac..2c4c5a34b3 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 29478a9c4c..c44c0a77b7 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 87adc44f0d..188bd1d2d9 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 4cfc745c9c..9e512d8899 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 76b5460929..1b13ff0a9b 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 979b7bd3a8..a3d8ac6c6f 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 7f655e2919..6795fb06b2 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 3ededb5abe..77ecdaa0a4 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 b503094381..552da03f96 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 558dc47c18..b97cfbba71 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 52b8c7f654..71daf0e100 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 4e6f8c79dd..f70a43ed67 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 c638bfb794..2f1acc5d90 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 07b3038f0a..60a0cad516 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 979cef3d82..89014826fd 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 78586dc592..986d25ddf6 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 1638cf0d28..4f64434d8d 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 196f07d5e6..a7a3f95127 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 372d08b322..821bdd56aa 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 a54e2ac5f8..4b26a17ea5 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 38230b3db1..96985c10b2 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 07bcd3ed43..2dca849243 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 5a2a78beed..f80ee67bad 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 4500a0f45b..8c81ab3317 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 cd6e98646f..7952dfdc15 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 be9dac6bd0..92f34b9ced 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 459143dad6..5f8c40d8d2 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 9a092756a2..b85aadd396 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 b8fdd20c1b..87a91636ce 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 84b11ad168..13c1cf900e 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 ed9dd8fcbf..a5302904fe 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 3bcf213709..b26dfa4444 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 a0b0db1718..e67447b4dc 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 f87ae55a21..e4bbe29efd 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 5440b53bdd..cf2fcac580 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 13a67f4283..4c7b64a4c5 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 17711883e7..3a4817b7f0 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 d57e5b031d..ba098c309e 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 a72fe9d8b8..ea24eba34b 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 b7cb480109..3f8ecda7f9 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 e1a33c746d..240ced649a 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() diff --git a/src/filename_isdir.cxx b/src/filename_isdir.cxx index 47e1de58f1..f19e464b6e 100644 --- a/src/filename_isdir.cxx +++ b/src/filename_isdir.cxx @@ -20,6 +20,7 @@ #include "Fl_System_Driver.H" #include #include +#include /** Determines if a file exists and is a directory from its filename. diff --git a/src/fl_read_image.cxx b/src/fl_read_image.cxx index 129aeaa545..0d5f7ec5cf 100644 --- a/src/fl_read_image.cxx +++ b/src/fl_read_image.cxx @@ -40,7 +40,7 @@ uchar *fl_read_image(uchar *p, int X, int Y, int w, int h, int alpha) { uchar *image_data = NULL; Fl_RGB_Image *img; - if (fl_find(fl_window) == 0) { // read from off_screen buffer + if (Fl_Surface_Device::surface()->as_image_surface()) { // read from off_screen buffer img = Fl::screen_driver()->read_win_rectangle(X, Y, w, h, 0); if (!img) { return NULL; diff --git a/src/fl_utf8.cxx b/src/fl_utf8.cxx index efb7fa5d5e..b7801207e5 100644 --- a/src/fl_utf8.cxx +++ b/src/fl_utf8.cxx @@ -23,6 +23,7 @@ #include #include "utf8_internal.h" +#include #include #include