aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/devices/VirtualPointer.cpp
blob: 2b46ff28244444123be6d093637c3934ddff7417 (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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include "VirtualPointer.hpp"
#include "../protocols/VirtualPointer.hpp"

SP<CVirtualPointer> CVirtualPointer::create(SP<CVirtualPointerV1Resource> resource) {
    SP<CVirtualPointer> pPointer = SP<CVirtualPointer>(new CVirtualPointer(resource));

    pPointer->self = pPointer;

    return pPointer;
}

CVirtualPointer::CVirtualPointer(SP<CVirtualPointerV1Resource> resource) : pointer(resource) {
    if (!resource->good())
        return;

    auto mouse = resource->wlr();

    // clang-format off
    hyprListener_destroy.initCallback(&mouse->base.events.destroy, [this] (void* owner, void* data) {
        disconnectCallbacks();
        events.destroy.emit();
    }, this, "CVirtualPointer");

    hyprListener_motion.initCallback(&mouse->events.motion, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_motion_event*)data;

        pointerEvents.motion.emit(SMotionEvent{
            .timeMs  = E->time_msec,
            .delta   = {E->delta_x, E->delta_y},
            .unaccel = {E->unaccel_dx, E->unaccel_dy},
        });
    }, this, "CVirtualPointer");

    hyprListener_motionAbsolute.initCallback(&mouse->events.motion_absolute, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_motion_absolute_event*)data;

        pointerEvents.motionAbsolute.emit(SMotionAbsoluteEvent{
            .timeMs   = E->time_msec,
            .absolute = {E->x, E->y},
        });
    }, this, "CVirtualPointer");

    hyprListener_button.initCallback(&mouse->events.button, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_button_event*)data;

        pointerEvents.button.emit(SButtonEvent{
            .timeMs = E->time_msec,
            .button = E->button,
            .state  = (wl_pointer_button_state)E->state,
        });
    }, this, "CVirtualPointer");

    hyprListener_axis.initCallback(&mouse->events.axis, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_axis_event*)data;

        pointerEvents.axis.emit(SAxisEvent{
            .timeMs            = E->time_msec,
            .source            = E->source,
            .axis              = E->orientation,
            .relativeDirection = E->relative_direction,
            .delta             = E->delta,
            .deltaDiscrete     = E->delta_discrete,
        });
    }, this, "CVirtualPointer");

    hyprListener_swipeBegin.initCallback(&mouse->events.swipe_begin, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_swipe_begin_event*)data;

        pointerEvents.swipeBegin.emit(SSwipeBeginEvent{
            .timeMs  = E->time_msec,
            .fingers = E->fingers,
        });
    }, this, "CVirtualPointer");

    hyprListener_swipeEnd.initCallback(&mouse->events.swipe_end, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_swipe_end_event*)data;

        pointerEvents.swipeEnd.emit(SSwipeEndEvent{
            .timeMs    = E->time_msec,
            .cancelled = E->cancelled,
        });
    }, this, "CVirtualPointer");

    hyprListener_swipeUpdate.initCallback(&mouse->events.swipe_update, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_swipe_update_event*)data;

        pointerEvents.swipeUpdate.emit(SSwipeUpdateEvent{
            .timeMs  = E->time_msec,
            .fingers = E->fingers,
            .delta   = {E->dx, E->dy},
        });
    }, this, "CVirtualPointer");

    hyprListener_pinchBegin.initCallback(&mouse->events.pinch_begin, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_pinch_begin_event*)data;

        pointerEvents.pinchBegin.emit(SPinchBeginEvent{
            .timeMs    = E->time_msec,
            .fingers   = E->fingers,
        });
    }, this, "CVirtualPointer");

    hyprListener_pinchEnd.initCallback(&mouse->events.pinch_end, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_pinch_end_event*)data;

        pointerEvents.pinchEnd.emit(SPinchEndEvent{
            .timeMs    = E->time_msec,
            .cancelled = E->cancelled,
        });
    }, this, "CVirtualPointer");

    hyprListener_pinchUpdate.initCallback(&mouse->events.pinch_update, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_pinch_update_event*)data;

        pointerEvents.pinchUpdate.emit(SPinchUpdateEvent{
            .timeMs   = E->time_msec,
            .fingers  = E->fingers,
            .delta    = {E->dx, E->dy},
            .scale    = E->scale,
            .rotation = E->rotation,
        });
    }, this, "CVirtualPointer");

    hyprListener_holdBegin.initCallback(&mouse->events.hold_begin, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_hold_begin_event*)data;

        pointerEvents.holdBegin.emit(SHoldBeginEvent{
            .timeMs  = E->time_msec,
            .fingers = E->fingers,
        });
    }, this, "CVirtualPointer");

    hyprListener_holdEnd.initCallback(&mouse->events.hold_end, [this] (void* owner, void* data) {
        auto E = (wlr_pointer_hold_end_event*)data;

        pointerEvents.holdEnd.emit(SHoldEndEvent{
            .timeMs    = E->time_msec,
            .cancelled = E->cancelled,
        });
    }, this, "CVirtualPointer");

    // clang-format on

    deviceName = mouse->base.name ? mouse->base.name : "UNKNOWN";
}

bool CVirtualPointer::isVirtual() {
    return true;
}

void CVirtualPointer::disconnectCallbacks() {
    hyprListener_destroy.removeCallback();
    hyprListener_motion.removeCallback();
    hyprListener_motionAbsolute.removeCallback();
    hyprListener_button.removeCallback();
    hyprListener_axis.removeCallback();
    hyprListener_frame.removeCallback();
    hyprListener_swipeBegin.removeCallback();
    hyprListener_swipeEnd.removeCallback();
    hyprListener_swipeUpdate.removeCallback();
    hyprListener_pinchBegin.removeCallback();
    hyprListener_pinchEnd.removeCallback();
    hyprListener_pinchUpdate.removeCallback();
    hyprListener_holdBegin.removeCallback();
    hyprListener_holdEnd.removeCallback();
}

wlr_pointer* CVirtualPointer::wlr() {
    if (pointer.expired())
        return nullptr;
    return pointer.lock()->wlr();
}