// // 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" #include class Fl_Widget; 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; } // ---- Fl_Pen_SubscriberList implementation ------------------------------------ Fl_Pen_SubscriberList::Fl_Pen_SubscriberList() { items_ = 0; widgets_ = 0; count_ = 0; alloc_ = 0; } 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() { 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 { 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. */ Fl_Pen_Subscriber *Fl_Pen_SubscriberList::add(Fl_Widget *w) { Fl_Pen_Subscriber *existing; cleanup(); 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) { 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; } } } // ---- Fl_Pen_Driver implementation -------------------------------------------- // Override the methods below to handle subscriptions and queries by user apps. void Fl_Pen_Driver::subscribe(Fl_Widget* widget) { if (widget == 0) return; fl_pen_subscriber_list.add(widget); } void Fl_Pen_Driver::unsubscribe(Fl_Widget* widget) { if (widget == 0) return; fl_pen_subscriber_list.remove(widget); } void Fl_Pen_Driver::release() { fl_pen_pushed = 0; fl_pen_below = 0; } Fl_Pen_Trait Fl_Pen_Driver::traits() { return FL_PEN_TRAIT_NONE; } Fl_Pen_Trait Fl_Pen_Driver::pen_traits(int pen_id) { (void)pen_id; return FL_PEN_TRAIT_NONE; } // ---- Fl_Pen API -------------------------------------------------------------- void Fl_Pen_subscribe(Fl_Widget* widget) { fl_pen_driver->subscribe(widget); } void Fl_Pen_unsubscribe(Fl_Widget* widget) { fl_pen_driver->unsubscribe(widget); } void Fl_Pen_release(void) { fl_pen_driver->release(); } Fl_Pen_Trait Fl_Pen_driver_traits(void) { return fl_pen_driver->traits(); } Fl_Pen_Trait Fl_Pen_pen_traits(int pen_id) { return fl_pen_driver->pen_traits(pen_id); } double Fl_Pen_event_x(void) { return fl_pen_event_data.x; } double Fl_Pen_event_y(void) { return fl_pen_event_data.y; } double Fl_Pen_event_x_root(void) { return fl_pen_event_data.rx; } double Fl_Pen_event_y_root(void) { return fl_pen_event_data.ry; } int Fl_Pen_event_pen_id(void) { return fl_pen_event_data.pen_id; } double Fl_Pen_event_pressure(void) { return fl_pen_event_data.pressure; } double Fl_Pen_event_barrel_pressure(void) { return fl_pen_event_data.barrel_pressure; } double Fl_Pen_event_tilt_x(void) { return fl_pen_event_data.tilt_x; } double Fl_Pen_event_tilt_y(void) { return fl_pen_event_data.tilt_y; } double Fl_Pen_event_twist(void) { return fl_pen_event_data.twist; } double Fl_Pen_event_proximity(void) { return fl_pen_event_data.proximity; } Fl_Pen_State Fl_Pen_event_state(void) { return fl_pen_event_data.state; } Fl_Pen_State Fl_Pen_event_trigger(void) { return fl_pen_event_data.trigger; }