summaryrefslogtreecommitdiff
path: root/tests/cocoa/test_tablet.m
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;
}