Make hybrid Wayland/X11 platform.

This commit is contained in:
ManoloFLTK 2022-03-15 06:42:06 +01:00
parent 28981f6fd3
commit c720aae515
93 changed files with 1310 additions and 529 deletions

View File

@ -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)

View File

@ -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 ("")

View File

@ -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.

View File

@ -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();
};

View File

@ -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();

View File

@ -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.

View File

@ -23,6 +23,13 @@
# error "Never use <FL/mac.H> directly; include <FL/platform.H> 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

View File

@ -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)

View File

@ -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;
#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__ */
/* Allows all hybrid combinations except WIN32 + X11 with MSVC */
#if defined(_WIN32) && !defined(__MINGW32__)
struct dirent {char d_name[1];};
#else
# include <dirent.h>
#endif
#include <sys/types.h>
#include <dirent.h>
# 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 <dirent.h>
#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 <sys/types.h>
#include <dirent.h>
#elif defined(FLTK_USE_X11)
typedef unsigned long Fl_Offscreen;
typedef struct _XRegion *Fl_Region;
typedef int FL_SOCKET;
typedef struct __GLXcontextRec *GLContext;
#include <sys/types.h>
#include <dirent.h>
#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 <FL/Fl_Export.H>
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 */

View File

@ -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 <FL/wayland.H> directly; include <FL/platform.H> 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 <stdint.h>
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

View File

@ -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 <FL/win32.H> directly; include <FL/platform.H> instead."
#endif // !FL_PLATFORM_H
@ -26,6 +44,11 @@
#include <windows.h>
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);

View File

@ -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 <FL/x11.H> directly; include <FL/platform.H> instead."
@ -36,14 +51,21 @@
#endif
#include <X11/Xatom.h>
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);

View File

@ -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'.

View File

@ -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

View File

@ -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 <path-to-source> -B <path-to-build> -DCMAKE_BUILD_TYPE=Release -DOPTION_USE_WAYLAND=1
cmake -S <path-to-source> -B <path-to-build> -DCMAKE_BUILD_TYPE=Release -DOPTION_USE_WAYLAND=1
cd <path-to-build>; make
cd <path-to-build>; 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 <FL/platform.H>
#ifdef __APPLE__
*** macOS-specific code ***
#elif defined(_WIN32)
*** Windows-specific code ***
#else
*** X11-specific code ***
*** X11-specific code ***
*** Wayland-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 <FL/fl_config.h>
#ifdef __APPLE__
*** macOS-specific code ***
#elif defined(_WIN32)
*** Windows-specific code ***
#elif defined(FLTK_USE_X11)
*** X11-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.
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.
3 PLATFORM SPECIFIC NOTES
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 <package-name ...>
3.3 FreeBSD
-----------
4.3 FreeBSD
-----------
The Wayland platform is known to work with FreeBSD version 13.1 and the sway compositor.

View File

@ -21,17 +21,18 @@
#include <FL/Fl_Window.H>
// Cairo is currently supported for the following platforms:
// Win32, Apple Quartz, X11
// Win32, Apple Quartz, X11, Wayland
#if defined(FLTK_USE_X11) // X11
# include <cairo-xlib.h>
#elif defined(_WIN32) // Windows
#if defined(_WIN32) // Windows
# include <cairo-win32.h>
#elif defined(__APPLE__) // macOS
# include <cairo-quartz.h>
#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 <cairo-xlib.h>
#elif defined(FLTK_USE_X11) // X11
# include <cairo-xlib.h>
#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

View File

@ -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"
])

View File

@ -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 --enable-xft
Enable the Xft library for anti-aliased fonts under X11
\par --disable-xft
Disables the Xft library, resulting in non anti-aliased fonts (X11 platform).
\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

View File

@ -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 <FL/platform.H> // 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 <u>FLTK-defined</u> 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.

View File

@ -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
*

View File

@ -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
*

View File

@ -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))

View File

@ -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@

View File

@ -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)

View File

@ -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
\{ */

View File

@ -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) {

View File

@ -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) {

View File

@ -360,6 +360,7 @@
#include <stdlib.h>
#include "flstring.h"
#include <errno.h>
#include <sys/stat.h>
//
// File chooser label strings and sort function...

View File

@ -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;

View File

@ -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;
//

View File

@ -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:

View File

@ -24,8 +24,8 @@
#include <FL/Fl_Native_File_Chooser.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_File_Icon.H>
#include "Fl_System_Driver.H" // for struct stat
#include <string.h>
#include <sys/stat.h>

View File

@ -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*/) {}

View File

@ -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;

View File

@ -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; }

View File

@ -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()

View File

@ -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 windows window device.
\li other platforms: 0.

View File

@ -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();

View File

@ -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

View File

