1 /*
2     SPDX-FileCopyrightText: 2020 Benjamin Port <benjamin.port@enioka.com>
3 
4     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 
7 #include "keyboard_shortcuts_inhibit_v1_interface.h"
8 
9 #include <qwayland-server-keyboard-shortcuts-inhibit-unstable-v1.h>
10 
11 #include "display.h"
12 #include "seat_interface.h"
13 #include "surface_interface.h"
14 
15 static const int s_version = 1;
16 
17 namespace KWaylandServer
18 {
19 class KeyboardShortcutsInhibitorV1InterfacePrivate : public QtWaylandServer::zwp_keyboard_shortcuts_inhibitor_v1
20 {
21 public:
22     KeyboardShortcutsInhibitorV1InterfacePrivate(SurfaceInterface *surface,
23                                                  SeatInterface *seat,
24                                                  KeyboardShortcutsInhibitManagerV1Interface *manager,
25                                                  KeyboardShortcutsInhibitorV1Interface *q,
26                                                  wl_resource *resource);
27 
28     KeyboardShortcutsInhibitorV1Interface *q;
29     QPointer<KeyboardShortcutsInhibitManagerV1Interface> m_manager;
30     SurfaceInterface *const m_surface;
31     SeatInterface *const m_seat;
32     bool m_active;
33 
34 protected:
35     void zwp_keyboard_shortcuts_inhibitor_v1_destroy_resource(Resource *resource) override;
36 
37     void zwp_keyboard_shortcuts_inhibitor_v1_destroy(Resource *resource) override;
38 };
39 
40 class KeyboardShortcutsInhibitManagerV1InterfacePrivate : public QtWaylandServer::zwp_keyboard_shortcuts_inhibit_manager_v1
41 {
42 public:
43     KeyboardShortcutsInhibitManagerV1InterfacePrivate(Display *display, KeyboardShortcutsInhibitManagerV1Interface *q);
44 
45     void zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(Resource *resource,
46                                                                      uint32_t id,
47                                                                      struct ::wl_resource *surface_resource,
48                                                                      struct ::wl_resource *seat_resource) override;
49 
50     KeyboardShortcutsInhibitorV1Interface *findInhibitor(SurfaceInterface *surface, SeatInterface *seat) const;
51 
52     void removeInhibitor(SurfaceInterface *const surface, SeatInterface *const seat);
53 
54     KeyboardShortcutsInhibitManagerV1Interface *q;
55     Display *const m_display;
56     QHash<QPair<SurfaceInterface *, SeatInterface *>, KeyboardShortcutsInhibitorV1Interface *> m_inhibitors;
57 
58 protected:
59     void zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(Resource *resource) override;
60 };
61 
KeyboardShortcutsInhibitorV1InterfacePrivate(SurfaceInterface * surface,SeatInterface * seat,KeyboardShortcutsInhibitManagerV1Interface * manager,KeyboardShortcutsInhibitorV1Interface * q,wl_resource * resource)62 KeyboardShortcutsInhibitorV1InterfacePrivate::KeyboardShortcutsInhibitorV1InterfacePrivate(SurfaceInterface *surface,
63                                                                                            SeatInterface *seat,
64                                                                                            KeyboardShortcutsInhibitManagerV1Interface *manager,
65                                                                                            KeyboardShortcutsInhibitorV1Interface *q,
66                                                                                            wl_resource *resource)
67     : zwp_keyboard_shortcuts_inhibitor_v1(resource)
68     , q(q)
69     , m_manager(manager)
70     , m_surface(surface)
71     , m_seat(seat)
72     , m_active(false)
73 {
74 }
75 
zwp_keyboard_shortcuts_inhibitor_v1_destroy(Resource * resource)76 void KeyboardShortcutsInhibitorV1InterfacePrivate::zwp_keyboard_shortcuts_inhibitor_v1_destroy(Resource *resource)
77 {
78     wl_resource_destroy(resource->handle);
79 }
80 
zwp_keyboard_shortcuts_inhibitor_v1_destroy_resource(Resource * resource)81 void KeyboardShortcutsInhibitorV1InterfacePrivate::zwp_keyboard_shortcuts_inhibitor_v1_destroy_resource(Resource *resource)
82 {
83     Q_UNUSED(resource)
84     // Ensure manager don't track anymore this inhibitor
85     if (m_manager) {
86         m_manager->removeInhibitor(m_surface, m_seat);
87     }
88     delete q;
89 }
90 
KeyboardShortcutsInhibitorV1Interface(SurfaceInterface * surface,SeatInterface * seat,KeyboardShortcutsInhibitManagerV1Interface * manager,wl_resource * resource)91 KeyboardShortcutsInhibitorV1Interface::KeyboardShortcutsInhibitorV1Interface(SurfaceInterface *surface,
92                                                                              SeatInterface *seat,
93                                                                              KeyboardShortcutsInhibitManagerV1Interface *manager,
94                                                                              wl_resource *resource)
95     : QObject(nullptr)
96     , d(new KeyboardShortcutsInhibitorV1InterfacePrivate(surface, seat, manager, this, resource))
97 {
98 }
99 
100 KeyboardShortcutsInhibitorV1Interface::~KeyboardShortcutsInhibitorV1Interface() = default;
101 
setActive(bool active)102 void KeyboardShortcutsInhibitorV1Interface::setActive(bool active)
103 {
104     if (d->m_active == active) {
105         return;
106     }
107     d->m_active = active;
108     if (active) {
109         d->send_active();
110     } else {
111         d->send_inactive();
112     }
113 }
114 
isActive() const115 bool KeyboardShortcutsInhibitorV1Interface::isActive() const
116 {
117     return d->m_active;
118 }
119 
seat() const120 SeatInterface *KeyboardShortcutsInhibitorV1Interface::seat() const
121 {
122     return d->m_seat;
123 }
124 
surface() const125 SurfaceInterface *KeyboardShortcutsInhibitorV1Interface::surface() const
126 {
127     return d->m_surface;
128 }
129 
KeyboardShortcutsInhibitManagerV1InterfacePrivate(Display * display,KeyboardShortcutsInhibitManagerV1Interface * q)130 KeyboardShortcutsInhibitManagerV1InterfacePrivate::KeyboardShortcutsInhibitManagerV1InterfacePrivate(Display *display,
131                                                                                                      KeyboardShortcutsInhibitManagerV1Interface *q)
132     : zwp_keyboard_shortcuts_inhibit_manager_v1(*display, s_version)
133     , q(q)
134     , m_display(display)
135 {
136 }
137 
zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(Resource * resource,uint32_t id,wl_resource * surface_resource,wl_resource * seat_resource)138 void KeyboardShortcutsInhibitManagerV1InterfacePrivate::zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(Resource *resource,
139                                                                                                                     uint32_t id,
140                                                                                                                     wl_resource *surface_resource,
141                                                                                                                     wl_resource *seat_resource)
142 {
143     SeatInterface *seat = SeatInterface::get(seat_resource);
144     SurfaceInterface *surface = SurfaceInterface::get(surface_resource);
145     if (m_inhibitors.contains({surface, seat})) {
146         wl_resource_post_error(resource->handle, error::error_already_inhibited, "the shortcuts are already inhibited for this surface and seat");
147         return;
148     }
149 
150     wl_resource *inhibitorResource = wl_resource_create(resource->client(), &zwp_keyboard_shortcuts_inhibitor_v1_interface, resource->version(), id);
151     auto inhibitor = new KeyboardShortcutsInhibitorV1Interface(surface, seat, q, inhibitorResource);
152     m_inhibitors[{surface, seat}] = inhibitor;
153     Q_EMIT q->inhibitorCreated(inhibitor);
154     inhibitor->setActive(true);
155 }
156 
findInhibitor(SurfaceInterface * surface,SeatInterface * seat) const157 KeyboardShortcutsInhibitorV1Interface *KeyboardShortcutsInhibitManagerV1InterfacePrivate::findInhibitor(SurfaceInterface *surface, SeatInterface *seat) const
158 {
159     return m_inhibitors.value({surface, seat}, nullptr);
160 }
161 
zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(Resource * resource)162 void KeyboardShortcutsInhibitManagerV1InterfacePrivate::zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(Resource *resource)
163 {
164     wl_resource_destroy(resource->handle);
165 }
166 
removeInhibitor(SurfaceInterface * const surface,SeatInterface * const seat)167 void KeyboardShortcutsInhibitManagerV1InterfacePrivate::removeInhibitor(SurfaceInterface *const surface, SeatInterface *const seat)
168 {
169     m_inhibitors.remove({surface, seat});
170 }
171 
KeyboardShortcutsInhibitManagerV1Interface(Display * display,QObject * parent)172 KeyboardShortcutsInhibitManagerV1Interface::KeyboardShortcutsInhibitManagerV1Interface(Display *display, QObject *parent)
173     : QObject(parent)
174     , d(new KeyboardShortcutsInhibitManagerV1InterfacePrivate(display, this))
175 {
176 }
177 
178 KeyboardShortcutsInhibitManagerV1Interface::~KeyboardShortcutsInhibitManagerV1Interface() = default;
179 
findInhibitor(SurfaceInterface * surface,SeatInterface * seat) const180 KeyboardShortcutsInhibitorV1Interface *KeyboardShortcutsInhibitManagerV1Interface::findInhibitor(SurfaceInterface *surface, SeatInterface *seat) const
181 {
182     return d->findInhibitor(surface, seat);
183 }
184 
removeInhibitor(SurfaceInterface * surface,SeatInterface * seat)185 void KeyboardShortcutsInhibitManagerV1Interface::removeInhibitor(SurfaceInterface *surface, SeatInterface *seat)
186 {
187     d->removeInhibitor(surface, seat);
188 }
189 
190 }
191