diff options
| author | maxim nikonov <maxim.nikonov@hqo.co> | 2026-02-05 21:32:25 +0500 |
|---|---|---|
| committer | maxim nikonov <maxim.nikonov@hqo.co> | 2026-02-05 21:32:25 +0500 |
| commit | dc39575fb3ef90e5a2689babe7fb335cd88f6727 (patch) | |
| tree | 24f6cef8f2b558ae6f1f812c75be0c09a53fe417 /src/drivers | |
| parent | 7d3793ce1d8cb26e7608bf859beca21359cec6e9 (diff) | |
wip
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/Base/Fl_Base_Pen_Events.H | 85 | ||||
| -rw-r--r-- | src/drivers/Base/Fl_Base_Pen_Events.cxx | 188 | ||||
| -rw-r--r-- | src/drivers/Posix/Fl_Posix_System_Driver.cxx | 11 | ||||
| -rw-r--r-- | src/drivers/Unix/Fl_Unix_System_Driver.cxx | 89 |
4 files changed, 224 insertions, 149 deletions
diff --git a/src/drivers/Base/Fl_Base_Pen_Events.H b/src/drivers/Base/Fl_Base_Pen_Events.H index ba4882d0b..2259c51aa 100644 --- a/src/drivers/Base/Fl_Base_Pen_Events.H +++ b/src/drivers/Base/Fl_Base_Pen_Events.H @@ -22,37 +22,32 @@ #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; +typedef struct Fl_Pen_EventData { + double x; + double y; + double rx; + double ry; + double tilt_x; + double tilt_y; + double pressure; + double proximity; + double barrel_pressure; + double twist; + int pen_id; + Fl_Pen_State state; + Fl_Pen_State trigger; +} Fl_Pen_EventData; + +extern Fl_Pen_EventData fl_pen_event_data; + +void fl_pen_event_data_init(Fl_Pen_EventData *d); /* @@ -66,51 +61,55 @@ extern EventData e; including during event handling, the driver will remove the subscription. There is no need to explicitly unsubscribe. */ -class Subscriber : public Fl_Widget_Tracker { +class Fl_Pen_Subscriber : public Fl_Widget_Tracker { public: - Subscriber(Fl_Widget *w) : Fl_Widget_Tracker(w) { } + Fl_Pen_Subscriber(Fl_Widget *w) : Fl_Widget_Tracker(w) { } }; /* - Manage a list of subscribers. + Manage a list of subscribers using a simple array. */ -class SubscriberList : public std::map<Fl_Widget*, std::shared_ptr<Subscriber>> { +class Fl_Pen_SubscriberList { + Fl_Pen_Subscriber **items_; + Fl_Widget **widgets_; + int count_; + int alloc_; public: - SubscriberList() = default; + Fl_Pen_SubscriberList(); + ~Fl_Pen_SubscriberList(); void cleanup(); - std::shared_ptr<Subscriber> add(Fl_Widget *w); + Fl_Pen_Subscriber *add(Fl_Widget *w); void remove(Fl_Widget *w); + Fl_Pen_Subscriber *find(Fl_Widget *w); + int count() const { return count_; } + Fl_Pen_Subscriber *get(int i) const { return (i >= 0 && i < count_) ? items_[i] : 0; } }; -extern SubscriberList subscriber_list_; -extern std::shared_ptr<Subscriber> pushed_; -extern std::shared_ptr<Subscriber> below_pen_; +extern Fl_Pen_SubscriberList fl_pen_subscriber_list; +extern Fl_Pen_Subscriber *fl_pen_pushed; +extern Fl_Pen_Subscriber *fl_pen_below; /* 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 + for the FLTK API and stored in fl_pen_event_data. 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 { +class Fl_Pen_Driver { public: - Driver() = default; + Fl_Pen_Driver() { } 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); + virtual Fl_Pen_Trait traits(); + virtual Fl_Pen_Trait pen_traits(int pen_id); }; -extern Driver& driver; - -} // namespace Pen - -} // namespace Fl +extern Fl_Pen_Driver *fl_pen_driver; #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 index 12f207731..2214a61f5 100644 --- a/src/drivers/Base/Fl_Base_Pen_Events.cxx +++ b/src/drivers/Base/Fl_Base_Pen_Events.cxx @@ -15,134 +15,186 @@ // #include "src/drivers/Base/Fl_Base_Pen_Events.H" +#include <stdlib.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 +Fl_Pen_EventData fl_pen_event_data; +Fl_Pen_SubscriberList fl_pen_subscriber_list; +Fl_Pen_Subscriber *fl_pen_pushed = 0; +Fl_Pen_Subscriber *fl_pen_below = 0; + + +void fl_pen_event_data_init(Fl_Pen_EventData *d) { + d->x = 0.0; + d->y = 0.0; + d->rx = 0.0; + d->ry = 0.0; + d->tilt_x = 0.0; + d->tilt_y = 0.0; + d->pressure = 1.0; + d->proximity = 0.0; + d->barrel_pressure = 0.0; + d->twist = 0.0; + d->pen_id = 0; + d->state = (Fl_Pen_State)0; + d->trigger = (Fl_Pen_State)0; +} -using namespace Fl::Pen; +// ---- Fl_Pen_SubscriberList implementation ------------------------------------ +Fl_Pen_SubscriberList::Fl_Pen_SubscriberList() { + items_ = 0; + widgets_ = 0; + count_ = 0; + alloc_ = 0; +} -// ---- SubscriberList implementation ------------------------------------------ +Fl_Pen_SubscriberList::~Fl_Pen_SubscriberList() { + int i; + for (i = 0; i < count_; i++) { + delete items_[i]; + } + if (items_) free(items_); + if (widgets_) free(widgets_); +} /* Remove subscribers that have a 0 as a widget */ -void Fl::Pen::SubscriberList::cleanup() { - for (auto it = begin(); it != end(); ) { - if (!it->second->widget()) { - it = erase(it); +void Fl_Pen_SubscriberList::cleanup() { + int i, j; + for (i = 0, j = 0; i < count_; i++) { + if (items_[i]->widget()) { + if (i != j) { + items_[j] = items_[i]; + widgets_[j] = widgets_[i]; + } + j++; } else { - ++it; + delete items_[i]; } } + count_ = j; +} + +Fl_Pen_Subscriber *Fl_Pen_SubscriberList::find(Fl_Widget *w) { + int i; + for (i = 0; i < count_; i++) { + if (widgets_[i] == w) return items_[i]; + } + return 0; } /* Add a new subscriber, or return an existing one. */ -std::shared_ptr<Subscriber> Fl::Pen::SubscriberList::add(Fl_Widget *w) { +Fl_Pen_Subscriber *Fl_Pen_SubscriberList::add(Fl_Widget *w) { + Fl_Pen_Subscriber *existing; 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; + existing = find(w); + if (existing) return existing; + + if (count_ >= alloc_) { + int new_alloc = alloc_ ? alloc_ * 2 : 8; + items_ = (Fl_Pen_Subscriber **)realloc(items_, new_alloc * sizeof(Fl_Pen_Subscriber *)); + widgets_ = (Fl_Widget **)realloc(widgets_, new_alloc * sizeof(Fl_Widget *)); + alloc_ = new_alloc; } + Fl_Pen_Subscriber *sub = new Fl_Pen_Subscriber(w); + items_[count_] = sub; + widgets_[count_] = w; + count_++; + return sub; } /* 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); +void Fl_Pen_SubscriberList::remove(Fl_Widget *w) { + int i; + for (i = 0; i < count_; i++) { + if (widgets_[i] == w) { + items_[i]->clear(); + delete items_[i]; + count_--; + if (i < count_) { + items_[i] = items_[count_]; + widgets_[i] = widgets_[count_]; + } + return; + } } } -// ---- Driver implementation -------------------------------------------------- +// ---- Fl_Pen_Driver implementation -------------------------------------------- // Override the methods below to handle subscriptions and queries by user apps. -void Fl::Pen::Driver::subscribe(Fl_Widget* widget) { +void Fl_Pen_Driver::subscribe(Fl_Widget* widget) { if (widget == 0) return; - subscriber_list_.add(widget); + fl_pen_subscriber_list.add(widget); } -void Fl::Pen::Driver::unsubscribe(Fl_Widget* widget) { +void Fl_Pen_Driver::unsubscribe(Fl_Widget* widget) { if (widget == 0) return; - subscriber_list_.remove(widget); + fl_pen_subscriber_list.remove(widget); } -void Fl::Pen::Driver::release() { - pushed_ = 0; - below_pen_ = 0; +void Fl_Pen_Driver::release() { + fl_pen_pushed = 0; + fl_pen_below = 0; } -Trait Fl::Pen::Driver::traits() { - return Trait::NONE; +Fl_Pen_Trait Fl_Pen_Driver::traits() { + return FL_PEN_TRAIT_NONE; } -Trait Fl::Pen::Driver::pen_traits(int pen_id) { +Fl_Pen_Trait Fl_Pen_Driver::pen_traits(int pen_id) { (void)pen_id; - return Trait::NONE; + return FL_PEN_TRAIT_NONE; } -// ---- Fl::Pen API ------------------------------------------------------------ +// ---- Fl_Pen API -------------------------------------------------------------- -void Fl::Pen::subscribe(Fl_Widget* widget) { - driver.subscribe(widget); +void Fl_Pen_subscribe(Fl_Widget* widget) { + fl_pen_driver->subscribe(widget); } -void Fl::Pen::unsubscribe(Fl_Widget* widget) { - driver.unsubscribe(widget); +void Fl_Pen_unsubscribe(Fl_Widget* widget) { + fl_pen_driver->unsubscribe(widget); } -void Fl::Pen::release() { - driver.release(); +void Fl_Pen_release(void) { + fl_pen_driver->release(); } -Trait Fl::Pen::driver_traits() { - return driver.traits(); +Fl_Pen_Trait Fl_Pen_driver_traits(void) { + return fl_pen_driver->traits(); } -Trait Fl::Pen::pen_traits(int pen_id) { - return driver.pen_traits(pen_id); +Fl_Pen_Trait Fl_Pen_pen_traits(int pen_id) { + return fl_pen_driver->pen_traits(pen_id); } -double Fl::Pen::event_x() { return e.x; } +double Fl_Pen_event_x(void) { return fl_pen_event_data.x; } -double Fl::Pen::event_y() { return e.y; } +double Fl_Pen_event_y(void) { return fl_pen_event_data.y; } -double Fl::Pen::event_x_root() { return e.rx; } +double Fl_Pen_event_x_root(void) { return fl_pen_event_data.rx; } -double Fl::Pen::event_y_root() { return e.ry; } +double Fl_Pen_event_y_root(void) { return fl_pen_event_data.ry; } -int Fl::Pen::event_pen_id() { return e.pen_id; } +int Fl_Pen_event_pen_id(void) { return fl_pen_event_data.pen_id; } -double Fl::Pen::event_pressure() { return e.pressure; } +double Fl_Pen_event_pressure(void) { return fl_pen_event_data.pressure; } -double Fl::Pen::event_barrel_pressure() { return e.barrel_pressure; } +double Fl_Pen_event_barrel_pressure(void) { return fl_pen_event_data.barrel_pressure; } -double Fl::Pen::event_tilt_x() { return e.tilt_x; } +double Fl_Pen_event_tilt_x(void) { return fl_pen_event_data.tilt_x; } -double Fl::Pen::event_tilt_y() { return e.tilt_y; } +double Fl_Pen_event_tilt_y(void) { return fl_pen_event_data.tilt_y; } -double Fl::Pen::event_twist() { return e.twist; } +double Fl_Pen_event_twist(void) { return fl_pen_event_data.twist; } -double Fl::Pen::event_proximity() { return e.proximity; } +double Fl_Pen_event_proximity(void) { return fl_pen_event_data.proximity; } -State Fl::Pen::event_state() { return e.state; } +Fl_Pen_State Fl_Pen_event_state(void) { return fl_pen_event_data.state; } -State Fl::Pen::event_trigger() { return e.trigger; } +Fl_Pen_State Fl_Pen_event_trigger(void) { return fl_pen_event_data.trigger; } diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.cxx b/src/drivers/Posix/Fl_Posix_System_Driver.cxx index 299a1b901..babcc758b 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.cxx +++ b/src/drivers/Posix/Fl_Posix_System_Driver.cxx @@ -322,7 +322,6 @@ int Fl_Posix_System_Driver::close_fd(int fd) { return close(fd); } # include <fcntl.h> # include <pthread.h> # include <sys/ioctl.h> -# include <mutex> // for std::mutex (since C++11) // Pipe for thread messaging via Fl::awake()... static int thread_filedes[2]; @@ -372,12 +371,12 @@ static void unlock_function_rec() { // -- Start of "awake" implementation -- static void* thread_message_ = 0; -static std::mutex pipe_mutex; +static pthread_mutex_t pipe_mutex = PTHREAD_MUTEX_INITIALIZER; void Fl_Posix_System_Driver::awake(void* msg) { thread_message_ = msg; if (thread_filedes[1]) { - pipe_mutex.lock(); + pthread_mutex_lock(&pipe_mutex); int avail = 0; ioctl(thread_filedes[0], FIONREAD, &avail); if (avail == 0) { @@ -385,7 +384,7 @@ void Fl_Posix_System_Driver::awake(void* msg) { char dummy = 0; if (write(thread_filedes[1], &dummy, 1)==0) { /* ignore */ } } - pipe_mutex.unlock(); + pthread_mutex_unlock(&pipe_mutex); } } @@ -397,10 +396,10 @@ void* Fl_Posix_System_Driver::thread_message() { static void thread_awake_cb(int fd, void*) { if (thread_filedes[1]) { - pipe_mutex.lock(); + pthread_mutex_lock(&pipe_mutex); char dummy = 0; if (read(fd, &dummy, 1)==0) { /* This should never happen */ } - pipe_mutex.unlock(); + pthread_mutex_unlock(&pipe_mutex); } Fl_Awake_Handler func; void *data; diff --git a/src/drivers/Unix/Fl_Unix_System_Driver.cxx b/src/drivers/Unix/Fl_Unix_System_Driver.cxx index 443838c5d..ab6f678aa 100644 --- a/src/drivers/Unix/Fl_Unix_System_Driver.cxx +++ b/src/drivers/Unix/Fl_Unix_System_Driver.cxx @@ -30,7 +30,6 @@ #include <pwd.h> #include <string.h> // strerror(errno) #include <errno.h> // errno -#include <string> #if HAVE_DLSYM && HAVE_DLFCN_H #include <dlfcn.h> // for dlsym #endif @@ -537,53 +536,79 @@ char *Fl_Unix_System_Driver::preference_user_rootnode( const char *application, char *buffer) { + char home_path[FL_PATH_MAX]; + char prefs_path_14[FL_PATH_MAX]; + char prefs_path_13[FL_PATH_MAX]; + char *p; + int len; + // Find the path to the user's home directory. const char *home_path_c = getenv("HOME"); - std::string home_path = home_path_c ? home_path_c : ""; - if (home_path.empty()) { + if (home_path_c && home_path_c[0]) { + strlcpy(home_path, home_path_c, FL_PATH_MAX); + } else { + home_path[0] = '\0'; struct passwd *pw = getpwuid(getuid()); - if (pw) - home_path = pw->pw_dir; + if (pw && pw->pw_dir) + strlcpy(home_path, pw->pw_dir, FL_PATH_MAX); } // 1: Generate the 1.4 path for this vendor and application. const char *prefs_path_14_c = getenv("XDG_CONFIG_HOME"); - std::string prefs_path_14 = prefs_path_14_c ? prefs_path_14_c : ""; - if (prefs_path_14.empty()) { - prefs_path_14 = home_path + "/.config"; + if (!prefs_path_14_c || !prefs_path_14_c[0]) { + snprintf(prefs_path_14, FL_PATH_MAX, "%s/.config", home_path); } else { - if (prefs_path_14[prefs_path_14.size()-1]!='/') - prefs_path_14.append("/"); - if (prefs_path_14.find("~/")==0) // starts with "~" - prefs_path_14.replace(0, 1, home_path); - int h_env = prefs_path_14.find("${HOME}"); - if (h_env!=(int)prefs_path_14.npos) - prefs_path_14.replace(h_env, 7, home_path); - h_env = prefs_path_14.find("$HOME/"); - if (h_env!=(int)prefs_path_14.npos) - prefs_path_14.replace(h_env, 5, home_path); + strlcpy(prefs_path_14, prefs_path_14_c, FL_PATH_MAX); + len = (int)strlen(prefs_path_14); + if (len > 0 && prefs_path_14[len-1] != '/') { + strlcat(prefs_path_14, "/", FL_PATH_MAX); + len++; + } + // Handle ~/ at start + if (prefs_path_14[0] == '~' && prefs_path_14[1] == '/') { + char temp[FL_PATH_MAX]; + snprintf(temp, FL_PATH_MAX, "%s%s", home_path, prefs_path_14 + 1); + strlcpy(prefs_path_14, temp, FL_PATH_MAX); + } + // Handle ${HOME} + p = strstr(prefs_path_14, "${HOME}"); + if (p) { + char temp[FL_PATH_MAX]; + *p = '\0'; + snprintf(temp, FL_PATH_MAX, "%s%s%s", prefs_path_14, home_path, p + 7); + strlcpy(prefs_path_14, temp, FL_PATH_MAX); + } + // Handle $HOME/ + p = strstr(prefs_path_14, "$HOME/"); + if (p) { + char temp[FL_PATH_MAX]; + *p = '\0'; + snprintf(temp, FL_PATH_MAX, "%s%s%s", prefs_path_14, home_path, p + 5); + strlcpy(prefs_path_14, temp, FL_PATH_MAX); + } } - if (prefs_path_14[prefs_path_14.size()-1]!='/') - prefs_path_14.append("/"); - prefs_path_14.append(vendor); + len = (int)strlen(prefs_path_14); + if (len > 0 && prefs_path_14[len-1] != '/') + strlcat(prefs_path_14, "/", FL_PATH_MAX); + strlcat(prefs_path_14, vendor, FL_PATH_MAX); // 2: If this base path does not exist, try the 1.3 path - if (::access(prefs_path_14.c_str(), F_OK) == -1) { - std::string prefs_path_13 = home_path + "/.fltk/" + vendor; - if (::access(prefs_path_13.c_str(), F_OK) == 0) { - prefs_path_13.append("/"); - prefs_path_13.append(application); - prefs_path_13.append(".prefs"); - strlcpy(buffer, prefs_path_13.c_str(), FL_PATH_MAX); + if (::access(prefs_path_14, F_OK) == -1) { + snprintf(prefs_path_13, FL_PATH_MAX, "%s/.fltk/%s", home_path, vendor); + if (::access(prefs_path_13, F_OK) == 0) { + strlcat(prefs_path_13, "/", FL_PATH_MAX); + strlcat(prefs_path_13, application, FL_PATH_MAX); + strlcat(prefs_path_13, ".prefs", FL_PATH_MAX); + strlcpy(buffer, prefs_path_13, FL_PATH_MAX); return buffer; } } // 3: neither path exists, return the 1.4 file path and name - prefs_path_14.append("/"); - prefs_path_14.append(application); - prefs_path_14.append(".prefs"); - strlcpy(buffer, prefs_path_14.c_str(), FL_PATH_MAX); + strlcat(prefs_path_14, "/", FL_PATH_MAX); + strlcat(prefs_path_14, application, FL_PATH_MAX); + strlcat(prefs_path_14, ".prefs", FL_PATH_MAX); + strlcpy(buffer, prefs_path_14, FL_PATH_MAX); return buffer; } |