@ -81,7 +81,7 @@ int fl_mac_os_version = Fl_Darwin_System_Driver::calc_mac_os_version();
// 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 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
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 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
}
// 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 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
}
// 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 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
{ // 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 @@ Fl_X* Fl_Cocoa_Window_Driver::makeWindow()
[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 @@ void Fl_Cocoa_Window_Driver::make_current()
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 @@ void Fl_Cocoa_Window_Driver::destroy(FLWindow *xid) {
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 @@ void Fl_Cocoa_Window_Driver::map() {
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];

View File

@ -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);
}
}

View File

@ -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 <unistd.h>
# include <time.h>
@ -53,6 +57,11 @@
# include <X11/keysym.h>
# include "Xutf8.h"
#if FLTK_USE_CAIRO
# include <cairo-xlib.h>
# include <cairo/cairo.h>
#endif // FLTK_USE_CAIRO
#define USE_XRANDR (HAVE_DLSYM && HAVE_DLFCN_H) // means attempt to dynamically load libXrandr.so
#if USE_XRANDR
#include <dlfcn.h>
@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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 <FL/platform.H>
#include <cairo/cairo.h>
#include <pango/pangocairo.h>
#include <stdlib.h>
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_;
}

View File

@ -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()) { }

View File

@ -347,7 +347,7 @@ int Fl_Cocoa_Printer_Driver::begin_page (void)
CGContextSaveGState(gc);
CGContextSaveGState(gc);
fl_line_style(FL_SOLID);
fl_window = (Window)1; // TODO: something better
fl_window = (FLWindow*)1; // TODO: something better
fl_clip_region(0);
return status != noErr;
}

View File

@ -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,

View File

@ -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);
}

View File

@ -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) {

View File

@ -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();
}

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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();

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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_);

View File

@ -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();

View File

@ -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];

View File

@ -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());
}

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -18,6 +18,7 @@
#include "Fl_Wayland_System_Driver.H"
#include <FL/Fl.H>
#include "Fl_Wayland_Window_Driver.H"
#include "Fl_Wayland_Screen_Driver.H"
#include <FL/platform.H>
#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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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 <cairo-xlib.h>
#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"
Fl_Copy_Surface_Driver *Fl_Copy_Surface_Driver::newCopySurfaceDriver(int w, int h)
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
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_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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 <GL/glx.h>
# 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

View File

@ -17,11 +17,9 @@
#include <config.h>
#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 <FL/Fl.H>
#include <FL/platform.H>
#include <FL/fl_ask.H>
@ -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;
}

View File

@ -26,6 +26,11 @@
#include "../../Fl_Window_Driver.H"
#include <config.h>
#include <FL/platform.H> // 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);

View File

@ -18,9 +18,13 @@
#include <config.h>
#include "Fl_X11_Window_Driver.H"
#include "Fl_X11_Screen_Driver.H"
#include "../Xlib/Fl_Xlib_Graphics_Driver.H"
#if FLTK_USE_CAIRO
# include <cairo-xlib.h>
# 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 <FL/Fl_Overlay_Window.H>
#include <FL/Fl_Menu_Window.H>
#include <FL/Fl_Tooltip.H>
@ -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};

View File

@ -14,9 +14,14 @@
// https://www.fltk.org/bugs.php
//
#include <config.h>
#include <FL/platform.H>
#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
}

View File

@ -19,6 +19,9 @@
#include <FL/Fl_Copy_Surface.H>
#include <FL/platform.H>
#if FLTK_USE_CAIRO
# include <cairo/cairo.h>
#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

View File

@ -19,16 +19,35 @@
#include <FL/Fl.H>
#include <FL/platform.H>
#include <FL/fl_draw.H>
#include "Fl_Xlib_Graphics_Driver.H"
#include "../X11/Fl_X11_Screen_Driver.H"
#if FLTK_USE_CAIRO
# include <cairo-xlib.h>
# include "../Cairo/Fl_Display_Cairo_Graphics_Driver.H"
# include <cairo/cairo.h>
#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
}

View File

@ -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

View File

@ -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);
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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);

View File

@ -18,6 +18,9 @@
#define FL_XLIB_IMAGE_SURFACE_DRIVER_H
#include <FL/Fl_Image_Surface.H>
#if FLTK_USE_CAIRO
# include <cairo/cairo.h>
#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

View File

@ -14,28 +14,47 @@
// https://www.fltk.org/bugs.php
//
#include "Fl_Xlib_Graphics_Driver.H"
#include <FL/platform.H>
#include "Fl_Xlib_Image_Surface_Driver.H"
#include "../../Fl_Screen_Driver.H"
#if FLTK_USE_CAIRO
# include <cairo-xlib.h>
# 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()

View File

@ -20,6 +20,7 @@
#include "Fl_System_Driver.H"
#include <FL/filename.H>
#include <FL/Fl.H>
#include <sys/stat.h>
/**
Determines if a file exists and is a directory from its filename.

View File

@ -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;

View File

@ -23,6 +23,7 @@
#include <FL/fl_utf8.h>
#include "utf8_internal.h"
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>