File indexing completed on 2024-11-10 04:57:25
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 <QList> 0012 // Wayland 0013 #include <wayland-server.h> 0014 0015 namespace KWin 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 QString securityContextAppId; 0030 qreal scaleOverride = 1.0; 0031 0032 private: 0033 static void destroyListenerCallback(wl_listener *listener, void *data); 0034 static void destroyLateListenerCallback(wl_listener *listener, void *data); 0035 ClientConnection *q; 0036 wl_listener destroyListener; 0037 wl_listener destroyLateListener; 0038 static QList<ClientConnectionPrivate *> s_allClients; 0039 }; 0040 0041 QList<ClientConnectionPrivate *> ClientConnectionPrivate::s_allClients; 0042 0043 ClientConnectionPrivate::ClientConnectionPrivate(wl_client *c, Display *display, ClientConnection *q) 0044 : client(c) 0045 , display(display) 0046 , q(q) 0047 { 0048 s_allClients << this; 0049 0050 destroyListener.notify = destroyListenerCallback; 0051 wl_client_add_destroy_listener(c, &destroyListener); 0052 0053 destroyLateListener.notify = destroyLateListenerCallback; 0054 wl_client_add_destroy_late_listener(c, &destroyLateListener); 0055 0056 wl_client_get_credentials(client, &pid, &user, &group); 0057 executablePath = executablePathFromPid(pid); 0058 } 0059 0060 ClientConnectionPrivate::~ClientConnectionPrivate() 0061 { 0062 s_allClients.removeAt(s_allClients.indexOf(this)); 0063 } 0064 0065 void ClientConnectionPrivate::destroyListenerCallback(wl_listener *listener, void *data) 0066 { 0067 wl_client *client = reinterpret_cast<wl_client *>(data); 0068 auto it = std::find_if(s_allClients.constBegin(), s_allClients.constEnd(), [client](ClientConnectionPrivate *c) { 0069 return c->client == client; 0070 }); 0071 Q_ASSERT(it != s_allClients.constEnd()); 0072 auto p = (*it); 0073 auto q = p->q; 0074 0075 Q_EMIT q->aboutToBeDestroyed(); 0076 wl_list_remove(&p->destroyListener.link); 0077 Q_EMIT q->disconnected(q); 0078 } 0079 0080 void ClientConnectionPrivate::destroyLateListenerCallback(wl_listener *listener, void *data) 0081 { 0082 wl_client *client = reinterpret_cast<wl_client *>(data); 0083 auto it = std::find_if(s_allClients.constBegin(), s_allClients.constEnd(), [client](ClientConnectionPrivate *c) { 0084 return c->client == client; 0085 }); 0086 Q_ASSERT(it != s_allClients.constEnd()); 0087 auto p = (*it); 0088 auto q = p->q; 0089 0090 wl_list_remove(&p->destroyLateListener.link); 0091 delete q; 0092 } 0093 0094 ClientConnection::ClientConnection(wl_client *c, Display *parent) 0095 : QObject(parent) 0096 , d(new ClientConnectionPrivate(c, parent, this)) 0097 { 0098 } 0099 0100 ClientConnection::~ClientConnection() = default; 0101 0102 void ClientConnection::flush() 0103 { 0104 wl_client_flush(d->client); 0105 } 0106 0107 void ClientConnection::destroy() 0108 { 0109 wl_client_destroy(d->client); 0110 } 0111 0112 wl_resource *ClientConnection::getResource(quint32 id) const 0113 { 0114 return wl_client_get_object(d->client, id); 0115 } 0116 0117 wl_client *ClientConnection::client() const 0118 { 0119 return d->client; 0120 } 0121 0122 ClientConnection::operator wl_client *() 0123 { 0124 return d->client; 0125 } 0126 0127 ClientConnection::operator wl_client *() const 0128 { 0129 return d->client; 0130 } 0131 0132 Display *ClientConnection::display() const 0133 { 0134 return d->display; 0135 } 0136 0137 gid_t ClientConnection::groupId() const 0138 { 0139 return d->group; 0140 } 0141 0142 pid_t ClientConnection::processId() const 0143 { 0144 return d->pid; 0145 } 0146 0147 uid_t ClientConnection::userId() const 0148 { 0149 return d->user; 0150 } 0151 0152 QString ClientConnection::executablePath() const 0153 { 0154 return d->executablePath; 0155 } 0156 0157 void ClientConnection::setScaleOverride(qreal scaleOveride) 0158 { 0159 Q_ASSERT(scaleOveride != 0); 0160 d->scaleOverride = scaleOveride; 0161 Q_EMIT scaleOverrideChanged(); 0162 } 0163 0164 qreal ClientConnection::scaleOverride() const 0165 { 0166 return d->scaleOverride; 0167 } 0168 0169 void ClientConnection::setSecurityContextAppId(const QString &appId) 0170 { 0171 d->securityContextAppId = appId; 0172 } 0173 0174 QString ClientConnection::securityContextAppId() const 0175 { 0176 return d->securityContextAppId; 0177 } 0178 } 0179 0180 #include "moc_clientconnection.cpp"