File indexing completed on 2024-06-09 04:20:41
0001 /* 0002 * SPDX-FileCopyrightText: 2012 Daniel Nicoletti <dantti12@gmail.com> 0003 * SPDX-FileCopyrightText: 2015 Boudewijn Rempt <boud@valdyas.org> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "KisColord.h" 0009 0010 #include <klocalizedstring.h> 0011 #include <kis_debug.h> 0012 0013 0014 #include "CdInterface.h" 0015 #include "CdProfileInterface.h" 0016 #include "CdDeviceInterface.h" 0017 0018 0019 struct Profile { 0020 QString kind; 0021 QString filename; 0022 QString title; 0023 qulonglong created; 0024 QString colorspace; 0025 }; 0026 0027 struct Device { 0028 0029 ~Device() { 0030 qDeleteAll(profiles); 0031 profiles.clear(); 0032 } 0033 0034 QString id; 0035 QString kind; 0036 QString model; 0037 QString vendor; 0038 QString colorspace; 0039 0040 QList<Profile*> profiles; 0041 0042 }; 0043 0044 KisColord::KisColord(QObject *parent) 0045 : QObject(parent) 0046 { 0047 //dbgKrita << "Creating KisColorD"; 0048 0049 m_cdInterface = new CdInterface(QLatin1String("org.freedesktop.ColorManager"), 0050 QLatin1String("/org/freedesktop/ColorManager"), 0051 QDBusConnection::systemBus(), 0052 this); 0053 0054 // listen to colord for device events 0055 connect(m_cdInterface, SIGNAL(DeviceAdded(QDBusObjectPath)), 0056 this, SLOT(deviceAdded(QDBusObjectPath))); 0057 connect(m_cdInterface, SIGNAL(DeviceRemoved(QDBusObjectPath)), 0058 this, SLOT(deviceRemoved(QDBusObjectPath))); 0059 connect(m_cdInterface, SIGNAL(DeviceChanged(QDBusObjectPath)), 0060 this, SLOT(deviceChanged(QDBusObjectPath))); 0061 0062 // Ask for devices 0063 QDBusPendingReply<QList<QDBusObjectPath> > async = m_cdInterface->GetDevices(); 0064 QDBusPendingCallWatcher *displayWatcher = new QDBusPendingCallWatcher(async, this); 0065 connect(displayWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), 0066 this, SLOT(gotDevices(QDBusPendingCallWatcher*))); 0067 0068 0069 // Make sure we know is colord is running 0070 QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.freedesktop.ColorManager", 0071 QDBusConnection::systemBus(), 0072 QDBusServiceWatcher::WatchForOwnerChange, 0073 this); 0074 0075 connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), 0076 this, SLOT(serviceOwnerChanged(QString,QString,QString))); 0077 } 0078 0079 KisColord::~KisColord() 0080 { 0081 qDeleteAll(m_devices); 0082 m_devices.clear(); 0083 } 0084 0085 QStringList KisColord::devices(const QString &type) const 0086 { 0087 QStringList res; 0088 Q_FOREACH (Device *dev, m_devices.values()) { 0089 if (type == dev->kind) { 0090 res << dev->id; 0091 } 0092 } 0093 return res; 0094 } 0095 0096 const QString KisColord::deviceName(const QString &id) const 0097 { 0098 QString res; 0099 Q_FOREACH (Device *dev, m_devices.values()) { 0100 if (dev->id == id) { 0101 res = dev->model + ", " + dev->vendor; 0102 } 0103 } 0104 return res; 0105 } 0106 0107 QByteArray KisColord::deviceProfile(const QString &id, int p) 0108 { 0109 QByteArray ba; 0110 Device *dev = 0; 0111 Profile *profile = 0; 0112 Q_FOREACH (Device *d, m_devices.values()) { 0113 if (d->id == id) { 0114 dev = d; 0115 break; 0116 } 0117 } 0118 0119 if (dev) { 0120 if (dev->profiles.size() > 0) { 0121 if (dev->profiles.size() < p) { 0122 profile = dev->profiles[p]; 0123 } 0124 else { 0125 profile = dev->profiles[0]; 0126 } 0127 } 0128 0129 if (profile) { 0130 //dbgKrita << "profile filename" << profile->filename; 0131 QFile f(profile->filename); 0132 if (f.open(QFile::ReadOnly)) { 0133 ba = f.readAll(); 0134 } 0135 else { 0136 dbgKrita << "Could not load profile" << profile->title << profile->filename; 0137 } 0138 } 0139 } 0140 0141 return ba; 0142 } 0143 0144 0145 0146 void KisColord::serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner) 0147 { 0148 Q_UNUSED(serviceName); 0149 if (newOwner.isEmpty() || oldOwner != newOwner) { 0150 // colord has quit or restarted 0151 qDeleteAll(m_devices); 0152 m_devices.clear(); 0153 } 0154 emit changed(); 0155 } 0156 0157 void KisColord::gotDevices(QDBusPendingCallWatcher *call) 0158 { 0159 //dbgKrita << "Got devices!!!"; 0160 0161 QDBusPendingReply<QList<QDBusObjectPath> > reply = *call; 0162 if (reply.isError()) { 0163 dbgKrita << "Unexpected message" << reply.error().message(); 0164 } else { 0165 QList<QDBusObjectPath> devices = reply.argumentAt<0>(); 0166 Q_FOREACH (const QDBusObjectPath &device, devices) { 0167 deviceAdded(device, false); 0168 } 0169 emit changed(); 0170 } 0171 //dbgKrita << "gotDevices" << m_devices.count(); 0172 call->deleteLater(); 0173 } 0174 0175 void KisColord::deviceChanged(const QDBusObjectPath &objectPath) 0176 { 0177 CdDeviceInterface device(QLatin1String("org.freedesktop.ColorManager"), 0178 objectPath.path(), 0179 QDBusConnection::systemBus()); 0180 if (!device.isValid()) { 0181 return; 0182 } 0183 0184 if (!m_devices.contains(objectPath)) { 0185 //dbgKrita << "deviceChanged for an unknown device" << objectPath.path(); 0186 deviceAdded(objectPath, false); 0187 return; 0188 } 0189 0190 QList<QDBusObjectPath> profiles = device.profiles(); 0191 0192 Device *dev = m_devices[objectPath]; 0193 qDeleteAll(dev->profiles); 0194 dev->profiles.clear(); 0195 0196 addProfilesToDevice(dev, profiles); 0197 0198 //dbgKrita << "deviceChanged" << dev->id << "with" << profiles.size() << "profiles"; 0199 0200 emit changed(dev->id); 0201 } 0202 0203 void KisColord::deviceAdded(const QDBusObjectPath &objectPath, bool emitChanged) 0204 { 0205 if (m_devices.contains(objectPath)) { 0206 //dbgKrita << "Device is already on the list" << objectPath.path(); 0207 return; 0208 } 0209 0210 CdDeviceInterface device(QLatin1String("org.freedesktop.ColorManager"), 0211 objectPath.path(), 0212 QDBusConnection::systemBus()); 0213 if (!device.isValid()) { 0214 dbgKrita << "Got an invalid device" << objectPath.path(); 0215 return; 0216 } 0217 0218 Device *dev = new Device; 0219 0220 dev->id = device.deviceId(); 0221 dev->kind = device.kind(); 0222 dev->model = device.model(); 0223 dev->vendor = device.vendor(); 0224 dev->colorspace = device.colorspace(); 0225 0226 m_devices[objectPath] = dev; 0227 0228 QList<QDBusObjectPath> profiles = device.profiles(); 0229 addProfilesToDevice(dev, profiles); 0230 0231 // dbgKrita << "deviceAdded" << dev->id 0232 // << dev->kind 0233 // << dev->model 0234 // << dev->vendor 0235 // << "with" << profiles.size() << "profiles"; 0236 0237 if (emitChanged) { 0238 emit changed(); 0239 } 0240 } 0241 0242 void KisColord::deviceRemoved(const QDBusObjectPath &objectPath) 0243 { 0244 if (m_devices.contains(objectPath)) { 0245 delete m_devices.take(objectPath); 0246 } 0247 emit changed(); 0248 } 0249 0250 void KisColord::addProfilesToDevice(Device *dev, QList<QDBusObjectPath> profiles) const 0251 { 0252 0253 Q_FOREACH (const QDBusObjectPath &profileObjectPath, profiles) { 0254 0255 CdProfileInterface profile(QLatin1String("org.freedesktop.ColorManager"), 0256 profileObjectPath.path(), 0257 QDBusConnection::systemBus()); 0258 if (!profile.isValid()) { 0259 return; 0260 } 0261 0262 0263 Profile *p = new Profile; 0264 0265 p->kind = profile.kind(); 0266 p->filename = profile.filename(); 0267 p->title = profile.title(); 0268 p->created = profile.created(); 0269 p->colorspace = profile.colorspace(); 0270 0271 dev->profiles << p; 0272 } 0273 } 0274