diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | src/drivers/Base/Fl_Base_Pen_Events.H | 116 | ||||
| -rw-r--r-- | src/drivers/Base/Fl_Base_Pen_Events.cxx | 148 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Pen_Events.mm | 175 | ||||
| -rw-r--r-- | src/drivers/Stubs/Fl_Stubs_Pen_Events.cxx | 73 | ||||
| -rw-r--r-- | src/drivers/Wayland/fl_wayland_platform_init.cxx | 9 | ||||
| -rw-r--r-- | src/drivers/WinAPI/fl_WinAPI_platform_init.cxx | 8 | ||||
| -rw-r--r-- | src/drivers/X11/fl_X11_platform_init.cxx | 8 |
8 files changed, 327 insertions, 221 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 64c936412..62e731337 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -241,7 +241,7 @@ if(FLTK_USE_X11 AND NOT FLTK_USE_WAYLAND) drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx drivers/X11/fl_X11_platform_init.cxx - drivers/Stubs/Fl_Stubs_Pen_Events.cxx + drivers/Base/Fl_Base_Pen_Events.cxx Fl_x.cxx fl_dnd_x.cxx Fl_Native_File_Chooser_FLTK.cxx @@ -291,6 +291,7 @@ if(FLTK_USE_X11 AND NOT FLTK_USE_WAYLAND) drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H drivers/Xlib/Fl_Xlib_Image_Surface_Driver.H drivers/Unix/Fl_Unix_System_Driver.H + drivers/Base/Fl_Base_Pen_Events.H ) if(FLTK_USE_CAIRO) set(DRIVER_HEADER_FILES ${DRIVER_HEADER_FILES} @@ -318,7 +319,7 @@ elseif(FLTK_USE_WAYLAND) drivers/Wayland/fl_wayland_clipboard_dnd.cxx drivers/Wayland/fl_wayland_platform_init.cxx drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx - drivers/Stubs/Fl_Stubs_Pen_Events.cxx + drivers/Base/Fl_Base_Pen_Events.cxx Fl_Native_File_Chooser_FLTK.cxx Fl_Native_File_Chooser_GTK.cxx ) @@ -350,6 +351,7 @@ elseif(FLTK_USE_WAYLAND) drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.H drivers/Wayland/Fl_Wayland_Image_Surface_Driver.H drivers/Unix/Fl_Unix_System_Driver.H + drivers/Base/Fl_Base_Pen_Events.H ) elseif(APPLE) @@ -371,6 +373,7 @@ elseif(APPLE) drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx drivers/Posix/Fl_Posix_System_Driver.cxx drivers/Darwin/Fl_Darwin_System_Driver.cxx + drivers/Base/Fl_Base_Pen_Events.cxx Fl_get_key_mac.cxx drivers/Darwin/fl_macOS_platform_init.cxx ) @@ -384,6 +387,7 @@ elseif(APPLE) drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.H drivers/Quartz/Fl_Font.H drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H + drivers/Base/Fl_Base_Pen_Events.H ) else() @@ -405,7 +409,7 @@ else() drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx - drivers/Stubs/Fl_Stubs_Pen_Events.cxx + drivers/Base/Fl_Base_Pen_Events.cxx Fl_win32.cxx fl_dnd_win32.cxx Fl_Native_File_Chooser_WIN32.cxx @@ -420,6 +424,7 @@ else() drivers/GDI/Fl_Font.H drivers/GDI/Fl_GDI_Copy_Surface_Driver.H drivers/GDI/Fl_GDI_Image_Surface_Driver.H + drivers/Base/Fl_Base_Pen_Events.H ) endif(FLTK_USE_X11 AND NOT FLTK_USE_WAYLAND) diff --git a/src/drivers/Base/Fl_Base_Pen_Events.H b/src/drivers/Base/Fl_Base_Pen_Events.H new file mode 100644 index 000000000..ba4882d0b --- /dev/null +++ b/src/drivers/Base/Fl_Base_Pen_Events.H @@ -0,0 +1,116 @@ +// +// Definition of default Pen/Tablet event driver. +// +// Copyright 2025 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 +// + + +#ifndef FL_BASE_PEN_EVENTS_H +#define FL_BASE_PEN_EVENTS_H + +#include <config.h> +#include <FL/core/pen_events.H> +#include <FL/Fl.H> + +#include <map> +#include <memory> + + +class Fl_Widget; + +namespace Fl { + +namespace Pen { + +/* Pen event data storage. + A second storage may be useful if the driver needs to collect pen data + from multiple events, or if one system event can send multiple FLTK events. +*/ +typedef struct EventData { + double x { 0.0 }; + double y { 0.0 }; + double rx { 0.0 }; + double ry { 0.0 }; + double tilt_x { 0.0 }; + double tilt_y { 0.0 }; + double pressure { 1.0 }; + double proximity { 0.0 }; + double barrel_pressure { 0.0 }; + double twist { 0.0 }; + int pen_id { 0 }; + Fl::Pen::State state { (Fl::Pen::State)0 }; + Fl::Pen::State trigger { (Fl::Pen::State)0 }; +} EventData; + +extern EventData e; + + +/* + Widgets and windows must subscribe to pen events. This is to reduce the amount + of events sent into the widget hierarchy. + + Usually there is a pretty small number of subscribers, so looping through the + subscriber list should not be an issue. + + All subscribers track their widget. If a widget is deleted while subscribed, + including during event handling, the driver will remove the subscription. + There is no need to explicitly unsubscribe. + */ +class Subscriber : public Fl_Widget_Tracker { +public: + Subscriber(Fl_Widget *w) : Fl_Widget_Tracker(w) { } +}; + + +/* + Manage a list of subscribers. + */ +class SubscriberList : public std::map<Fl_Widget*, std::shared_ptr<Subscriber>> { +public: + SubscriberList() = default; + void cleanup(); + std::shared_ptr<Subscriber> add(Fl_Widget *w); + void remove(Fl_Widget *w); +}; + +extern SubscriberList subscriber_list_; +extern std::shared_ptr<Subscriber> pushed_; +extern std::shared_ptr<Subscriber> below_pen_; + +/* The base driver for calls by apps into the pen system. + + Most traffic is generated by system events. The data is then converted + for the FLTK API and stored in Fl::Pen::e. The Pen interface then sends + the appropriate FLTK events to the subscribers. + + This driver class manages calls from the app into FLTK, including subscriber + management and queries for driver an pen abilities. +*/ +class Driver { +public: + Driver() = default; + virtual void subscribe(Fl_Widget* widget); + virtual void unsubscribe(Fl_Widget* widget); + virtual void release(); + virtual Trait traits(); + virtual Trait pen_traits(int pen_id); +}; + +extern Driver& driver; + +} // namespace Pen + +} // namespace Fl + + +#endif // FL_BASE_PEN_EVENTS_H diff --git a/src/drivers/Base/Fl_Base_Pen_Events.cxx b/src/drivers/Base/Fl_Base_Pen_Events.cxx new file mode 100644 index 000000000..f4ebbd8ad --- /dev/null +++ b/src/drivers/Base/Fl_Base_Pen_Events.cxx @@ -0,0 +1,148 @@ +// +// Implementation of default Pen/Tablet event driver. +// +// Copyright 2025 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 +// + +#include "src/drivers/Base/Fl_Base_Pen_Events.H" + + +class Fl_Widget; + + +namespace Fl { + +namespace Pen { + +EventData e; +SubscriberList subscriber_list_; +std::shared_ptr<Subscriber> pushed_; +std::shared_ptr<Subscriber> below_pen_; + +} // namespace Pen + +} // namespace Fl + + +using namespace Fl::Pen; + + +// ---- SubscriberList implementation ------------------------------------------ + +/* Remove subscribers that have a nullptr as a widget */ +void Fl::Pen::SubscriberList::cleanup() { + for (auto it = begin(); it != end(); ) { + if (!it->second->widget()) { + it = erase(it); + } else { + ++it; + } + } +} + +/* Add a new subscriber, or return an existing one. */ +std::shared_ptr<Subscriber> Fl::Pen::SubscriberList::add(Fl_Widget *w) { + cleanup(); + auto it = find(w); + if (it == end()) { + auto sub = std::make_shared<Subscriber>(w); + insert(std::make_pair(w, sub)); + return sub; + } else { + return it->second; + } +} + +/* Remove a subscriber from the list. */ +void Fl::Pen::SubscriberList::remove(Fl_Widget *w) { + auto it = find(w); + if (it != end()) { + it->second->clear(); + erase(it); + } +} + +// ---- Driver implementation -------------------------------------------------- +// Override the methods below to handle subscriptions and queries by user apps. + +void Fl::Pen::Driver::subscribe(Fl_Widget* widget) { + if (widget == nullptr) return; + subscriber_list_.add(widget); +} + +void Fl::Pen::Driver::unsubscribe(Fl_Widget* widget) { + if (widget == nullptr) return; + subscriber_list_.remove(widget); +} + +void Fl::Pen::Driver::release() { + pushed_ = nullptr; + below_pen_ = nullptr; +} + +Trait Fl::Pen::Driver::traits() { + return Trait::NONE; +} + +Trait Fl::Pen::Driver::pen_traits(int pen_id) { + (void)pen_id; + return Trait::NONE; +} + +// ---- Fl::Pen API ------------------------------------------------------------ + +void Fl::Pen::subscribe(Fl_Widget* widget) { + driver.subscribe(widget); +} + +void Fl::Pen::unsubscribe(Fl_Widget* widget) { + driver.unsubscribe(widget); +} + +void Fl::Pen::release() { + driver.release(); +} + +Trait Fl::Pen::driver_traits() { + return driver.traits(); +} + +Trait Fl::Pen::pen_traits(int pen_id) { + return driver.pen_traits(pen_id); +} + +double Fl::Pen::event_x() { return e.x; } + +double Fl::Pen::event_y() { return e.y; } + +double Fl::Pen::event_x_root() { return e.rx; } + +double Fl::Pen::event_y_root() { return e.ry; } + +int Fl::Pen::event_pen_id() { return e.pen_id; } + +double Fl::Pen::event_pressure() { return e.pressure; } + +double Fl::Pen::event_barrel_pressure() { return e.barrel_pressure; } + +double Fl::Pen::event_tilt_x() { return e.tilt_x; } + +double Fl::Pen::event_tilt_y() { return e.tilt_y; } + +double Fl::Pen::event_twist() { return e.twist; } + +double Fl::Pen::event_proximity() { return e.proximity; } + +State Fl::Pen::event_state() { return e.state; } + +State Fl::Pen::event_trigger() { return e.trigger; } diff --git a/src/drivers/Cocoa/Fl_Cocoa_Pen_Events.mm b/src/drivers/Cocoa/Fl_Cocoa_Pen_Events.mm index c2840a41e..1ebbd11eb 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Pen_Events.mm +++ b/src/drivers/Cocoa/Fl_Cocoa_Pen_Events.mm @@ -14,81 +14,17 @@ // https://www.fltk.org/bugs.php // +#include "src/drivers/Base/Fl_Base_Pen_Events.H" -#include <config.h> -#include <FL/platform.H> -#include <FL/core/pen_events.H> #include <FL/Fl.H> #include <FL/Fl_Window.H> -#include <FL/Fl_Tooltip.H> -#include <FL/Fl_Widget_Tracker.H> #include "../../Fl_Screen_Driver.H" #import <Cocoa/Cocoa.h> -#include <map> -#include <memory> extern Fl_Window *fl_xmousewin; -/* - Widgets and windows must subscribe to pen events. This is to reduce the amount - of events sent into the widget hierarchy. - - Usually there is a pretty small number of subscribers, so looping through the - subscriber list should not be an issue. - - All subscribers track their widget. If a widget is deleted while subscribed, - including during event handling, the driver will remove the subscription. - There is no need to explicitly unsubscribe. - */ -class Subscriber : public Fl_Widget_Tracker { -public: - Subscriber(Fl_Widget *w) : Fl_Widget_Tracker(w) { } -}; - - -/* - Manage a list of subscribers. - */ -class SubscriberList : public std::map<Fl_Widget*, std::shared_ptr<Subscriber>> { -public: - SubscriberList() = default; - /* Remove subscribers that have a nullptr as a widget */ - void cleanup() { - for (auto it = begin(); it != end(); ) { - if (!it->second->widget()) { - it = erase(it); - } else { - ++it; - } - } - } - /* Add a new subscriber, or return an existing one. */ - std::shared_ptr<Subscriber> add(Fl_Widget *w) { - cleanup(); - auto it = find(w); - if (it == end()) { - auto sub = std::make_shared<Subscriber>(w); - insert(std::make_pair(w, sub)); - return sub; - } else { - return it->second; - } - } - /* Remove a subscriber from the list. */ - void remove(Fl_Widget *w) { - auto it = find(w); - if (it != end()) { - it->second->clear(); - erase(it); - } - } -}; - -static SubscriberList subscriber_list_; -static std::shared_ptr<Subscriber> pushed_; -static std::shared_ptr<Subscriber> below_pen_; static NSPointingDeviceType device_type_ { NSPointingDeviceTypePen }; // The trait list keeps track of traits for every pen ID that appears while @@ -109,103 +45,53 @@ static Fl::Pen::Trait driver_traits_ { // Notably missing: PROXIMITY }; -struct EventData { - double x { 0.0 }; - double y { 0.0 }; - double rx { 0.0 }; - double ry { 0.0 }; - double tilt_x { 0.0 }; - double tilt_y { 0.0 }; - double pressure { 1.0 }; - double barrel_pressure { 0.0 }; - double twist { 0.0 }; - int pen_id { 0 }; - Fl::Pen::State state { (Fl::Pen::State)0 }; - Fl::Pen::State trigger { (Fl::Pen::State)0 }; -}; - // Temporary storage of event data for the driver; -static struct EventData ev; +static Fl::Pen::EventData ev; namespace Fl { namespace Private { + // Global mouse position at mouse down event extern int e_x_down; extern int e_y_down; + }; // namespace Private namespace Pen { -// The event data that is made available to the user during event handling -struct EventData e; -} // namespace Pen - -} // namespace Fl - -using namespace Fl::Pen; - - -// Return a bit for everything that AppKit could return. -Trait Fl::Pen::driver_traits() { - return driver_traits_; -} - -Trait Fl::Pen::pen_traits(int pen_id) { - auto it = trait_list_.find(pen_id); - if (pen_id == 0) - return current_pen_trait_; - if (it == trait_list_.end()) { - return Trait::DRIVER_AVAILABLE; - } else { - return it->second; +class Cocoa_Driver : public Driver { +public: + Cocoa_Driver() = default; + //virtual void subscribe(Fl_Widget* widget) override; + //virtual void unsubscribe(Fl_Widget* widget) override; + //virtual void release() override; + virtual Trait traits() override { return driver_traits_; } + virtual Trait pen_traits(int pen_id) override { + auto it = trait_list_.find(pen_id); + if (pen_id == 0) + return current_pen_trait_; + if (it == trait_list_.end()) { + return Trait::DRIVER_AVAILABLE; + } else { + return it->second; + } } -} - -void Fl::Pen::subscribe(Fl_Widget* widget) { - if (widget == nullptr) return; - subscriber_list_.add(widget); -} - -void Fl::Pen::unsubscribe(Fl_Widget* widget) { - if (widget == nullptr) return; - subscriber_list_.remove(widget); -} - -void Fl::Pen::release() { - pushed_ = nullptr; - below_pen_ = nullptr; -} - -double Fl::Pen::event_x() { return e.x; } - -double Fl::Pen::event_y() { return e.y; } - -double Fl::Pen::event_x_root() { return e.rx; } - -double Fl::Pen::event_y_root() { return e.ry; } - -int Fl::Pen::event_pen_id() { return e.pen_id; } - -double Fl::Pen::event_pressure() { return e.pressure; } - -double Fl::Pen::event_barrel_pressure() { return e.barrel_pressure; } +}; -double Fl::Pen::event_tilt_x() { return e.tilt_x; } +Cocoa_Driver cocoa_driver; +Driver& driver { cocoa_driver }; -double Fl::Pen::event_tilt_y() { return e.tilt_y; } +} // namespace Pen -double Fl::Pen::event_twist() { return e.twist; } +} // namespace Fl -// Not supported in AppKit NSEvent -double Fl::Pen::event_proximity() { return 0.0; } -State Fl::Pen::event_state() { return e.state; } +using namespace Fl::Pen; -State Fl::Pen::event_trigger() { return e.trigger; } -/** +/* Copy the event state. */ static void copy_state() { @@ -218,7 +104,7 @@ static void copy_state() { Fl::e_y_root = (int)ev.ry; } -/** +/* Offset coordinates for subwindows and subsubwindows. */ static void offset_subwindow_event(Fl_Widget *w, double &x, double &y) { @@ -321,8 +207,7 @@ static State button_to_trigger(NSInteger button, bool down) { /* Handle events coming from Cocoa. - TODO: clickCount: store in Fl::event_clicks() - capabilityMask is useless, because it is vendor defined + `capabilityMask` is useless, because it is vendor defined If a modal window is open, AppKit will send window specific events only there. */ bool fl_cocoa_tablet_handler(NSEvent *event, Fl_Window *eventWindow) { @@ -477,7 +362,7 @@ bool fl_cocoa_tablet_handler(NSEvent *event, Fl_Window *eventWindow) { return 0; } } else { - // Anything to do here? + // Proximity events were handled earlier. } if (!receiver) diff --git a/src/drivers/Stubs/Fl_Stubs_Pen_Events.cxx b/src/drivers/Stubs/Fl_Stubs_Pen_Events.cxx deleted file mode 100644 index 6b3512023..000000000 --- a/src/drivers/Stubs/Fl_Stubs_Pen_Events.cxx +++ /dev/null @@ -1,73 +0,0 @@ -// -// Definition of default Pen/Tablet event driver. -// -// Copyright 2025 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 -// - - -#include <config.h> -#include <FL/platform.H> -#include <FL/core/pen_events.H> -#include <FL/Fl.H> - -class Fl_Widget; - -namespace Fl { - -namespace Pen { - -// double e_pressure_; - -} // namespace Pen - -} // namespace Fl - - -using namespace Fl::Pen; - - -Trait Fl::Pen::driver_traits() { return Trait::NONE; } - -Trait Fl::Pen::pen_traits(int pen_id) { return Trait::NONE; } - -void Fl::Pen::subscribe(Fl_Widget* widget) { } - -void Fl::Pen::unsubscribe(Fl_Widget* widget) { } - -void Fl::Pen::release() { } - -double Fl::Pen::event_x() { return 0.0; } - -double Fl::Pen::event_y() { return 0.0; } - -double Fl::Pen::event_x_root() { return 0.0; } - -double Fl::Pen::event_y_root() { return 0.0; } - -int Fl::Pen::event_pen_id() { return 0; } - -double Fl::Pen::event_pressure() { return 1.0; } - -double Fl::Pen::event_barrel_pressure() { return 0.0; } - -double Fl::Pen::event_tilt_x() { return 0.0; } - -double Fl::Pen::event_tilt_y() { return 0.0; } - -double Fl::Pen::event_twist() { return 0.0; } - -double Fl::Pen::event_proximity() { return 0.0; } - -State Fl::Pen::event_state() { return Fl::Pen::State::NONE; } - -State Fl::Pen::event_trigger() { return Fl::Pen::State::NONE; } diff --git a/src/drivers/Wayland/fl_wayland_platform_init.cxx b/src/drivers/Wayland/fl_wayland_platform_init.cxx index bd6089f96..70c44348e 100644 --- a/src/drivers/Wayland/fl_wayland_platform_init.cxx +++ b/src/drivers/Wayland/fl_wayland_platform_init.cxx @@ -21,6 +21,7 @@ #include "../Unix/Fl_Unix_System_Driver.H" #include "Fl_Wayland_Window_Driver.H" #include "Fl_Wayland_Image_Surface_Driver.H" +#include "../Base/Fl_Base_Pen_Events.H" #ifdef FLTK_USE_X11 # include "../Xlib/Fl_Xlib_Copy_Surface_Driver.H" # include "../Cairo/Fl_X11_Cairo_Graphics_Driver.H" @@ -143,3 +144,11 @@ Fl_Image_Surface_Driver *Fl_Image_Surface_Driver::newImageSurfaceDriver(int w, i #endif return new Fl_Wayland_Image_Surface_Driver(w, h, high_res, off); } + +namespace FL { +namespace Pen{ +Driver default_driver; +Driver& driver { default_driver }; +} // namespace Pen +} // namespace FL + diff --git a/src/drivers/WinAPI/fl_WinAPI_platform_init.cxx b/src/drivers/WinAPI/fl_WinAPI_platform_init.cxx index fa6b41d24..49c7436c3 100644 --- a/src/drivers/WinAPI/fl_WinAPI_platform_init.cxx +++ b/src/drivers/WinAPI/fl_WinAPI_platform_init.cxx @@ -21,6 +21,7 @@ #include "Fl_WinAPI_System_Driver.H" #include "Fl_WinAPI_Window_Driver.H" #include "../GDI/Fl_GDI_Image_Surface_Driver.H" +#include "../Base/Fl_Base_Pen_Events.H" Fl_Copy_Surface_Driver *Fl_Copy_Surface_Driver::newCopySurfaceDriver(int w, int h) @@ -81,3 +82,10 @@ Fl_Image_Surface_Driver *Fl_Image_Surface_Driver::newImageSurfaceDriver(int w, i { return new Fl_GDI_Image_Surface_Driver(w, h, high_res, off); } + +namespace FL { +namespace Pen{ +Driver default_driver; +Driver& driver { default_driver }; +} // namespace Pen +} // namespace FL diff --git a/src/drivers/X11/fl_X11_platform_init.cxx b/src/drivers/X11/fl_X11_platform_init.cxx index e9d40dbc3..a6b0ad82b 100644 --- a/src/drivers/X11/fl_X11_platform_init.cxx +++ b/src/drivers/X11/fl_X11_platform_init.cxx @@ -26,6 +26,7 @@ #include "../Unix/Fl_Unix_System_Driver.H" #include "Fl_X11_Window_Driver.H" #include "../Xlib/Fl_Xlib_Image_Surface_Driver.H" +#include "../Base/Fl_Base_Pen_Events.H" Fl_Copy_Surface_Driver *Fl_Copy_Surface_Driver::newCopySurfaceDriver(int w, int h) @@ -73,3 +74,10 @@ Fl_Image_Surface_Driver *Fl_Image_Surface_Driver::newImageSurfaceDriver(int w, i { return new Fl_Xlib_Image_Surface_Driver(w, h, high_res, off); } + +namespace FL { +namespace Pen{ +Driver default_driver; +Driver& driver { default_driver }; +} // namespace Pen +} // namespace FL |
