File indexing completed on 2024-11-10 04:57:25
0001 /* 0002 SPDX-FileCopyrightText: 2023 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "wayland/cursorshape_v1.h" 0008 #include "wayland/clientconnection.h" 0009 #include "wayland/display.h" 0010 #include "wayland/pointer.h" 0011 #include "wayland/surface.h" 0012 #include "wayland/tablet_v2.h" 0013 0014 #include <QPointer> 0015 0016 #include "qwayland-server-cursor-shape-v1.h" 0017 0018 namespace KWin 0019 { 0020 0021 static constexpr int s_version = 1; 0022 0023 class CursorShapeManagerV1InterfacePrivate : public QtWaylandServer::wp_cursor_shape_manager_v1 0024 { 0025 public: 0026 CursorShapeManagerV1InterfacePrivate(Display *display); 0027 0028 protected: 0029 void wp_cursor_shape_manager_v1_destroy(Resource *resource) override; 0030 void wp_cursor_shape_manager_v1_get_pointer(Resource *resource, uint32_t cursor_shape_device, struct ::wl_resource *pointer) override; 0031 void wp_cursor_shape_manager_v1_get_tablet_tool_v2(Resource *resource, uint32_t cursor_shape_device, struct ::wl_resource *tablet_tool) override; 0032 }; 0033 0034 class CursorShapeDeviceV1Interface : public QtWaylandServer::wp_cursor_shape_device_v1 0035 { 0036 public: 0037 CursorShapeDeviceV1Interface(PointerInterface *pointer, wl_resource *resource); 0038 CursorShapeDeviceV1Interface(TabletToolV2Interface *tabletTool, wl_resource *resource); 0039 0040 QPointer<PointerInterface> pointer; 0041 QPointer<TabletToolV2Interface> tabletTool; 0042 0043 protected: 0044 void wp_cursor_shape_device_v1_destroy_resource(Resource *resource) override; 0045 void wp_cursor_shape_device_v1_destroy(Resource *resource) override; 0046 void wp_cursor_shape_device_v1_set_shape(Resource *resource, uint32_t serial, uint32_t shape) override; 0047 }; 0048 0049 CursorShapeManagerV1InterfacePrivate::CursorShapeManagerV1InterfacePrivate(Display *display) 0050 : QtWaylandServer::wp_cursor_shape_manager_v1(*display, s_version) 0051 { 0052 } 0053 0054 void CursorShapeManagerV1InterfacePrivate::wp_cursor_shape_manager_v1_destroy(Resource *resource) 0055 { 0056 wl_resource_destroy(resource->handle); 0057 } 0058 0059 void CursorShapeManagerV1InterfacePrivate::wp_cursor_shape_manager_v1_get_pointer(Resource *resource, uint32_t cursor_shape_device, struct ::wl_resource *pointer) 0060 { 0061 wl_resource *device = wl_resource_create(resource->client(), &wp_cursor_shape_device_v1_interface, resource->version(), cursor_shape_device); 0062 if (!device) { 0063 wl_resource_post_no_memory(resource->handle); 0064 return; 0065 } 0066 new CursorShapeDeviceV1Interface(PointerInterface::get(pointer), device); 0067 } 0068 0069 void CursorShapeManagerV1InterfacePrivate::wp_cursor_shape_manager_v1_get_tablet_tool_v2(Resource *resource, uint32_t cursor_shape_device, struct ::wl_resource *tablet_tool) 0070 { 0071 wl_resource *device = wl_resource_create(resource->client(), &wp_cursor_shape_device_v1_interface, resource->version(), cursor_shape_device); 0072 if (!device) { 0073 wl_resource_post_no_memory(resource->handle); 0074 return; 0075 } 0076 new CursorShapeDeviceV1Interface(TabletToolV2Interface::get(tablet_tool), device); 0077 } 0078 0079 CursorShapeManagerV1Interface::CursorShapeManagerV1Interface(Display *display, QObject *parent) 0080 : QObject(parent) 0081 , d(std::make_unique<CursorShapeManagerV1InterfacePrivate>(display)) 0082 { 0083 } 0084 0085 CursorShapeManagerV1Interface::~CursorShapeManagerV1Interface() 0086 { 0087 } 0088 0089 CursorShapeDeviceV1Interface::CursorShapeDeviceV1Interface(PointerInterface *pointer, wl_resource *resource) 0090 : QtWaylandServer::wp_cursor_shape_device_v1(resource) 0091 , pointer(pointer) 0092 { 0093 } 0094 0095 CursorShapeDeviceV1Interface::CursorShapeDeviceV1Interface(TabletToolV2Interface *tabletTool, wl_resource *resource) 0096 : QtWaylandServer::wp_cursor_shape_device_v1(resource) 0097 , tabletTool(tabletTool) 0098 { 0099 } 0100 0101 void CursorShapeDeviceV1Interface::wp_cursor_shape_device_v1_destroy_resource(Resource *resource) 0102 { 0103 delete this; 0104 } 0105 0106 void CursorShapeDeviceV1Interface::wp_cursor_shape_device_v1_destroy(Resource *resource) 0107 { 0108 wl_resource_destroy(resource->handle); 0109 } 0110 0111 static QByteArray shapeName(uint32_t shape) 0112 { 0113 switch (shape) { 0114 case QtWaylandServer::wp_cursor_shape_device_v1::shape_default: 0115 return QByteArrayLiteral("default"); 0116 case QtWaylandServer::wp_cursor_shape_device_v1::shape_context_menu: 0117 return QByteArrayLiteral("context-menu"); 0118 case QtWaylandServer::wp_cursor_shape_device_v1::shape_help: 0119 return QByteArrayLiteral("help"); 0120 case QtWaylandServer::wp_cursor_shape_device_v1::shape_pointer: 0121 return QByteArrayLiteral("pointer"); 0122 case QtWaylandServer::wp_cursor_shape_device_v1::shape_progress: 0123 return QByteArrayLiteral("progress"); 0124 case QtWaylandServer::wp_cursor_shape_device_v1::shape_wait: 0125 return QByteArrayLiteral("wait"); 0126 case QtWaylandServer::wp_cursor_shape_device_v1::shape_cell: 0127 return QByteArrayLiteral("cell"); 0128 case QtWaylandServer::wp_cursor_shape_device_v1::shape_crosshair: 0129 return QByteArrayLiteral("crosshair"); 0130 case QtWaylandServer::wp_cursor_shape_device_v1::shape_text: 0131 return QByteArrayLiteral("text"); 0132 case QtWaylandServer::wp_cursor_shape_device_v1::shape_vertical_text: 0133 return QByteArrayLiteral("vertical-text"); 0134 case QtWaylandServer::wp_cursor_shape_device_v1::shape_alias: 0135 return QByteArrayLiteral("alias"); 0136 case QtWaylandServer::wp_cursor_shape_device_v1::shape_copy: 0137 return QByteArrayLiteral("copy"); 0138 case QtWaylandServer::wp_cursor_shape_device_v1::shape_move: 0139 return QByteArrayLiteral("move"); 0140 case QtWaylandServer::wp_cursor_shape_device_v1::shape_no_drop: 0141 return QByteArrayLiteral("no-drop"); 0142 case QtWaylandServer::wp_cursor_shape_device_v1::shape_not_allowed: 0143 return QByteArrayLiteral("not-allowed"); 0144 case QtWaylandServer::wp_cursor_shape_device_v1::shape_grab: 0145 return QByteArrayLiteral("grab"); 0146 case QtWaylandServer::wp_cursor_shape_device_v1::shape_grabbing: 0147 return QByteArrayLiteral("grabbing"); 0148 case QtWaylandServer::wp_cursor_shape_device_v1::shape_e_resize: 0149 return QByteArrayLiteral("e-resize"); 0150 case QtWaylandServer::wp_cursor_shape_device_v1::shape_n_resize: 0151 return QByteArrayLiteral("n-resize"); 0152 case QtWaylandServer::wp_cursor_shape_device_v1::shape_ne_resize: 0153 return QByteArrayLiteral("ne-resize"); 0154 case QtWaylandServer::wp_cursor_shape_device_v1::shape_nw_resize: 0155 return QByteArrayLiteral("nw-resize"); 0156 case QtWaylandServer::wp_cursor_shape_device_v1::shape_s_resize: 0157 return QByteArrayLiteral("s-resize"); 0158 case QtWaylandServer::wp_cursor_shape_device_v1::shape_se_resize: 0159 return QByteArrayLiteral("se-resize"); 0160 case QtWaylandServer::wp_cursor_shape_device_v1::shape_sw_resize: 0161 return QByteArrayLiteral("sw-resize"); 0162 case QtWaylandServer::wp_cursor_shape_device_v1::shape_w_resize: 0163 return QByteArrayLiteral("w-resize"); 0164 case QtWaylandServer::wp_cursor_shape_device_v1::shape_ew_resize: 0165 return QByteArrayLiteral("ew-resize"); 0166 case QtWaylandServer::wp_cursor_shape_device_v1::shape_ns_resize: 0167 return QByteArrayLiteral("ns-resize"); 0168 case QtWaylandServer::wp_cursor_shape_device_v1::shape_nesw_resize: 0169 return QByteArrayLiteral("nesw-resize"); 0170 case QtWaylandServer::wp_cursor_shape_device_v1::shape_nwse_resize: 0171 return QByteArrayLiteral("nwse-resize"); 0172 case QtWaylandServer::wp_cursor_shape_device_v1::shape_col_resize: 0173 return QByteArrayLiteral("col-resize"); 0174 case QtWaylandServer::wp_cursor_shape_device_v1::shape_row_resize: 0175 return QByteArrayLiteral("row-resize"); 0176 case QtWaylandServer::wp_cursor_shape_device_v1::shape_all_scroll: 0177 return QByteArrayLiteral("all-scroll"); 0178 case QtWaylandServer::wp_cursor_shape_device_v1::shape_zoom_in: 0179 return QByteArrayLiteral("zoom-in"); 0180 case QtWaylandServer::wp_cursor_shape_device_v1::shape_zoom_out: 0181 return QByteArrayLiteral("zoom-out"); 0182 default: 0183 return QByteArrayLiteral("default"); 0184 } 0185 } 0186 0187 void CursorShapeDeviceV1Interface::wp_cursor_shape_device_v1_set_shape(Resource *resource, uint32_t serial, uint32_t shape) 0188 { 0189 if (shape < shape_default || shape > shape_zoom_out) { 0190 wl_resource_post_error(resource->handle, error_invalid_shape, "unknown cursor shape"); 0191 return; 0192 } 0193 if (pointer) { 0194 if (!pointer->focusedSurface() || pointer->focusedSurface()->client()->client() != resource->client()) { 0195 return; 0196 } 0197 if (pointer->focusedSerial() == serial) { 0198 Q_EMIT pointer->cursorChanged(shapeName(shape)); 0199 } 0200 } else if (tabletTool) { 0201 if (!tabletTool->currentSurface() || tabletTool->currentSurface()->client()->client() != resource->client()) { 0202 return; 0203 } 0204 if (tabletTool->proximitySerial() == serial) { 0205 Q_EMIT tabletTool->cursorChanged(shapeName(shape)); 0206 } 0207 } 0208 } 0209 0210 } // namespace KWin