blob: f1489a11caf981cb578bce45eb0c04bf0e2297ad (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#import <AppKit/AppKit.h>
#include <yasl/native.h>
#include <assert.h>
/* A strict event double catches querying tablet-only properties on ordinary
* mouse events, and proximity-only properties on tablet point events. */
@interface TabletSample : NSObject
@property NSEventType type;
@property NSEventSubtype subtype;
@property NSEventModifierFlags modifierFlags;
@property NSPoint locationInWindow;
@property NSInteger buttonNumber;
@property NSUInteger buttonMask;
@property(getter=isEnteringProximity) BOOL enteringProximity;
@property NSPointingDeviceType tool;
@property float samplePressure;
@property NSPoint sampleTilt;
@end
@implementation TabletSample
- (float)pressure
{
assert(self.type == NSEventTypeTabletPoint || self.subtype == NSEventSubtypeTabletPoint);
return self.samplePressure;
}
- (NSPoint)tilt
{
assert(self.type == NSEventTypeTabletPoint || self.subtype == NSEventSubtypeTabletPoint);
return self.sampleTilt;
}
- (NSPointingDeviceType)pointingDeviceType
{
assert(self.type == NSEventTypeTabletProximity || self.subtype == NSEventSubtypeTabletProximity);
return self.tool;
}
@end
static struct yasl_mouse_event next(struct yasl_surface *surface)
{
struct yasl_input_event event;
while (yasl_surface_input_poll(surface, &event))
if (event.kind == YASL_INPUT_MOUSE) return event.mouse;
assert(!"Expected a pointer event");
return (struct yasl_mouse_event){0};
}
int main(void)
{
@autoreleasepool {
struct yasl_display *display = yasl_display_open(NULL, NULL);
assert(display && (yasl_display_caps(display) & YASL_CAP_TABLET));
struct yasl_surface_spec spec = {.title = "Tablet test", .size = {320, 240}};
struct yasl_surface *surface = yasl_surface_create_toplevel(display, &spec);
assert(surface);
NSWindow *window = (NSWindow *)yasl_surface_get_native_handle(surface);
NSView *view = window.contentView;
struct yasl_input_event event;
while (yasl_surface_input_poll(surface, &event)) {}
TabletSample *sample = [TabletSample new];
NSEvent *native = (NSEvent *)sample;
sample.type = NSEventTypeTabletProximity;
sample.enteringProximity = YES;
sample.tool = NSPointingDeviceTypePen;
[view tabletProximity:native];
sample.type = NSEventTypeMouseMoved;
sample.subtype = NSEventSubtypeTabletPoint;
sample.locationInWindow = NSMakePoint(100, 120);
sample.sampleTilt = NSMakePoint(-0.5, 0.5);
[view mouseMoved:native];
struct yasl_mouse_event ev = next(surface);
assert(ev.device == YASL_PTR_DEV_PEN && ev.kind == YASL_PTR_MOTION && !ev.pen.pressure);
assert(ev.pen.tilt_x == -45 && ev.pen.tilt_y == -45);
sample.type = NSEventTypeLeftMouseDown;
sample.samplePressure = 0.5;
[view mouseDown:native];
ev = next(surface);
assert(ev.device == YASL_PTR_DEV_PEN && ev.kind == YASL_PTR_PRESS && ev.button == 0);
assert(ev.pen.pressure == 32767);
struct yasl_vector2i position = ev.pos;
/* Native tablet events cover stationary pressure changes. */
sample.type = NSEventTypeTabletPoint;
sample.subtype = NSEventSubtypeMouseEvent;
sample.buttonMask = NSEventButtonMaskPenTip;
sample.samplePressure = 1.5;
[view tabletPoint:native];
ev = next(surface);
assert(ev.kind == YASL_PTR_MOTION && ev.pen.pressure == 65535);
assert(ev.pos.x == position.x && ev.pos.y == position.y);
sample.samplePressure = 0; /* Zero does not release a held tip button. */
[view tabletPoint:native];
assert(next(surface).kind == YASL_PTR_MOTION);
sample.buttonMask = 0;
[view tabletPoint:native];
ev = next(surface);
assert(ev.kind == YASL_PTR_RELEASE && !ev.pen.pressure && ev.device == YASL_PTR_DEV_PEN);
sample.type = NSEventTypeTabletProximity;
sample.enteringProximity = NO;
[view tabletProximity:native];
assert(next(surface).kind == YASL_PTR_LEAVE);
sample.enteringProximity = YES;
sample.tool = NSPointingDeviceTypeEraser;
[view tabletProximity:native];
sample.type = NSEventTypeTabletPoint;
sample.samplePressure = 0.75;
sample.buttonMask = NSEventButtonMaskPenTip;
[view tabletPoint:native];
ev = next(surface);
assert(ev.device == YASL_PTR_DEV_ERASER && ev.kind == YASL_PTR_PRESS && ev.pen.pressure > 0);
sample.type = NSEventTypeTabletProximity;
sample.enteringProximity = NO;
[view tabletProximity:native];
ev = next(surface);
assert(ev.device == YASL_PTR_DEV_ERASER && ev.kind == YASL_PTR_LEAVE && !ev.pen.pressure);
sample.type = NSEventTypeMouseMoved;
[view mouseMoved:native];
ev = next(surface);
assert(ev.device == YASL_PTR_DEV_MOUSE && !ev.pen.pressure);
[sample release];
yasl_surface_destroy(surface);
yasl_display_close(display);
}
return 0;
}
|