File indexing completed on 2024-05-19 16:35:16
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #include "clientconnection.h" 0007 #include "display.h" 0008 #include "utils/executable_path.h" 0009 // Qt 0010 #include <QFileInfo> 0011 #include <QVector> 0012 // Wayland 0013 #include <wayland-server.h> 0014 0015 namespace KWaylandServer 0016 { 0017 class ClientConnectionPrivate 0018 { 0019 public: 0020 ClientConnectionPrivate(wl_client *c, Display *display, ClientConnection *q); 0021 ~ClientConnectionPrivate(); 0022 0023 wl_client *client; 0024 Display *display; 0025 pid_t pid = 0; 0026 uid_t user = 0; 0027 gid_t group = 0; 0028 QString executablePath; 0029 0030 qreal scaleOverride = 1.0; 0031 0032 private: 0033 static void destroyListenerCallback(wl_listener *listener, void *data); 0034 ClientConnection *q; 0035 wl_listener listener; 0036 static QVector<ClientConnectionPrivate *> s_allClients; 0037 }; 0038 0039 QVector<ClientConnectionPrivate *> ClientConnectionPrivate::s_allClients; 0040 0041 ClientConnectionPrivate::ClientConnectionPrivate(wl_client *c, Display *display, ClientConnection *q) 0042 : client(c) 0043 , display(display) 0044 , q(q) 0045 { 0046 s_allClients << this; 0047 listener.notify = destroyListenerCallback; 0048 wl_client_add_destroy_listener(c, &listener); 0049 wl_client_get_credentials(client, &pid, &user, &group); 0050 executablePath = executablePathFromPid(pid); 0051 } 0052 0053 ClientConnectionPrivate::~ClientConnectionPrivate() 0054 { 0055 if (client) { 0056 wl_list_remove(&listener.link); 0057 } 0058 s_allClients.removeAt(s_allClients.indexOf(this)); 0059 } 0060 0061 void ClientConnectionPrivate::destroyListenerCallback(wl_listener *listener, void *data) 0062 { 0063 wl_client *client = reinterpret_cast<wl_client *>(data); 0064 auto it = std::find_if(s_allClients.constBegin(), s_allClients.constEnd(), [client](ClientConnectionPrivate *c) { 0065 return c->client == client; 0066 }); 0067 Q_ASSERT(it != s_allClients.constEnd()); 0068 auto p = (*it); 0069 auto q = p->q; 0070 Q_EMIT q->aboutToBeDestroyed(); 0071 p->client = nullptr; 0072 wl_list_remove(&p->listener.link); 0073 Q_EMIT q->disconnected(q); 0074 q->deleteLater(); 0075 } 0076 0077 ClientConnection::ClientConnection(wl_client *c, Display *parent) 0078 : QObject(parent) 0079 , d(new ClientConnectionPrivate(c, parent, this)) 0080 { 0081 } 0082 0083 ClientConnection::~ClientConnection() = default; 0084 0085 void ClientConnection::flush() 0086 { 0087 if (!d->client) { 0088 return; 0089 } 0090 wl_client_flush(d->client); 0091 } 0092 0093 void ClientConnection::destroy() 0094 { 0095 if (!d->client) { 0096 return; 0097 } 0098 wl_client_destroy(d->client); 0099 } 0100 0101 wl_resource *ClientConnection::getResource(quint32 id) const 0102 { 0103 if (!d->client) { 0104 return nullptr; 0105 } 0106 return wl_client_get_object(d->client, id); 0107 } 0108 0109 wl_client *ClientConnection::client() const 0110 { 0111 return d->client; 0112 } 0113 0114 ClientConnection::operator wl_client *() 0115 { 0116 return d->client; 0117 } 0118 0119 ClientConnection::operator wl_client *() const 0120 { 0121 return d->client; 0122 } 0123 0124 Display *ClientConnection::display() const 0125 { 0126 return d->display; 0127 } 0128 0129 gid_t ClientConnection::groupId() const 0130 { 0131 return d->group; 0132 } 0133 0134 pid_t ClientConnection::processId() const 0135 { 0136 return d->pid; 0137 } 0138 0139 uid_t ClientConnection::userId() const 0140 { 0141 return d->user; 0142 } 0143 0144 QString ClientConnection::executablePath() const 0145 { 0146 return d->executablePath; 0147 } 0148 0149 void ClientConnection::setScaleOverride(qreal scaleOveride) 0150 { 0151 d->scaleOverride = scaleOveride; 0152 Q_EMIT scaleOverrideChanged(); 0153 } 0154 0155 qreal ClientConnection::scaleOverride() const 0156 { 0157 return d->scaleOverride; 0158 } 0159 }