diff options
Diffstat (limited to 'src')
70 files changed, 881 insertions, 350 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 63b5b8399..a9bc91710 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -191,7 +191,7 @@ endif (FLTK_USE_X11 AND NOT OPTION_PRINT_SUPPORT) set (DRIVER_FILES) -if (FLTK_USE_X11) +if (FLTK_USE_X11 AND NOT OPTION_USE_WAYLAND) # X11 (including APPLE with X11) @@ -202,13 +202,6 @@ if (FLTK_USE_X11) drivers/Posix/Fl_Posix_System_Driver.cxx drivers/Unix/Fl_Unix_System_Driver.cxx drivers/X11/Fl_X11_System_Driver.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx - drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx drivers/X11/fl_X11_platform_init.cxx @@ -223,29 +216,56 @@ if (FLTK_USE_X11) set (DRIVER_FILES ${DRIVER_FILES} Fl_Native_File_Chooser_Kdialog.cxx) endif (OPTION_USE_KDIALOG) - if (USE_XFT) + if (FLTK_USE_CAIRO) set (DRIVER_FILES ${DRIVER_FILES} - drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx + drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx ) - if (USE_PANGO) - set (DRIVER_FILES ${DRIVER_FILES} drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx) - endif (USE_PANGO) else () + if (USE_XFT) + set (DRIVER_FILES ${DRIVER_FILES} + drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx + ) + if (USE_PANGO) + set (DRIVER_FILES ${DRIVER_FILES} drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx) + endif (USE_PANGO) + else () + set (DRIVER_FILES ${DRIVER_FILES} + drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx + ) + endif (USE_XFT) set (DRIVER_FILES ${DRIVER_FILES} - drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx + drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx ) - endif (USE_XFT) + endif (FLTK_USE_CAIRO) set (DRIVER_HEADER_FILES drivers/Posix/Fl_Posix_System_Driver.H drivers/X11/Fl_X11_Screen_Driver.H drivers/X11/Fl_X11_Window_Driver.H drivers/X11/Fl_X11_System_Driver.H + drivers/Xlib/Fl_Xlib_Graphics_Driver.H drivers/Xlib/Fl_Font.H drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H drivers/Unix/Fl_Unix_System_Driver.H ) + if (FLTK_USE_CAIRO) + set (DRIVER_HEADER_FILES ${DRIVER_HEADER_FILES} + drivers/Cairo/Fl_Cairo_Graphics_Driver.H + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H + ) + elseif (USE_PANGO) + set (DRIVER_HEADER_FILES ${DRIVER_HEADER_FILES} + drivers/Cairo/Fl_Cairo_Graphics_Driver.H + ) + endif (FLTK_USE_CAIRO) elseif (OPTION_USE_WAYLAND) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_BINARY_DIR}") @@ -262,9 +282,18 @@ elseif (OPTION_USE_WAYLAND) drivers/Wayland/fl_wayland_clipboard_dnd.cxx drivers/Wayland/fl_wayland_platform_init.cxx drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx Fl_Native_File_Chooser_FLTK.cxx Fl_Native_File_Chooser_GTK.cxx Fl_Native_File_Chooser_Kdialog.cxx + drivers/X11/Fl_X11_Screen_Driver.cxx + drivers/X11/Fl_X11_Window_Driver.cxx + drivers/X11/Fl_X11_System_Driver.cxx + drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx + drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx + Fl_x.cxx + fl_dnd_x.cxx + Fl_get_key.cxx ) set (DRIVER_HEADER_FILES drivers/Posix/Fl_Posix_System_Driver.H @@ -272,6 +301,8 @@ elseif (OPTION_USE_WAYLAND) drivers/Wayland/Fl_Wayland_Screen_Driver.H drivers/Wayland/Fl_Wayland_Window_Driver.H drivers/Wayland/Fl_Wayland_Graphics_Driver.H + drivers/Cairo/Fl_Cairo_Graphics_Driver.H + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.H drivers/Wayland/Fl_Wayland_Image_Surface_Driver.H drivers/Unix/Fl_Unix_System_Driver.H @@ -346,7 +377,7 @@ else () drivers/GDI/Fl_GDI_Image_Surface_Driver.H ) -endif (FLTK_USE_X11) +endif (FLTK_USE_X11 AND NOT OPTION_USE_WAYLAND) source_group("Header Files" FILES ${HEADER_FILES}) source_group("Driver Source Files" FILES ${DRIVER_FILES}) @@ -392,19 +423,22 @@ set (GL_DRIVER_FILES drivers/OpenGL/Fl_OpenGL_Graphics_Driver_rect.cxx drivers/OpenGL/Fl_OpenGL_Graphics_Driver_vertex.cxx ) -if (FLTK_USE_X11) +if (OPTION_USE_WAYLAND) + set (GL_DRIVER_FILES ${GL_DRIVER_FILES} + drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx + drivers/X11/Fl_X11_Gl_Window_Driver.cxx + drivers/Wayland/fl_wayland_gl_platform_init.cxx) + set (GL_DRIVER_HEADER_FILES drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H drivers/X11/Fl_X11_Gl_Window_Driver.H) +elseif (FLTK_USE_X11) set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/X11/Fl_X11_Gl_Window_Driver.cxx drivers/X11/fl_X11_gl_platform_init.cxx) set (GL_DRIVER_HEADER_FILES drivers/X11/Fl_X11_Gl_Window_Driver.H) -elseif (OPTION_USE_WAYLAND) - set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx drivers/Wayland/fl_wayland_gl_platform_init.cxx) - set (GL_DRIVER_HEADER_FILES drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H) elseif (APPLE) set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx drivers/Cocoa/fl_macOS_gl_platform_init.cxx) set (GL_DRIVER_HEADER_FILES drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H) elseif (WIN32) set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx drivers/WinAPI/fl_WinAPI_gl_platform_init.cxx) set (GL_DRIVER_HEADER_FILES drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.H) -endif (FLTK_USE_X11) +endif (OPTION_USE_WAYLAND) set (GL_DRIVER_HEADER_FILES ${GL_DRIVER_FILES} drivers/OpenGL/Fl_OpenGL_Display_Device.H @@ -621,7 +655,7 @@ if (OPTION_USE_WAYLAND) if (OPTION_USE_SYSTEM_LIBDECOR) list (APPEND OPTIONAL_LIBS "-ldecor-0") endif (OPTION_USE_SYSTEM_LIBDECOR) - list (APPEND OPTIONAL_LIBS "-lwayland-cursor -lwayland-client -lxkbcommon -ldl -ldbus-1") + list (APPEND OPTIONAL_LIBS "-lwayland-cursor -lwayland-client -lxkbcommon -ldl -ldbus-1 -lXcursor -lXrender -lXinerama -lXfixes -lXft -lXext -lX11") if (GTK_FOUND) list (APPEND OPTIONAL_LIBS ${GTK_LDFLAGS} ) endif (GTK_FOUND) diff --git a/src/Fl.cxx b/src/Fl.cxx index bac2ffa33..7b7cb2b7e 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -99,8 +99,10 @@ Fl_Screen_Driver *Fl::screen_driver() /** Returns a pointer to the unique Fl_System_Driver object of the platform */ Fl_System_Driver *Fl::system_driver() { - static Fl_System_Driver* system_driver_ = Fl_System_Driver::newSystemDriver(); - return system_driver_; + if (!Fl_Screen_Driver::system_driver) { + Fl_Screen_Driver::system_driver = Fl_System_Driver::newSystemDriver(); + } + return Fl_Screen_Driver::system_driver; } // @@ -578,21 +580,15 @@ int Fl::program_should_quit_ = 0; Fl_X* Fl_X::first; #endif +/** Returns the Fl_Window that corresponds to the given window reference, + or \c NULL if not found. + \deprecated Kept in the X11, Windows, and macOS platforms for compatibility + with FLTK versions before 1.4. + Please use fl_x11_find(Window), fl_wl_find(struct wld_window*), + fl_win32_find(HWND) or fl_mac_find(FLWindow*) with FLTK 1.4.0 and above. +*/ Fl_Window* fl_find(Window xid) { - Fl_X *window; - for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next) { - if (window->xid == xid) { - if (window != Fl_X::first && !Fl::modal()) { - // make this window be first to speed up searches - // this is not done if modal is true to avoid messing up modal stack - *pp = window->next; - window->next = Fl_X::first; - Fl_X::first = window; - } - return window->w; - } - } - return 0; + return Fl_Window_Driver::find((fl_uintptr_t)xid); } /** @@ -630,7 +626,7 @@ Fl_Window* Fl::next_window(const Fl_Window* window) { */ void Fl::first_window(Fl_Window* window) { if (!window || !window->shown()) return; - fl_find( Fl_X::i(window)->xid ); + Fl_Window_Driver::find( Fl_X::i(window)->xid ); } /** @@ -2021,7 +2017,7 @@ void fl_close_display() FL_EXPORT Window fl_xid_(const Fl_Window *w) { Fl_X *temp = Fl_X::i(w); - return temp ? temp->xid : 0; + return temp ? (Window)temp->xid : 0; } /** \addtogroup group_macosx \{ */ diff --git a/src/Fl_Color_Chooser.cxx b/src/Fl_Color_Chooser.cxx index 9111dba7e..643ba4f3c 100644 --- a/src/Fl_Color_Chooser.cxx +++ b/src/Fl_Color_Chooser.cxx @@ -506,7 +506,7 @@ static int copy_rgb(double r, double g, double b) { int Fl_Color_Chooser::handle(int e) { - unsigned int mods = Fl::event_state() & (FL_META | FL_CTRL | FL_ALT); + int mods = Fl::event_state() & (FL_META | FL_CTRL | FL_ALT); unsigned int shift = Fl::event_state() & FL_SHIFT; switch (e) { diff --git a/src/Fl_Device.cxx b/src/Fl_Device.cxx index c4f1dec36..d5e1b27c4 100644 --- a/src/Fl_Device.cxx +++ b/src/Fl_Device.cxx @@ -97,6 +97,10 @@ Fl_Surface_Device::~Fl_Surface_Device() if (surface_ == this) surface_ = NULL; } +/** Returns non-NULL if this surface is an Fl_Image_Surface object + \version 1.4.0 + */ +Fl_Image_Surface *Fl_Surface_Device::as_image_surface() { return NULL; } /** A constructor that sets the graphics driver used by the display */ Fl_Display_Device::Fl_Display_Device(Fl_Graphics_Driver *graphics_driver) : Fl_Surface_Device(graphics_driver) { diff --git a/src/Fl_File_Chooser2.cxx b/src/Fl_File_Chooser2.cxx index ca17df124..e0192bfa1 100644 --- a/src/Fl_File_Chooser2.cxx +++ b/src/Fl_File_Chooser2.cxx @@ -360,6 +360,7 @@ #include <stdlib.h> #include "flstring.h" #include <errno.h> +#include <sys/stat.h> // // File chooser label strings and sort function... diff --git a/src/Fl_Image_Surface.cxx b/src/Fl_Image_Surface.cxx index e2870e578..1a5f5ec31 100644 --- a/src/Fl_Image_Surface.cxx +++ b/src/Fl_Image_Surface.cxx @@ -37,6 +37,7 @@ */ Fl_Image_Surface::Fl_Image_Surface(int w, int h, int high_res, Fl_Offscreen off) : Fl_Widget_Surface(NULL) { platform_surface = Fl_Image_Surface_Driver::newImageSurfaceDriver(w, h, high_res, off); + platform_surface->image_surface_ = this; if (platform_surface) driver(platform_surface->driver()); } @@ -88,6 +89,10 @@ int Fl_Image_Surface_Driver::printable_rect(int *w, int *h) { *w = width; *h = height; return 0; } + +Fl_Image_Surface *Fl_Image_Surface_Driver::as_image_surface() { + return image_surface_; +} /** \} \endcond @@ -149,6 +154,12 @@ void Fl_Image_Surface::rescale() { delete rgb; } + +Fl_Image_Surface *Fl_Image_Surface::as_image_surface() { + return this; +} + + // implementation of the fl_XXX_offscreen() functions static Fl_Image_Surface **offscreen_api_surface = NULL; diff --git a/src/Fl_Input.cxx b/src/Fl_Input.cxx index 880b7c676..bc94a8897 100644 --- a/src/Fl_Input.cxx +++ b/src/Fl_Input.cxx @@ -374,7 +374,7 @@ int Fl_Input::handle_key() { return 1; } - unsigned int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT); + int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT); unsigned int shift = Fl::event_state() & FL_SHIFT; unsigned int multiline = (input_type() == FL_MULTILINE_INPUT) ? 1 : 0; // diff --git a/src/Fl_Message.cxx b/src/Fl_Message.cxx index 7047fbf23..246835d6c 100644 --- a/src/Fl_Message.cxx +++ b/src/Fl_Message.cxx @@ -548,7 +548,7 @@ void Fl_Message::icon_label(const char *str) { // handle ctrl-c (command-c on macOS) to copy message text int Fl_Message_Box::handle(int e) { - unsigned int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT); + int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT); switch (e) { case FL_KEYBOARD: case FL_SHORTCUT: diff --git a/src/Fl_Native_File_Chooser_FLTK.cxx b/src/Fl_Native_File_Chooser_FLTK.cxx index 144ca950d..178ce1baf 100644 --- a/src/Fl_Native_File_Chooser_FLTK.cxx +++ b/src/Fl_Native_File_Chooser_FLTK.cxx @@ -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> diff --git a/src/Fl_Screen_Driver.H b/src/Fl_Screen_Driver.H index 135a7bf5f..3047aedc5 100644 --- a/src/Fl_Screen_Driver.H +++ b/src/Fl_Screen_Driver.H @@ -43,6 +43,7 @@ class Fl_Window; class Fl_RGB_Image; class Fl_Group; class Fl_Input; +class Fl_System_Driver; /** A base class describing the interface between FLTK and screen-related operations. @@ -68,6 +69,7 @@ public: static char bg_set; static char bg2_set; static char fg_set; + static Fl_System_Driver *system_driver; virtual float scale(int) { return 1; } virtual void scale(int /*n*/, float /*f*/) {} diff --git a/src/Fl_Screen_Driver.cxx b/src/Fl_Screen_Driver.cxx index 22008dae2..3f0d1b4f8 100644 --- a/src/Fl_Screen_Driver.cxx +++ b/src/Fl_Screen_Driver.cxx @@ -34,6 +34,7 @@ char Fl_Screen_Driver::bg_set = 0; char Fl_Screen_Driver::bg2_set = 0; char Fl_Screen_Driver::fg_set = 0; +Fl_System_Driver *Fl_Screen_Driver::system_driver = NULL; int Fl_Screen_Driver::keyboard_screen_scaling = 1; diff --git a/src/Fl_System_Driver.H b/src/Fl_System_Driver.H index e8930486e..0abab55df 100644 --- a/src/Fl_System_Driver.H +++ b/src/Fl_System_Driver.H @@ -84,6 +84,8 @@ public: static const int fl_YValue; static const int fl_XNegative; static const int fl_YNegative; + static int command_key; + static int control_key; // implement if the system adds unwanted program argument(s) virtual int single_arg(const char *) { return 0; } diff --git a/src/Fl_System_Driver.cxx b/src/Fl_System_Driver.cxx index ee5e990ce..44b47bc7c 100644 --- a/src/Fl_System_Driver.cxx +++ b/src/Fl_System_Driver.cxx @@ -83,11 +83,30 @@ static Fl_System_Driver::Keyname default_key_table[] = { {FL_Delete, "Delete"} }; + +int Fl_System_Driver::command_key = 0; +int Fl_System_Driver::control_key = 0; + + +int fl_command_modifier() { + if (!Fl_System_Driver::command_key) Fl::system_driver(); + return Fl_System_Driver::command_key; +} + + +int fl_control_modifier() { + if (!Fl_System_Driver::control_key) Fl::system_driver(); + return Fl_System_Driver::control_key; +} + + Fl_System_Driver::Fl_System_Driver() { // initialize default key table (used in fl_shortcut.cxx) key_table = default_key_table; key_table_size = sizeof(default_key_table)/sizeof(*default_key_table); + command_key = FL_CTRL; + control_key = FL_META; } Fl_System_Driver::~Fl_System_Driver() diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx index 56f672f44..2d589f495 100644 --- a/src/Fl_Window.cxx +++ b/src/Fl_Window.cxx @@ -879,6 +879,8 @@ const Fl_Image* Fl_Window::shape() {return pWindowDriver->shape();} bool Fl_Window::is_a_rescale() {return Fl_Window_Driver::is_a_rescale_;} /** Returns a platform-specific identification of a shown window, or 0 if not shown. + \note This identification may differ from the platform-specific reference of an + Fl_Window object used by functions fl_x11_xid(), fl_mac_xid(), fl_x11_find(), and fl_mac_find(). \li X11 platform: the window's XID. \li macOS platform: The window number of the window’s window device. \li other platforms: 0. diff --git a/src/Fl_Window_Driver.H b/src/Fl_Window_Driver.H index 24878e71d..03333c958 100644 --- a/src/Fl_Window_Driver.H +++ b/src/Fl_Window_Driver.H @@ -61,6 +61,8 @@ public: Fl_Window_Driver(Fl_Window *); virtual ~Fl_Window_Driver(); static Fl_Window_Driver *newWindowDriver(Fl_Window *); + static fl_uintptr_t xid(const Fl_Window *win); + static Fl_Window *find(fl_uintptr_t xid); int wait_for_expose_value; Fl_Offscreen other_xid; // offscreen bitmap (overlay and double-buffered windows) virtual int screen_num(); diff --git a/src/Fl_Window_Driver.cxx b/src/Fl_Window_Driver.cxx index 23c66be7f..a9faa3211 100644 --- a/src/Fl_Window_Driver.cxx +++ b/src/Fl_Window_Driver.cxx @@ -258,6 +258,32 @@ void Fl_Window_Driver::menu_window_area(int &X, int &Y, int &W, int &H, int nscr scr_driver->screen_work_area(X, Y, W, H, nscreen); } +/** Returns the platform-specific reference of the given window, or NULL if that window isn't shown. + \version 1.4.0 */ +fl_uintptr_t Fl_Window_Driver::xid(const Fl_Window *win) { + Fl_X *flx = win->i; + return flx ? flx->xid : 0; +} + +/** Returns a pointer to the Fl_Window corresponding to the platform-specific reference \p xid of a shown window. + \version 1.4.0 */ +Fl_Window *Fl_Window_Driver::find(fl_uintptr_t xid) { + Fl_X *window; + for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next) { + if (window->xid == xid) { + if (window != Fl_X::first && !Fl::modal()) { + // make this window be first to speed up searches + // this is not done if modal is true to avoid messing up modal stack + *pp = window->next; + window->next = Fl_X::first; + Fl_X::first = window; + } + return window->w; + } + } + return 0; +} + /** \} \endcond diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 05a748b8e..663fd2956 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -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]; diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index 6480aabd4..da4dddcd7 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -636,7 +636,7 @@ void Fl_WinAPI_Screen_Driver::enable_im() { Fl_X *i = Fl_X::first; while (i) { - flImmAssociateContextEx(i->xid, 0, IACE_DEFAULT); + flImmAssociateContextEx((HWND)i->xid, 0, IACE_DEFAULT); i = i->next; } @@ -648,7 +648,7 @@ void Fl_WinAPI_Screen_Driver::disable_im() { Fl_X *i = Fl_X::first; while (i) { - flImmAssociateContextEx(i->xid, 0, 0); + flImmAssociateContextEx((HWND)i->xid, 0, 0); i = i->next; } @@ -1288,7 +1288,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar break; case WM_PAINT: { - Fl_Region R, R2; + HRGN R, R2; Fl_X *i = Fl_X::i(window); Fl_Window_Driver::driver(window)->wait_for_expose_value = 0; char redraw_whole_window = false; @@ -1307,7 +1307,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar } // convert i->region in FLTK units to R2 in drawing units - R2 = Fl_GDI_Graphics_Driver::scale_region(i->region, scale, NULL); + R2 = Fl_GDI_Graphics_Driver::scale_region((HRGN)i->region, scale, NULL); RECT r_box; if (scale != 1 && GetRgnBox(R, &r_box) != NULLREGION) { @@ -1316,10 +1316,10 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar r_box.right = LONG(r_box.right / scale); r_box.top = LONG(r_box.top / scale); r_box.bottom = LONG(r_box.bottom / scale); - Fl_Region R3 = CreateRectRgn(r_box.left, r_box.top, r_box.right + 1, r_box.bottom + 1); + HRGN R3 = CreateRectRgn(r_box.left, r_box.top, r_box.right + 1, r_box.bottom + 1); if (!i->region) i->region = R3; else { - CombineRgn(i->region, i->region, R3, RGN_OR); + CombineRgn((HRGN)i->region, (HRGN)i->region, R3, RGN_OR); DeleteObject(R3); } } @@ -2185,7 +2185,7 @@ Fl_X *Fl_WinAPI_Window_Driver::makeWindow() { wlen = fl_utf8toUtf16(w->label(), (unsigned)l, (unsigned short *)lab, wlen); lab[wlen] = 0; } - x->xid = CreateWindowExW(styleEx, + x->xid = (fl_uintptr_t)CreateWindowExW(styleEx, class_namew, lab, style, xp, yp, wp, hp, parent, @@ -2208,14 +2208,14 @@ Fl_X *Fl_WinAPI_Window_Driver::makeWindow() { for x and y. We can then use GetWindowRect to determine which monitor the window was placed on. */ RECT rect; - GetWindowRect(x->xid, &rect); + GetWindowRect((HWND)x->xid, &rect); make_fullscreen(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); } // Setup clipboard monitor target if there are registered handlers and // no window is targeted. if (!fl_clipboard_notify_empty() && clipboard_wnd == NULL) - fl_clipboard_notify_target(x->xid); + fl_clipboard_notify_target((HWND)x->xid); wait_for_expose_value = 1; if (show_iconic()) { @@ -2239,14 +2239,14 @@ Fl_X *Fl_WinAPI_Window_Driver::makeWindow() { // If we've captured the mouse, we dont want to activate any // other windows from the code, or we lose the capture. - ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE : + ShowWindow((HWND)x->xid, !showit ? SW_SHOWMINNOACTIVE : (Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL); // Register all windows for potential drag'n'drop operations - RegisterDragDrop(x->xid, flIDropTarget); + RegisterDragDrop((HWND)x->xid, flIDropTarget); if (!im_enabled) - flImmAssociateContextEx(x->xid, 0, 0); + flImmAssociateContextEx((HWND)x->xid, 0, 0); return x; } @@ -2256,6 +2256,8 @@ Fl_X *Fl_WinAPI_Window_Driver::makeWindow() { HINSTANCE fl_display = GetModuleHandle(NULL); +HINSTANCE fl_win32_display() { return fl_display; } + void Fl_WinAPI_Window_Driver::set_minmax(LPMINMAXINFO minmax) { int td, wd, hd, dummy_x, dummy_y; @@ -2632,10 +2634,10 @@ void Fl_WinAPI_Window_Driver::show() { } else { // Once again, we would lose the capture if we activated the window. Fl_X *i = Fl_X::i(pWindow); - if (IsIconic(i->xid)) - OpenIcon(i->xid); + if (IsIconic((HWND)i->xid)) + OpenIcon((HWND)i->xid); if (!fl_capture) - BringWindowToTop(i->xid); + BringWindowToTop((HWND)i->xid); // ShowWindow(i->xid,fl_capture?SW_SHOWNOACTIVATE:SW_RESTORE); } } diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index d29bf82c5..b189dc470 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -41,7 +41,11 @@ # include "drivers/X11/Fl_X11_Screen_Driver.H" # include "drivers/X11/Fl_X11_Window_Driver.H" # include "drivers/X11/Fl_X11_System_Driver.H" +#if FLTK_USE_CAIRO +# include "drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H" +#else # include "drivers/Xlib/Fl_Xlib_Graphics_Driver.H" +#endif # include "print_button.h" # include <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; diff --git a/src/Makefile b/src/Makefile index 94aaf0b96..8be30e3cf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -207,9 +207,11 @@ GLCPPFILES_OSX = drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx \ GLCPPFILES_X11 = drivers/X11/Fl_X11_Gl_Window_Driver.cxx \ drivers/X11/fl_X11_gl_platform_init.cxx GLCPPFILES_XFT = $(GLCPPFILES_X11) +GLCPPFILES_CAIRO = $(GLCPPFILES_X11) GLCPPFILES_WIN = drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx \ drivers/WinAPI/fl_WinAPI_gl_platform_init.cxx GLCPPFILES_WAYLAND = drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx \ + drivers/X11/Fl_X11_Gl_Window_Driver.cxx \ drivers/Wayland/fl_wayland_gl_platform_init.cxx GLCPPFILES += $(GLCPPFILES_$(BUILD)) @@ -258,13 +260,6 @@ QUARTZCPPFILES = \ # These C++ files are used under condition: BUILD_X11 XLIBCPPFILES = \ - drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx \ - drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx \ drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx \ drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx \ drivers/X11/Fl_X11_Window_Driver.cxx \ @@ -280,7 +275,21 @@ XLIBCPPFILES = \ Fl_Native_File_Chooser_GTK.cxx\ Fl_Native_File_Chooser_Kdialog.cxx \ Fl_get_key.cxx - + +# These graphics driver files are used under condition: BUILD_CAIRO +CAIROGDFILES = \ + drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx \ + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx + +# These graphics driver files are used under condition: BUILD_X11 AND BUILD_XFT +XLIBGDFILES = drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx \ + drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx + # These C++ files are used under condition: BUILD_WAYLAND WLCPPFILES = \ drivers/Posix/Fl_Posix_Printer_Driver.cxx \ @@ -296,7 +305,16 @@ WLCPPFILES = \ drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx \ drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx \ drivers/Wayland/fl_wayland_platform_init.cxx \ - drivers/Wayland/fl_wayland_clipboard_dnd.cxx + drivers/Wayland/fl_wayland_clipboard_dnd.cxx \ + drivers/X11/Fl_X11_Screen_Driver.cxx \ + drivers/X11/Fl_X11_Window_Driver.cxx \ + drivers/X11/Fl_X11_System_Driver.cxx \ + drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx \ + drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx \ + drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx \ + Fl_x.cxx \ + fl_dnd_x.cxx \ + Fl_get_key.cxx # fl_dnd_x.cxx Fl_Native_File_Chooser_GTK.cxx @@ -364,7 +382,7 @@ FLTKFLAGS = -DFL_LIBRARY include ../makeinclude # makeinclude has set this variable: -# BUILD = {WIN|X11|XFT|OSX|WAYLAND} +# BUILD = {WIN|X11|XFT|CAIRO|OSX|WAYLAND} MMFILES_OSX = $(OBJCPPFILES) MMFILES = $(MMFILES_$(BUILD)) @@ -372,8 +390,9 @@ MMFILES = $(MMFILES_$(BUILD)) CPPFILES += $(PSCPPFILES) CPPFILES_OSX = $(QUARTZCPPFILES) -CPPFILES_XFT = $(XLIBCPPFILES) $(XLIBXFTFILES) -CPPFILES_X11 = $(XLIBCPPFILES) $(XLIBFONTFILES) +CPPFILES_XFT = $(XLIBCPPFILES) $(XLIBGDFILES) $(XLIBXFTFILES) +CPPFILES_X11 = $(XLIBCPPFILES) $(XLIBGDFILES) $(XLIBFONTFILES) +CPPFILES_CAIRO = $(XLIBCPPFILES) $(CAIROGDFILES) CPPFILES_WAYLAND = $(WLCPPFILES) $(WLXFTFILES) @@ -383,6 +402,7 @@ CPPFILES += $(CPPFILES_$(BUILD)) CFILES_X11 = $(XLIBCFILES) $(XLIBXCFILES) +CFILES_CAIRO = $(XLIBCFILES) CFILES_XFT = $(XLIBCFILES) CFILES_WAYLAND = $(WLCFILES) diff --git a/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H b/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H new file mode 100644 index 000000000..76986af9a --- /dev/null +++ b/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H @@ -0,0 +1,37 @@ +// +// Support for using Cairo to draw into X11 windows for the Fast Light Tool Kit (FLTK). +// +// Copyright 2022 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +/* \file + Declaration of class Fl_Display_Cairo_Graphics_Driver. +*/ + +#ifndef FL_DISPLAY_CAIRO_GRAPHICS_DRIVER_H +# define FL_DISPLAY_CAIRO_GRAPHICS_DRIVER_H + +#include "Fl_Cairo_Graphics_Driver.H" + +class Fl_Display_Cairo_Graphics_Driver : public Fl_Cairo_Graphics_Driver { +private: + static void *gc_; +public: + virtual void scale(float f); + virtual float scale() {return Fl_Graphics_Driver::scale();} + virtual void gc(void *value); + virtual void* gc(); + virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy); + }; + +#endif // FL_DISPLAY_CAIRO_GRAPHICS_DRIVER_H diff --git a/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx b/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx new file mode 100644 index 000000000..02df902d8 --- /dev/null +++ b/src/drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx @@ -0,0 +1,64 @@ +// +// Support for using Cairo to draw into X11 windows for the Fast Light Tool Kit (FLTK). +// +// Copyright 2022 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +/* \file + Implementation of class Fl_Display_Cairo_Graphics_Driver . +*/ + +#include "Fl_Display_Cairo_Graphics_Driver.H" +#include <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_; +} diff --git a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx index 6491332e3..d1ed8df1e 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx @@ -1,7 +1,7 @@ // // Class Fl_Cocoa_Gl_Window_Driver for the Fast Light Tool Kit (FLTK). // -// Copyright 2021 by Bill Spitzak and others. +// Copyright 2021-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -66,7 +66,7 @@ GLContext Fl_Cocoa_Gl_Window_Driver::create_gl_context(Fl_Window* window, const // resets the pile of string textures used to draw strings // necessary before the first context is created if (!shared_ctx) gl_texture_reset(); - context = Fl_Cocoa_Window_Driver::create_GLcontext_for_window(((Fl_Cocoa_Gl_Choice*)g)->pixelformat, shared_ctx, window); + context = Fl_Cocoa_Window_Driver::create_GLcontext_for_window(((Fl_Cocoa_Gl_Choice*)g)->pixelformat, (NSOpenGLContext*)shared_ctx, window); if (!context) return 0; add_context(context); return (context); @@ -76,7 +76,7 @@ void Fl_Cocoa_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) if (context != cached_context || w != cached_window) { cached_context = context; cached_window = w; - Fl_Cocoa_Window_Driver::GLcontext_makecurrent(context); + Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)context); } } @@ -86,7 +86,7 @@ void Fl_Cocoa_Gl_Window_Driver::delete_gl_context(GLContext context) { cached_window = 0; Fl_Cocoa_Window_Driver::GL_cleardrawable(); } - Fl_Cocoa_Window_Driver::GLcontext_release(context); + Fl_Cocoa_Window_Driver::GLcontext_release((NSOpenGLContext*)context); del_context(context); } @@ -143,7 +143,7 @@ void Fl_Cocoa_Gl_Window_Driver::make_current_before() { if (d->changed_resolution()){ d->changed_resolution(false); pWindow->invalidate(); - Fl_Cocoa_Window_Driver::GLcontext_update(pWindow->context()); + Fl_Cocoa_Window_Driver::GLcontext_update((NSOpenGLContext*)pWindow->context()); } } @@ -179,13 +179,13 @@ void Fl_Cocoa_Gl_Window_Driver::swap_buffers() { glRasterPos3f(pos[0], pos[1], pos[2]); // restore original glRasterPos } else - Fl_Cocoa_Window_Driver::flush_context(pWindow->context());//aglSwapBuffers((AGLContext)context_); + Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)pWindow->context());//aglSwapBuffers((AGLContext)context_); } char Fl_Cocoa_Gl_Window_Driver::swap_type() {return copy;} void Fl_Cocoa_Gl_Window_Driver::resize(int is_a_resize, int w, int h) { - Fl_Cocoa_Window_Driver::GLcontext_update(pWindow->context()); + Fl_Cocoa_Window_Driver::GLcontext_update((NSOpenGLContext*)pWindow->context()); } /* Some old Apple hardware doesn't implement the GL_EXT_texture_rectangle extension. @@ -202,7 +202,7 @@ char *Fl_Cocoa_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, i fl_draw(str, n, 0, fl_height() - fl_descent()); // get the alpha channel only of the bitmap char *alpha_buf = new char[w*h], *r = alpha_buf, *q; - q = (char*)CGBitmapContextGetData(surf->offscreen()); + q = (char*)CGBitmapContextGetData((CGContextRef)surf->offscreen()); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { *r++ = *(q+3); @@ -215,7 +215,7 @@ char *Fl_Cocoa_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, i } void Fl_Cocoa_Gl_Window_Driver::gl_start() { - Fl_Cocoa_Window_Driver::gl_start(gl_start_context); + Fl_Cocoa_Window_Driver::gl_start((NSOpenGLContext*)gl_start_context); } // convert BGRA to RGB and also exchange top and bottom @@ -247,8 +247,8 @@ Fl_RGB_Image* Fl_Cocoa_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int if (factor != 1) { w *= factor; h *= factor; x *= factor; y *= factor; } - Fl_Cocoa_Window_Driver::GLcontext_makecurrent(glw->context()); - Fl_Cocoa_Window_Driver::flush_context(glw->context()); // to capture also the overlay and for directGL demo + Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)glw->context()); + Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)glw->context()); // to capture also the overlay and for directGL demo // Read OpenGL context pixels directly. // For extra safety, save & restore OpenGL states that are changed glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); @@ -266,10 +266,16 @@ Fl_RGB_Image* Fl_Cocoa_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int baseAddress = convert_BGRA_to_RGB(baseAddress, w, h, mByteWidth); Fl_RGB_Image *img = new Fl_RGB_Image(baseAddress, w, h, 3, 3 * w); img->alloc_array = 1; - Fl_Cocoa_Window_Driver::flush_context(glw->context()); + Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)glw->context()); return img; } + +FL_EXPORT NSOpenGLContext *fl_mac_glcontext(GLContext rc) { + return (NSOpenGLContext*)rc; +} + + class Fl_Gl_Cocoa_Plugin : public Fl_Cocoa_Plugin { public: Fl_Gl_Cocoa_Plugin() : Fl_Cocoa_Plugin(name()) { } diff --git a/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm b/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm index fd278cf75..c587caf37 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm +++ b/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm @@ -347,7 +347,7 @@ int Fl_Cocoa_Printer_Driver::begin_page (void) CGContextSaveGState(gc); CGContextSaveGState(gc); fl_line_style(FL_SOLID); - fl_window = (Window)1; // TODO: something better + fl_window = (FLWindow*)1; // TODO: something better fl_clip_region(0); return status != noErr; } diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx index 01c3b0f95..33b0392c4 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx @@ -140,7 +140,7 @@ void Fl_Cocoa_Screen_Driver::grab(Fl_Window* win) { if (win) { if (!Fl::grab_) { - fl_capture = Fl_X::i(Fl::first_window())->xid; + fl_capture = (FLWindow*)(Fl_X::i(Fl::first_window())->xid); Fl_Cocoa_Window_Driver::driver(Fl::first_window())->set_key_window(); } Fl::grab_ = win; @@ -315,8 +315,8 @@ int Fl_Cocoa_Screen_Driver::input_widget_handle_key(int key, unsigned mods, unsi void Fl_Cocoa_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &height) { - width = CGBitmapContextGetWidth(off); - height = CGBitmapContextGetHeight(off); + width = CGBitmapContextGetWidth((CGContextRef)off); + height = CGBitmapContextGetHeight((CGContextRef)off); } Fl_RGB_Image *Fl_Cocoa_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *window, diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx index b7f213da0..019e2b7f5 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx @@ -224,10 +224,10 @@ void Fl_Cocoa_Window_Driver::hide() { if (ip && !parent()) pWindow->cursor(FL_CURSOR_DEFAULT); if ( hide_common() ) return; q_release_context(this); - if ( ip->xid == fl_window ) + if ( ip->xid == (fl_uintptr_t)fl_window ) fl_window = 0; if (ip->region) Fl_Graphics_Driver::default_driver().XDestroyRegion(ip->region); - destroy(ip->xid); + destroy((FLWindow*)ip->xid); delete subRect(); delete ip; } @@ -338,3 +338,13 @@ int Fl_Cocoa_Window_Driver::screen_num() { if (pWindow->parent()) return pWindow->top_window()->screen_num(); else return screen_num_; } + + +FLWindow *fl_mac_xid(const Fl_Window *win) { + return (FLWindow*)Fl_Window_Driver::xid(win); +} + + +Fl_Window *fl_mac_find(FLWindow *xid) { + return Fl_Window_Driver::find((fl_uintptr_t)xid); +} diff --git a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx index 0c8015dba..2c4c5a34b 100644 --- a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx +++ b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx @@ -93,6 +93,8 @@ Fl_Darwin_System_Driver::Fl_Darwin_System_Driver() : Fl_Posix_System_Driver() { // initialize key table key_table = darwin_key_table; key_table_size = sizeof(darwin_key_table)/sizeof(*darwin_key_table); + command_key = FL_META; + control_key = FL_CTRL; } int Fl_Darwin_System_Driver::single_arg(const char *arg) { diff --git a/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx b/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx index 29478a9c4..c44c0a77b 100644 --- a/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx +++ b/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx @@ -64,7 +64,7 @@ Fl_GDI_Copy_Surface_Driver::~Fl_GDI_Copy_Surface_Driver() { fl_color(FL_WHITE); // draw white background fl_rectf(0, 0, W, H); PlayEnhMetaFile((HDC)surf->driver()->gc(), hmf, &rect); // draw metafile to offscreen buffer - SetClipboardData(CF_BITMAP, surf->offscreen()); + SetClipboardData(CF_BITMAP, (HBITMAP)surf->offscreen()); Fl_Surface_Device::pop_current(); delete surf; @@ -80,7 +80,7 @@ Fl_GDI_Copy_Surface_Driver::~Fl_GDI_Copy_Surface_Driver() { void Fl_GDI_Copy_Surface_Driver::set_current() { driver()->gc(gc); - fl_window = (Window)1; + fl_window = (HWND)1; Fl_Surface_Device::set_current(); } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx index 87adc44f0..188bd1d2d 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx @@ -75,6 +75,10 @@ static FL_BLENDFUNCTION blendfunc = { 0, 0, 255, 1}; */ HDC fl_gc = 0; + +HDC fl_win32_gc() { return fl_gc; } + + Fl_GDI_Graphics_Driver::Fl_GDI_Graphics_Driver() { mask_bitmap_ = NULL; gc_ = NULL; @@ -157,7 +161,7 @@ void Fl_GDI_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offsc if (w <= 0 || h <= 0) return; HDC new_gc = CreateCompatibleDC(gc_); int save = SaveDC(new_gc); - SelectObject(new_gc, bitmap); + SelectObject(new_gc, (HBITMAP)bitmap); BitBlt(gc_, x, y, w, h, new_gc, srcx, srcy, SRCCOPY); RestoreDC(new_gc, save); DeleteDC(new_gc); @@ -211,8 +215,8 @@ void Fl_GDI_Graphics_Driver::untranslate_all() { #endif void Fl_GDI_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { - Fl_Region R = XRectangleRegion(X, Y, W, H); - CombineRgn(r, r, R, RGN_OR); + HRGN R = (HRGN)XRectangleRegion(X, Y, W, H); + CombineRgn((HRGN)r, (HRGN)r, R, RGN_OR); XDestroyRegion(R); } @@ -241,7 +245,7 @@ Fl_Region Fl_GDI_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { } void Fl_GDI_Graphics_Driver::XDestroyRegion(Fl_Region r) { - DeleteObject(r); + DeleteObject((HRGN)r); } @@ -287,7 +291,7 @@ HRGN Fl_GDI_Graphics_Driver::scale_region(HRGN r, float f, Fl_GDI_Graphics_Drive Fl_Region Fl_GDI_Graphics_Driver::scale_clip(float f) { - HRGN r = rstack[rstackptr]; + HRGN r = (HRGN)rstack[rstackptr]; HRGN r2 = scale_region(r, f, this); return (r == r2 ? NULL : (rstack[rstackptr] = r2, r)); } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx index 4cfc745c9..9e512d889 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx @@ -590,7 +590,7 @@ void Fl_GDI_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, RestoreDC(new_gc,save); DeleteDC(new_gc); } else if (img->d()==2 || img->d()==4) { - copy_offscreen_with_alpha(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(img), cx, cy); + copy_offscreen_with_alpha(X, Y, W, H, (HBITMAP)*Fl_Graphics_Driver::id(img), cx, cy); } else { copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(img), cx, cy); } @@ -653,7 +653,7 @@ void Fl_GDI_Printer_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, void Fl_GDI_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_uintptr_t &mask_) { if (id_) { - DeleteObject((Fl_Offscreen)id_); + DeleteObject((HBITMAP)id_); id_ = 0; } @@ -817,5 +817,5 @@ void Fl_GDI_Graphics_Driver::cache(Fl_Pixmap *img) { } void Fl_GDI_Graphics_Driver::uncache_pixmap(fl_uintptr_t offscreen) { - DeleteObject((Fl_Offscreen)offscreen); + DeleteObject((HBITMAP)offscreen); } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx index 76b546092..1b13ff0a9 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx @@ -138,10 +138,10 @@ void Fl_GDI_Graphics_Driver::polygon_unscaled(int x, int y, int x1, int y1, int // --- clipping void Fl_GDI_Graphics_Driver::push_clip(int x, int y, int w, int h) { - Fl_Region r; + HRGN r; if (w > 0 && h > 0) { - r = XRectangleRegion(x,y,w,h); - Fl_Region current = rstack[rstackptr]; + r = (HRGN)XRectangleRegion(x,y,w,h); + HRGN current = (HRGN)rstack[rstackptr]; if (current) { CombineRgn(r,r,current,RGN_AND); } @@ -155,14 +155,14 @@ void Fl_GDI_Graphics_Driver::push_clip(int x, int y, int w, int h) { int Fl_GDI_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ X = x; Y = y; W = w; H = h; - Fl_Region r = rstack[rstackptr]; + HRGN r = (HRGN)rstack[rstackptr]; if (!r) return 0; // The win32 API makes no distinction between partial and complete // intersection, so we have to check for partial intersection ourselves. // However, given that the regions may be composite, we have to do // some voodoo stuff... - Fl_Region rr = XRectangleRegion(x,y,w,h); - Fl_Region temp = CreateRectRgn(0,0,0,0); + HRGN rr = (HRGN)XRectangleRegion(x,y,w,h); + HRGN temp = CreateRectRgn(0,0,0,0); int ret; if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint W = H = 0; @@ -189,7 +189,7 @@ int Fl_GDI_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int Fl_GDI_Graphics_Driver::not_clipped(int x, int y, int w, int h) { if (x+w <= 0 || y+h <= 0) return 0; - Fl_Region r = rstack[rstackptr]; + HRGN r = (HRGN)rstack[rstackptr]; if (!r) return 1; RECT rect; if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { // in case of print context, convert coords from logical to device @@ -206,8 +206,8 @@ void Fl_GDI_Graphics_Driver::restore_clip() { fl_clip_state_number++; if (gc_) { HRGN r = NULL; - if (rstack[rstackptr]) r = scale_clip(scale()); - SelectClipRgn(gc_, rstack[rstackptr]); // if region is NULL, clip is automatically cleared + if (rstack[rstackptr]) r = (HRGN)scale_clip(scale()); + SelectClipRgn(gc_, (HRGN)rstack[rstackptr]); // if region is NULL, clip is automatically cleared if (r) unscale_clip(r); } } diff --git a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H index 979b7bd3a..a3d8ac6c6 100644 --- a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H +++ b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.H @@ -24,7 +24,7 @@ class Fl_GDI_Image_Surface_Driver : public Fl_Image_Surface_Driver { virtual void end_current(); public: - Window pre_window; + HWND pre_window; int _savedc; Fl_GDI_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off); ~Fl_GDI_Image_Surface_Driver(); diff --git a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx index 7f655e291..6795fb06b 100644 --- a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx +++ b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx @@ -29,8 +29,8 @@ Fl_GDI_Image_Surface_Driver::Fl_GDI_Image_Surface_Driver(int w, int h, int high_ h = int(h*d); } HDC gc = (HDC)Fl_Graphics_Driver::default_driver().gc(); - offscreen = off ? off : CreateCompatibleBitmap( (gc ? gc : fl_GetDC(0) ) , w, h); - if (!offscreen) offscreen = CreateCompatibleBitmap(fl_GetDC(0), w, h); + offscreen = off ? off : (Fl_Offscreen)CreateCompatibleBitmap( (gc ? gc : fl_GetDC(0) ) , w, h); + if (!offscreen) offscreen = (Fl_Offscreen)CreateCompatibleBitmap(fl_GetDC(0), w, h); driver(Fl_Graphics_Driver::newMainGraphicsDriver()); if (d != 1 && high_res) ((Fl_GDI_Graphics_Driver*)driver())->scale(d); origin.x = origin.y = 0; @@ -38,13 +38,13 @@ Fl_GDI_Image_Surface_Driver::Fl_GDI_Image_Surface_Driver(int w, int h, int high_ Fl_GDI_Image_Surface_Driver::~Fl_GDI_Image_Surface_Driver() { - if (offscreen && !external_offscreen) DeleteObject(offscreen); + if (offscreen && !external_offscreen) DeleteObject((HBITMAP)offscreen); delete driver(); } void Fl_GDI_Image_Surface_Driver::set_current() { - HDC gc = fl_makeDC(offscreen); + HDC gc = fl_makeDC((HBITMAP)offscreen); driver()->gc(gc); SetWindowOrgEx(gc, origin.x, origin.y, NULL); Fl_Surface_Device::set_current(); diff --git a/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx index 3ededb5ab..77ecdaa0a 100644 --- a/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx @@ -49,7 +49,7 @@ Fl_Quartz_Copy_Surface_Driver::Fl_Quartz_Copy_Surface_Driver(int w, int h) : Fl_ void Fl_Quartz_Copy_Surface_Driver::set_current() { driver()->gc(gc); - fl_window = (Window)1; + fl_window = (FLWindow*)1; Fl_Surface_Device::set_current(); } diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx index b50309438..552da03f9 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx @@ -84,6 +84,10 @@ void Fl_Quartz_Graphics_Driver::global_gc() fl_gc = (CGContextRef)gc(); } + +CGContextRef fl_mac_gc() { return fl_gc; } + + void Fl_Quartz_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) { // draw portion srcx,srcy,w,h of osrc to position x,y (top-left) of the graphics driver's surface CGContextRef src = (CGContextRef)osrc; @@ -127,7 +131,8 @@ CGRect Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(int x, int y, int w, int h return CGRectMake(x - 0.5, y - 0.5, w, h); } -void Fl_Quartz_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { +void Fl_Quartz_Graphics_Driver::add_rectangle_to_region(Fl_Region r_, int X, int Y, int W, int H) { + struct flCocoaRegion *r = (struct flCocoaRegion*)r_; CGRect arg = Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(X, Y, W, H); int j; // don't add a rectangle totally inside the Fl_Region for(j = 0; j < r->count; j++) { @@ -140,15 +145,16 @@ void Fl_Quartz_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int } Fl_Region Fl_Quartz_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { - Fl_Region R = (Fl_Region)malloc(sizeof(*R)); + struct flCocoaRegion* R = (struct flCocoaRegion*)malloc(sizeof(struct flCocoaRegion)); R->count = 1; R->rects = (CGRect *)malloc(sizeof(CGRect)); *(R->rects) = Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(x, y, w, h); return R; } -void Fl_Quartz_Graphics_Driver::XDestroyRegion(Fl_Region r) { - if(r) { +void Fl_Quartz_Graphics_Driver::XDestroyRegion(Fl_Region r_) { + if (r_) { + struct flCocoaRegion *r = (struct flCocoaRegion*)r_; free(r->rects); free(r); } diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx index 558dc47c1..b97cfbba7 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx @@ -250,7 +250,7 @@ void Fl_Quartz_Graphics_Driver::cache(Fl_Pixmap *img) { Fl_Surface_Device::push_current(surf); fl_draw_pixmap(img->data(), 0, 0, FL_BLACK); Fl_Surface_Device::pop_current(); - CGContextRef src = Fl_Graphics_Driver::get_offscreen_and_delete_image_surface(surf); + CGContextRef src = (CGContextRef)Fl_Graphics_Driver::get_offscreen_and_delete_image_surface(surf); void *cgdata = CGBitmapContextGetData(src); int sw = CGBitmapContextGetWidth(src); int sh = CGBitmapContextGetHeight(src); diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx index 52b8c7f65..71daf0e10 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx @@ -218,11 +218,12 @@ void Fl_Quartz_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, in // --- clipping // intersects current and x,y,w,h rectangle and returns result as a new Fl_Region -static Fl_Region intersect_region_and_rect(Fl_Region current, int x,int y,int w, int h) +static Fl_Region intersect_region_and_rect(Fl_Region current_, int x,int y,int w, int h) { - if (current == NULL) return Fl_Graphics_Driver::default_driver().XRectangleRegion(x,y,w,h); + if (current_ == NULL) return Fl_Graphics_Driver::default_driver().XRectangleRegion(x,y,w,h); + struct flCocoaRegion* current = (struct flCocoaRegion*)current_; CGRect r = Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(x, y, w, h); - Fl_Region outr = (Fl_Region)malloc(sizeof(*outr)); + struct flCocoaRegion* outr = (struct flCocoaRegion*)malloc(sizeof(struct flCocoaRegion)); outr->count = current->count; outr->rects =(CGRect*)malloc(outr->count * sizeof(CGRect)); int j = 0; @@ -236,7 +237,7 @@ static Fl_Region intersect_region_and_rect(Fl_Region current, int x,int y,int w, } else { Fl_Graphics_Driver::default_driver().XDestroyRegion(outr); - outr = Fl_Graphics_Driver::default_driver().XRectangleRegion(0,0,0,0); + outr = (struct flCocoaRegion*)Fl_Graphics_Driver::default_driver().XRectangleRegion(0,0,0,0); } return outr; } @@ -261,7 +262,7 @@ void Fl_Quartz_Graphics_Driver::push_clip(int x, int y, int w, int h) { int Fl_Quartz_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ X = x; Y = y; W = w; H = h; - Fl_Region r = rstack[rstackptr]; + struct flCocoaRegion* r = (struct flCocoaRegion*)rstack[rstackptr]; if (!r) return 0; CGRect arg = fl_cgrectmake_cocoa(x, y, w, h); CGRect u = CGRectMake(0,0,0,0); @@ -283,7 +284,7 @@ int Fl_Quartz_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& int Fl_Quartz_Graphics_Driver::not_clipped(int x, int y, int w, int h) { if (x+w <= 0 || y+h <= 0) return 0; - Fl_Region r = rstack[rstackptr]; + struct flCocoaRegion* r = (struct flCocoaRegion*)rstack[rstackptr]; if (!r) return 1; CGRect arg = fl_cgrectmake_cocoa(x, y, w, h); for (int i = 0; i < r->count; i++) { @@ -295,7 +296,7 @@ int Fl_Quartz_Graphics_Driver::not_clipped(int x, int y, int w, int h) { void Fl_Quartz_Graphics_Driver::restore_clip() { fl_clip_state_number++; - Fl_Region r = rstack[rstackptr]; + struct flCocoaRegion* r = (struct flCocoaRegion*)rstack[rstackptr]; if ( fl_window || gc_ ) { // clipping for a true window or an offscreen buffer if (gc_) { CGContextRestoreGState(gc_); diff --git a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H index 4e6f8c79d..f70a43ed6 100644 --- a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H +++ b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H @@ -23,7 +23,7 @@ class Fl_Quartz_Image_Surface_Driver : public Fl_Image_Surface_Driver { virtual void end_current(); public: - Window pre_window; + FLWindow *pre_window; Fl_Quartz_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off); ~Fl_Quartz_Image_Surface_Driver(); void set_current(); diff --git a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx index c638bfb79..2f1acc5d9 100644 --- a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx @@ -32,25 +32,25 @@ Fl_Quartz_Image_Surface_Driver::Fl_Quartz_Image_Surface_Driver(int w, int h, int W *= s; H *= s; } CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); - offscreen = off ? off : CGBitmapContextCreate(calloc(W*H,4), W, H, 8, W*4, lut, kCGImageAlphaPremultipliedLast); + offscreen = off ? off : (Fl_Offscreen)CGBitmapContextCreate(calloc(W*H,4), W, H, 8, W*4, lut, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(lut); driver(new Fl_Quartz_Graphics_Driver); - CGContextTranslateCTM(offscreen, 0.5*s, -0.5*s); // as when drawing to a window + CGContextTranslateCTM((CGContextRef)offscreen, 0.5*s, -0.5*s); // as when drawing to a window if (high_res) { - CGContextScaleCTM(offscreen, s, s); + CGContextScaleCTM((CGContextRef)offscreen, s, s); driver()->scale(s); } - CGContextSetShouldAntialias(offscreen, false); - CGContextTranslateCTM(offscreen, 0, height); - CGContextScaleCTM(offscreen, 1.0f, -1.0f); - CGContextSaveGState(offscreen); - CGContextSetRGBFillColor(offscreen, 1, 1, 1, 0); - CGContextFillRect(offscreen, CGRectMake(0,0,w,h)); + CGContextSetShouldAntialias((CGContextRef)offscreen, false); + CGContextTranslateCTM((CGContextRef)offscreen, 0, height); + CGContextScaleCTM((CGContextRef)offscreen, 1.0f, -1.0f); + CGContextSaveGState((CGContextRef)offscreen); + CGContextSetRGBFillColor((CGContextRef)offscreen, 1, 1, 1, 0); + CGContextFillRect((CGContextRef)offscreen, CGRectMake(0,0,w,h)); } Fl_Quartz_Image_Surface_Driver::~Fl_Quartz_Image_Surface_Driver() { if (offscreen && !external_offscreen) { - void *data = CGBitmapContextGetData(offscreen); + void *data = CGBitmapContextGetData((CGContextRef)offscreen); free(data); CGContextRelease((CGContextRef)offscreen); } @@ -60,30 +60,30 @@ Fl_Quartz_Image_Surface_Driver::~Fl_Quartz_Image_Surface_Driver() { void Fl_Quartz_Image_Surface_Driver::set_current() { Fl_Surface_Device::set_current(); pre_window = fl_window; - driver()->gc(offscreen); + driver()->gc((CGContextRef)offscreen); fl_window = 0; - ((Fl_Quartz_Graphics_Driver*)driver())->high_resolution( CGBitmapContextGetWidth(offscreen) > (size_t)width ); + ((Fl_Quartz_Graphics_Driver*)driver())->high_resolution( CGBitmapContextGetWidth((CGContextRef)offscreen) > (size_t)width ); } void Fl_Quartz_Image_Surface_Driver::translate(int x, int y) { - CGContextRestoreGState(offscreen); - CGContextSaveGState(offscreen); - CGContextTranslateCTM(offscreen, x, y); - CGContextSaveGState(offscreen); + CGContextRestoreGState((CGContextRef)offscreen); + CGContextSaveGState((CGContextRef)offscreen); + CGContextTranslateCTM((CGContextRef)offscreen, x, y); + CGContextSaveGState((CGContextRef)offscreen); } void Fl_Quartz_Image_Surface_Driver::untranslate() { - CGContextRestoreGState(offscreen); + CGContextRestoreGState((CGContextRef)offscreen); } Fl_RGB_Image* Fl_Quartz_Image_Surface_Driver::image() { - CGContextFlush(offscreen); - int W = CGBitmapContextGetWidth(offscreen); - int H = CGBitmapContextGetHeight(offscreen); - int bpr = CGBitmapContextGetBytesPerRow(offscreen); - int bpp = CGBitmapContextGetBitsPerPixel(offscreen)/8; - uchar *base = (uchar*)CGBitmapContextGetData(offscreen); + CGContextFlush((CGContextRef)offscreen); + int W = CGBitmapContextGetWidth((CGContextRef)offscreen); + int H = CGBitmapContextGetHeight((CGContextRef)offscreen); + int bpr = CGBitmapContextGetBytesPerRow((CGContextRef)offscreen); + int bpp = CGBitmapContextGetBitsPerPixel((CGContextRef)offscreen)/8; + uchar *base = (uchar*)CGBitmapContextGetData((CGContextRef)offscreen); int idx, idy; uchar *pdst, *psrc; unsigned char *data = new uchar[W * H * 3]; diff --git a/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx index 07b3038f0..60a0cad51 100644 --- a/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx @@ -43,7 +43,7 @@ Fl_Wayland_Copy_Surface_Driver::~Fl_Wayland_Copy_Surface_Driver() { void Fl_Wayland_Copy_Surface_Driver::set_current() { Fl_Surface_Device::set_current(); - ((Fl_Wayland_Graphics_Driver*)driver())->set_buffer(img_surf->offscreen()); + ((Fl_Wayland_Graphics_Driver*)driver())->set_buffer((struct fl_wld_buffer *)img_surf->offscreen()); } diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx index 979cef3d8..89014826f 100644 --- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx @@ -94,7 +94,7 @@ char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, { // write str to a bitmap just big enough Fl_Image_Surface *surf = new Fl_Image_Surface(w, h); - Fl_Font f=fl_font(); + Fl_Font f = fl_font(); Fl_Surface_Device::push_current(surf); fl_color(FL_BLACK); fl_rectf(0, 0, w, h); @@ -104,7 +104,8 @@ char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, // get the R channel only of the bitmap char *alpha_buf = new char[w*h], *r = alpha_buf, *q; for (int i = 0; i < h; i++) { - q = (char*)surf->offscreen()->draw_buffer + i * surf->offscreen()->stride; + struct fl_wld_buffer *off = (struct fl_wld_buffer *)surf->offscreen(); + q = (char*)off->draw_buffer + i * off->stride; for (int j = 0; j < w; j++) { *r++ = *q; q += 4; @@ -174,7 +175,7 @@ GLContext Fl_Wayland_Gl_Window_Driver::create_gl_context(Fl_Window* window, cons if (context_list && nContext) shared_ctx = context_list[0]; static const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - GLContext ctx = (GLContext)eglCreateContext(egl_display, ((Fl_Wayland_Gl_Choice*)g)->egl_conf, shared_ctx?shared_ctx:EGL_NO_CONTEXT, context_attribs); + GLContext ctx = (GLContext)eglCreateContext(egl_display, ((Fl_Wayland_Gl_Choice*)g)->egl_conf, shared_ctx?(EGLContext)shared_ctx:EGL_NO_CONTEXT, context_attribs); //fprintf(stderr, "eglCreateContext=%p shared_ctx=%p\n", ctx, shared_ctx); if (ctx) add_context(ctx); @@ -183,7 +184,7 @@ GLContext Fl_Wayland_Gl_Window_Driver::create_gl_context(Fl_Window* window, cons void Fl_Wayland_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) { - struct wld_window *win = fl_xid(w); + struct wld_window *win = fl_wl_xid(w); if (!win) return; Fl_Wayland_Window_Driver *dr = Fl_Wayland_Window_Driver::driver(w); EGLSurface target_egl_surface = NULL; @@ -221,7 +222,7 @@ void Fl_Wayland_Gl_Window_Driver::delete_gl_context(GLContext context) { cached_window = 0; } //EGLBoolean b = - eglDestroyContext(egl_display, context); + eglDestroyContext(egl_display, (EGLContext)context); //fprintf(stderr,"EGL context %p destroyed %s\n", context, b==EGL_TRUE?"successfully":"w/ error"); //b = eglDestroySurface(egl_display, egl_surface); @@ -246,7 +247,7 @@ void Fl_Wayland_Gl_Window_Driver::redraw_overlay() { void Fl_Wayland_Gl_Window_Driver::make_current_before() { if (!egl_window) { - struct wld_window *win = fl_xid(pWindow); + struct wld_window *win = fl_wl_xid(pWindow); struct wl_surface *surface = win->wl_surface; egl_window = wl_egl_window_create(surface, pWindow->pixel_w(), pWindow->pixel_h()); if (egl_window == EGL_NO_SURFACE) { @@ -270,7 +271,7 @@ void Fl_Wayland_Gl_Window_Driver::make_current_before() { float Fl_Wayland_Gl_Window_Driver::pixels_per_unit() { int ns = Fl_Window_Driver::driver(pWindow)->screen_num(); - int wld_scale = pWindow->shown() ? fl_xid(pWindow)->scale : 1; + int wld_scale = pWindow->shown() ? fl_wl_xid(pWindow)->scale : 1; return wld_scale * Fl::screen_driver()->scale(ns); } @@ -360,7 +361,7 @@ static void delayed_flush(Fl_Gl_Window *win) { void Fl_Wayland_Gl_Window_Driver::resize(int is_a_resize, int W, int H) { if (!egl_window) return; - struct wld_window *win = fl_xid(pWindow); + struct wld_window *win = fl_wl_xid(pWindow); float f = Fl::screen_scale(pWindow->screen_num()); W = (W * win->scale) * f; H = (H * win->scale) * f; @@ -404,4 +405,7 @@ void Fl_Wayland_Gl_Window_Driver::gl_start() { glClear(GL_COLOR_BUFFER_BIT); } + +FL_EXPORT EGLContext fl_wl_glcontext(GLContext rc) { return (EGLContext)rc; } + #endif // HAVE_GL diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx index 78586dc59..986d25ddf 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx @@ -149,8 +149,9 @@ void Fl_Wayland_Graphics_Driver::set_color(Fl_Color i, unsigned c) { } -void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) { +void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen src, int srcx, int srcy) { // draw portion srcx,srcy,w,h of osrc to position x,y (top-left) of the graphics driver's surface + struct fl_wld_buffer *osrc = (struct fl_wld_buffer *)src; int height = osrc->data_size / osrc->stride; cairo_matrix_t matrix; cairo_get_matrix(cairo_, &matrix); diff --git a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx index 1638cf0d2..4f64434d8 100644 --- a/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx @@ -33,12 +33,13 @@ Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, i w = int(w*d); h = int(h*d); } - offscreen = (struct fl_wld_buffer*)calloc(1, sizeof(struct fl_wld_buffer)); - offscreen->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w); - offscreen->data_size = offscreen->stride * h; - offscreen->draw_buffer = (uchar*)malloc(offscreen->data_size); - offscreen->width = w; - Fl_Wayland_Graphics_Driver::cairo_init(offscreen, w, h, offscreen->stride, CAIRO_FORMAT_RGB24); + struct fl_wld_buffer *off_ = (struct fl_wld_buffer*)calloc(1, sizeof(struct fl_wld_buffer)); + off_->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w); + off_->data_size = off_->stride * h; + off_->draw_buffer = (uchar*)malloc(off_->data_size); + off_->width = w; + offscreen = (Fl_Offscreen)off_; + Fl_Wayland_Graphics_Driver::cairo_init(off_, w, h, off_->stride, CAIRO_FORMAT_RGB24); } driver(new Fl_Wayland_Graphics_Driver()); if (d != 1 && high_res) driver()->scale(d); @@ -47,24 +48,24 @@ Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, i Fl_Wayland_Image_Surface_Driver::~Fl_Wayland_Image_Surface_Driver() { if (offscreen && !external_offscreen) { - cairo_destroy(offscreen->cairo_); - free(offscreen->draw_buffer); - free(offscreen); + cairo_destroy(((struct fl_wld_buffer *)offscreen)->cairo_); + free(((struct fl_wld_buffer *)offscreen)->draw_buffer); + free((struct fl_wld_buffer *)offscreen); } delete driver(); } void Fl_Wayland_Image_Surface_Driver::set_current() { Fl_Surface_Device::set_current(); - ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer(offscreen); + ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer((struct fl_wld_buffer*)offscreen); pre_window = Fl_Wayland_Window_Driver::wld_window; - fl_window = Fl_Wayland_Window_Driver::wld_window = NULL; + Fl_Wayland_Window_Driver::wld_window = NULL; } void Fl_Wayland_Image_Surface_Driver::end_current() { - cairo_surface_t *surf = cairo_get_target(offscreen->cairo_); + cairo_surface_t *surf = cairo_get_target(((struct fl_wld_buffer *)offscreen)->cairo_); cairo_surface_flush(surf); - fl_window = Fl_Wayland_Window_Driver::wld_window = pre_window; + Fl_Wayland_Window_Driver::wld_window = pre_window; } void Fl_Wayland_Image_Surface_Driver::translate(int x, int y) { @@ -77,20 +78,20 @@ void Fl_Wayland_Image_Surface_Driver::untranslate() { Fl_RGB_Image* Fl_Wayland_Image_Surface_Driver::image() { // Convert depth-4 image in draw_buffer to a depth-3 image while exchanging R and B colors - int height = offscreen->data_size / offscreen->stride; - uchar *rgb = new uchar[offscreen->width * height * 3]; + int height = ((struct fl_wld_buffer *)offscreen)->data_size / ((struct fl_wld_buffer *)offscreen)->stride; + uchar *rgb = new uchar[((struct fl_wld_buffer *)offscreen)->width * height * 3]; uchar *p = rgb; uchar *q; for (int j = 0; j < height; j++) { - q = offscreen->draw_buffer + j*offscreen->stride; - for (int i = 0; i < offscreen->width; i++) { // exchange R and B colors, transmit G + q = ((struct fl_wld_buffer *)offscreen)->draw_buffer + j*((struct fl_wld_buffer *)offscreen)->stride; + for (int i = 0; i < ((struct fl_wld_buffer *)offscreen)->width; i++) { // exchange R and B colors, transmit G *p = *(q+2); *(p+1) = *(q+1); *(p+2) = *q; p += 3; q += 4; } } - Fl_RGB_Image *image = new Fl_RGB_Image(rgb, offscreen->width, height, 3); + Fl_RGB_Image *image = new Fl_RGB_Image(rgb, ((struct fl_wld_buffer *)offscreen)->width, height, 3); image->alloc_array = 1; return image; } diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H index 196f07d5e..a7a3f9512 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H @@ -64,6 +64,10 @@ class Fl_Wayland_Screen_Driver : public Fl_Screen_Driver static bool insertion_point_location_is_valid; public: static struct wl_display *wl_display; + // use it to make sure the Wayland leg was selected and fl_open_display() has run + static struct wl_registry *wl_registry; + // true when an app is forbidden to use its Wayland leg + static bool wld_disabled; static void insertion_point_location(int x, int y, int height); static bool insertion_point_location(int *px, int *py, int *pwidth, int *pheight); int get_mouse_unscaled(int &xx, int &yy); diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx index 372d08b32..821bdd56a 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx @@ -227,13 +227,16 @@ static inline void checkdouble() { struct wl_display *Fl_Wayland_Screen_Driver::wl_display = NULL; +struct wl_registry *Fl_Wayland_Screen_Driver::wl_registry = NULL; +bool Fl_Wayland_Screen_Driver::wld_disabled = false; + Fl_Window *Fl_Wayland_Screen_Driver::surface_to_window(struct wl_surface *surface) { if (surface) { Fl_X *xp = Fl_X::first; while (xp) { - if (xp->xid->wl_surface == surface) return xp->w; + if (((struct wld_window*)xp->xid)->wl_surface == surface) return xp->w; xp = xp->next; } } @@ -335,9 +338,9 @@ static void pointer_button(void *data, win = win->top_window(); wld_event_time = time; if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED && seat->pointer_focus == NULL && - fl_xid(win)->kind == Fl_Wayland_Window_Driver::DECORATED) { + (fl_wl_xid(win))->kind == Fl_Wayland_Window_Driver::DECORATED) { // click on titlebar - libdecor_frame_move(fl_xid(win)->frame, seat->wl_seat, serial); + libdecor_frame_move(fl_wl_xid(win)->frame, seat->wl_seat, serial); return; } int b = 0; @@ -907,7 +910,7 @@ static void output_done(void *data, struct wl_output *wl_output) //fprintf(stderr, "output_done output=%p\n",output); Fl_X *xp = Fl_X::first; while (xp) { // all mapped windows - struct wld_window *win = xp->xid; + struct wld_window *win = (struct wld_window*)xp->xid; wl_list_for_each(window_output, &(win->outputs), link) { // all Fl_Wayland_Window_Driver::window_output for this window if (window_output->output == output) { Fl_Wayland_Window_Driver *win_driver = Fl_Wayland_Window_Driver::driver(win->fl_win); @@ -1041,7 +1044,7 @@ static void registry_handle_global_remove(void *data, struct wl_registry *regist if (output->id == name) { // the screen being removed Fl_X *xp = Fl_X::first; while (xp) { // all mapped windows - struct wld_window *win = xp->xid; + struct wld_window *win = (struct wld_window*)xp->xid; wl_list_for_each_safe(window_output, tmp, &(win->outputs), link) { // all Fl_Wayland_Window_Driver::window_output for this window if (window_output->output == output) { wl_list_remove(&window_output->link); @@ -1086,16 +1089,16 @@ Fl_Wayland_Screen_Driver::Fl_Wayland_Screen_Driver() : Fl_Screen_Driver() { } void Fl_Wayland_Screen_Driver::open_display_platform() { - struct wl_registry *wl_registry; - static bool beenHereDoneThat = false; if (beenHereDoneThat) return; beenHereDoneThat = true; - wl_display = wl_display_connect(NULL); if (!wl_display) { - Fl::fatal("No Wayland connection\n"); + wl_display = wl_display_connect(NULL); + if (!wl_display) { + Fl::fatal("No Wayland connection\n"); + } } wl_list_init(&seats); wl_list_init(&outputs); @@ -1121,6 +1124,7 @@ void Fl_Wayland_Screen_Driver::close_display() { Fl::remove_fd(wl_display_get_fd(Fl_Wayland_Screen_Driver::wl_display)); wl_display_disconnect(Fl_Wayland_Screen_Driver::wl_display); Fl_Wayland_Screen_Driver::wl_display = NULL; + Fl_Wayland_Screen_Driver::wl_registry = NULL; } @@ -1141,7 +1145,7 @@ void Fl_Wayland_Screen_Driver::init_workarea() int Fl_Wayland_Screen_Driver::x() { - if (!Fl_Wayland_Screen_Driver::wl_display) open_display(); + if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl_Wayland_Screen_Driver::output *output; wl_list_for_each(output, &outputs, link) { break; @@ -1150,7 +1154,7 @@ int Fl_Wayland_Screen_Driver::x() { } int Fl_Wayland_Screen_Driver::y() { - if (!Fl_Wayland_Screen_Driver::wl_display) open_display(); + if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl_Wayland_Screen_Driver::output *output; wl_list_for_each(output, &outputs, link) { break; @@ -1159,7 +1163,7 @@ int Fl_Wayland_Screen_Driver::y() { } int Fl_Wayland_Screen_Driver::w() { - if (!Fl_Wayland_Screen_Driver::wl_display) open_display(); + if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl_Wayland_Screen_Driver::output *output; wl_list_for_each(output, &outputs, link) { break; @@ -1168,7 +1172,7 @@ int Fl_Wayland_Screen_Driver::w() { } int Fl_Wayland_Screen_Driver::h() { - if (!Fl_Wayland_Screen_Driver::wl_display) open_display(); + if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); Fl_Wayland_Screen_Driver::output *output; wl_list_for_each(output, &outputs, link) { break; @@ -1178,7 +1182,7 @@ int Fl_Wayland_Screen_Driver::h() { void Fl_Wayland_Screen_Driver::init() { - if (!Fl_Wayland_Screen_Driver::wl_display) open_display(); + if (!Fl_Wayland_Screen_Driver::wl_registry) open_display(); } @@ -1315,8 +1319,8 @@ const char *Fl_Wayland_Screen_Driver::get_system_scheme() Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, bool ignore, bool *p_ignore) { - Window xid = win ? fl_xid(win) : NULL; - struct fl_wld_buffer *buffer = win ? xid->buffer : (Fl_Offscreen)Fl_Surface_Device::surface()->driver()->gc(); + struct wld_window* xid = win ? fl_wl_xid(win) : NULL; + struct fl_wld_buffer *buffer = win ? xid->buffer : (struct fl_wld_buffer *)Fl_Surface_Device::surface()->driver()->gc(); float s = win ? xid->scale * scale(win->screen_num()) : Fl_Surface_Device::surface()->driver()->scale(); int Xs, Ys, ws, hs; @@ -1346,8 +1350,9 @@ Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w, } -void Fl_Wayland_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &height) +void Fl_Wayland_Screen_Driver::offscreen_size(Fl_Offscreen off_, int &width, int &height) { + struct fl_wld_buffer *off = (struct fl_wld_buffer *)off_; width = off->width; height = off->data_size / off->stride; } @@ -1457,3 +1462,8 @@ void Fl_Wayland_Screen_Driver::reset_spot() { Fl_Wayland_Screen_Driver::next_marked_length = 0; Fl_Wayland_Screen_Driver::insertion_point_location_is_valid = false; } + + +struct wl_display *fl_wl_display() { + return Fl_Wayland_Screen_Driver::wl_display; +} diff --git a/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx index a54e2ac5f..4b26a17ea 100644 --- a/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_System_Driver.cxx @@ -18,6 +18,7 @@ #include "Fl_Wayland_System_Driver.H" #include <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); diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 38230b3db..96985c10b 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -49,7 +49,7 @@ extern "C" { #define fl_max(a,b) ((a) > (b) ? (a) : (b)) -Window fl_window; + struct wld_window *Fl_Wayland_Window_Driver::wld_window = NULL; @@ -112,7 +112,7 @@ void Fl_Wayland_Window_Driver::decorated_win_size(int &w, int &h) h = win->h(); if (!win->shown() || win->parent() || !win->border() || !win->visible()) return; int X, titlebar_height; - libdecor_frame_translate_coordinate(fl_xid(win)->frame, 0, 0, &X, &titlebar_height); + libdecor_frame_translate_coordinate(fl_wl_xid(win)->frame, 0, 0, &X, &titlebar_height); //printf("titlebar_height=%d\n",titlebar_height); h = win->h() + ceil(titlebar_height / Fl::screen_scale(win->screen_num())); } @@ -135,7 +135,7 @@ int Fl_Wayland_Window_Driver::decorated_w() } struct xdg_toplevel *Fl_Wayland_Window_Driver::xdg_toplevel() { - Window w = fl_xid(pWindow); + struct wld_window * w = fl_wl_xid(pWindow); struct xdg_toplevel *top = NULL; if (w->kind == DECORATED) top = libdecor_frame_get_xdg_toplevel(w->frame); else if (w->kind == UNFRAMED) top = w->xdg_toplevel; @@ -144,10 +144,10 @@ struct xdg_toplevel *Fl_Wayland_Window_Driver::xdg_toplevel() { void Fl_Wayland_Window_Driver::take_focus() { - Window w = fl_xid(pWindow); + struct wld_window *w = fl_wl_xid(pWindow); if (w) { Fl_Window *old_first = Fl::first_window(); - Window first_xid = (old_first ? fl_xid(old_first->top_window()) : NULL); + struct wld_window *first_xid = (old_first ? fl_wl_xid(old_first->top_window()) : NULL); if (first_xid && first_xid != w && xdg_toplevel()) { // this will move the target window to the front Fl_Wayland_Window_Driver *top_dr = Fl_Wayland_Window_Driver::driver(old_first->top_window()); @@ -157,7 +157,7 @@ void Fl_Wayland_Window_Driver::take_focus() xdg_toplevel_set_parent(xdg_toplevel(), NULL); } // this sets the first window - fl_find(w); + fl_wl_find(w); } } @@ -185,7 +185,7 @@ void Fl_Wayland_Window_Driver::flush_overlay() fl_copy_offscreen(0, 0, oWindow->w(), oWindow->h(), other_xid, 0, 0); } if (overlay() == oWindow) oWindow->draw_overlay(); - Window xid = fl_xid(pWindow); + struct wld_window * xid = fl_wl_xid(pWindow); wl_surface_damage_buffer(xid->wl_surface, 0, 0, pWindow->w() * xid->scale, pWindow->h() * xid->scale); } @@ -295,7 +295,7 @@ void Fl_Wayland_Window_Driver::capture_titlebar_and_borders(Fl_RGB_Image*& top, top = left = bottom = right = NULL; if (pWindow->decorated_h() == h()) return; int htop = pWindow->decorated_h() - pWindow->h(); - struct wld_window *wwin = fl_xid(pWindow); + struct wld_window *wwin = fl_wl_xid(pWindow); int width, height, stride; uchar *cairo_data = fl_libdecor_titlebar_buffer(wwin->frame, &width, &height, &stride); if (!cairo_data) return; @@ -342,7 +342,7 @@ void Fl_Wayland_Window_Driver::make_current() { Fl::fatal(err_message); } - struct wld_window *window = fl_xid(pWindow); + struct wld_window *window = fl_wl_xid(pWindow); if (window->buffer) { ((Fl_Cairo_Graphics_Driver*)fl_graphics_driver)->needs_commit_tag( &window->buffer->draw_buffer_needs_commit); @@ -355,7 +355,7 @@ void Fl_Wayland_Window_Driver::make_current() { } fl_graphics_driver->clip_region(0); - fl_window = Fl_Wayland_Window_Driver::wld_window = window; + Fl_Wayland_Window_Driver::wld_window = window; float scale = Fl::screen_scale(pWindow->screen_num()) * window->scale; if (!window->buffer) { window->buffer = Fl_Wayland_Graphics_Driver::create_shm_buffer( @@ -385,11 +385,11 @@ void Fl_Wayland_Window_Driver::flush() { if (scale != fl_graphics_driver->scale() || W != pWindow->w() || H != pWindow->h()) gl_plugin()->invalidate(pWindow); return; } - struct wld_window *window = fl_xid(pWindow); + struct wld_window *window = fl_wl_xid(pWindow); if (!window || !window->configured_width) return; Fl_X *i = Fl_X::i(pWindow); - Fl_Region r = i->region; + struct flCairoRegion* r = (struct flCairoRegion*)i->region; float f = Fl::screen_scale(pWindow->screen_num()); if (r && window->buffer) { for (int i = 0; i < r->count; i++) { @@ -440,7 +440,7 @@ void Fl_Wayland_Window_Driver::hide() { ip->region = 0; } screen_num_ = -1; - struct wld_window *wld_win = ip->xid; + struct wld_window *wld_win = (struct wld_window*)ip->xid; if (wld_win) { // this test makes sure ip->xid has not been destroyed already Fl_Wayland_Graphics_Driver::buffer_release(wld_win); //fprintf(stderr, "Before hide: sub=%p frame=%p xdg=%p top=%p pop=%p surf=%p\n", wld_win->subsurface, wld_win->frame, wld_win->xdg_surface, wld_win->xdg_toplevel, wld_win->xdg_popup, wld_win->wl_surface); @@ -479,7 +479,7 @@ void Fl_Wayland_Window_Driver::hide() { } free(wld_win); if (pWindow->as_gl_window() && in_flush) { - ip->xid = NULL; + ip->xid = 0; ip->next = NULL; // to end the loop in calling Fl::flush() Fl::add_timeout(.01, (Fl_Timeout_Handler)delayed_delete_Fl_X, ip); } else { @@ -490,9 +490,9 @@ void Fl_Wayland_Window_Driver::hide() { void Fl_Wayland_Window_Driver::map() { Fl_X* ip = Fl_X::i(pWindow); - struct wld_window *wl_win = ip->xid; + struct wld_window *wl_win = (struct wld_window*)ip->xid; if (wl_win->kind == SUBWINDOW && !wl_win->subsurface) { - struct wld_window *parent = fl_xid(pWindow->window()); + struct wld_window *parent = fl_wl_xid(pWindow->window()); if (parent) { Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); wl_win->subsurface = wl_subcompositor_get_subsurface(scr_driver->wl_subcompositor, wl_win->wl_surface, parent->wl_surface); @@ -512,7 +512,7 @@ void Fl_Wayland_Window_Driver::map() { void Fl_Wayland_Window_Driver::unmap() { Fl_X* ip = Fl_X::i(pWindow); - struct wld_window *wl_win = ip->xid; + struct wld_window *wl_win = (struct wld_window*)ip->xid; if (wl_win->kind == SUBWINDOW && wl_win->wl_surface) { wl_surface_attach(wl_win->wl_surface, NULL, 0, 0); Fl_Wayland_Graphics_Driver::buffer_release(wl_win); @@ -525,7 +525,7 @@ void Fl_Wayland_Window_Driver::unmap() { void Fl_Wayland_Window_Driver::size_range() { if (shown()) { Fl_X* ip = Fl_X::i(pWindow); - struct wld_window *wl_win = ip->xid; + struct wld_window *wl_win = (struct wld_window*)ip->xid; float f = Fl::screen_scale(pWindow->screen_num()); if (wl_win->kind == DECORATED && wl_win->frame) { int X,Y,W,H; @@ -553,7 +553,7 @@ void Fl_Wayland_Window_Driver::size_range() { void Fl_Wayland_Window_Driver::iconize() { Fl_X* ip = Fl_X::i(pWindow); - struct wld_window *wl_win = ip->xid; + struct wld_window *wl_win = (struct wld_window*)ip->xid; if (wl_win->kind == DECORATED) { libdecor_frame_set_minimized(wl_win->frame); Fl::handle(FL_HIDE, pWindow); @@ -577,7 +577,7 @@ void Fl_Wayland_Window_Driver::decoration_sizes(int *top, int *left, int *right int Fl_Wayland_Window_Driver::scroll(int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, void (*draw_area)(void*, int,int,int,int), void* data) { - Window xid = fl_xid(pWindow); + struct wld_window * xid = fl_wl_xid(pWindow); struct fl_wld_buffer *buffer = xid->buffer; float s = xid->scale * fl_graphics_driver->scale(); if (s != 1) { @@ -781,7 +781,7 @@ static void handle_configure(struct libdecor_frame *frame, void Fl_Wayland_Window_Driver::wait_for_expose() { Fl_Window_Driver::wait_for_expose(); - Window xid = fl_xid(pWindow); + struct wld_window * xid = fl_wl_xid(pWindow); if (pWindow->fullscreen_active()) { if (xid->kind == DECORATED) { while (!(xid->state & LIBDECOR_WINDOW_STATE_FULLSCREEN) || !(xid->state & LIBDECOR_WINDOW_STATE_ACTIVE)) { @@ -897,7 +897,7 @@ static void popup_done(void *data, struct xdg_popup *xdg_popup) { #if USE_GRAB_POPUP if (mem_grabbing_popup == xdg_popup) { Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); - libdecor_frame_popup_ungrab(fl_xid(mem_parent)->frame, scr_driver->get_seat_name()); + libdecor_frame_popup_ungrab(fl_wl_xid(mem_parent)->frame, scr_driver->get_seat_name()); mem_grabbing_popup = NULL; mem_parent = NULL; } @@ -1003,7 +1003,7 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow() if (!target) target = Fl::first_window(); Fl_Window *parent_win = target->top_window(); while (parent_win && parent_win->menu_window()) parent_win = Fl::next_window(parent_win); - Window parent_xid = fl_xid(parent_win); + struct wld_window * parent_xid = fl_wl_xid(parent_win); struct xdg_surface *parent_xdg = parent_xid->xdg_surface; float f = Fl::screen_scale(parent_win->screen_num()); //fprintf(stderr, "menu parent_win=%p pos:%dx%d size:%dx%d\n", parent_win, pWindow->x(), pWindow->y(), pWindow->w(), pWindow->h()); @@ -1029,7 +1029,8 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow() } else if ( pWindow->border() && !pWindow->parent() ) { // a decorated window new_window->kind = DECORATED; - if (!scr_driver->libdecor_context) scr_driver->libdecor_context = libdecor_new(Fl_Wayland_Screen_Driver::wl_display, &libdecor_iface); + if (!scr_driver->libdecor_context) + scr_driver->libdecor_context = libdecor_new(Fl_Wayland_Screen_Driver::wl_display, &libdecor_iface); new_window->frame = libdecor_decorate(scr_driver->libdecor_context, new_window->wl_surface, &libdecor_frame_iface, new_window); //fprintf(stderr, "makeWindow: libdecor_decorate=%p pos:%dx%d\n", new_window->frame, pWindow->x(), pWindow->y()); @@ -1046,7 +1047,7 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow() } else if (pWindow->parent()) { // for subwindows (GL or non-GL) new_window->kind = SUBWINDOW; - struct wld_window *parent = fl_xid(pWindow->window()); + struct wld_window *parent = fl_wl_xid(pWindow->window()); new_window->subsurface = wl_subcompositor_get_subsurface(scr_driver->wl_subcompositor, new_window->wl_surface, parent->wl_surface); //fprintf(stderr, "makeWindow: subsurface=%p\n", new_window->subsurface); float f = Fl::screen_scale(pWindow->top_window()->screen_num()); @@ -1073,9 +1074,9 @@ Fl_X *Fl_Wayland_Window_Driver::makeWindow() } Fl_Window *old_first = Fl::first_window(); - Window first_xid = (old_first ? fl_xid(old_first) : NULL); + struct wld_window * first_xid = (old_first ? fl_wl_xid(old_first) : NULL); Fl_X *xp = new Fl_X; - xp->xid = new_window; + xp->xid = (fl_uintptr_t)new_window; other_xid = 0; xp->w = pWindow; i(xp); @@ -1244,7 +1245,7 @@ int Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor c) { void Fl_Wayland_Window_Driver::update_scale() { - struct wld_window *window = fl_xid(pWindow); + struct wld_window *window = fl_wl_xid(pWindow); int scale = 0; Fl_Wayland_Window_Driver::window_output *window_output; @@ -1265,7 +1266,7 @@ void Fl_Wayland_Window_Driver::update_scale() void Fl_Wayland_Window_Driver::use_border() { if (!shown() || pWindow->parent()) return; pWindow->wait_for_expose(); // useful for border(0) just after show() - struct libdecor_frame *frame = fl_xid(pWindow)->frame; + struct libdecor_frame *frame = fl_wl_xid(pWindow)->frame; if (frame && Fl_Wayland_Screen_Driver::compositor != Fl_Wayland_Screen_Driver::KDE) { libdecor_frame_set_visibility(frame, pWindow->border()); pWindow->redraw(); @@ -1310,10 +1311,10 @@ void Fl_Wayland_Window_Driver::fullscreen_off(int X, int Y, int W, int H) { void Fl_Wayland_Window_Driver::label(const char *name, const char *iname) { - if (shown() && !parent() && fl_xid(pWindow)->kind == DECORATED) { + if (shown() && !parent() && fl_wl_xid(pWindow)->kind == DECORATED) { if (!name) name = ""; if (!iname) iname = fl_filename_name(name); - libdecor_frame_set_title(fl_xid(pWindow)->frame, name); + libdecor_frame_set_title(fl_wl_xid(pWindow)->frame, name); } } @@ -1322,7 +1323,7 @@ int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int // build a new wl_cursor and its image struct wl_cursor *new_cursor = (struct wl_cursor*)malloc(sizeof(struct wl_cursor)); struct cursor_image *new_image = (struct cursor_image*)calloc(1, sizeof(struct cursor_image)); - int scale = fl_xid(pWindow)->scale; + int scale = fl_wl_xid(pWindow)->scale; new_image->image.width = rgb->w() * scale; new_image->image.height = rgb->h() * scale; new_image->image.hotspot_x = hotx * scale; @@ -1338,7 +1339,7 @@ int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int new_cursor->images[0] = (struct wl_cursor_image*)new_image; new_cursor->name = strdup("custom cursor"); // draw the rgb image to the cursor's drawing buffer - Fl_Image_Surface *img_surf = new Fl_Image_Surface(new_image->image.width, new_image->image.height, 0, offscreen); + Fl_Image_Surface *img_surf = new Fl_Image_Surface(new_image->image.width, new_image->image.height, 0, (Fl_Offscreen)offscreen); Fl_Surface_Device::push_current(img_surf); Fl_Wayland_Graphics_Driver *driver = (Fl_Wayland_Graphics_Driver*)img_surf->driver(); cairo_scale(driver->cr(), scale, scale); @@ -1361,7 +1362,7 @@ int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int // This is only to fix a bug in libdecor where what libdecor_frame_set_min_content_size() // does is often destroyed by libdecor-cairo. static void delayed_minsize(Fl_Window *win) { - struct wld_window *wl_win = fl_xid(win); + struct wld_window *wl_win = fl_wl_xid(win); Fl_Window_Driver *driver = Fl_Window_Driver::driver(win); if (wl_win->kind == Fl_Wayland_Window_Driver::DECORATED) { float f = Fl::screen_scale(win->screen_num()); @@ -1377,7 +1378,7 @@ static void delayed_minsize(Fl_Window *win) { void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) { - struct wld_window *fl_win = fl_xid(pWindow); + struct wld_window *fl_win = fl_wl_xid(pWindow); if (fl_win && fl_win->kind == DECORATED && !xdg_toplevel()) { pWindow->wait_for_expose(); } @@ -1448,7 +1449,7 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) { } void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) { - Window xid_menu = fl_xid(pWindow); + struct wld_window * xid_menu = fl_wl_xid(pWindow); if (y == pWindow->y() && y >= 0) return; int true_y = y; int y_offset = 0; @@ -1468,7 +1469,7 @@ void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) { xid_menu->xdg_surface = xdg_wm_base_get_xdg_surface(scr_driver->xdg_wm_base, xid_menu->wl_surface); xdg_surface_add_listener(xid_menu->xdg_surface, &xdg_surface_listener, xid_menu); struct xdg_positioner *positioner = xdg_wm_base_create_positioner(scr_driver->xdg_wm_base); - Window parent_xid = fl_xid(Fl_Window_Driver::menu_parent()); + struct wld_window * parent_xid = fl_wl_xid(Fl_Window_Driver::menu_parent()); float f = Fl::screen_scale(Fl_Window_Driver::menu_parent()->screen_num()); int popup_x = x * f, popup_y = y * f; if (parent_xid->kind == DECORATED) @@ -1504,7 +1505,7 @@ void Fl_Wayland_Window_Driver::menu_window_area(int &X, int &Y, int &W, int &H, } -struct wl_surface *fl_wl_surface(Window xid) { +FL_EXPORT struct wl_surface *fl_wl_surface(struct wld_window *xid) { return xid->wl_surface; } @@ -1514,8 +1515,13 @@ cairo_t *fl_wl_cairo() { } -struct wl_display *fl_wl_display() { - return Fl_Wayland_Screen_Driver::wl_display; +Fl_Window *fl_wl_find(struct wld_window *xid) { + return Fl_Window_Driver::find((fl_uintptr_t)xid); +} + + +struct wld_window *fl_wl_xid(const Fl_Window *win) { + return (struct wld_window *)Fl_Window_Driver::xid(win); } diff --git a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx index 07bcd3ed4..2dca84924 100644 --- a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx +++ b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx @@ -34,7 +34,6 @@ //////////////////////////////////////////////////////////////// // Code used for copy and paste and DnD into the program: -//static Window fl_dnd_source_window; static char *fl_selection_buffer[2]; static int fl_selection_length[2]; @@ -99,7 +98,7 @@ static void data_source_handle_cancelled(void *data, struct wl_data_source *sour wl_data_source_destroy(source); doing_dnd = false; if (dnd_icon) { - Fl_Offscreen off = (Fl_Offscreen)wl_surface_get_user_data(dnd_icon); + struct fl_wld_buffer * off = (struct fl_wld_buffer *)wl_surface_get_user_data(dnd_icon); struct wld_window fake_window; fake_window.buffer = off; Fl_Wayland_Graphics_Driver::buffer_release(&fake_window); @@ -190,9 +189,9 @@ static Fl_Offscreen offscreen_from_text(const char *text, int scale) { if (width > 300*scale) width = 300*scale; height = nl * fl_height() + 3; width += 6; - Fl_Offscreen off = Fl_Wayland_Graphics_Driver::create_shm_buffer(width, height); + struct fl_wld_buffer * off = Fl_Wayland_Graphics_Driver::create_shm_buffer(width, height); memset(off->draw_buffer, 0, off->data_size); - Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 0, off); + Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 0, (Fl_Offscreen)off); Fl_Surface_Device::push_current(surf); p = text; fl_font(FL_HELVETICA, 10 * scale); @@ -213,7 +212,7 @@ static Fl_Offscreen offscreen_from_text(const char *text, int scale) { delete surf; cairo_surface_flush( cairo_get_target(off->cairo_) ); memcpy(off->data, off->draw_buffer, off->data_size); - return off; + return (Fl_Offscreen)off; } @@ -226,13 +225,13 @@ int Fl_Wayland_Screen_Driver::dnd(int use_selection) { wl_data_source_add_listener(source, &data_source_listener, (void*)0); wl_data_source_offer(source, wld_plain_text_clipboard); wl_data_source_set_actions(source, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY); - Fl_Offscreen off = NULL; + struct fl_wld_buffer * off = NULL; int s = 1; if (use_selection) { // use the text as dragging icon Fl_Widget *current = Fl::pushed() ? Fl::pushed() : Fl::first_window(); - s = fl_xid(current->top_window())->scale; - off = offscreen_from_text(fl_selection_buffer[0], s); + s = fl_wl_xid(current->top_window())->scale; + off = (struct fl_wld_buffer *)offscreen_from_text(fl_selection_buffer[0], s); dnd_icon = wl_compositor_create_surface(scr_driver->wl_compositor); } else dnd_icon = NULL; doing_dnd = true; @@ -571,7 +570,7 @@ void Fl_Wayland_Screen_Driver::paste(Fl_Widget &receiver, int clipboard, const c receiver.handle(FL_PASTE); } else if (type == Fl::clipboard_image && clipboard_contains(Fl::clipboard_image)) { if (get_clipboard_image()) return; - Window xid = fl_xid(receiver.top_window()); + struct wld_window * xid = fl_wl_xid(receiver.top_window()); if (xid && xid->scale > 1) { Fl_RGB_Image *rgb = (Fl_RGB_Image*)Fl::e_clipboard_data; rgb->scale(rgb->data_w() / xid->scale, rgb->data_h() / xid->scale); diff --git a/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx b/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx index 5a2a78bee..f80ee67ba 100644 --- a/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx +++ b/src/drivers/Wayland/fl_wayland_gl_platform_init.cxx @@ -16,9 +16,12 @@ #include "Fl_Wayland_Gl_Window_Driver.H" +#include "Fl_Wayland_Screen_Driver.H" +#include "../X11/Fl_X11_Gl_Window_Driver.H" Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w) { - return new Fl_Wayland_Gl_Window_Driver(w); + if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Gl_Window_Driver(w); + return new Fl_X11_Gl_Window_Driver(w); } diff --git a/src/drivers/Wayland/fl_wayland_platform_init.cxx b/src/drivers/Wayland/fl_wayland_platform_init.cxx index 4500a0f45..8c81ab331 100644 --- a/src/drivers/Wayland/fl_wayland_platform_init.cxx +++ b/src/drivers/Wayland/fl_wayland_platform_init.cxx @@ -22,10 +22,61 @@ #include "Fl_Wayland_Window_Driver.H" #include "Fl_Wayland_Image_Surface_Driver.H" +#include "../Xlib/Fl_Xlib_Copy_Surface_Driver.H" +#include <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" + +#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_Copy_Surface_Driver *Fl_Copy_Surface_Driver::newCopySurfaceDriver(int w, int h) +Fl_System_Driver *Fl_System_Driver::newSystemDriver() { - return new Fl_Wayland_Copy_Surface_Driver(w, h); + const char *backend = ::getenv("FLTK_BACKEND"); + // fprintf(stderr, "FLTK_BACKEND='%s' XDG_RUNTIME_DIR='%s'\n",backend ? backend : "", xdg ? xdg : ""); + if (backend && strcmp(backend, "wayland") == 0) { + Fl_Wayland_Screen_Driver::wl_display = wl_display_connect(NULL); + if (!Fl_Wayland_Screen_Driver::wl_display) { + fprintf(stderr, "Error: no Wayland connection available, FLTK_BACKEND = '%s'\n", backend); + exit(1); + } + return new Fl_Wayland_System_Driver(); + } + else if (backend && strcmp(backend, "x11") == 0) { + return new Fl_X11_System_Driver(); + } + else if (!backend) { + if (!Fl_Wayland_Screen_Driver::wld_disabled && ::getenv("XDG_RUNTIME_DIR")) { + // env var XDG_RUNTIME_DIR is necessary for wayland + // is a Wayland connection available ? + Fl_Wayland_Screen_Driver::wl_display = wl_display_connect(NULL); + if (Fl_Wayland_Screen_Driver::wl_display) { // Yes, use Wayland drivers + // puts("using wayland"); + return new Fl_Wayland_System_Driver(); + } + } + return new Fl_X11_System_Driver(); + } + fprintf(stderr, "Error: unexpected value of FLTK_BACKEND: '%s'\n", backend); + exit(1); + return NULL; } @@ -52,32 +103,43 @@ static Fl_Fontdesc built_in_table[] = { // Pango font names FL_EXPORT Fl_Fontdesc *fl_fonts = built_in_table; -Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver() -{ - fl_graphics_driver = new Fl_Wayland_Graphics_Driver(); +Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver() { + if (Fl_Wayland_Screen_Driver::wl_display) { + fl_graphics_driver = new Fl_Wayland_Graphics_Driver(); +puts("using Fl_Wayland_Graphics_Driver"); + } else { + fl_graphics_driver = new Fl_Display_Cairo_Graphics_Driver(); +puts("using Fl_Display_Cairo_Graphics_Driver"); + } return fl_graphics_driver; } -Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver() -{ - return new Fl_Wayland_Screen_Driver(); +Fl_Copy_Surface_Driver *Fl_Copy_Surface_Driver::newCopySurfaceDriver(int w, int h) { + if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Copy_Surface_Driver(w, h); + return new Fl_Xlib_Copy_Surface_Driver(w, h); } -Fl_System_Driver *Fl_System_Driver::newSystemDriver() -{ - return new Fl_Wayland_System_Driver(); +Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver() { + if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Screen_Driver(); + + Fl_X11_Screen_Driver *d = new Fl_X11_Screen_Driver(); + for (int i = 0; i < MAX_SCREENS; i++) d->screens[i].scale = 1; + d->current_xft_dpi = 0.; // means the value of the Xft.dpi resource is still unknown + return d; } Fl_Window_Driver *Fl_Window_Driver::newWindowDriver(Fl_Window *w) { - return new Fl_Wayland_Window_Driver(w); + if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Window_Driver(w); + return new Fl_X11_Window_Driver(w); } Fl_Image_Surface_Driver *Fl_Image_Surface_Driver::newImageSurfaceDriver(int w, int h, int high_res, Fl_Offscreen off) { - return new Fl_Wayland_Image_Surface_Driver(w, h, high_res, off); + if (Fl_Wayland_Screen_Driver::wl_display) return new Fl_Wayland_Image_Surface_Driver(w, h, high_res, off); + return new Fl_Xlib_Image_Surface_Driver(w, h, high_res, off); } diff --git a/src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx index cd6e98646..7952dfdc1 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx @@ -1,7 +1,7 @@ // // Class Fl_WinAPI_Gl_Window_Driver for the Fast Light Tool Kit (FLTK). // -// Copyright 2021 by Bill Spitzak and others. +// Copyright 2021-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -129,8 +129,8 @@ GLContext Fl_WinAPI_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_X* i = Fl_X::i(window); HDC hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc; if (!hdc) { - hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc = GetDCEx(i->xid, 0, DCX_CACHE); - fl_save_dc(i->xid, hdc); + hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc = GetDCEx((HWND)i->xid, 0, DCX_CACHE); + fl_save_dc((HWND)i->xid, hdc); SetPixelFormat(hdc, ((Fl_WinAPI_Gl_Choice*)g)->pixelformat, (PIXELFORMATDESCRIPTOR*)(&((Fl_WinAPI_Gl_Choice*)g)->pfd)); # if USE_COLORMAP if (fl_palette) SelectPalette(hdc, fl_palette, FALSE); @@ -139,7 +139,7 @@ GLContext Fl_WinAPI_Gl_Window_Driver::create_gl_context(Fl_Window* window, const GLContext context = layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc); if (context) { if (context_list && nContext) - wglShareLists(context_list[0], context); + wglShareLists((HGLRC)context_list[0], (HGLRC)context); add_context(context); } return context; @@ -150,7 +150,7 @@ void Fl_WinAPI_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) if (context != cached_context || w != cached_window) { cached_context = context; cached_window = w; - wglMakeCurrent(Fl_WinAPI_Window_Driver::driver(w)->private_dc, context); + wglMakeCurrent(Fl_WinAPI_Window_Driver::driver(w)->private_dc, (HGLRC)context); } } @@ -160,7 +160,7 @@ void Fl_WinAPI_Gl_Window_Driver::delete_gl_context(GLContext context) { cached_window = 0; wglMakeCurrent(0, 0); } - wglDeleteContext(context); + wglDeleteContext((HGLRC)context); del_context(context); } @@ -368,4 +368,6 @@ void Fl_WinAPI_Gl_Window_Driver::get_list(Fl_Font_Descriptor *fd, int r) { } +FL_EXPORT HGLRC fl_win32_glcontext(GLContext rc) { return (HGLRC)rc; } + #endif // HAVE_GL diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx index be9dac6bd..92f34b9ce 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx @@ -450,7 +450,7 @@ Fl_RGB_Image *Fl_WinAPI_Screen_Driver::read_win_rectangle_unscaled(int X, int Y, void Fl_WinAPI_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &height) { BITMAP bitmap; - if ( GetObject(off, sizeof(BITMAP), &bitmap) ) { + if ( GetObject((HBITMAP)off, sizeof(BITMAP), &bitmap) ) { width = bitmap.bmWidth; height = bitmap.bmHeight; } diff --git a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx index 459143dad..5f8c40d8d 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx @@ -317,7 +317,7 @@ void Fl_WinAPI_Window_Driver::flush_double() for an Fl_Double_Window. */ HDC sgc = fl_gc; - fl_gc = fl_makeDC(other_xid); + fl_gc = fl_makeDC((HBITMAP)other_xid); int savedc = SaveDC(fl_gc); fl_graphics_driver->gc(fl_gc); fl_graphics_driver->restore_clip(); // duplicate clip region into new gc @@ -462,7 +462,7 @@ void Fl_WinAPI_Window_Driver::hide() { int count = 0; Fl_Window *win, **doit = NULL; for (win = Fl::first_window(); win && ip; win = Fl::next_window(win)) { - if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == ip->xid) { + if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == (HWND)ip->xid) { count++; } } @@ -470,7 +470,7 @@ void Fl_WinAPI_Window_Driver::hide() { doit = new Fl_Window*[count]; count = 0; for (win = Fl::first_window(); win && ip; win = Fl::next_window(win)) { - if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == ip->xid) { + if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == (HWND)ip->xid) { doit[count++] = win; } } @@ -485,14 +485,14 @@ void Fl_WinAPI_Window_Driver::hide() { // icons(NULL, 0); // free_icons() is called by the Fl_Window destructor // this little trick keeps the current clipboard alive, even if we are about // to destroy the window that owns the selection. - if (GetClipboardOwner()==ip->xid) + if (GetClipboardOwner() == (HWND)ip->xid) fl_update_clipboard(); // Make sure we unlink this window from the clipboard chain - fl_clipboard_notify_retarget(ip->xid); + fl_clipboard_notify_retarget((HWND)ip->xid); // Send a message to myself so that I'll get out of the event loop... - PostMessage(ip->xid, WM_APP, 0, 0); - if (private_dc) fl_release_dc(ip->xid, private_dc); - if (ip->xid == fl_window && fl_graphics_driver->gc()) { + PostMessage((HWND)ip->xid, WM_APP, 0, 0); + if (private_dc) fl_release_dc((HWND)ip->xid, private_dc); + if ((HWND)ip->xid == fl_window && fl_graphics_driver->gc()) { fl_release_dc(fl_window, (HDC)fl_graphics_driver->gc()); fl_window = (HWND)-1; fl_graphics_driver->gc(0); @@ -505,11 +505,11 @@ void Fl_WinAPI_Window_Driver::hide() { // this little trickery seems to avoid the popup window stacking problem HWND p = GetForegroundWindow(); - if (p==GetParent(ip->xid)) { - ShowWindow(ip->xid, SW_HIDE); + if (p==GetParent((HWND)ip->xid)) { + ShowWindow((HWND)ip->xid, SW_HIDE); ShowWindow(p, SW_SHOWNA); } - DestroyWindow(ip->xid); + DestroyWindow((HWND)ip->xid); // end of fix for STR#3079 if (count) { int ii; @@ -541,7 +541,7 @@ void Fl_WinAPI_Window_Driver::unmap() { #if !defined(FL_DOXYGEN) // FIXME - silence Doxygen warning void Fl_WinAPI_Window_Driver::make_fullscreen(int X, int Y, int W, int H) { - Window xid = fl_xid(pWindow); + HWND xid = fl_xid(pWindow); int top, bottom, left, right; int sx, sy, sw, sh; @@ -589,7 +589,7 @@ void Fl_WinAPI_Window_Driver::fullscreen_off(int X, int Y, int W, int H) { // Remove the xid temporarily so that Fl_WinAPI_Window_Driver::fake_X_wm() behaves like it // does in Fl_WinAPI_Window_Driver::makeWindow(). HWND xid = fl_xid(pWindow); - Fl_X::i(pWindow)->xid = NULL; + Fl_X::i(pWindow)->xid = 0; int wx, wy, bt, bx, by; switch (fake_X_wm(wx, wy, bt, bx, by)) { case 0: @@ -603,7 +603,7 @@ void Fl_WinAPI_Window_Driver::fullscreen_off(int X, int Y, int W, int H) { } break; } - Fl_X::i(pWindow)->xid = xid; + Fl_X::i(pWindow)->xid = (fl_uintptr_t)xid; // compute window position and size in scaled units float s = Fl::screen_driver()->scale(screen_num()); int scaledX = int(ceil(X*s)), scaledY= int(ceil(Y*s)), scaledW = int(ceil(W*s)), scaledH = int(ceil(H*s)); @@ -712,3 +712,13 @@ void Fl_WinAPI_Window_Driver::resize_after_screen_change(void *data) { const Fl_Image* Fl_WinAPI_Window_Driver::shape() { return shape_data_ ? shape_data_->shape_ : NULL; } + + +HWND fl_win32_xid(const Fl_Window *win) { + return (HWND)Fl_Window_Driver::xid(win); +} + + +Fl_Window *fl_win32_find(HWND xid) { + return Fl_Window_Driver::find((fl_uintptr_t)xid); +} diff --git a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx index 9a092756a..b85aadd39 100644 --- a/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Gl_Window_Driver.cxx @@ -1,7 +1,7 @@ // // Class Fl_X11_Gl_Window_Driver for the Fast Light Tool Kit (FLTK). // -// Copyright 2021 by Bill Spitzak and others. +// Copyright 2021-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -21,8 +21,6 @@ #include "../../Fl_Screen_Driver.H" #include "../../Fl_Window_Driver.H" #include "Fl_X11_Gl_Window_Driver.H" -#include "../Xlib/Fl_Font.H" -#include "../Xlib/Fl_Xlib_Graphics_Driver.H" # include <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 diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx index b8fdd20c1..87a91636c 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx @@ -17,11 +17,9 @@ #include <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; } diff --git a/src/drivers/X11/Fl_X11_Window_Driver.H b/src/drivers/X11/Fl_X11_Window_Driver.H index 84b11ad16..13c1cf900 100644 --- a/src/drivers/X11/Fl_X11_Window_Driver.H +++ b/src/drivers/X11/Fl_X11_Window_Driver.H @@ -26,6 +26,11 @@ #include "../../Fl_Window_Driver.H" #include <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); diff --git a/src/drivers/X11/Fl_X11_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Window_Driver.cxx index ed9dd8fcb..a5302904f 100644 --- a/src/drivers/X11/Fl_X11_Window_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Window_Driver.cxx @@ -18,9 +18,13 @@ #include <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,10 +430,16 @@ 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); delete ip; @@ -504,6 +552,15 @@ const Fl_Image* Fl_X11_Window_Driver::shape() { return shape_data_ ? shape_data_->shape_ : NULL; } +Fl_Window *fl_x11_find(Window xid) { + return Fl_Window_Driver::find((fl_uintptr_t)xid); +} + +Window fl_x11_xid(const Fl_Window *win) { + return (Window)Fl_Window_Driver::xid(win); +} + + #if USE_XFT Fl_X11_Window_Driver::type_for_resize_window_between_screens Fl_X11_Window_Driver::data_for_resize_window_between_screens_ = {0, false}; diff --git a/src/drivers/X11/fl_X11_platform_init.cxx b/src/drivers/X11/fl_X11_platform_init.cxx index 3bcf21370..b26dfa444 100644 --- a/src/drivers/X11/fl_X11_platform_init.cxx +++ b/src/drivers/X11/fl_X11_platform_init.cxx @@ -14,9 +14,14 @@ // https://www.fltk.org/bugs.php // +#include <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 } diff --git a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H index a0b0db171..e67447b4d 100644 --- a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H +++ b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H @@ -19,6 +19,9 @@ #include <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 diff --git a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx index f87ae55a2..e4bbe29ef 100644 --- a/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx @@ -19,16 +19,35 @@ #include <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 } diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H index 5440b53bd..cf2fcac58 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H @@ -76,7 +76,7 @@ protected: #endif virtual int height_unscaled(); virtual int descent_unscaled(); - virtual Region scale_clip(float f); + virtual Fl_Region scale_clip(float f); #if USE_XFT void drawUCS4(const void *str, int n, int x, int y); #endif diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx index 13a67f428..4c7b64a4c 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx @@ -38,6 +38,8 @@ int Fl_Xlib_Graphics_Driver::fl_overlay = 0; */ GC fl_gc = 0; +GC fl_x11_gc() { return fl_gc; } + Fl_Xlib_Graphics_Driver::Fl_Xlib_Graphics_Driver(void) { mask_bitmap_ = NULL; short_point = NULL; @@ -71,14 +73,14 @@ void Fl_Xlib_Graphics_Driver::scale(float f) { } void Fl_Xlib_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) { - XCopyArea(fl_display, pixmap, fl_window, gc_, srcx*scale(), srcy*scale(), w*scale(), h*scale(), (x+offset_x_)*scale(), (y+offset_y_)*scale()); + XCopyArea(fl_display, (Pixmap)pixmap, fl_window, gc_, srcx*scale(), srcy*scale(), w*scale(), h*scale(), (x+offset_x_)*scale(), (y+offset_y_)*scale()); } void Fl_Xlib_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H) { XRectangle R; R.x = X; R.y = Y; R.width = W; R.height = H; - XUnionRectWithRegion(&R, r, r); + XUnionRectWithRegion(&R, (Region)r, (Region)r); } void Fl_Xlib_Graphics_Driver::transformed_vertex0(float fx, float fy) { @@ -144,8 +146,8 @@ void Fl_Xlib_Graphics_Driver::font_name(int num, const char *name) { } -Region Fl_Xlib_Graphics_Driver::scale_clip(float f) { - Region r = rstack[rstackptr]; +Fl_Region Fl_Xlib_Graphics_Driver::scale_clip(float f) { + Region r = (Region)rstack[rstackptr]; if (r == 0 || (f == 1 && offset_x_ == 0 && offset_y_ == 0) ) return 0; Region r2 = XCreateRegion(); for (int i = 0; i < r->numRects; i++) { @@ -153,7 +155,7 @@ Region Fl_Xlib_Graphics_Driver::scale_clip(float f) { int y = floor(r->rects[i].y1 + offset_y_, f); int w = floor((r->rects[i].x2 + offset_x_) , f) - x; int h = floor((r->rects[i].y2 + offset_y_) , f) - y; - Region R = XRectangleRegion(x, y, w, h); + Region R = (Region)XRectangleRegion(x, y, w, h); XUnionRegion(R, r2, r2); ::XDestroyRegion(R); } diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx index 17711883e..3a4817b7f 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx @@ -720,7 +720,7 @@ void Fl_Xlib_Graphics_Driver::draw_unscaled(const char *str, int n, int x, int y else //if (draw_window != fl_window) XftDrawChange(draw_, draw_window = fl_window); - Region region = fl_clip_region(); + Region region = (Region)fl_clip_region(); if (!(region && XEmptyRegion(region))) { XftDrawSetClip(draw_, region); @@ -756,7 +756,7 @@ void Fl_Xlib_Graphics_Driver::drawUCS4(const void *str, int n, int x, int y) { else //if (draw_window != fl_window) XftDrawChange(draw_, draw_window = fl_window); - Region region = fl_clip_region(); + Region region = (Region)fl_clip_region(); if (region && XEmptyRegion(region)) return; XftDrawSetClip(draw_, region); @@ -1192,7 +1192,7 @@ static void fl_pango_layout_get_pixel_extents(PangoLayout *layout, int &dx, int void Fl_Xlib_Graphics_Driver::do_draw(int from_right, const char *str, int n, int x, int y) { if (!fl_display || n == 0) return; - Region region = clip_region(); + Region region = (Region)clip_region(); if (region && XEmptyRegion(region)) return; if (!playout_) context(); diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx index d57e5b031..ba098c309 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx @@ -718,8 +718,8 @@ void Fl_Xlib_Graphics_Driver::cache(Fl_RGB_Image *img) { if (depth == 1 || depth == 3) { surface = new Fl_Image_Surface(img->data_w(), img->data_h()); } else if (fl_can_do_alpha_blending()) { - Fl_Offscreen pixmap = XCreatePixmap(fl_display, RootWindow(fl_display, fl_screen), img->data_w(), img->data_h(), 32); - surface = new Fl_Image_Surface(img->data_w(), img->data_h(), 0, pixmap); + Pixmap pixmap = XCreatePixmap(fl_display, RootWindow(fl_display, fl_screen), img->data_w(), img->data_h(), 32); + surface = new Fl_Image_Surface(img->data_w(), img->data_h(), 0, (Fl_Offscreen)pixmap); depth |= FL_IMAGE_WITH_ALPHA; } else { *Fl_Graphics_Driver::id(img) = 0; @@ -806,14 +806,14 @@ int Fl_Xlib_Graphics_Driver::scale_and_render_pixmap(Fl_Offscreen pixmap, int de static XRenderPictFormat *fmt24 = XRenderFindStandardFormat(fl_display, PictStandardRGB24); static XRenderPictFormat *fmt32 = XRenderFindStandardFormat(fl_display, PictStandardARGB32); static XRenderPictFormat *dstfmt = XRenderFindVisualFormat(fl_display, fl_visual->visual); - Picture src = XRenderCreatePicture(fl_display, pixmap, has_alpha ?fmt32:fmt24, 0, &srcattr); + Picture src = XRenderCreatePicture(fl_display, (Pixmap)pixmap, has_alpha ?fmt32:fmt24, 0, &srcattr); Picture dst = XRenderCreatePicture(fl_display, fl_window, dstfmt, 0, &srcattr); if (!src || !dst) { fprintf(stderr, "Failed to create Render pictures (%lu %lu)\n", src, dst); return 0; } Fl_Region r = scale_clip(scale()); - const Fl_Region clipr = clip_region(); + const Region clipr = (Region)clip_region(); if (clipr) XRenderSetPictureClipRegion(fl_display, dst, clipr); unscale_clip(r); @@ -849,7 +849,7 @@ int Fl_Xlib_Graphics_Driver::scale_and_render_pixmap(Fl_Offscreen pixmap, int de void Fl_Xlib_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_uintptr_t &mask_) { if (id_) { - XFreePixmap(fl_display, (Fl_Offscreen)id_); + XFreePixmap(fl_display, (Pixmap)id_); id_ = 0; } } @@ -882,8 +882,8 @@ void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, in // be done in a single Xlib call for a multi-rectangle clip region. Thus, we // process each rectangle of the intersection between the clip region and XYWH. // See also STR #3206. - Region r = XRectangleRegion(X,Y,W,H); - XIntersectRegion(r, clip_region(), r); + Region r = (Region)XRectangleRegion(X,Y,W,H); + XIntersectRegion(r, (Region)clip_region(), r); int X1, Y1, W1, H1; for (int i = 0; i < r->numRects; i++) { X1 = r->rects[i].x1; @@ -929,5 +929,5 @@ void Fl_Xlib_Graphics_Driver::cache(Fl_Pixmap *pxm) { } void Fl_Xlib_Graphics_Driver::uncache_pixmap(fl_uintptr_t offscreen) { - XFreePixmap(fl_display, (Fl_Offscreen)offscreen); + XFreePixmap(fl_display, (Pixmap)offscreen); } diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx index a72fe9d8b..ea24eba34 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx @@ -194,7 +194,7 @@ int Fl_Xlib_Graphics_Driver::clip_rect(int &x, int &y, int &w, int &h) { Fl_Region Fl_Xlib_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { XRectangle R; - Fl_Region r = XCreateRegion(); // create an empty region + Region r = XCreateRegion(); // create an empty region if (clip_rect(x, y, w, h)) // outside valid coordinate space return r; // empty region R.x = x; R.y = y; R.width = w; R.height = h; @@ -203,7 +203,7 @@ Fl_Region Fl_Xlib_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) } void Fl_Xlib_Graphics_Driver::XDestroyRegion(Fl_Region r) { - ::XDestroyRegion(r); + ::XDestroyRegion((Region)r); } // --- line and polygon drawing @@ -312,12 +312,12 @@ void Fl_Xlib_Graphics_Driver::draw_clipped_line(int x1, int y1, int x2, int y2) // --- clipping void Fl_Xlib_Graphics_Driver::push_clip(int x, int y, int w, int h) { - Fl_Region r; + Region r; if (w > 0 && h > 0) { - r = XRectangleRegion(x, y, w, h); // does X coordinate clipping - Fl_Region current = rstack[rstackptr]; + r = (Region)XRectangleRegion(x, y, w, h); // does X coordinate clipping + Region current = (Region)rstack[rstackptr]; if (current) { - Fl_Region temp = XCreateRegion(); + Region temp = XCreateRegion(); XIntersectRegion(current, r, temp); XDestroyRegion(r); r = temp; @@ -337,7 +337,7 @@ int Fl_Xlib_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y W = H = 0; return 2; } - Fl_Region r = rstack[rstackptr]; + Region r = (Region)rstack[rstackptr]; if (!r) { // no clipping region if (X != x || Y != y || W != w || H != h) // pre-clipped return 1; // partially outside, region differs @@ -352,8 +352,8 @@ int Fl_Xlib_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y default: // partial: break; } - Fl_Region rr = XRectangleRegion(X, Y, W, H); - Fl_Region temp = XCreateRegion(); + Region rr = (Region)XRectangleRegion(X, Y, W, H); + Region temp = XCreateRegion(); XIntersectRegion(r, rr, temp); XRectangle rect; XClipBox(temp, &rect); @@ -365,7 +365,7 @@ int Fl_Xlib_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y int Fl_Xlib_Graphics_Driver::not_clipped(int x, int y, int w, int h) { if (x+w <= 0 || y+h <= 0) return 0; - Fl_Region r = rstack[rstackptr]; + Region r = (Region)rstack[rstackptr]; if (!r) return 1; // get rid of coordinates outside the 16-bit range the X calls take. if (clip_rect(x,y,w,h)) return 0; // clipped @@ -375,10 +375,10 @@ int Fl_Xlib_Graphics_Driver::not_clipped(int x, int y, int w, int h) { void Fl_Xlib_Graphics_Driver::restore_clip() { fl_clip_state_number++; if (gc_) { - Region r = rstack[rstackptr]; + Region r = (Region)rstack[rstackptr]; if (r) { - Region r2 = scale_clip(scale()); - XSetRegion(fl_display, gc_, rstack[rstackptr]); + Region r2 = (Region)scale_clip(scale()); + XSetRegion(fl_display, gc_, (Region)rstack[rstackptr]); unscale_clip(r2); } else XSetClipMask(fl_display, gc_, 0); diff --git a/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H b/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H index b7cb48010..3f8ecda7f 100644 --- a/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H +++ b/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H @@ -18,6 +18,9 @@ #define FL_XLIB_IMAGE_SURFACE_DRIVER_H #include <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 diff --git a/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx index e1a33c746..240ced649 100644 --- a/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx @@ -14,28 +14,47 @@ // https://www.fltk.org/bugs.php // -#include "Fl_Xlib_Graphics_Driver.H" +#include <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() diff --git a/src/filename_isdir.cxx b/src/filename_isdir.cxx index 47e1de58f..f19e464b6 100644 --- a/src/filename_isdir.cxx +++ b/src/filename_isdir.cxx @@ -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. diff --git a/src/fl_read_image.cxx b/src/fl_read_image.cxx index 129aeaa54..0d5f7ec5c 100644 --- a/src/fl_read_image.cxx +++ b/src/fl_read_image.cxx @@ -40,7 +40,7 @@ uchar *fl_read_image(uchar *p, int X, int Y, int w, int h, int alpha) { uchar *image_data = NULL; Fl_RGB_Image *img; - if (fl_find(fl_window) == 0) { // read from off_screen buffer + if (Fl_Surface_Device::surface()->as_image_surface()) { // read from off_screen buffer img = Fl::screen_driver()->read_win_rectangle(X, Y, w, h, 0); if (!img) { return NULL; diff --git a/src/fl_utf8.cxx b/src/fl_utf8.cxx index efb7fa5d5..b7801207e 100644 --- a/src/fl_utf8.cxx +++ b/src/fl_utf8.cxx @@ -23,6 +23,7 @@ #include <FL/fl_utf8.h> #include "utf8_internal.h" +#include <sys/stat.h> #include <string.h> #include <stdlib.h> |
