Skip to content

Commit 585ba2d

Browse files
committed
Prepare input API for multipointer support
1 parent 447316c commit 585ba2d

22 files changed

+281
-131
lines changed

panda/src/device/evdevInputDevice.cxx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ init_device() {
557557

558558
if (test_bit(EV_REL, evtypes)) {
559559
enable_feature(Feature::pointer);
560+
add_pointer(PointerType::unknown, 0);
560561
}
561562

562563
if (test_bit(EV_FF, evtypes)) {
@@ -669,9 +670,8 @@ process_events() {
669670

670671
n_read /= sizeof(struct input_event);
671672

672-
int x = _pointer_data.get_x();
673-
int y = _pointer_data.get_y();
674-
bool have_pointer = false;
673+
int rel_x = 0;
674+
int rel_y = 0;
675675
double time = ClockObject::get_global_clock()->get_frame_time();
676676
int index;
677677

@@ -689,9 +689,8 @@ process_events() {
689689
break;
690690

691691
case EV_REL:
692-
if (code == REL_X) x += events[i].value;
693-
if (code == REL_Y) y += events[i].value;
694-
have_pointer = true;
692+
if (code == REL_X) rel_x += events[i].value;
693+
if (code == REL_Y) rel_y += events[i].value;
695694
break;
696695

697696
case EV_ABS:
@@ -728,8 +727,8 @@ process_events() {
728727
}
729728
}
730729

731-
if (have_pointer) {
732-
set_pointer(true, x, y, time);
730+
if (rel_x != 0 || rel_y != 0) {
731+
pointer_moved(0, rel_x, rel_y, time);
733732
}
734733

735734
return true;

panda/src/device/inputDevice.I

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
INLINE InputDevice::
2020
InputDevice() {
2121
_button_events = new ButtonEventList;
22+
_pointer_events = new PointerEventList;
2223
}
2324

2425
/**
@@ -142,16 +143,6 @@ has_battery() const {
142143
return has_feature(Feature::battery);
143144
}
144145

145-
/**
146-
* Returns the PointerData associated with the input device's pointer. This
147-
* only makes sense if has_pointer() also returns true.
148-
*/
149-
INLINE PointerData InputDevice::
150-
get_pointer() const {
151-
LightMutexHolder holder(_lock);
152-
return _pointer_data;
153-
}
154-
155146
/**
156147
* Returns the TrackerData associated with the input device's tracker. This
157148
* only makes sense if has_tracker() also returns true.

panda/src/device/inputDevice.cxx

Lines changed: 85 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ InputDevice(const std::string &name, DeviceClass dev_class) :
2929
_is_connected(true)
3030
{
3131
_button_events = new ButtonEventList;
32+
_pointer_events = new PointerEventList;
3233
}
3334

3435
/**
@@ -80,7 +81,7 @@ get_button_events() {
8081
bool InputDevice::
8182
has_pointer_event() const {
8283
LightMutexHolder holder(_lock);
83-
return (_pointer_events != 0);
84+
return _pointer_events != nullptr && !_pointer_events->empty();
8485
}
8586

8687
/**
@@ -90,8 +91,8 @@ has_pointer_event() const {
9091
PT(PointerEventList) InputDevice::
9192
get_pointer_events() {
9293
LightMutexHolder holder(_lock);
93-
PT(PointerEventList) result = _pointer_events;
94-
_pointer_events.clear();
94+
PT(PointerEventList) result = new PointerEventList;
95+
swap(_pointer_events, result);
9596
return result;
9697
}
9798

@@ -149,69 +150,116 @@ add_axis(Axis axis, int minimum, int maximum) {
149150
}
150151

151152
/**
152-
* Records that a mouse movement has taken place.
153+
* Records that a new pointer was found.
154+
*/
155+
int InputDevice::
156+
add_pointer(PointerType type, int id, bool primary) {
157+
nassertr(_lock.debug_is_locked(), -1);
158+
159+
PointerData data;
160+
data._id = id;
161+
data._type = type;
162+
163+
int index = (int)_pointers.size();
164+
if (_num_pointers == _pointers.size()) {
165+
_pointers.push_back(data);
166+
} else {
167+
_pointers[index] = data;
168+
}
169+
++_num_pointers;
170+
171+
return index;
172+
}
173+
174+
/**
175+
* Removes a previously added pointer. If the current pressure is not zero,
176+
* it will generate an event doing so.
153177
*/
154178
void InputDevice::
155-
set_pointer(bool inwin, double x, double y, double time) {
179+
remove_pointer(int id) {
156180
nassertv(_lock.debug_is_locked());
157-
_pointer_data._in_window = inwin;
158-
_pointer_data._xpos = x;
159-
_pointer_data._ypos = y;
160181

161-
if (_enable_pointer_events) {
162-
int seq = _event_sequence++;
163-
if (_pointer_events.is_null()) {
164-
_pointer_events = new PointerEventList();
182+
size_t i;
183+
for (i = 0; i < _pointers.size(); ++i) {
184+
if (_pointers[i]._id == id) {
185+
break;
165186
}
166-
_pointer_events->add_event(_pointer_data._in_window,
167-
_pointer_data._xpos,
168-
_pointer_data._ypos,
169-
seq, time);
187+
}
188+
189+
if (i < _pointers.size()) {
190+
if (_pointers[i]._pressure != 0.0) {
191+
_pointers[i]._pressure = 0.0;
192+
193+
if (_enable_pointer_events) {
194+
int seq = _event_sequence++;
195+
double time = ClockObject::get_global_clock()->get_frame_time();
196+
_pointer_events->add_event(_pointers[i], seq, time);
197+
}
198+
}
199+
200+
// Replace it with the last one.
201+
if (i != _pointers.size() - 1) {
202+
_pointers[i] = _pointers.back();
203+
}
204+
--_num_pointers;
170205
}
171206
}
172207

173208
/**
174-
* Records that the mouse pointer has left the window.
209+
* Records that pointer data for a pointer has changed. This can also be used
210+
* to add a new pointer.
175211
*/
176212
void InputDevice::
177-
set_pointer_out_of_window(double time) {
213+
update_pointer(PointerData data, double time) {
178214
nassertv(_lock.debug_is_locked());
179-
_pointer_data._in_window = false;
215+
216+
PointerData *ptr = nullptr;
217+
for (size_t i = 0; i < _pointers.size(); ++i) {
218+
if (_pointers[i]._id == data._id) {
219+
ptr = &_pointers[i];
220+
*ptr = data;
221+
break;
222+
}
223+
}
224+
if (ptr == nullptr) {
225+
_pointers.push_back(data);
226+
ptr = &_pointers.back();
227+
}
180228

181229
if (_enable_pointer_events) {
182230
int seq = _event_sequence++;
183-
if (_pointer_events.is_null()) {
184-
_pointer_events = new PointerEventList();
185-
}
186-
_pointer_events->add_event(_pointer_data._in_window,
187-
_pointer_data._xpos,
188-
_pointer_data._ypos,
189-
seq, time);
231+
_pointer_events->add_event(*ptr, seq, time);
190232
}
191233
}
192234

193235
/**
194-
* Records that a relative mouse movement has taken place.
236+
* Records that a relative pointer movement has taken place.
195237
*/
196238
void InputDevice::
197-
pointer_moved(double x, double y, double time) {
239+
pointer_moved(int id, double x, double y, double time) {
198240
nassertv(_lock.debug_is_locked());
199-
_pointer_data._xpos += x;
200-
_pointer_data._ypos += y;
241+
242+
PointerData *ptr = nullptr;
243+
for (size_t i = 0; i < _pointers.size(); ++i) {
244+
if (_pointers[i]._id == id) {
245+
ptr = &_pointers[i];
246+
_pointers[i]._xpos = x;
247+
_pointers[i]._ypos = y;
248+
break;
249+
}
250+
}
251+
nassertv_always(ptr != nullptr);
201252

202253
if (device_cat.is_spam() && (x != 0 || y != 0)) {
203254
device_cat.spam()
204-
<< "Pointer moved by " << x << " x " << y << "\n";
255+
<< "Pointer " << id << " moved by " << x << " x " << y << "\n";
205256
}
206257

207258
if (_enable_pointer_events) {
208259
int seq = _event_sequence++;
209-
if (_pointer_events.is_null()) {
210-
_pointer_events = new PointerEventList();
211-
}
212-
_pointer_events->add_event(_pointer_data._in_window,
213-
_pointer_data._xpos,
214-
_pointer_data._ypos,
260+
_pointer_events->add_event(ptr->_in_window,
261+
ptr->_xpos,
262+
ptr->_ypos,
215263
x, y, seq, time);
216264
}
217265
}

panda/src/device/inputDevice.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ class EXPCL_PANDA_DEVICE InputDevice : public TypedReferenceCount {
201201
INLINE bool has_vibration() const;
202202
INLINE bool has_battery() const;
203203

204-
INLINE PointerData get_pointer() const;
205204
INLINE TrackerData get_tracker() const;
206205
INLINE BatteryData get_battery() const;
207206

@@ -244,7 +243,6 @@ class EXPCL_PANDA_DEVICE InputDevice : public TypedReferenceCount {
244243
INLINE bool has_feature(Feature feature) const;
245244

246245
// Getters for the various types of device data.
247-
MAKE_PROPERTY2(pointer, has_pointer, get_pointer);
248246
MAKE_PROPERTY2(tracker, has_tracker, get_tracker);
249247
MAKE_PROPERTY2(battery, has_battery, get_battery);
250248

@@ -285,10 +283,10 @@ class EXPCL_PANDA_DEVICE InputDevice : public TypedReferenceCount {
285283
int add_axis(Axis axis, int minimum, int maximum, bool centered);
286284
int add_axis(Axis axis, int minimum, int maximum);
287285

288-
void set_pointer(bool inwin, double x, double y, double time);
289-
void set_pointer_out_of_window(double time);
290-
291-
void pointer_moved(double x, double y, double time);
286+
int add_pointer(PointerType type, int id, bool primary = false);
287+
void remove_pointer(int id);
288+
void update_pointer(PointerData data, double time);
289+
void pointer_moved(int id, double x, double y, double time);
292290
void button_changed(int index, bool down);
293291
void axis_changed(int index, int value);
294292
void set_axis_value(int index, double state);
@@ -323,6 +321,10 @@ class EXPCL_PANDA_DEVICE InputDevice : public TypedReferenceCount {
323321
PT(ButtonEventList) _button_events;
324322
PT(PointerEventList) _pointer_events;
325323

324+
size_t _num_pointers = 0;
325+
typedef pvector<PointerData> Pointers;
326+
Pointers _pointers;
327+
326328
PUBLISHED:
327329
typedef pvector<ButtonState> Buttons;
328330
typedef pvector<AxisState> Axes;

panda/src/display/graphicsWindow.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ get_pointer(int device) const {
363363
{
364364
LightMutexHolder holder(_input_lock);
365365
nassertr(device >= 0 && device < (int)_input_devices.size(), MouseData());
366-
result = _input_devices[device]->get_pointer();
366+
result = ((const GraphicsWindowInputDevice *)_input_devices[device].p())->get_pointer();
367367
}
368368
return result;
369369
}

panda/src/display/graphicsWindowInputDevice.I

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,27 @@
1212
*/
1313

1414
/**
15-
* To be called by a particular kind of GraphicsWindow to indicate that the
16-
* pointer is within the window, at the given pixel coordinates.
15+
* Returns the PointerData associated with the input device's pointer. This
16+
* only makes sense if has_pointer() also returns true.
1717
*/
18-
INLINE void GraphicsWindowInputDevice::
19-
set_pointer_in_window(double x, double y, double time) {
18+
INLINE PointerData GraphicsWindowInputDevice::
19+
get_pointer() const {
2020
LightMutexHolder holder(_lock);
21-
InputDevice::set_pointer(true, x, y, time);
21+
if (!_pointers.empty()) {
22+
return _pointers[0];
23+
} else {
24+
return PointerData();
25+
}
2226
}
2327

2428
/**
2529
* To be called by a particular kind of GraphicsWindow to indicate that the
26-
* pointer is no longer within the window.
30+
* pointer data has changed.
2731
*/
2832
INLINE void GraphicsWindowInputDevice::
29-
set_pointer_out_of_window(double time) {
33+
update_pointer(PointerData data, double time) {
3034
LightMutexHolder holder(_lock);
31-
InputDevice::set_pointer_out_of_window(time);
35+
InputDevice::update_pointer(std::move(data), time);
3236
}
3337

3438
/**
@@ -38,5 +42,15 @@ set_pointer_out_of_window(double time) {
3842
INLINE void GraphicsWindowInputDevice::
3943
pointer_moved(double x, double y, double time) {
4044
LightMutexHolder holder(_lock);
41-
InputDevice::pointer_moved(x, y, time);
45+
InputDevice::pointer_moved(0, x, y, time);
46+
}
47+
48+
/**
49+
* To be called by a particular kind of GraphicsWindow to indicate that the
50+
* pointer no longer exists.
51+
*/
52+
INLINE void GraphicsWindowInputDevice::
53+
remove_pointer(int id) {
54+
LightMutexHolder holder(_lock);
55+
InputDevice::remove_pointer(id);
4256
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy