diffstat for libkscreen-5.2.2 libkscreen-5.3.0 CMakeLists.txt | 15 backends/CMakeLists.txt | 4 backends/fake/fake.cpp | 15 backends/fake/fake.h | 2 backends/fake/parser.cpp | 37 +- backends/qscreen/qscreenscreen.cpp | 21 - backends/xcbeventlistener.cpp | 213 +++++++++++ backends/xcbeventlistener.h | 78 ++++ backends/xcbwrapper.cpp | 67 +++ backends/xcbwrapper.h | 211 +++++++++++ backends/xrandr/CMakeLists.txt | 9 backends/xrandr/xlibandxrandr.h | 36 - backends/xrandr/xrandr.cpp | 265 ++++++-------- backends/xrandr/xrandr.h | 50 +- backends/xrandr/xrandrconfig.cpp | 536 +++++++++++++---------------- backends/xrandr/xrandrconfig.h | 31 - backends/xrandr/xrandrcrtc.cpp | 119 ++++++ backends/xrandr/xrandrcrtc.h | 68 +++ backends/xrandr/xrandrmode.cpp | 13 backends/xrandr/xrandrmode.h | 10 backends/xrandr/xrandroutput.cpp | 372 +++++++++----------- backends/xrandr/xrandroutput.h | 75 +--- backends/xrandr/xrandrscreen.cpp | 26 - backends/xrandr/xrandrscreen.h | 1 backends/xrandr/xrandrxcbhelper.cpp | 272 -------------- backends/xrandr/xrandrxcbhelper.h | 81 ---- backends/xrandr1.1/CMakeLists.txt | 6 backends/xrandr1.1/fixx11h.h | 301 ---------------- backends/xrandr1.1/wrapper.h | 174 --------- backends/xrandr1.1/xlibandxcb.h | 38 -- backends/xrandr1.1/xrandr11.cpp | 60 +-- backends/xrandr1.1/xrandr11.h | 8 debian/changelog | 65 ++- debian/control | 52 ++ debian/copyright | 119 ++++-- debian/libkf5screen-dev.acc.in | 20 - debian/libkf5screen-dev.install | 9 debian/libkf5screen6.install | 4 debian/libkf5screen6.symbols | 15 debian/meta/upstream_scm.json | 4 debian/rules | 3 debian/source/lintian-overrides | 1 debian/tests/acc | 11 debian/tests/control | 6 debian/tests/testsuite | 3 debian/watch | 5 interfaces/org.kde.KScreen.FakeBackend.xml | 7 src/backendlauncher/backendloader.cpp | 4 src/backendlauncher/main.cpp | 24 - src/config.cpp | 169 +++++---- src/config.h | 22 + src/configoperation.cpp | 2 src/getconfigoperation.cpp | 9 src/output.cpp | 6 src/output.h | 6 src/types.h | 12 56 files changed, 1851 insertions(+), 1941 deletions(-) diff -Nru libkscreen-5.2.2/CMakeLists.txt libkscreen-5.3.0/CMakeLists.txt --- libkscreen-5.2.2/CMakeLists.txt 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/CMakeLists.txt 2015-04-23 10:04:35.000000000 +0000 @@ -1,9 +1,9 @@ project(libkscreen) -set(PROJECT_VERSION "5.2.2") +set(PROJECT_VERSION "5.3.0") cmake_minimum_required(VERSION 2.8.12) -find_package(ECM 0.0.11 REQUIRED NO_MODULE) +find_package(ECM 1.3.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(KDEInstallDirs) include(KDECompilerSettings) @@ -20,15 +20,8 @@ find_package(XCB COMPONENTS XCB RANDR) set_package_properties(XCB PROPERTIES - TYPE OPTIONAL - PURPOSE "Required for building XRandR 1.1 backend" -) - -find_package(X11) -set_package_properties(X11 PROPERTIES DESCRIPTION "X11 libraries" - URL "http://www.x.org" - TYPE OPTIONAL - PURPOSE "Required for building XRandR 1.2 backend" + TYPE REQUIRED + PURPOSE "Required for building XRandR backends" ) set(KF5_VERSION ${PROJECT_VERSION}) #When we are happy with the api, we can sync with frameworks diff -Nru libkscreen-5.2.2/backends/CMakeLists.txt libkscreen-5.3.0/backends/CMakeLists.txt --- libkscreen-5.2.2/backends/CMakeLists.txt 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/CMakeLists.txt 2015-04-23 10:04:35.000000000 +0000 @@ -1,6 +1,4 @@ add_subdirectory(fake) add_subdirectory(qscreen) add_subdirectory(xrandr) -# if (XCB_FOUND AND X11_XCB_FOUND) - add_subdirectory(xrandr1.1) -# endif(XCB_FOUND AND X11_XCB_FOUND) +add_subdirectory(xrandr1.1) diff -Nru libkscreen-5.2.2/backends/fake/fake.cpp libkscreen-5.3.0/backends/fake/fake.cpp --- libkscreen-5.2.2/backends/fake/fake.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/fake/fake.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -173,3 +173,18 @@ output->setRotation(rot); Q_EMIT configChanged(mConfig); } + +void Fake::addOutput(int outputId, const QString &name) +{ + KScreen::OutputPtr output(new KScreen::Output); + output->setId(outputId); + output->setName(name); + mConfig->addOutput(output); + Q_EMIT configChanged(mConfig); +} + +void Fake::removeOutput(int outputId) +{ + mConfig->removeOutput(outputId); + Q_EMIT configChanged(mConfig); +} diff -Nru libkscreen-5.2.2/backends/fake/fake.h libkscreen-5.3.0/backends/fake/fake.h --- libkscreen-5.2.2/backends/fake/fake.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/fake/fake.h 2015-04-23 10:04:35.000000000 +0000 @@ -45,6 +45,8 @@ void setPrimary(int outputId, bool primary); void setCurrentModeId(int outputId, const QString &modeId); void setRotation(int outputId, int rotation); + void addOutput(int outputId, const QString &name); + void removeOutput(int outputId); private Q_SLOTS: void delayedInit(); diff -Nru libkscreen-5.2.2/backends/fake/parser.cpp libkscreen-5.3.0/backends/fake/parser.cpp --- libkscreen-5.2.2/backends/fake/parser.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/fake/parser.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -23,6 +23,8 @@ #include "output.h" #include +#include +#include #include #include #include @@ -78,21 +80,30 @@ return screen; } -void Parser::qvariant2qobject(const QVariantMap& variant, QObject* object) +void Parser::qvariant2qobject(const QVariantMap &variant, QObject *object) { - for ( QVariantMap::const_iterator iter = variant.begin(); iter != variant.end(); ++iter ) - { - const QVariant property = object->property( iter.key().toLatin1() ); - Q_ASSERT( property.isValid() ); - if ( property.isValid() ) - { + const QMetaObject *metaObject = object->metaObject(); + for (QVariantMap::const_iterator iter = variant.begin(); iter != variant.end(); ++iter) { + const int propertyIndex = metaObject->indexOfProperty(qPrintable(iter.key())); + if (propertyIndex == -1) { + qWarning() << "Skipping non-existent property" << iter.key(); + continue; + } + const QMetaProperty metaProperty = metaObject->property(propertyIndex); + if (!metaProperty.isWritable()) { + qWarning() << "Skipping read-only property" << iter.key(); + continue; + } + + const QVariant property = object->property(iter.key().toLatin1()); + Q_ASSERT(property.isValid()); + if (property.isValid()) { QVariant value = iter.value(); - if ( value.canConvert( property.type() ) ) - { - value.convert( property.type() ); - object->setProperty( iter.key().toLatin1(), value ); - } else if ( QString( QLatin1String("QVariant") ).compare( QLatin1String( property.typeName() ) ) == 0) { - object->setProperty( iter.key().toLatin1(), value ); + if (value.canConvert(property.type())) { + value.convert(property.type()); + object->setProperty(iter.key().toLatin1(), value); + } else if (QString(QLatin1String("QVariant")).compare(QLatin1String(property.typeName())) == 0) { + object->setProperty(iter.key().toLatin1(), value); } } } diff -Nru libkscreen-5.2.2/backends/qscreen/qscreenscreen.cpp libkscreen-5.3.0/backends/qscreen/qscreenscreen.cpp --- libkscreen-5.2.2/backends/qscreen/qscreenscreen.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/qscreen/qscreenscreen.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -46,13 +46,20 @@ void QScreenScreen::updateKScreenScreen(ScreenPtr &screen) const { + if (!screen) { + return; + } + auto primary = QGuiApplication::primaryScreen(); - QSize _s = primary->availableVirtualGeometry().size(); - screen->setCurrentSize(_s); - screen->setId(1); - screen->setMaxSize(_s); - screen->setMinSize(_s); - screen->setCurrentSize(_s); - screen->setMaxActiveOutputsCount(QGuiApplication::screens().count()); + if (primary) { + QSize _s = primary->availableVirtualGeometry().size(); + + screen->setCurrentSize(_s); + screen->setId(1); + screen->setMaxSize(_s); + screen->setMinSize(_s); + screen->setCurrentSize(_s); + screen->setMaxActiveOutputsCount(QGuiApplication::screens().count()); + } } diff -Nru libkscreen-5.2.2/backends/xcbeventlistener.cpp libkscreen-5.3.0/backends/xcbeventlistener.cpp --- libkscreen-5.2.2/backends/xcbeventlistener.cpp 1970-01-01 00:00:00.000000000 +0000 +++ libkscreen-5.3.0/backends/xcbeventlistener.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -0,0 +1,213 @@ +/************************************************************************************* + * Copyright 2012, 2013 Daniel Vrátil * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * + *************************************************************************************/ + +#include "xcbeventlistener.h" + +#include +#include + +#include + +Q_LOGGING_CATEGORY(KSCREEN_XCB_HELPER, "kscreen.xcb.helper") + +XCBEventListener::XCBEventListener(): + QObject(), + m_isRandrPresent(false), + m_randrBase(0), + m_randrErrorBase(0), + m_majorOpcode(0), + m_eventType(0), + m_versionMajor(0), + m_versionMinor(0), + m_window(0) +{ + QLoggingCategory::setFilterRules(QStringLiteral("kscreen.xcb.helper = true")); + + xcb_connection_t* c = QX11Info::connection(); + xcb_prefetch_extension_data(c, &xcb_randr_id); + auto cookie = xcb_randr_query_version(c, XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION); + const auto *queryExtension = xcb_get_extension_data(c, &xcb_randr_id); + if (!queryExtension) { + qCDebug(KSCREEN_XCB_HELPER) << "Fail to query for xrandr extension"; + return; + } + if (!queryExtension->present) { + qCDebug(KSCREEN_XCB_HELPER) << "XRandR extension is not present at all"; + return; + } + + m_isRandrPresent = queryExtension->present; + m_randrBase = queryExtension->first_event; + m_randrErrorBase = queryExtension->first_error; + m_majorOpcode = queryExtension->major_opcode; + + xcb_generic_error_t *error = NULL; + auto* versionReply = xcb_randr_query_version_reply(c, cookie, &error); + Q_ASSERT_X(versionReply, "xrandrxcbhelper", "Query to fetch xrandr version failed"); + if (error) { + qFatal("Error while querying for xrandr version: %d", error->error_code); + } + m_versionMajor = versionReply->major_version; + m_versionMinor = versionReply->minor_version; + free(versionReply); + + qCDebug(KSCREEN_XCB_HELPER).nospace() << "Detected XRandR " << m_versionMajor << "." << m_versionMinor; + qCDebug(KSCREEN_XCB_HELPER) << "Event Base: " << m_randrBase; + qCDebug(KSCREEN_XCB_HELPER) << "Event Error: "<< m_randrErrorBase; + + uint32_t rWindow = QX11Info::appRootWindow(); + m_window = xcb_generate_id(c); + xcb_create_window(c, XCB_COPY_FROM_PARENT, m_window, + rWindow, + 0, 0, 1, 1, 0, XCB_COPY_FROM_PARENT, + XCB_COPY_FROM_PARENT, 0, NULL); + + xcb_randr_select_input(c, m_window, + XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE | + XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE | + XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE | + XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY + ); + + qApp->installNativeEventFilter(this); +} + +XCBEventListener::~XCBEventListener() +{ + if (m_window && QX11Info::connection()) { + xcb_destroy_window(QX11Info::connection(), m_window); + } +} + +QString XCBEventListener::rotationToString(xcb_randr_rotation_t rotation) +{ + switch (rotation) { + case XCB_RANDR_ROTATION_ROTATE_0: + return "Rotate_0"; + case XCB_RANDR_ROTATION_ROTATE_90: + return "Rotate_90"; + case XCB_RANDR_ROTATION_ROTATE_180: + return "Rotate_180"; + case XCB_RANDR_ROTATION_ROTATE_270: + return "Rotate_270"; + case XCB_RANDR_ROTATION_REFLECT_X: + return "Reflect_X"; + case XCB_RANDR_ROTATION_REFLECT_Y: + return "REflect_Y"; + } + + return QString("invalid value (%1)").arg(rotation); +} + +QString XCBEventListener::connectionToString(xcb_randr_connection_t connection) +{ + switch (connection) { + case XCB_RANDR_CONNECTION_CONNECTED: + return "Connected"; + case XCB_RANDR_CONNECTION_DISCONNECTED: + return "Disconnected"; + case XCB_RANDR_CONNECTION_UNKNOWN: + return "UnknownConnection"; + } + + return QString("invalid value (%1)").arg(connection); +} + +bool XCBEventListener::nativeEventFilter(const QByteArray& eventType, void* message, long int* result) +{ + Q_UNUSED(result); + + if (eventType != "xcb_generic_event_t") { + return false; + } + + xcb_generic_event_t* e = static_cast(message); + const uint8_t xEventType = e->response_type & ~0x80; + + //If this event is not xcb_randr_notify, we don't want it + if (xEventType == m_randrBase + XCB_RANDR_SCREEN_CHANGE_NOTIFY) { + handleScreenChange(e); + } + if (xEventType == m_randrBase + XCB_RANDR_NOTIFY) { + handleXRandRNotify(e); + } + + return false; +} + +void XCBEventListener::handleScreenChange(xcb_generic_event_t* e) +{ + xcb_randr_screen_change_notify_event_t *e2 = + (xcb_randr_screen_change_notify_event_t *) e; + + // Only accept notifications for our window + if (e2->request_window != m_window) { + return; + } + + qCDebug(KSCREEN_XCB_HELPER) << "RRScreenChangeNotify"; + qCDebug(KSCREEN_XCB_HELPER) << "\tWindow:" << e2->request_window; + qCDebug(KSCREEN_XCB_HELPER) << "\tRoot:" << e2->root; + qCDebug(KSCREEN_XCB_HELPER) << "\tRotation: " << rotationToString((xcb_randr_rotation_t) e2->rotation); + qCDebug(KSCREEN_XCB_HELPER) << "\tSize ID:" << e2->sizeID; + qCDebug(KSCREEN_XCB_HELPER) << "\tSize: " << e2->width << e2->height; + qCDebug(KSCREEN_XCB_HELPER) << "\tSizeMM: " << e2->mwidth << e2->mheight; + + Q_EMIT screenChanged((xcb_randr_rotation_t) e2->rotation, QSize(e2->width, e2->height), QSize(e2->mwidth, e2->mheight)); + Q_EMIT outputsChanged(); +} + +void XCBEventListener::handleXRandRNotify(xcb_generic_event_t* e) +{ + xcb_randr_notify_event_t* + randrEvent = reinterpret_cast(e); + + if (randrEvent->subCode == XCB_RANDR_NOTIFY_CRTC_CHANGE) { + xcb_randr_crtc_change_t crtc = randrEvent->u.cc; + qCDebug(KSCREEN_XCB_HELPER) << "RRNotify_CrtcChange"; + qCDebug(KSCREEN_XCB_HELPER) << "\tCRTC: " << crtc.crtc; + qCDebug(KSCREEN_XCB_HELPER) << "\tMode: " << crtc.mode; + qCDebug(KSCREEN_XCB_HELPER) << "\tRotation: " << rotationToString((xcb_randr_rotation_t) crtc.rotation); + qCDebug(KSCREEN_XCB_HELPER) << "\tGeometry: " << crtc.x << crtc.y << crtc.width << crtc.height; + Q_EMIT crtcChanged(crtc.crtc, crtc.mode, (xcb_randr_rotation_t) crtc.rotation, + QRect(crtc.x, crtc.y, crtc.width, crtc.height)); + + } else if(randrEvent->subCode == XCB_RANDR_NOTIFY_OUTPUT_CHANGE) { + xcb_randr_output_change_t output = randrEvent->u.oc; + qCDebug(KSCREEN_XCB_HELPER) << "RRotify_OutputChange"; + qCDebug(KSCREEN_XCB_HELPER) << "\tOutput: " << output.output; + qCDebug(KSCREEN_XCB_HELPER) << "\tCRTC: " << output.crtc; + qCDebug(KSCREEN_XCB_HELPER) << "\tMode: " << output.mode; + qCDebug(KSCREEN_XCB_HELPER) << "\tRotation: " << rotationToString((xcb_randr_rotation_t) output.rotation); + qCDebug(KSCREEN_XCB_HELPER) << "\tConnection: " << connectionToString((xcb_randr_connection_t) output.connection); + qCDebug(KSCREEN_XCB_HELPER) << "\tSubpixel Order: " << output.subpixel_order; + Q_EMIT outputChanged(output.output, output.crtc, output.mode, + (xcb_randr_connection_t) output.connection); + + } else if(randrEvent->subCode == XCB_RANDR_NOTIFY_OUTPUT_PROPERTY) { + xcb_randr_output_property_t property = randrEvent->u.op; + + XCB::ScopedPointer reply(xcb_get_atom_name_reply(QX11Info::connection(), + xcb_get_atom_name(QX11Info::connection(), property.atom), NULL)); + + qCDebug(KSCREEN_XCB_HELPER) << "RRNotify_OutputProperty (ignored)"; + qCDebug(KSCREEN_XCB_HELPER) << "\tOutput: " << property.output; + qCDebug(KSCREEN_XCB_HELPER) << "\tProperty: " << xcb_get_atom_name_name(reply.data()); + qCDebug(KSCREEN_XCB_HELPER) << "\tState (newValue, Deleted): " << property.status; + } +} diff -Nru libkscreen-5.2.2/backends/xcbeventlistener.h libkscreen-5.3.0/backends/xcbeventlistener.h --- libkscreen-5.2.2/backends/xcbeventlistener.h 1970-01-01 00:00:00.000000000 +0000 +++ libkscreen-5.3.0/backends/xcbeventlistener.h 2015-04-23 10:04:35.000000000 +0000 @@ -0,0 +1,78 @@ +/************************************************************************************* + * Copyright 2012, 2013 Daniel Vrátil * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * + *************************************************************************************/ + +#ifndef XRANDRX11HELPER_H +#define XRANDRX11HELPER_H + +#include +#include +#include +#include + +#include "xcbwrapper.h" + +class XCBEventListener : public QObject, + public QAbstractNativeEventFilter +{ + Q_OBJECT + + public: + XCBEventListener(); + ~XCBEventListener(); + + bool nativeEventFilter(const QByteArray& eventType, void* message, long int* result) Q_DECL_OVERRIDE; + + Q_SIGNALS: + /* Emitted when only XRandR 1.1 or older is available */ + void screenChanged(xcb_randr_rotation_t rotation, + const QSize &sizePx, + const QSize &sizeMm); + void outputsChanged(); + + /* Emitted only when XRandR 1.2 or newer is available */ + void crtcChanged(xcb_randr_crtc_t crtc, + xcb_randr_mode_t mode, + xcb_randr_rotation_t rotation, + const QRect &geom); + void outputChanged(xcb_randr_output_t output, + xcb_randr_crtc_t crtc, + xcb_randr_mode_t mode, + xcb_randr_connection_t connection); + void outputPropertyChanged(xcb_randr_output_t output); + + private: + QString rotationToString(xcb_randr_rotation_t rotation); + QString connectionToString(xcb_randr_connection_t connection); + void handleScreenChange(xcb_generic_event_t *e); + void handleXRandRNotify(xcb_generic_event_t *e); + + protected: + bool m_isRandrPresent; + bool m_event11; + int m_randrBase; + int m_randrErrorBase; + int m_majorOpcode; + int m_eventType; + int m_versionMajor; + int m_versionMinor; + + uint32_t m_window; +}; + +Q_DECLARE_LOGGING_CATEGORY(KSCREEN_XCB_HELPER) +#endif // XRANDRX11HELPER_H diff -Nru libkscreen-5.2.2/backends/xcbwrapper.cpp libkscreen-5.3.0/backends/xcbwrapper.cpp --- libkscreen-5.2.2/backends/xcbwrapper.cpp 1970-01-01 00:00:00.000000000 +0000 +++ libkscreen-5.3.0/backends/xcbwrapper.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -0,0 +1,67 @@ +/******************************************************************** + K Win - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2012, 2013 Martin Gräßlin +Copyright (C) 2015 Daniel Vrátil + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +#include "xcbwrapper.h" + +static xcb_connection_t *sXRandR11XCBConnection = 0; + +xcb_connection_t* XCB::connection() +{ + // Use our own connection to make sure that we won't mess up Qt's connection + // if something goes wrong on our side. + if (sXRandR11XCBConnection == 0) { + sXRandR11XCBConnection = xcb_connect(0, 0); + } + return sXRandR11XCBConnection; +} + +void XCB::closeConnection() +{ + if (sXRandR11XCBConnection) { + xcb_disconnect(sXRandR11XCBConnection); + sXRandR11XCBConnection = 0; + } +} + +xcb_screen_t* XCB::screenOfDisplay(xcb_connection_t* c, int screen) +{ + for (auto iter = xcb_setup_roots_iterator(xcb_get_setup(c)); + iter.rem; --screen, xcb_screen_next(&iter)) + { + if (screen == 0) { + return iter.data; + } + } + + return Q_NULLPTR; +} + + +XCB::GrabServer::GrabServer() +{ + xcb_grab_server(connection()); +} + +XCB::GrabServer::~GrabServer() +{ + xcb_ungrab_server(connection()); + xcb_flush(connection()); +} diff -Nru libkscreen-5.2.2/backends/xcbwrapper.h libkscreen-5.3.0/backends/xcbwrapper.h --- libkscreen-5.2.2/backends/xcbwrapper.h 1970-01-01 00:00:00.000000000 +0000 +++ libkscreen-5.3.0/backends/xcbwrapper.h 2015-04-23 10:04:35.000000000 +0000 @@ -0,0 +1,211 @@ +/******************************************************************** + K Win - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2012, 2013 Martin Gräßlin +Copyright (C) 2015 Daniel Vrátil + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +#ifndef XCB_WRAPPER_H +#define XCB_WRAPPER_H + +#include +#include + +#include +#include + +#include +#include + +namespace XCB +{ + +template +using ScopedPointer = QScopedPointer; + +xcb_connection_t *connection(); +void closeConnection(); +xcb_screen_t *screenOfDisplay(xcb_connection_t *c, int screen); + +struct GrabServer +{ + GrabServer(); + ~GrabServer(); +}; + +template +class Wrapper +{ +public: + Wrapper() + : m_retrieved(false) + , m_window(XCB_WINDOW_NONE) + , m_reply(Q_NULLPTR) + { + m_cookie.sequence = 0; + } + explicit Wrapper(const RequestFuncArgs& ... args) + : m_retrieved(false) + , m_cookie(requestFunc(connection(), args ...)) + , m_window(requestWindow(args ...)) + , m_reply(Q_NULLPTR) + { + } + explicit Wrapper(const Wrapper &other) + : m_retrieved(other.m_retrieved) + , m_cookie(other.m_cookie) + , m_window(other.m_window) + , m_reply(Q_NULLPTR) + { + takeFromOther(const_cast(other)); + } + virtual ~Wrapper() { + cleanup(); + } + inline Wrapper &operator=(const Wrapper &other) { + if (this != &other) { + // if we had managed a reply, free it + cleanup(); + // copy members + m_retrieved = other.m_retrieved; + m_cookie = other.m_cookie; + m_window = other.m_window; + m_reply = other.m_reply; + // take over the responsibility for the reply pointer + takeFromOther(const_cast(other)); + } + return *this; + } + + inline operator const Reply*() const { + getReply(); + return m_reply; + } + inline const Reply* operator->() const { + getReply(); + return m_reply; + } + inline bool isNull() const { + getReply(); + return m_reply == NULL; + } + inline operator bool() const { + return !isNull(); + } + inline const Reply* data() const { + getReply(); + return m_reply; + } + inline xcb_window_t window() const { + return m_window; + } + inline bool isRetrieved() const { + return m_retrieved; + } + /** + * Returns the value of the reply pointer referenced by this object. The reply pointer of + * this object will be reset to null. Calling any method which requires the reply to be valid + * will crash. + * + * Callers of this function take ownership of the pointer. + **/ + inline Reply *take() { + getReply(); + Reply *ret = m_reply; + m_reply = Q_NULLPTR; + m_window = XCB_WINDOW_NONE; + return ret; + } + +protected: + void getReply() const { + if (m_retrieved || !m_cookie.sequence) { + return; + } + m_reply = replyFunc(connection(), m_cookie, NULL); + m_retrieved = true; + } + +private: + inline void cleanup() { + if (!m_retrieved && m_cookie.sequence) { + xcb_discard_reply(connection(), m_cookie.sequence); + } else if (m_reply) { + free(m_reply); + } + } + inline void takeFromOther(Wrapper &other) { + if (m_retrieved) { + m_reply = other.take(); + } else { + //ensure that other object doesn't try to get the reply or discards it in the dtor + other.m_retrieved = true; + other.m_window = XCB_WINDOW_NONE; + } + } + template + constexpr xcb_window_t requestWindow(const Args & ... args) { + return std::is_same>::type, xcb_window_t>::value + ? std::get<0>(std::tuple(args ...)) + : static_cast(XCB_WINDOW_NONE); + } + + mutable bool m_retrieved; + Cookie m_cookie; + xcb_window_t m_window; + mutable Reply *m_reply; +}; + +#define XCB_DECLARE_TYPE(name, xcb_request, ...) \ + typedef Wrapper name + +XCB_DECLARE_TYPE(ScreenInfo, xcb_randr_get_screen_info, + xcb_window_t); + +XCB_DECLARE_TYPE(ScreenSize, xcb_randr_get_screen_size_range, + xcb_window_t); + +XCB_DECLARE_TYPE(PrimaryOutput, xcb_randr_get_output_primary, + xcb_window_t); + +XCB_DECLARE_TYPE(InternAtom, xcb_intern_atom, + uint8_t, uint16_t, const char *); + +XCB_DECLARE_TYPE(OutputInfo, xcb_randr_get_output_info, + xcb_randr_output_t, xcb_timestamp_t); + +XCB_DECLARE_TYPE(CRTCInfo, xcb_randr_get_crtc_info, + xcb_randr_crtc_t, xcb_timestamp_t); + +XCB_DECLARE_TYPE(AtomName, xcb_get_atom_name, + xcb_atom_t); + +} + +#endif \ No newline at end of file diff -Nru libkscreen-5.2.2/backends/xrandr/CMakeLists.txt libkscreen-5.3.0/backends/xrandr/CMakeLists.txt --- libkscreen-5.2.2/backends/xrandr/CMakeLists.txt 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/CMakeLists.txt 2015-04-23 10:04:35.000000000 +0000 @@ -1,15 +1,16 @@ include_directories(${CMAKE_SOURCE_DIR}/src ${CMAKE_BUILD_DIR} - ${X11_Xrandr_INCLUDE_PATH} ) set(xrandr_SRCS xrandr.cpp - xrandrxcbhelper.cpp xrandrconfig.cpp + xrandrcrtc.cpp xrandroutput.cpp xrandrmode.cpp xrandrscreen.cpp + ../xcbwrapper.cpp + ../xcbeventlistener.cpp ) add_library(KSC_XRandR MODULE ${xrandr_SRCS}) @@ -18,9 +19,7 @@ target_link_libraries(KSC_XRandR Qt5::Core Qt5::Gui Qt5::X11Extras - ${X11_Xrandr_LIB} - ${X11_LIBRARIES} - ${XCB_LIBRARIES} #for xrandrxcbhelper + ${XCB_LIBRARIES} KF5::Screen ) diff -Nru libkscreen-5.2.2/backends/xrandr/xlibandxrandr.h libkscreen-5.3.0/backends/xrandr/xlibandxrandr.h --- libkscreen-5.2.2/backends/xrandr/xlibandxrandr.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xlibandxrandr.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/************************************************************************************* - * Copyright (C) 2012 by Alejandro Fiestas Olivares * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - *************************************************************************************/ - -#ifndef XLIBANDXRANDR_H -#define XLIBANDXRANDR_H - -extern "C" -{ -#include -#include -#define INT8 _X11INT8 -#define INT32 _X11INT32 -#include -#undef INT8 -#undef INT32 -#include -} - -#include "../xrandr1.1/fixx11h.h" - -#endif // XLIBANDXRANDR diff -Nru libkscreen-5.2.2/backends/xrandr/xrandr.cpp libkscreen-5.3.0/backends/xrandr/xrandr.cpp --- libkscreen-5.2.2/backends/xrandr/xrandr.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandr.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -19,7 +19,9 @@ #include "xrandr.h" #include "xrandrconfig.h" -#include "xrandrxcbhelper.h" +#include "xrandrscreen.h" +#include "../xcbwrapper.h" +#include "../xcbeventlistener.h" #include "config.h" #include "output.h" @@ -29,15 +31,14 @@ #include #include #include +#include +#include #include #include -#include - -Display* XRandR::s_display = 0; -int XRandR::s_screen = 0; -Window XRandR::s_rootWindow = 0; +xcb_screen_t* XRandR::s_screen = 0; +xcb_window_t XRandR::s_rootWindow = 0; XRandRConfig* XRandR::s_internalConfig = 0; int XRandR::s_randrBase = 0; int XRandR::s_randrError = 0; @@ -53,18 +54,25 @@ : KScreen::AbstractBackend() , m_x11Helper(0) , m_isValid(false) + , m_configChangeCompressor(0) { QLoggingCategory::setFilterRules(QLatin1Literal("kscreen.xrandr.debug = true")); + qRegisterMetaType("xcb_randr_output_t"); + qRegisterMetaType("xcb_randr_crtc_t"); + qRegisterMetaType("xcb_randr_mode_t"); + qRegisterMetaType("xcb_randr_connection_t"); + qRegisterMetaType("xcb_randr_rotation_t"); + // Use our own connection to make sure that we won't mess up Qt's connection // if something goes wrong on our side. xcb_generic_error_t *error = 0; xcb_randr_query_version_reply_t* version; - xcb_connection_t *connection = xcb_connect(0, 0); - version = xcb_randr_query_version_reply(connection, xcb_randr_query_version(connection, XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION), &error); - xcb_disconnect(connection); + XCB::connection(); + version = xcb_randr_query_version_reply(XCB::connection(), xcb_randr_query_version(XCB::connection(), XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION), &error); if (!version || error) { + XCB::closeConnection(); free(error); return; } @@ -72,16 +80,19 @@ if ((version->major_version > 1) || ((version->major_version == 1) && (version->minor_version >= 2))) { m_isValid = true; } else { + XCB::closeConnection(); qCWarning(KSCREEN_XRANDR) << "XRandR extension not available or unsupported version"; return; } - if (s_display == 0) { - s_display = QX11Info::display(); - s_screen = DefaultScreen(s_display); - s_rootWindow = XRootWindow(s_display, s_screen); - - XRRQueryExtension(s_display, &s_randrBase, &s_randrError); + if (s_screen == 0) { + s_screen = XCB::screenOfDisplay(XCB::connection(), QX11Info::appScreen()); + s_rootWindow = s_screen->root; + + xcb_prefetch_extension_data(XCB::connection(), &xcb_randr_id); + auto reply = xcb_get_extension_data(XCB::connection(), &xcb_randr_id); + s_randrBase = reply->first_event; + s_randrError = reply->first_error; } XRandR::s_has_1_3 = (version->major_version > 1 || (version->major_version == 1 && version->minor_version >= 3)); @@ -91,14 +102,25 @@ } if (!s_monitorInitialized) { - m_x11Helper = new XRandRXCBHelper(); - /* In case of XRandR 1.0 or 1.1 */ - connect(m_x11Helper, SIGNAL(outputsChanged()), SLOT(updateConfig())); - - /* XRandR >= 1.2 */ - connect(m_x11Helper, SIGNAL(outputChanged(RROutput)), SLOT(updateOutput(RROutput))); - connect(m_x11Helper, SIGNAL(crtcChanged(RRCrtc)), SLOT(updateCrtc(RRCrtc))); - connect(s_internalConfig, SIGNAL(outputRemoved(int)), SLOT(outputRemovedSlot())); + m_x11Helper = new XCBEventListener(); + connect(m_x11Helper, &XCBEventListener::outputChanged, + this, &XRandR::outputChanged, + Qt::QueuedConnection); + connect(m_x11Helper, &XCBEventListener::crtcChanged, + this, &XRandR::crtcChanged, + Qt::QueuedConnection); + connect(m_x11Helper, &XCBEventListener::screenChanged, + this, &XRandR::screenChanged, + Qt::QueuedConnection); + + m_configChangeCompressor = new QTimer(this); + m_configChangeCompressor->setSingleShot(true); + m_configChangeCompressor->setInterval(500); + connect(m_configChangeCompressor, &QTimer::timeout, + [&]() { + qCDebug(KSCREEN_XRANDR) << "Emitting configChanged()"; + Q_EMIT configChanged(config()); + }); s_monitorInitialized = true; } @@ -120,45 +142,62 @@ } -void XRandR::updateConfig() -{ - s_internalConfig->update(); - Q_EMIT configChanged(config()); -} - -void XRandR::outputRemovedSlot() +void XRandR::outputChanged(xcb_randr_output_t output, xcb_randr_crtc_t crtc, + xcb_randr_mode_t mode, xcb_randr_connection_t connection) { - Q_EMIT configChanged(config()); -} - -void XRandR::updateOutput(RROutput output) -{ - XRandROutput *xOutput = s_internalConfig->outputs().value(output); + XRandROutput *xOutput = s_internalConfig->output(output); + XCB::PrimaryOutput primary(XRandR::rootWindow()); if (!xOutput) { s_internalConfig->addNewOutput(output); } else { - RROutput primary = XRRGetOutputPrimary(XRandR::display(), XRandR::rootWindow()); - xOutput->update((output == primary) ? XRandROutput::SetPrimary : XRandROutput::UnsetPrimary); - if (output == primary) { - s_internalConfig->m_primaryOutput = output; + switch (crtc == XCB_NONE && mode == XCB_NONE && connection == XCB_RANDR_CONNECTION_DISCONNECTED) { + case true: { + XCB::OutputInfo info(output, XCB_TIME_CURRENT_TIME); + if (info.isNull()) { + s_internalConfig->removeOutput(output); + qCDebug(KSCREEN_XRANDR) << "Output" << output << " removed"; + break; + } + // info is valid: fall-through } + case false: { + xOutput->update(crtc, mode, connection, (primary->output == output)); + qCDebug(KSCREEN_XRANDR) << "Output" << xOutput->id() << ": connected =" << xOutput->isConnected() << ", enabled =" << xOutput->isEnabled(); + break; + } + } // switch } - Q_EMIT configChanged(config()); + m_configChangeCompressor->start(); } -void XRandR::updateCrtc(RRCrtc crtc) +void XRandR::crtcChanged(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, + xcb_randr_rotation_t rotation, const QRect& geom) { - XRRCrtcInfo* crtcInfo = XRRCrtc(crtc); - for (int i = 0; i < crtcInfo->noutput; ++i) { - XRandROutput *xOutput = s_internalConfig->outputs().value(crtcInfo->outputs[i]); - xOutput->update(); + XRandRCrtc *xCrtc = s_internalConfig->crtc(crtc); + if (!xCrtc) { + s_internalConfig->addNewCrtc(crtc); + } else { + xCrtc->update(mode, rotation, geom); } - XRRFreeCrtcInfo(crtcInfo); - Q_EMIT configChanged(config()); + m_configChangeCompressor->start(); } +void XRandR::screenChanged(xcb_randr_rotation_t rotation, + const QSize &sizePx, const QSize &sizeMm) +{ + Q_UNUSED(rotation); + Q_UNUSED(sizeMm); + + XRandRScreen *xScreen = s_internalConfig->screen(); + Q_ASSERT(xScreen); + xScreen->update(sizePx); + + m_configChangeCompressor->start(); +} + + ConfigPtr XRandR::config() const { return s_internalConfig->toKScreenConfig(); @@ -177,14 +216,12 @@ QByteArray XRandR::edid(int outputId) const { - const XRandROutput::Map outputs = s_internalConfig->outputs(); - const XRandROutput *output = outputs.value(outputId); + const XRandROutput *output = s_internalConfig->output(outputId); if (!output) { - return 0; + return QByteArray(); } - const QByteArray rawEdid = output->edid(); - return rawEdid; + return output->edid(); } bool XRandR::isValid() const @@ -192,47 +229,39 @@ return m_isValid; } -quint8* XRandR::getXProperty(Display *dpy, RROutput output, Atom atom, size_t &len) +quint8* XRandR::getXProperty(xcb_randr_output_t output, xcb_atom_t atom, size_t &len) { - unsigned char *prop = 0; - int actual_format; - unsigned long nitems, bytes_after; - Atom actual_type; quint8 *result; - XRRGetOutputProperty(dpy, output, atom, - 0, 100, false, false, - AnyPropertyType, - &actual_type, &actual_format, - &nitems, &bytes_after, &prop); - - if (actual_type == XA_INTEGER && actual_format == 8) { - result = new quint8[nitems]; - memcpy(result, prop, nitems); - len = nitems; + auto cookie = xcb_randr_get_output_property(XCB::connection(), output, atom, + XCB_ATOM_ANY, + 0, 100, false, false); + auto reply = xcb_randr_get_output_property_reply(XCB::connection(), cookie, NULL); + if (reply->type == XCB_ATOM_INTEGER && reply->format == 8) { + result = new quint8[reply->num_items]; + memcpy(result, xcb_randr_get_output_property_data(reply), reply->num_items); + len = reply->num_items; } else { - result = NULL; + result = nullptr; } - XFree (prop); + free(reply); return result; } -quint8 *XRandR::outputEdid(int outputId, size_t &len) +quint8 *XRandR::outputEdid(xcb_randr_output_t outputId, size_t &len) { - Atom edid_atom; quint8 *result; - edid_atom = XInternAtom(QX11Info::display(), RR_PROPERTY_RANDR_EDID, false); - result = XRandR::getXProperty(QX11Info::display(), outputId, edid_atom, len); + auto edid_atom = XCB::InternAtom(false, 4, "EDID")->atom; + result = XRandR::getXProperty(outputId, edid_atom, len); if (result == NULL) { - edid_atom = XInternAtom(QX11Info::display(), "EDID_DATA", false); - result = XRandR::getXProperty(QX11Info::display(), outputId, edid_atom, len); + auto edid_atom = XCB::InternAtom(false, 9, "EDID_DATA")->atom; + result = XRandR::getXProperty(outputId, edid_atom, len); } - if (result == NULL) { - edid_atom = XInternAtom(QX11Info::display(), "XFree86_DDC_EDID1_RAWDATA", false); - result = XRandR::getXProperty(QX11Info::display(), outputId, edid_atom, len); + auto edid_atom = XCB::InternAtom(false, 25, "XFree86_DDC_EDID1_RAWDATA")->atom; + result = XRandR::getXProperty(outputId, edid_atom, len); } if (result) { @@ -247,91 +276,35 @@ return 0; } -RRCrtc XRandR::outputCrtc(int outputId) -{ - RRCrtc crtcId; - XRROutputInfo* outputInfo = XRROutput(outputId); - qCDebug(KSCREEN_XRANDR) << "Output" << outputId << "has CRTC" << outputInfo->crtc; - - crtcId = outputInfo->crtc; - XRRFreeOutputInfo(outputInfo); - - return crtcId; -} - -RRCrtc XRandR::freeCrtc(int outputId) -{ - XRROutputInfo* outputInfo = XRROutput(outputId); - - XRRCrtcInfo *crtc; - for (int i = 0; i < outputInfo->ncrtc; ++i) - { - const RRCrtc crtcId = outputInfo->crtcs[i]; - crtc = XRRCrtc(crtcId); - if (!crtc->noutput) { - qCDebug(KSCREEN_XRANDR) << "Found free CRTC" << crtcId; - XRRFreeCrtcInfo(crtc); - return crtcId; - } - XRRFreeCrtcInfo(crtc); - } - - qCDebug(KSCREEN_XRANDR) << "No free CRTC found!"; - return 0; -} - -XRRScreenResources* XRandR::screenResources() +xcb_randr_get_screen_resources_reply_t* XRandR::screenResources() { - XRRScreenResources *resources; - if (XRandR::s_has_1_3) { if (XRandR::s_xorgCacheInitialized) { - resources = XRRGetScreenResourcesCurrent(s_display, s_rootWindow); + // HACK: This abuses the fact that xcb_randr_get_screen_resources_reply_t + // and xcb_randr_get_screen_resources_current_reply_t are the same + return reinterpret_cast( + xcb_randr_get_screen_resources_current_reply(XCB::connection(), + xcb_randr_get_screen_resources_current(XCB::connection(), XRandR::rootWindow()), + NULL)); } else { /* XRRGetScreenResourcesCurrent is faster then XRRGetScreenResources * because it returns cached values. However the cached values are not * available until someone calls XRRGetScreenResources first. In case * we happen to be the first ones, we need to fill the cache first. */ - resources = XRRGetScreenResources(s_display, s_rootWindow); XRandR::s_xorgCacheInitialized = true; } - } else { - resources = XRRGetScreenResources(s_display, s_rootWindow); } - return resources; -} - -XRROutputInfo* XRandR::XRROutput(int outputId) -{ - XRRScreenResources *resources = screenResources(); - XRROutputInfo *info = XRRGetOutputInfo(s_display, resources, outputId); - XRRFreeScreenResources(resources); - - return info; -} - -XRRCrtcInfo* XRandR::XRRCrtc(int crtcId) -{ - XRRScreenResources *resources = screenResources(); - XRRCrtcInfo *info = XRRGetCrtcInfo(s_display, resources, crtcId); - XRRFreeScreenResources(resources); - - return info; - -} - -Display *XRandR::display() -{ - return s_display; + return xcb_randr_get_screen_resources_reply(XCB::connection(), + xcb_randr_get_screen_resources(XCB::connection(), XRandR::rootWindow()), NULL); } -Window XRandR::rootWindow() +xcb_window_t XRandR::rootWindow() { return s_rootWindow; } -int XRandR::screen() +xcb_screen_t* XRandR::screen() { return s_screen; } diff -Nru libkscreen-5.2.2/backends/xrandr/xrandr.h libkscreen-5.3.0/backends/xrandr/xrandr.h --- libkscreen-5.2.2/backends/xrandr/xrandr.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandr.h 2015-04-23 10:04:35.000000000 +0000 @@ -20,13 +20,17 @@ #ifndef XRANDR_BACKEND_H #define XRANDR_BACKEND_H -#include "xlibandxrandr.h" #include "abstractbackend.h" #include #include -class XRandRXCBHelper; +#include "../xcbwrapper.h" + +class QRect; +class QTimer; + +class XCBEventListener; class XRandRConfig; namespace KScreen { class Output; @@ -48,29 +52,31 @@ virtual bool isValid() const; virtual QByteArray edid(int outputId) const; - static RRCrtc outputCrtc(int outputId); - static quint8 *outputEdid(int outputId, size_t &len); - static RRCrtc freeCrtc(int outputId); - static XRRScreenResources* screenResources(); - static XRROutputInfo* XRROutput(int outputId); - static XRRCrtcInfo* XRRCrtc(int crtcId); - static Display* display(); - static int screen(); - static Window rootWindow(); + static quint8 *outputEdid(xcb_randr_output_t outputId, size_t &len); + static xcb_randr_get_screen_resources_reply_t* screenResources(); + static xcb_screen_t* screen(); + static xcb_window_t rootWindow(); private Q_SLOTS: - void updateConfig(); - void outputRemovedSlot(); - - void updateOutput(RROutput output); - void updateCrtc(RRCrtc crtc); + void outputChanged(xcb_randr_output_t output, + xcb_randr_crtc_t crtc, + xcb_randr_mode_t mode, + xcb_randr_connection_t connection); + void crtcChanged(xcb_randr_crtc_t crtc, + xcb_randr_mode_t mode, + xcb_randr_rotation_t rotation, + const QRect &geom); + void screenChanged(xcb_randr_rotation_t rotation, + const QSize &sizePx, + const QSize &sizeMm); private: - static quint8* getXProperty(Display *dpy, RROutput output, Atom atom, size_t &len); + static quint8* getXProperty(xcb_randr_output_t output, + xcb_atom_t atom, + size_t &len); - static Display* s_display; - static int s_screen; - static Window s_rootWindow; + static xcb_screen_t *s_screen; + static xcb_window_t s_rootWindow; static XRandRConfig *s_internalConfig; static int s_randrBase; static int s_randrError; @@ -78,8 +84,10 @@ static bool s_has_1_3; static bool s_xorgCacheInitialized; - XRandRXCBHelper *m_x11Helper; + XCBEventListener *m_x11Helper; bool m_isValid; + + QTimer *m_configChangeCompressor; }; Q_DECLARE_LOGGING_CATEGORY(KSCREEN_XRANDR) diff -Nru libkscreen-5.2.2/backends/xrandr/xrandrconfig.cpp libkscreen-5.3.0/backends/xrandr/xrandrconfig.cpp --- libkscreen-5.2.2/backends/xrandr/xrandrconfig.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandrconfig.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -1,6 +1,6 @@ /************************************************************************************* * Copyright (C) 2012 by Alejandro Fiestas Olivares * - * Copyright (C) 2012, 2013 by Daniel Vrátil * + * Copyright (C) 2012 - 2015 by Daniel Vrátil * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * @@ -22,86 +22,84 @@ #include "xrandr.h" #include "xrandrmode.h" #include "xrandroutput.h" +#include "xrandrcrtc.h" #include "config.h" #include "output.h" #include "edid.h" +#include "../xcbwrapper.h" + #include #include +#include using namespace KScreen; XRandRConfig::XRandRConfig() : QObject() - , m_primaryOutput(-1) - , m_screen(new XRandRScreen(this)) + , m_screen(Q_NULLPTR) { - XRRScreenResources* resources = XRandR::screenResources(); - - const RROutput primary = XRRGetOutputPrimary(XRandR::display(), XRandR::rootWindow()); - - RROutput id; - for (int i = 0; i < resources->noutput; ++i) - { - id = resources->outputs[i]; + m_screen = new XRandRScreen(this); - XRandROutput *output = createNewOutput(id, (id == primary)); - m_outputs.insert(id, output); - if (id == primary) { - m_primaryOutput = output->id(); - } + XCB::ScopedPointer resources(XRandR::screenResources()); + xcb_randr_crtc_t *crtcs = xcb_randr_get_screen_resources_crtcs(resources.data()); + for (int i = 0, c = xcb_randr_get_screen_resources_crtcs_length(resources.data()); i < c; ++i) { + addNewCrtc(crtcs[i]); } - XRRFreeScreenResources(resources); + xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_outputs(resources.data()); + for (int i = 0, c = xcb_randr_get_screen_resources_outputs_length(resources.data()); i < c; ++i) { + addNewOutput(outputs[i]); + } } XRandRConfig::~XRandRConfig() { + qDeleteAll(m_outputs); + qDeleteAll(m_crtcs); + delete m_screen; } -void XRandRConfig::update() +XRandROutput::Map XRandRConfig::outputs() const { - m_screen->update(); + return m_outputs; +} - const RROutput primary = XRRGetOutputPrimary(XRandR::display(), XRandR::rootWindow()); +XRandROutput* XRandRConfig::output(xcb_randr_output_t output) const +{ + return m_outputs[output]; +} - m_primaryOutput = -1; - for (auto iter = m_outputs.begin(); iter != m_outputs.end(); ++iter) { - XRandROutput *output = iter.value(); - output->update((iter.key() == (int) primary) ? XRandROutput::SetPrimary : XRandROutput::UnsetPrimary); - if (iter.key() == (int) primary) { - m_primaryOutput = output->id(); - } - } +XRandRCrtc::Map XRandRConfig::crtcs() const +{ + return m_crtcs; } -XRandROutput::Map XRandRConfig::outputs() const +XRandRCrtc* XRandRConfig::crtc(xcb_randr_crtc_t crtc) const { - return m_outputs; + return m_crtcs[crtc]; } -void XRandRConfig::addNewOutput(const RROutput id) +XRandRScreen* XRandRConfig::screen() const { - const RROutput primary = XRRGetOutputPrimary(XRandR::display(), XRandR::rootWindow()); - XRandROutput *output = createNewOutput(id, (id == primary)); - m_outputs.insert(id, output); - if (id == primary) { - m_primaryOutput = id; - } + return m_screen; } -XRandROutput* XRandRConfig::createNewOutput(RROutput id, bool primary) + +void XRandRConfig::addNewOutput(xcb_randr_output_t id) { - XRandROutput *xOutput = new XRandROutput(id, primary, this); - connect(xOutput, SIGNAL(outputRemoved(int)), SLOT(outputRemovedSlot(int))); + XRandROutput *xOutput = new XRandROutput(id, this); + m_outputs.insert(id, xOutput); +} - return xOutput; +void XRandRConfig::addNewCrtc(xcb_randr_crtc_t crtc) +{ + m_crtcs.insert(crtc, new XRandRCrtc(crtc, this)); } -void XRandRConfig::outputRemovedSlot(int id) +void XRandRConfig::removeOutput(xcb_randr_output_t id) { - m_outputs.remove(id); - Q_EMIT outputRemoved(id); + delete m_outputs.take(id); } KScreen::ConfigPtr XRandRConfig::toKScreenConfig() const @@ -110,120 +108,73 @@ KScreen::OutputList kscreenOutputs; for (auto iter = m_outputs.constBegin(); iter != m_outputs.constEnd(); ++iter) { - XRandROutput *output = iter.value(); - //FIXME XRandR backend should keep updated itself - output->update(XRandROutput::NoChange); - KScreen::OutputPtr kscreenOutput = output->toKScreenOutput(); + KScreen::OutputPtr kscreenOutput = (*iter)->toKScreenOutput(); kscreenOutputs.insert(kscreenOutput->id(), kscreenOutput); } - config->setOutputs(kscreenOutputs); config->setScreen(m_screen->toKScreenScreen()); - if (m_primaryOutput != -1 && (!config->primaryOutput() || config->primaryOutput()->id() != m_primaryOutput)) { - config->setPrimaryOutput(kscreenOutputs.value(m_primaryOutput)); - } return config; } -void XRandRConfig::updateKScreenConfig(ConfigPtr &config) const -{ - KScreen::ScreenPtr kscreenScreen = config->screen(); - m_screen->updateKScreenScreen(kscreenScreen); - config->setScreen(kscreenScreen); - - //Removing removed outputs - KScreen::OutputList outputs = config->outputs(); - Q_FOREACH(const KScreen::OutputPtr &output, outputs) { - if (!m_outputs.contains(output->id())) { - config->removeOutput(output->id()); - } - } - - XRandROutput::Map::ConstIterator iter; - KScreen::OutputList kscreenOutputs = config->outputs(); - for (iter = m_outputs.constBegin(); iter != m_outputs.constEnd(); ++iter) { - XRandROutput *output = iter.value(); - KScreen::OutputPtr kscreenOutput = kscreenOutputs[output->id()]; - - if (!kscreenOutput) { - kscreenOutput = output->toKScreenOutput(); - kscreenOutputs.insert(kscreenOutput->id(), kscreenOutput); - continue; - } - output->updateKScreenOutput(kscreenOutput); - } - config->setOutputs(kscreenOutputs); - - if (!config->primaryOutput() || config->primaryOutput()->id() != m_primaryOutput) { - config->setPrimaryOutput(config->output(m_primaryOutput)); - } -} - void XRandRConfig::applyKScreenConfig(const KScreen::ConfigPtr &config) { - KScreen::OutputList outputs = config->outputs(); - QSize newSize = screenSize(config); + const KScreen::OutputList kscreenOutputs = config->outputs(); + const QSize newScreenSize = screenSize(config); const QSize currentScreenSize = m_screen->currentSize(); - - int neededCrtc = 0; - int primaryOutput = 0; - int oldPrimary = 0; + int neededCrtcs = 0; + xcb_randr_output_t primaryOutput = 0; + xcb_randr_output_t oldPrimaryOutput = 0; Q_FOREACH (const XRandROutput *xrandrOutput, m_outputs) { if (xrandrOutput->isPrimary()) { - oldPrimary = xrandrOutput->id(); + oldPrimaryOutput = xrandrOutput->id(); break; } } KScreen::OutputList toDisable, toEnable, toChange; - QHash currentCrtc; - Q_FOREACH(const KScreen::OutputPtr &output, outputs) { - XRandROutput *currentOutput = m_outputs.value(output->id()); - currentOutput->update(currentOutput->isPrimary() ? XRandROutput::SetPrimary : XRandROutput::UnsetPrimary); - + Q_FOREACH(const KScreen::OutputPtr &kscreenOutput, kscreenOutputs) { + xcb_randr_output_t outputId = kscreenOutput->id(); + XRandROutput *currentOutput = output(outputId); //Only set the output as primary if it is enabled. - if (output->isPrimary() && output->isEnabled()) { - primaryOutput = currentOutput->id(); + if (kscreenOutput->isPrimary() && kscreenOutput->isEnabled()) { + primaryOutput = outputId; } - bool currentEnabled = currentOutput->isEnabled(); - if (!output->isEnabled() && currentEnabled) { - toDisable.insert(output->id(), output); + const bool currentEnabled = currentOutput->isEnabled(); + if (!kscreenOutput->isEnabled() && currentEnabled) { + toDisable.insert(outputId, kscreenOutput); continue; - } else if (output->isEnabled() && !currentEnabled) { - toEnable.insert(output->id(), output); - neededCrtc ++; + } else if (kscreenOutput->isEnabled() && !currentEnabled) { + toEnable.insert(outputId, kscreenOutput); + ++neededCrtcs; continue; - } else if (!output->isEnabled() && !currentEnabled) { + } else if (!kscreenOutput->isEnabled() && !currentEnabled) { continue; } - neededCrtc ++; + ++neededCrtcs; - if (output->currentModeId() != currentOutput->currentModeId()) { - if (!toChange.contains(output->id())) { - currentCrtc.insert(output->id(), XRandR::outputCrtc(output->id())); - toChange.insert(output->id(), output); + if (kscreenOutput->currentModeId() != currentOutput->currentModeId()) { + if (!toChange.contains(outputId)) { + toChange.insert(outputId, kscreenOutput); } } - if (output->pos() != currentOutput->position()) { - if (!toChange.contains(output->id())) { - currentCrtc.insert(output->id(), XRandR::outputCrtc(output->id())); - toChange.insert(output->id(), output); + if (kscreenOutput->pos() != currentOutput->position()) { + if (!toChange.contains(outputId)) { + toChange.insert(outputId, kscreenOutput); } } - if (output->rotation() != currentOutput->rotation()) { - if( !toChange.contains(output->id())) { - currentCrtc.insert(output->id(), XRandR::outputCrtc(output->id())); - toChange.insert(output->id(), output); + if (kscreenOutput->rotation() != currentOutput->rotation()) { + if (!toChange.contains(outputId)) { + toChange.insert(outputId, kscreenOutput); } } - XRandRMode* currentMode = currentOutput->currentMode(); + XRandRMode *currentMode = currentOutput->modes().value(kscreenOutput->currentModeId().toInt()); // For some reason, in some environments currentMode is null // which doesn't make sense because it is the *current* mode... @@ -232,86 +183,73 @@ // figure out how this happened. if (!currentMode) { qWarning() << "Current mode is null:" - << "ModeId:" << currentOutput->currentModeId() - << "Mode: " << currentOutput->currentMode() - << "Output: " << currentOutput->id(); + << "ModeId:" << currentOutput->currentModeId() + << "Mode: " << currentOutput->currentMode() + << "Output: " << currentOutput->id(); // qDebug() << kRealBacktrace(256); printConfig(config); printInternalCond(); return; } - const QSize size = currentMode->size(); - int x, y; - - //TODO: Move this code within libkscreen - y = currentOutput->position().y(); - if (currentOutput->isHorizontal()) { - y += size.height(); - } else { - y += size.width(); + // If the output would not fit into new screen size, we need to disable + // it and reposition it + const QRect geom = kscreenOutput->geometry(); + if (geom.right() > newScreenSize.width() || geom.bottom() > newScreenSize.height()) { + if (!toDisable.contains(outputId)) { + qCDebug(KSCREEN_XRANDR) << "The new output would not fit into screen - new geometry: " << geom << ", new screen size:" << newScreenSize; + toDisable.insert(outputId, kscreenOutput); + } } + } // Q_FOREACH (const KScreen::OutputPtr &kscreenOutput, kscreenOutputs) - x = currentOutput->position().x(); - if (currentOutput->isHorizontal()) { - x += size.width(); - } else { - x += size.height(); - } + const KScreen::ScreenPtr kscreenScreen = config->screen(); + if (newScreenSize.width() > kscreenScreen->maxSize().width() || + newScreenSize.height() > kscreenScreen->maxSize().height()) { + qCDebug(KSCREEN_XRANDR) << "The new screen size is too big - requested: " << newScreenSize << ", maximum: " << kscreenScreen->maxSize(); + return; + } - if (x > newSize.width() || y > newSize.height()) { - if (!toDisable.contains(output->id())) { - qCDebug(KSCREEN_XRANDR) << "Output doesn't fit: " << x << "x" << y << newSize; - toDisable.insert(output->id(), output); - } - } - }//Q_FOREACH(KScreen::Output *output, outputs) + qCDebug(KSCREEN_XRANDR) << "Needed CRTCs: " << neededCrtcs; + XCB::ScopedPointer screenResources(XRandR::screenResources()); + if (neededCrtcs > screenResources->num_crtcs) { + qCDebug(KSCREEN_XRANDR) << "We need more CRTCs than we have available - requested: " << neededCrtcs << ", available: " << screenResources->num_crtcs; + return; + } - const KScreen::ScreenPtr screen = config->screen(); - if (newSize.width() > screen->maxSize().width() || - newSize.height() > screen->maxSize().height()) { - qCDebug(KSCREEN_XRANDR) << "The new size is too big: " << newSize << " - " << screen->maxSize(); - return;//Too big - } - - qCDebug(KSCREEN_XRANDR) << neededCrtc; - XRRScreenResources *screenResources = XRandR::screenResources(); - if (neededCrtc > screenResources->ncrtc) { - qCDebug(KSCREEN_XRANDR) << "We need more crtc than we have: " << neededCrtc << " - " << screenResources->ncrtc; - XRRFreeScreenResources(screenResources); - return;//We don't have enough crtc - } - XRRFreeScreenResources(screenResources); - - qCDebug(KSCREEN_XRANDR) << "Actions to perform: "; - qCDebug(KSCREEN_XRANDR) << "\t Primary Output: " << primaryOutput; - qCDebug(KSCREEN_XRANDR) << "\t Change Screen Size: " << (newSize != currentScreenSize); - if (newSize != currentScreenSize) { - qCDebug(KSCREEN_XRANDR) << "\t Old: " << currentScreenSize; - qCDebug(KSCREEN_XRANDR) << "\t New: " << newSize; + qCDebug(KSCREEN_XRANDR) << "Actions to perform:"; + qCDebug(KSCREEN_XRANDR) << "\tPrimary Output:" << (primaryOutput != oldPrimaryOutput); + if (primaryOutput != oldPrimaryOutput) { + qCDebug(KSCREEN_XRANDR) << "\t\tOld:" << oldPrimaryOutput; + qCDebug(KSCREEN_XRANDR) << "\t\tNew:" << primaryOutput; + } + qCDebug(KSCREEN_XRANDR) << "\tChange Screen Size:" << (newScreenSize != currentScreenSize); + if (newScreenSize != currentScreenSize) { + qCDebug(KSCREEN_XRANDR) << "\t\tOld:" << currentScreenSize; + qCDebug(KSCREEN_XRANDR) << "\t\tNew:" << newScreenSize; } - qCDebug(KSCREEN_XRANDR) << "\t Disable outputs: " << !toDisable.isEmpty(); + qCDebug(KSCREEN_XRANDR) << "\tDisable outputs:" << !toDisable.isEmpty(); if (!toDisable.isEmpty()) { qCDebug(KSCREEN_XRANDR) << "\t\t" << toDisable.keys(); } - qCDebug(KSCREEN_XRANDR) << "\t Change outputs: " << !toChange.isEmpty(); + qCDebug(KSCREEN_XRANDR) << "\tChange outputs:" << !toChange.isEmpty(); if (!toChange.isEmpty()) { qCDebug(KSCREEN_XRANDR) << "\t\t" << toChange.keys(); } - qCDebug(KSCREEN_XRANDR) << "\t Enable outputs: " << !toEnable.isEmpty(); + qCDebug(KSCREEN_XRANDR) << "\tEnable outputs:" << !toEnable.isEmpty(); if (!toEnable.isEmpty()) { qCDebug(KSCREEN_XRANDR) << "\t\t" << toEnable.keys(); } - XGrabServer(XRandR::display()); + // Grab the server so that no-one else can do changes to XRandR and to block + // change notifications until we are done + XCB::GrabServer grabber; //If there is nothing to do, not even bother - if (oldPrimary == primaryOutput && toDisable.isEmpty() && toEnable.isEmpty() && toChange.isEmpty()) { - if (newSize != currentScreenSize) { - setScreenSize(newSize); + if (oldPrimaryOutput == primaryOutput && toDisable.isEmpty() && toEnable.isEmpty() && toChange.isEmpty()) { + if (newScreenSize != currentScreenSize) { + setScreenSize(newScreenSize); } - XUngrabServer(XRandR::display()); - XFlush(XRandR::display()); return; } @@ -319,14 +257,13 @@ disableOutput(output); } - if (newSize != currentScreenSize) { - setScreenSize(newSize); + if (newScreenSize != currentScreenSize) { + setScreenSize(newScreenSize); } bool forceScreenSizeUpdate = false; Q_FOREACH(const KScreen::OutputPtr &output, toChange) { - if (!changeOutput(output, currentCrtc[output->id()])) { - + if (!changeOutput(output)) { /* If we disabled the output before changing it and XRandR failed * to re-enable it, then update screen size too */ if (toDisable.contains(output->id())) { @@ -345,18 +282,15 @@ } } - if (oldPrimary != primaryOutput) { + if (oldPrimaryOutput != primaryOutput) { setPrimaryOutput(primaryOutput); } if (forceScreenSizeUpdate) { - newSize = screenSize(config); - qCDebug(KSCREEN_XRANDR) << "forced to change screen Size: " << newSize; + const QSize newSize = screenSize(config); + qCDebug(KSCREEN_XRANDR) << "forced to change screen size: " << newSize; setScreenSize(newSize); } - - XUngrabServer(XRandR::display()); - XFlush(XRandR::display()); } void XRandRConfig::printConfig(const ConfigPtr &config) const @@ -457,46 +391,19 @@ QSize XRandRConfig::screenSize(const KScreen::ConfigPtr &config) const { QRect rect; - QSize outputSize; Q_FOREACH(const KScreen::OutputPtr &output, config->outputs()) { - if (!output->isEnabled() || !output->isConnected()) { - qCDebug(KSCREEN_XRANDR) << "Disabled/Disconnected output: " << output->name(); + if (!output->isConnected() || !output->isEnabled()) { continue; } const ModePtr currentMode = output->currentMode(); if (!currentMode) { - qCDebug(KSCREEN_XRANDR) << "Output: " << output->name() << " has no current Mode"; + qCDebug(KSCREEN_XRANDR) << "Output: " << output->name() << " has no current Mode!"; continue; } - const QSize outputSize = currentMode->size(); - - qCDebug(KSCREEN_XRANDR) << "Output: " << output->name() << " Size: " << outputSize << " Pos: " << output->pos(); - if (output->pos().x() < rect.x()) { - rect.setX(output->pos().x()); - } - - if (output->pos().y() < rect.y()) { - rect.setY(output->pos().y()); - } - - QPoint bottomRight; - if (output->isHorizontal()) { - bottomRight = QPoint(output->pos().x() + outputSize.width(), - output->pos().y() + outputSize.height()); - } else { - bottomRight = QPoint(output->pos().x() + outputSize.height(), - output->pos().y() + outputSize.width()); - } - - if (bottomRight.x() > rect.width()) { - rect.setWidth(bottomRight.x()); - } - - if (bottomRight.y() > rect.height()) { - rect.setHeight(bottomRight.y()); - } + const QRect outputGeom = output->geometry(); + rect = rect.united(outputGeom); } const QSize size = QSize(rect.width(), rect.height()); @@ -504,83 +411,156 @@ return size; } -bool XRandRConfig::setScreenSize(const QSize& size) const +bool XRandRConfig::setScreenSize(const QSize &size) const { - const double dpi = (25.4 * DisplayHeight(XRandR::display(), XRandR::screen())) / DisplayHeightMM(XRandR::display(), XRandR::screen()); - - qCDebug(KSCREEN_XRANDR) << "DPI: " << dpi; - qCDebug(KSCREEN_XRANDR) << "Size: " << size; - + const double dpi = (25.4 * XRandR::screen()->height_in_pixels / XRandR::screen()->height_in_millimeters); const int widthMM = ((25.4 * size.width()) / dpi); const int heightMM = ((25.4 * size.height()) / dpi); - qCDebug(KSCREEN_XRANDR) << size << " " << widthMM << "x" << heightMM; - XRRSetScreenSize(XRandR::display(), XRandR::rootWindow(), - size.width(), size.height(), widthMM, heightMM); - - qDebug(KSCREEN_XRANDR) << "Applied screen size change to " << size; + qCDebug(KSCREEN_XRANDR) << "RRSetScreenSize"; + qCDebug(KSCREEN_XRANDR) << "\tDPI:" << dpi; + qCDebug(KSCREEN_XRANDR) << "\tSize:" << size; + qCDebug(KSCREEN_XRANDR) << "\tSizeMM:" << QSize(widthMM, heightMM); + + xcb_randr_set_screen_size(XCB::connection(), XRandR::rootWindow(), + size.width(), size.height(), widthMM, heightMM); + m_screen->update(size); return true; } -void XRandRConfig::setPrimaryOutput(int outputId) const -{ - XRRSetOutputPrimary(XRandR::display(), XRandR::rootWindow(), outputId); -} - -bool XRandRConfig::disableOutput(const OutputPtr &output) const +void XRandRConfig::setPrimaryOutput(xcb_randr_output_t outputId) const { - const int crtcId = XRandR::outputCrtc(output->id()); - qCDebug(KSCREEN_XRANDR) << "Disabling: " << output->id() << "(CRTC" << crtcId << ")"; - - XRRScreenResources *screenResources = XRandR::screenResources(); - const Status s = XRRSetCrtcConfig(XRandR::display(), screenResources, crtcId, CurrentTime, - 0, 0, None, RR_Rotate_0, NULL, 0); - XRRFreeScreenResources(screenResources); + qCDebug(KSCREEN_XRANDR) << "RRSetOutputPrimary"; + qCDebug(KSCREEN_XRANDR) << "\tNew primary:" << outputId; + xcb_randr_set_output_primary(XCB::connection(), XRandR::rootWindow(), outputId); - qCDebug(KSCREEN_XRANDR) << "XRRSetCrtcConfig() returned" << s; - - // Update the cached output now, otherwise we get RRNotify_CrtcChange notification - // for an outdated output, which can lead to a crash. - if (s == RRSetConfigSuccess) { - m_outputs.value(output->id())->update(); + for (XRandROutput *output : m_outputs) { + output->setIsPrimary(output->id() == outputId); } - return (s == RRSetConfigSuccess); } -bool XRandRConfig::enableOutput(const OutputPtr &output) const +bool XRandRConfig::disableOutput(const OutputPtr &kscreenOutput) const { - qCDebug(KSCREEN_XRANDR) << "Enabling: " << output->id(); - RROutput *outputs = new RROutput[1]; - XRRScreenResources *screenResources = XRandR::screenResources(); - outputs[0] = output->id(); - const Status s = XRRSetCrtcConfig(XRandR::display(), screenResources, XRandR::freeCrtc(output->id()), - CurrentTime, output->pos().rx(), output->pos().ry(), output->currentModeId().toInt(), - output->rotation(), outputs, 1); - XRRFreeScreenResources(screenResources); - qCDebug(KSCREEN_XRANDR) << "XRRSetCrtcConfig() returned" << s; - - if (s == RRSetConfigSuccess) { - m_outputs.value(output->id())->update(); + XRandROutput *xOutput = output(kscreenOutput->id()); + Q_ASSERT(xOutput); + Q_ASSERT(xOutput->crtc()); + if (!xOutput->crtc()) { + qCWarning(KSCREEN_XRANDR) << "Attempting to disable output without CRTC, wth?"; + return false; } - return (s == RRSetConfigSuccess); -} -bool XRandRConfig::changeOutput(const OutputPtr &output, int crtcId) const -{ - qCDebug(KSCREEN_XRANDR) << "Updating: " << output->id() << "with CRTC" << crtcId; + const xcb_randr_crtc_t crtc = xOutput->crtc()->crtc(); - RROutput *outputs = new RROutput[1]; - XRRScreenResources *screenResources = XRandR::screenResources(); - outputs[0] = output->id(); - const Status s = XRRSetCrtcConfig(XRandR::display(), screenResources, crtcId, - CurrentTime, output->pos().rx(), output->pos().ry(), output->currentModeId().toInt(), - output->rotation(), outputs, 1); - XRRFreeScreenResources(screenResources); + qCDebug(KSCREEN_XRANDR) << "RRSetCrtcConfig (disable output)"; + qCDebug(KSCREEN_XRANDR) << "\tCRTC:" << crtc; - qCDebug(KSCREEN_XRANDR) << "XRRSetCrtcConfig() returned" << s; + auto cookie = xcb_randr_set_crtc_config(XCB::connection(), crtc, + XCB_CURRENT_TIME, XCB_CURRENT_TIME, + 0, 0, + XCB_NONE, + XCB_RANDR_ROTATION_ROTATE_0, + 0, NULL); + XCB::ScopedPointer reply(xcb_randr_set_crtc_config_reply(XCB::connection(), cookie, NULL)); + if (!reply) { + qCDebug(KSCREEN_XRANDR) << "\tResult: unknown (error)"; + return false; + } + qCDebug(KSCREEN_XRANDR) << "\tResult:" << reply->status; - if (s == RRSetConfigSuccess) { - m_outputs.value(output->id())->update(); + // Update the cached output now, otherwise we get RRNotify_CrtcChange notification + // for an outdated output, which can lead to a crash. + if (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS) { + xOutput->update(XCB_NONE, XCB_NONE, xOutput->isConnected() ? XCB_RANDR_CONNECTION_CONNECTED : XCB_RANDR_CONNECTION_DISCONNECTED, + kscreenOutput->isPrimary()); + } + return (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS); +} + +bool XRandRConfig::enableOutput(const OutputPtr &kscreenOutput) const +{ + xcb_randr_output_t outputs[1] { static_cast(kscreenOutput->id()) }; + + XRandRCrtc *freeCrtc = Q_NULLPTR; + qCDebug(KSCREEN_XRANDR) << m_crtcs; + Q_FOREACH (XRandRCrtc *crtc, m_crtcs) { + qCDebug(KSCREEN_XRANDR) << "Testing CRTC" << crtc->crtc(); + qCDebug(KSCREEN_XRANDR) << "\tFree:" << crtc->isFree(); + qCDebug(KSCREEN_XRANDR) << "\tMode:" << crtc->mode(); + qCDebug(KSCREEN_XRANDR) << "\tPossible outputs:" << crtc->possibleOutputs(); + qCDebug(KSCREEN_XRANDR) << "\tConnected outputs:" << crtc->outputs(); + qCDebug(KSCREEN_XRANDR) << "\tGeometry:" << crtc->geometry(); + if (crtc->isFree() && crtc->possibleOutputs().contains(kscreenOutput->id())) { + freeCrtc = crtc; + break; + } + } + if (!freeCrtc) { + qCWarning(KSCREEN_XRANDR) << "Failed to get free CRTC for output" << kscreenOutput->id(); + return false; + } + + qCDebug(KSCREEN_XRANDR) << "RRSetCrtcConfig (enable output)"; + qCDebug(KSCREEN_XRANDR) << "\tOutput:" << kscreenOutput->id() << "(" << kscreenOutput->name() << ")"; + qCDebug(KSCREEN_XRANDR) << "\tNew CRTC:" << freeCrtc->crtc(); + qCDebug(KSCREEN_XRANDR) << "\tPos:" << kscreenOutput->pos(); + qCDebug(KSCREEN_XRANDR) << "\tMode:" << kscreenOutput->currentModeId() << "(" << kscreenOutput->currentMode()->size() << ")"; + qCDebug(KSCREEN_XRANDR) << "\tRotation:" << kscreenOutput->rotation(); + + auto cookie = xcb_randr_set_crtc_config(XCB::connection(), freeCrtc->crtc(), + XCB_CURRENT_TIME, XCB_CURRENT_TIME, + kscreenOutput->pos().rx(), kscreenOutput->pos().ry(), + kscreenOutput->currentModeId().toInt(), + kscreenOutput->rotation(), + 1, outputs); + XCB::ScopedPointer reply(xcb_randr_set_crtc_config_reply(XCB::connection(), cookie, NULL)); + if (!reply) { + qCDebug(KSCREEN_XRANDR) << "Result: unknown (error)"; + return false; + } + qCDebug(KSCREEN_XRANDR) << "\tResult:" << reply->status; + + if (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS) { + XRandROutput *xOutput = output(kscreenOutput->id()); + xOutput->update(freeCrtc->crtc(), kscreenOutput->currentModeId().toInt(), + XCB_RANDR_CONNECTION_CONNECTED, kscreenOutput->isPrimary()); + } + return (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS); +} + +bool XRandRConfig::changeOutput(const OutputPtr &kscreenOutput) const +{ + XRandROutput *xOutput = output(kscreenOutput->id()); + Q_ASSERT(xOutput); + Q_ASSERT(xOutput->crtc()); + if (!xOutput->crtc()) { + qCWarning(KSCREEN_XRANDR) << "Attempting to change output without valid CRTC"; + } + + qCDebug(KSCREEN_XRANDR) << "RRSetCrtcConfig (change output)"; + qCDebug(KSCREEN_XRANDR) << "\tOutput:" << kscreenOutput->id() << "(" << kscreenOutput->name() << ")"; + qCDebug(KSCREEN_XRANDR) << "\tCRTC:" << xOutput->crtc()->crtc(); + qCDebug(KSCREEN_XRANDR) << "\tPos:" << kscreenOutput->pos(); + qCDebug(KSCREEN_XRANDR) << "\tMode:" << kscreenOutput->currentModeId() << "(" << kscreenOutput->currentMode()->size() << ")"; + qCDebug(KSCREEN_XRANDR) << "\tRotation:" << kscreenOutput->rotation(); + + xcb_randr_output_t outputs[1] { static_cast(kscreenOutput->id()) }; + + auto cookie = xcb_randr_set_crtc_config(XCB::connection(), xOutput->crtc()->crtc(), + XCB_CURRENT_TIME, XCB_CURRENT_TIME, + kscreenOutput->pos().rx(), kscreenOutput->pos().ry(), + kscreenOutput->currentModeId().toInt(), + kscreenOutput->rotation(), + 1, outputs); + XCB::ScopedPointer reply(xcb_randr_set_crtc_config_reply(XCB::connection(), cookie, NULL)); + if (!reply) { + qCDebug(KSCREEN_XRANDR) << "\tResult: unknown (error)"; + return false; + } + qCDebug(KSCREEN_XRANDR) << "\tResult: " << reply->status; + + if (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS) { + xOutput->update(xOutput->crtc()->crtc(), kscreenOutput->currentModeId().toInt(), + XCB_RANDR_CONNECTION_CONNECTED, kscreenOutput->isPrimary()); } - return (s == RRSetConfigSuccess); + return (reply->status == XCB_RANDR_SET_CONFIG_SUCCESS); } diff -Nru libkscreen-5.2.2/backends/xrandr/xrandrconfig.h libkscreen-5.3.0/backends/xrandr/xrandrconfig.h --- libkscreen-5.2.2/backends/xrandr/xrandrconfig.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandrconfig.h 2015-04-23 10:04:35.000000000 +0000 @@ -22,6 +22,7 @@ #include #include "xrandr.h" +#include "xrandrcrtc.h" #include "xrandroutput.h" class XRandRScreen; @@ -37,16 +38,21 @@ explicit XRandRConfig(); virtual ~XRandRConfig(); - void update(); - XRandROutput::Map outputs() const; - void addNewOutput(const RROutput id); + XRandROutput *output(xcb_randr_output_t output) const; + + XRandRCrtc::Map crtcs() const; + XRandRCrtc *crtc(xcb_randr_crtc_t crtc) const; + + XRandRScreen *screen() const; + + void addNewOutput(xcb_randr_output_t id); + void addNewCrtc(xcb_randr_crtc_t crtc); + void removeOutput(xcb_randr_output_t id); KScreen::ConfigPtr toKScreenConfig() const; - void updateKScreenConfig(KScreen::ConfigPtr &config) const; void applyKScreenConfig(const KScreen::ConfigPtr &config); - int m_primaryOutput; private: /** * We need to print stuff to discover the damn bug @@ -55,20 +61,15 @@ void printConfig(const KScreen::ConfigPtr &config) const; void printInternalCond() const; QSize screenSize(const KScreen::ConfigPtr &config) const; - bool setScreenSize(const QSize& size) const; - void setPrimaryOutput(int outputId) const; + bool setScreenSize(const QSize &size) const; + void setPrimaryOutput(xcb_randr_output_t outputId) const; bool disableOutput(const KScreen::OutputPtr &output) const; bool enableOutput(const KScreen::OutputPtr &output) const; - bool changeOutput(const KScreen::OutputPtr &output, int crtcId) const; - XRandROutput* createNewOutput(RROutput id, bool primary); + bool changeOutput(const KScreen::OutputPtr &output) const; + XRandROutput::Map m_outputs; + XRandRCrtc::Map m_crtcs; XRandRScreen *m_screen; - -Q_SIGNALS: - void outputRemoved(int id); - -private Q_SLOTS: - void outputRemovedSlot(int id); }; #endif // XRANDRCONFIG_H diff -Nru libkscreen-5.2.2/backends/xrandr/xrandrcrtc.cpp libkscreen-5.3.0/backends/xrandr/xrandrcrtc.cpp --- libkscreen-5.2.2/backends/xrandr/xrandrcrtc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandrcrtc.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -0,0 +1,119 @@ +/* + * Copyright 2015 Daniel Vrátil + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "xrandrcrtc.h" +#include "xrandrconfig.h" +#include "xrandr.h" + +#include "../xcbwrapper.h" + +XRandRCrtc::XRandRCrtc(xcb_randr_crtc_t crtc, XRandRConfig *config) + : QObject(config) + , m_crtc(crtc) + , m_mode(0) + , m_rotation(XCB_RANDR_ROTATION_ROTATE_0) +{ + update(); +} + +xcb_randr_crtc_t XRandRCrtc::crtc() const +{ + return m_crtc; +} + +xcb_randr_mode_t XRandRCrtc::mode() const +{ + return m_mode; +} + +QRect XRandRCrtc::geometry() const +{ + return m_geometry; +} + +xcb_randr_rotation_t XRandRCrtc::rotation() const +{ + return m_rotation; +} + +QVector XRandRCrtc::possibleOutputs() +{ + return m_possibleOutputs; +} + +QVector XRandRCrtc::outputs() const +{ + return m_outputs; +} + +bool XRandRCrtc::connectOutput(xcb_randr_output_t output) +{ + qCDebug(KSCREEN_XRANDR) << "Connected output" << output << "to CRTC" << m_crtc; + if (!m_possibleOutputs.contains(output)) { + qCDebug(KSCREEN_XRANDR) << "Output" << output << "is not an allowed output for CRTC" << m_crtc; + return false; + } + + if (!m_outputs.contains(output)) { + m_outputs.append(output); + } + return true; +} + +void XRandRCrtc::disconectOutput(xcb_randr_output_t output) +{ + qCDebug(KSCREEN_XRANDR) << "Disconnected output" << output << "from CRTC" << m_crtc; + const int index = m_outputs.indexOf(output); + if (index > -1) { + m_outputs.remove(index); + } +} + +bool XRandRCrtc::isFree() const +{ + return m_outputs.isEmpty(); +} + +void XRandRCrtc::update() +{ + XCB::CRTCInfo crtcInfo(m_crtc, XCB_TIME_CURRENT_TIME); + m_mode = crtcInfo->mode; + m_rotation = (xcb_randr_rotation_t) crtcInfo->rotation; + m_geometry = QRect(crtcInfo->x, crtcInfo->y, crtcInfo->width, crtcInfo->height); + m_possibleOutputs.clear(); + m_possibleOutputs.reserve(crtcInfo->num_possible_outputs); + xcb_randr_output_t *possible = xcb_randr_get_crtc_info_possible(crtcInfo); + for (int i = 0; i < crtcInfo->num_possible_outputs; ++i) { + m_possibleOutputs.append(possible[i]); + } + xcb_randr_output_t *outputs = xcb_randr_get_crtc_info_outputs(crtcInfo); + for (int i = 0; i < crtcInfo->num_outputs; ++i) { + m_outputs.append(outputs[i]); + } +} + +void XRandRCrtc::update(xcb_randr_mode_t mode, xcb_randr_rotation_t rotation, const QRect &geom) +{ + m_mode = mode; + m_rotation = rotation; + m_geometry = geom; +} + diff -Nru libkscreen-5.2.2/backends/xrandr/xrandrcrtc.h libkscreen-5.3.0/backends/xrandr/xrandrcrtc.h --- libkscreen-5.2.2/backends/xrandr/xrandrcrtc.h 1970-01-01 00:00:00.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandrcrtc.h 2015-04-23 10:04:35.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright 2015 Daniel Vrátil + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef XRANDRCRTC_H +#define XRANDRCRTC_H + +#include +#include +#include +#include + +#include + +class XRandRConfig; + +class XRandRCrtc : public QObject +{ + Q_OBJECT + +public: + typedef QMap Map; + + + XRandRCrtc(xcb_randr_crtc_t crtc, XRandRConfig *config); + + xcb_randr_crtc_t crtc() const; + xcb_randr_mode_t mode() const; + xcb_randr_rotation_t rotation() const; + QRect geometry() const; + QVector possibleOutputs(); + QVector outputs() const; + + bool connectOutput(xcb_randr_output_t output); + void disconectOutput(xcb_randr_output_t output); + + bool isFree() const; + + void update(); + void update(xcb_randr_crtc_t mode, xcb_randr_rotation_t rotation, const QRect &geom); + +private: + xcb_randr_crtc_t m_crtc; + xcb_randr_mode_t m_mode; + xcb_randr_rotation_t m_rotation; + QRect m_geometry; + QVector m_possibleOutputs; + QVector m_outputs; +}; + +#endif // XRANDRCRTC_H diff -Nru libkscreen-5.2.2/backends/xrandr/xrandrmode.cpp libkscreen-5.3.0/backends/xrandr/xrandrmode.cpp --- libkscreen-5.2.2/backends/xrandr/xrandrmode.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandrmode.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -21,13 +21,14 @@ #include "mode.h" #include "output.h" -XRandRMode::XRandRMode(XRRModeInfo *modeInfo, XRandROutput *output) +XRandRMode::XRandRMode(const xcb_randr_mode_info_t &modeInfo, XRandROutput *output) : QObject(output) { - m_id = modeInfo->id; - m_name = QString::fromUtf8(modeInfo->name); - m_size = QSize(modeInfo->width, modeInfo->height); - m_refreshRate = ((float) modeInfo->dotClock / ((float) modeInfo->hTotal * (float) modeInfo->vTotal)); + m_id = modeInfo.id; + // FIXME XCB + //m_name = QString::fromUtf8(modeInfo->name); + m_size = QSize(modeInfo.width, modeInfo.height); + m_refreshRate = ((float) modeInfo.dot_clock / ((float) modeInfo.htotal * (float) modeInfo.vtotal)); } @@ -47,7 +48,7 @@ return kscreenMode; } -int XRandRMode::id() const +xcb_randr_mode_t XRandRMode::id() const { return m_id; } diff -Nru libkscreen-5.2.2/backends/xrandr/xrandrmode.h libkscreen-5.3.0/backends/xrandr/xrandrmode.h --- libkscreen-5.2.2/backends/xrandr/xrandrmode.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandrmode.h 2015-04-23 10:04:35.000000000 +0000 @@ -25,7 +25,7 @@ #include #include "types.h" -#include "xlibandxrandr.h" +#include "../xcbwrapper.h" class XRandROutput; namespace KScreen @@ -39,20 +39,20 @@ Q_OBJECT public: - typedef QMap Map; + typedef QMap Map; - explicit XRandRMode(XRRModeInfo* modeInfo, XRandROutput *output); + explicit XRandRMode(const xcb_randr_mode_info_t &modeInfo, XRandROutput *output); virtual ~XRandRMode(); KScreen::ModePtr toKScreenMode(); - int id() const; + xcb_randr_mode_t id() const; QSize size() const; float refreshRate() const; QString name() const; private: - int m_id; + xcb_randr_mode_t m_id; QString m_name; QSize m_size; float m_refreshRate; diff -Nru libkscreen-5.2.2/backends/xrandr/xrandroutput.cpp libkscreen-5.3.0/backends/xrandr/xrandroutput.cpp --- libkscreen-5.2.2/backends/xrandr/xrandroutput.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandroutput.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -28,45 +28,34 @@ Q_DECLARE_METATYPE(QList) -XRandROutput::XRandROutput(int id, bool primary, XRandRConfig *config) +XRandROutput::XRandROutput(xcb_randr_output_t id, XRandRConfig *config) : QObject(config) + , m_config(config) , m_id(id) , m_type(KScreen::Output::Unknown) - , m_rotation(KScreen::Output::None) - , m_connected(0) - , m_enabled(0) , m_primary(0) - , m_changedProperties(0) + , m_crtc(0) { - XRROutputInfo *outputInfo = XRandR::XRROutput(m_id); - updateOutput(outputInfo); - updateModes(outputInfo); - fetchType(); - m_primary = primary; - m_widthMm = outputInfo->mm_width; - m_heightMm = outputInfo->mm_height; - - XRRFreeOutputInfo(outputInfo); + init(); } - XRandROutput::~XRandROutput() { } -int XRandROutput::id() const +xcb_randr_output_t XRandROutput::id() const { return m_id; } bool XRandROutput::isConnected() const { - return m_connected; + return m_connected == XCB_RANDR_CONNECTION_CONNECTED; } bool XRandROutput::isEnabled() const { - return m_enabled; + return m_crtc != Q_NULLPTR && m_crtc->mode() != XCB_NONE; } bool XRandROutput::isPrimary() const @@ -76,7 +65,7 @@ QPoint XRandROutput::position() const { - return m_position; + return m_crtc ? m_crtc->geometry().topLeft() : QPoint(); } XRandRMode::Map XRandROutput::modes() const @@ -86,12 +75,15 @@ QString XRandROutput::currentModeId() const { - return m_currentMode; + return m_crtc ? QString::number(m_crtc->mode()) : QString(); } XRandRMode* XRandROutput::currentMode() const { - int modeId = m_currentMode.toInt(); + if (!m_crtc) { + return Q_NULLPTR; + } + int modeId = m_crtc->mode(); if (!m_modes.contains(modeId)) { return 0; } @@ -101,7 +93,7 @@ KScreen::Output::Rotation XRandROutput::rotation() const { - return m_rotation; + return static_cast(m_crtc ? m_crtc->rotation() : XCB_RANDR_ROTATION_ROTATE_0); } QByteArray XRandROutput::edid() const @@ -120,181 +112,186 @@ return m_edid; } -void XRandROutput::update(PrimaryChange primary) +XRandRCrtc* XRandROutput::crtc() const { - XRROutputInfo *outputInfo = XRandR::XRROutput(m_id); - if (!outputInfo) { - Q_EMIT outputRemoved(m_id); - deleteLater(); - return; - } + return m_crtc; +} - m_changedProperties = 0; - updateOutput(outputInfo); +void XRandROutput::update() +{ + init(); +} + +void XRandROutput::update(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, xcb_randr_connection_t conn, bool primary) +{ + qCDebug(KSCREEN_XRANDR) << "XRandROutput" << m_id << "update"; + qCDebug(KSCREEN_XRANDR) << "\tm_connected:" << m_connected; + qCDebug(KSCREEN_XRANDR) << "\tm_crtc" << m_crtc; + qCDebug(KSCREEN_XRANDR) << "\tCRTC:" << crtc; + qCDebug(KSCREEN_XRANDR) << "\tMODE:" << mode; + qCDebug(KSCREEN_XRANDR) << "\tConnection:" << conn; + qCDebug(KSCREEN_XRANDR) << "\tPrimary:" << primary; - if (primary != NoChange) { - const bool setPrimary = (primary == SetPrimary); - if (m_primary != setPrimary) { - m_primary = setPrimary; - m_changedProperties |= PropertyPrimary; + // Connected or disconnected + if (isConnected() != (conn == XCB_RANDR_CONNECTION_CONNECTED)) { + if (conn == XCB_RANDR_CONNECTION_CONNECTED) { + // New monitor has been connected, refresh everything + init(); + } else { + // Disconnected + m_connected = conn; + m_clones.clear(); + m_heightMm = 0; + m_widthMm = 0; + m_type = KScreen::Output::Unknown; + qDeleteAll(m_modes); + m_modes.clear(); + m_preferredModes.clear(); } } - if (m_changedProperties == 0) { - m_changedProperties = PropertyNone; + // A monitor has been enabled or disabled + // We don't use isEnabled(), because it checks for crtc && crtc->mode(), however + // crtc->mode may already be unset due to xcb_randr_crtc_tChangeNotify coming before + // xcb_randr_output_tChangeNotify and reseting the CRTC mode + + if ((m_crtc == Q_NULLPTR) != (crtc == XCB_NONE)) { + if (crtc == XCB_NONE && mode == XCB_NONE) { + // Monitor has been disabled + m_crtc->disconectOutput(m_id); + m_crtc = 0; + } else { + m_crtc = m_config->crtc(crtc); + m_crtc->connectOutput(m_id); + } } - XRRFreeOutputInfo(outputInfo); + // Primary has changed + m_primary = primary; } -void XRandROutput::updateOutput(const XRROutputInfo *outputInfo) +void XRandROutput::setIsPrimary(bool primary) { - const bool isConnected = (outputInfo->connection == RR_Connected); - - if (m_name != outputInfo->name) { - m_name = outputInfo->name; - m_changedProperties |= PropertyName; - } + m_primary = primary; +} - if (m_enabled != (outputInfo->crtc != None)) { - m_enabled = outputInfo->crtc != None; - m_changedProperties |= PropertyEnabled; - } - QList clones; - for (int i = 0; i < outputInfo->nclone; i++) { - clones << outputInfo->clones[i]; - } - if (isConnected && (m_clones != clones)) { - m_clones = clones; - m_changedProperties |= PropertyClones; +void XRandROutput::init() +{ + XCB::OutputInfo outputInfo(m_id, XCB_TIME_CURRENT_TIME); + Q_ASSERT(outputInfo); + if (!outputInfo) { + return; } - /* Don't update modes on disconnected output */ - if (isConnected && (outputInfo->crtc)) { - XRRCrtcInfo* crtcInfo = XRandR::XRRCrtc(outputInfo->crtc); - QRect rect; - rect.setRect(crtcInfo->x, crtcInfo->y, crtcInfo->width, crtcInfo->height); - if (m_position != rect.topLeft()) { - m_position = rect.topLeft(); - m_changedProperties |= PropertyPos; - } + XCB::PrimaryOutput primary(XRandR::rootWindow()); - if (crtcInfo->mode) { - if (m_currentMode != QString::number(crtcInfo->mode)) { - m_currentMode = QString::number(crtcInfo->mode); - m_changedProperties |= PropertyCurrentMode; - } - - if (m_rotation != crtcInfo->rotation) { - m_rotation = (KScreen::Output::Rotation) crtcInfo->rotation; - m_changedProperties |= PropertyRotation; - } - } - XRRFreeCrtcInfo(crtcInfo); + m_name = QString::fromUtf8((const char *) xcb_randr_get_output_info_name(outputInfo.data()), outputInfo->name_len); + m_type = fetchOutputType(m_id, m_name); + m_icon = QString(); + m_connected = (xcb_randr_connection_t) outputInfo->connection; + m_primary = (primary->output == m_id); + xcb_randr_output_t *clones = xcb_randr_get_output_info_clones(outputInfo.data()); + for (int i = 0; i < outputInfo->num_clones; ++i) { + m_clones.append(clones[i]); } - - /* When an output is disconnected then force reset most properties */ - if (m_connected != isConnected) { - m_connected = isConnected; - if (!m_connected) { - m_preferredModes.clear(); - m_enabled = false; - qDeleteAll(m_modes); - m_modes.clear(); - m_edid.clear(); - m_changedProperties |= PropertyConnected | PropertyEnabled | PropertyModes | PropertyEdid | PropertyPreferredMode; - } else { - updateModes(outputInfo); - m_changedProperties |= PropertyConnected | PropertyModes | PropertyPreferredMode; - } + m_widthMm = outputInfo->mm_width; + m_heightMm = outputInfo->mm_height; + m_crtc = m_config->crtc(outputInfo->crtc); + if (m_crtc) { + m_crtc->connectOutput(m_id); } + + updateModes(outputInfo); } -void XRandROutput::updateModes(const XRROutputInfo *outputInfo) +void XRandROutput::updateModes(const XCB::OutputInfo &outputInfo) { /* Init modes */ - XRRModeInfo* modeInfo; - XRRScreenResources *resources = XRandR::screenResources(); + auto screenResources = XRandR::screenResources(); + Q_ASSERT(screenResources); + if (!screenResources) { + return; + } + xcb_randr_mode_info_t *modes = xcb_randr_get_screen_resources_modes(screenResources); + xcb_randr_mode_t *outputModes = xcb_randr_get_output_info_modes(outputInfo.data()); m_preferredModes.clear(); qDeleteAll(m_modes); m_modes.clear(); - for (int i = 0; i < outputInfo->nmode; ++i) - { + for (int i = 0; i < outputInfo->num_modes; ++i) { /* Resources->modes contains all possible modes, we are only interested * in those listed in outputInfo->modes. */ - for (int j = 0; j < resources->nmode; ++j) { - modeInfo = &resources->modes[j]; - if (modeInfo->id != outputInfo->modes[i]) { + for (int j = 0; j < screenResources->num_modes; ++j) { + if (modes[j].id != outputModes[i]) { continue; } - XRandRMode *mode = new XRandRMode(modeInfo, this); - m_modes.insert(modeInfo->id, mode); + XRandRMode *mode = new XRandRMode(modes[j], this); + m_modes.insert(mode->id(), mode); - if (i < outputInfo->npreferred) { - m_preferredModes.append(QString::number(modeInfo->id)); + if (i < outputInfo->num_preferred) { + m_preferredModes.append(QString::number(mode->id())); } + break; } } - XRRFreeScreenResources(resources); } -void XRandROutput::fetchType() +KScreen::Output::Type XRandROutput::fetchOutputType(xcb_randr_output_t outputId, const QString &name) { - const QByteArray type = typeFromProperty(); + const QByteArray type = typeFromProperty(outputId); if (type.isEmpty()) { - m_type = typeFromName(); - return; + return typeFromName(name); } if (type.contains("VGA")) { - m_type = KScreen::Output::VGA; + return KScreen::Output::VGA; } else if (type.contains("DVI")) { - m_type = KScreen::Output::DVI; + return KScreen::Output::DVI; } else if (type.contains("DVI-I")) { - m_type = KScreen::Output::DVII; + return KScreen::Output::DVII; } else if (type.contains("DVI-A")) { - m_type = KScreen::Output::DVIA; + return KScreen::Output::DVIA; } else if (type.contains("DVI-D")) { - m_type = KScreen::Output::DVID; + return KScreen::Output::DVID; } else if (type.contains("HDMI")) { - m_type = KScreen::Output::HDMI; + return KScreen::Output::HDMI; } else if (type.contains("Panel")) { - m_type = KScreen::Output::Panel; + return KScreen::Output::Panel; } else if (type.contains("TV")) { - m_type = KScreen::Output::TV; + return KScreen::Output::TV; } else if (type.contains("TV-Composite")) { - m_type = KScreen::Output::TVComposite; + return KScreen::Output::TVComposite; } else if (type.contains("TV-SVideo")) { - m_type = KScreen::Output::TVSVideo; + return KScreen::Output::TVSVideo; } else if (type.contains("TV-Component")) { - m_type = KScreen::Output::TVComponent; + return KScreen::Output::TVComponent; } else if (type.contains("TV-SCART")) { - m_type = KScreen::Output::TVSCART; + return KScreen::Output::TVSCART; } else if (type.contains("TV-C4")) { - m_type = KScreen::Output::TVC4; + return KScreen::Output::TVC4; } else if (type.contains("DisplayPort")) { - m_type = KScreen::Output::DisplayPort; + return KScreen::Output::DisplayPort; } else if (type.contains("unknown")) { - m_type = KScreen::Output::Unknown; + return KScreen::Output::Unknown; } else { // qCDebug(KSCREEN_XRANDR) << "Output Type not translated:" << type; } + return KScreen::Output::Unknown; + } -KScreen::Output::Type XRandROutput::typeFromName() +KScreen::Output::Type XRandROutput::typeFromName(const QString &name) { - QStringList embedded; - embedded << "LVDS"; - embedded << "IDP"; - embedded << "EDP"; - embedded << "LCD"; + static const QStringList embedded = QStringList() << QLatin1String("LVDS") + << QLatin1String("IDP") + << QLatin1String("EDP") + << QLatin1String("LCD"); Q_FOREACH(const QString &pre, embedded) { - if (m_name.toUpper().startsWith(pre)) { + if (name.toUpper().startsWith(pre)) { return KScreen::Output::Panel; } } @@ -302,41 +299,40 @@ return KScreen::Output::Unknown; } -QByteArray XRandROutput::typeFromProperty() const +QByteArray XRandROutput::typeFromProperty(xcb_randr_output_t outputId) { QByteArray type; - const Atom atomType = XInternAtom (XRandR::display(), RR_PROPERTY_CONNECTOR_TYPE, True); - if (atomType == None) { + XCB::InternAtom atomType(true, 13, "ConnectorType"); + if (!atomType) { return type; } - unsigned char *prop; - int actualFormat; - unsigned long nitems, bytes_after; - Atom actualType; char *connectorType; - if (XRRGetOutputProperty(XRandR::display(), m_id, atomType, 0, 100, False, - False, AnyPropertyType, &actualType, &actualFormat, &nitems, - &bytes_after, &prop) != Success) { + auto cookie = xcb_randr_get_output_property(XCB::connection(), outputId, atomType, + XCB_ATOM_ANY, 0, 100, false, false); + XCB::ScopedPointer reply(xcb_randr_get_output_property_reply(XCB::connection(), cookie, NULL)); + if (!reply) { + return type; + } + if (!(reply->type == XCB_ATOM_ATOM && reply->format == 32 && reply->num_items == 1)) { return type; } - if (!(actualType == XA_ATOM && actualFormat == 32 && nitems == 1)) { + const uint8_t *prop = xcb_randr_get_output_property_data(reply.data()); + XCB::AtomName atomName(*reinterpret_cast(prop)); + if (!atomName) { return type; } - connectorType = XGetAtomName (XRandR::display(), *((Atom *) prop)); + connectorType = xcb_get_atom_name_name(atomName); if (!connectorType) { return type; } type = connectorType; - XFree (connectorType); - - return type; } @@ -344,67 +340,41 @@ { KScreen::OutputPtr kscreenOutput(new KScreen::Output); - m_changedProperties = 0; + const bool signalsBlocked = kscreenOutput->signalsBlocked(); + kscreenOutput->blockSignals(true); kscreenOutput->setId(m_id); kscreenOutput->setType(m_type); kscreenOutput->setSizeMm(QSize(m_widthMm, m_heightMm)); - updateKScreenOutput(kscreenOutput); - - return kscreenOutput; -} - -void XRandROutput::updateKScreenOutput(KScreen::OutputPtr &output) const -{ - if (!m_changedProperties || (m_changedProperties & PropertyName)) { - output->setName(m_name); - } - - if (!m_changedProperties || (m_changedProperties & PropertyIcon)) { - output->setIcon(m_icon); - } - - if (!m_changedProperties || (m_changedProperties & PropertyPos)) { - output->setPos(m_position); - } + kscreenOutput->setName(m_name); + kscreenOutput->setIcon(m_icon); - if (!m_changedProperties || (m_changedProperties & PropertyRotation)) { - output->setRotation(m_rotation); - } - - if (!m_changedProperties || (m_changedProperties & PropertyCurrentMode)) { - output->setCurrentModeId(m_currentMode); - } - - if (!m_changedProperties || (m_changedProperties & PropertyPreferredMode)) { - output->setPreferredModes(m_preferredModes); - } - - if (!m_changedProperties || (m_changedProperties & PropertyModes)) { - output->setModes(KScreen::ModeList()); - } - - if (!m_changedProperties || (m_changedProperties & PropertyConnected)) { - output->setConnected(m_connected); - } - - if (!m_changedProperties || (m_changedProperties & PropertyEnabled)) { - output->setEnabled(m_enabled); - } - - if (!m_changedProperties || (m_changedProperties & PropertyPrimary)) { - output->setPrimary(m_primary); - } - - if (!m_changedProperties || (m_changedProperties & PropertyClones)) { - output->setClones(m_clones); - } - - if (!m_changedProperties || (m_changedProperties & PropertyModes)) { + kscreenOutput->setConnected(isConnected()); + if (isConnected()) { KScreen::ModeList kscreenModes; - for (auto iter = m_modes.constBegin(); iter != m_modes.constEnd(); ++iter) { + for (auto iter = m_modes.constBegin(), end = m_modes.constEnd(); iter != end; ++iter) { XRandRMode *mode = iter.value(); kscreenModes.insert(QString::number(iter.key()), mode->toKScreenMode()); } - output->setModes(kscreenModes); + kscreenOutput->setModes(kscreenModes); + kscreenOutput->setPreferredModes(m_preferredModes); + kscreenOutput->setPrimary(m_primary); + kscreenOutput->setClones([](const QList &clones) { + QList kclones; + kclones.reserve(clones.size()); + for (xcb_randr_output_t o : clones) { + kclones.append(static_cast(o)); + } + return kclones; + }(m_clones)); + kscreenOutput->setEnabled(isEnabled()); + if (isEnabled()) { + kscreenOutput->setPos(position()); + kscreenOutput->setRotation(rotation()); + kscreenOutput->setCurrentModeId(currentModeId()); + } } + + + kscreenOutput->blockSignals(signalsBlocked); + return kscreenOutput; } diff -Nru libkscreen-5.2.2/backends/xrandr/xrandroutput.h libkscreen-5.3.0/backends/xrandr/xrandroutput.h --- libkscreen-5.2.2/backends/xrandr/xrandroutput.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandroutput.h 2015-04-23 10:04:35.000000000 +0000 @@ -24,11 +24,12 @@ #include #include -#include "xlibandxrandr.h" #include "xrandrmode.h" #include "output.h" +#include "../xcbwrapper.h" class XRandRConfig; +class XRandRCrtc; namespace KScreen { class Config; @@ -38,42 +39,22 @@ class XRandROutput : public QObject { Q_OBJECT - Q_FLAGS(Property Properties) public: - typedef QMap Map; + typedef QMap Map; - enum Property { - PropertyNone = 1 << 0, - PropertyId = 1 << 1, - PropertyName = 1 << 2, - PropertyIcon = 1 << 3, - PropertyModes = 1 << 4, - PropertyPos = 1 << 5, - PropertyRotation = 1 << 6, - PropertyCurrentMode = 1 << 7, - PropertyConnected = 1 << 8, - PropertyEnabled = 1 << 9, - PropertyPrimary = 1 << 10, - PropertyClones = 1 << 11, - PropertyEdid = 1 << 12, - PropertyPreferredMode = 1 << 13 - }; - - enum PrimaryChange { - NoChange = 0, - SetPrimary = 1, - UnsetPrimary = 2, - }; + explicit XRandROutput(xcb_randr_output_t id, XRandRConfig *config); + virtual ~XRandROutput(); - Q_DECLARE_FLAGS(Properties, Property) + void disabled(); + void disconnected(); - explicit XRandROutput(int id, bool primary, XRandRConfig *config = 0); - virtual ~XRandROutput(); + void update(); + void update(xcb_randr_crtc_t crtc, xcb_randr_mode_t mode, xcb_randr_connection_t conn, bool primary); - void update(PrimaryChange primary = NoChange); + void setIsPrimary(bool primary); - int id() const; + xcb_randr_output_t id() const; bool isEnabled() const; bool isConnected() const; bool isPrimary() const; @@ -82,42 +63,34 @@ XRandRMode::Map modes() const; XRandRMode* currentMode() const; KScreen::Output::Rotation rotation() const; - inline bool isHorizontal() const { return ((m_rotation == KScreen::Output::None) || (m_rotation == KScreen::Output::Inverted)); } + bool isHorizontal() const; QByteArray edid() const; + XRandRCrtc* crtc() const; KScreen::OutputPtr toKScreenOutput() const; - void updateKScreenOutput(KScreen::OutputPtr &output) const; - - void updateModes(const XRROutputInfo *outputInfo); - void addNewOutput(const RROutput output); - -Q_SIGNALS: - void outputRemoved(int id); private: - void updateOutput(const XRROutputInfo *outputInfo); - void fetchType(); - KScreen::Output::Type typeFromName(); - QByteArray typeFromProperty() const; + void init(); + void updateModes(const XCB::OutputInfo &outputInfo); + + static KScreen::Output::Type fetchOutputType(xcb_randr_output_t outputId, const QString &name); + static KScreen::Output::Type typeFromName(const QString &name); + static QByteArray typeFromProperty(xcb_randr_output_t outputId); - int m_id; + XRandRConfig *m_config; + xcb_randr_output_t m_id; QString m_name; + xcb_randr_connection_t m_connected; KScreen::Output::Type m_type; QString m_icon; XRandRMode::Map m_modes; - QPoint m_position; - KScreen::Output::Rotation m_rotation; - QString m_currentMode; QStringList m_preferredModes; - bool m_connected; - bool m_enabled; bool m_primary; - QList m_clones; + QList m_clones; mutable QByteArray m_edid; unsigned int m_widthMm; unsigned int m_heightMm; - - mutable int m_changedProperties; + XRandRCrtc *m_crtc; }; Q_DECLARE_METATYPE(XRandROutput::Map) diff -Nru libkscreen-5.2.2/backends/xrandr/xrandrscreen.cpp libkscreen-5.3.0/backends/xrandr/xrandrscreen.cpp --- libkscreen-5.2.2/backends/xrandr/xrandrscreen.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandrscreen.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -19,15 +19,19 @@ #include "xrandrscreen.h" #include "xrandrconfig.h" -#include "xlibandxrandr.h" - #include "screen.h" #include "config.h" + #include +#include "../xcbwrapper.h" + XRandRScreen::XRandRScreen(XRandRConfig *config) : QObject(config) { + XCB::ScreenSize size(XRandR::rootWindow()); + m_maxSize = QSize(size->max_width, size->max_height); + m_minSize = QSize(size->min_width, size->min_height); update(); } @@ -37,19 +41,17 @@ void XRandRScreen::update() { - Display *display = QX11Info::display(); - const int screen = DefaultScreen(display); - const Window rootWindow = XRootWindow(display, screen); - - XRRGetScreenSizeRange (display, rootWindow, - &m_minSize.rwidth(), &m_minSize.rheight(), - &m_maxSize.rwidth(), &m_maxSize.rheight()); - m_currentSize = QSize(DisplayWidth(display, screen),DisplayHeight(display, screen)); + xcb_screen_t *screen = XCB::screenOfDisplay(XCB::connection(), QX11Info::appScreen()); + m_currentSize = QSize(screen->width_in_pixels, screen->height_in_pixels); +} + +void XRandRScreen::update(const QSize &size) +{ + m_currentSize = size; } QSize XRandRScreen::currentSize() { - update(); return m_currentSize; } @@ -60,7 +62,7 @@ kscreenScreen->setMaxSize(m_maxSize); kscreenScreen->setMinSize(m_minSize); kscreenScreen->setCurrentSize(m_currentSize); - kscreenScreen->setMaxActiveOutputsCount(XRandR::screenResources()->ncrtc); + kscreenScreen->setMaxActiveOutputsCount(XRandR::screenResources()->num_crtcs); return kscreenScreen; } diff -Nru libkscreen-5.2.2/backends/xrandr/xrandrscreen.h libkscreen-5.3.0/backends/xrandr/xrandrscreen.h --- libkscreen-5.2.2/backends/xrandr/xrandrscreen.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandrscreen.h 2015-04-23 10:04:35.000000000 +0000 @@ -43,6 +43,7 @@ void updateKScreenScreen(KScreen::ScreenPtr &screen) const; void update(); + void update(const QSize &size); QSize currentSize(); private: diff -Nru libkscreen-5.2.2/backends/xrandr/xrandrxcbhelper.cpp libkscreen-5.3.0/backends/xrandr/xrandrxcbhelper.cpp --- libkscreen-5.2.2/backends/xrandr/xrandrxcbhelper.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandrxcbhelper.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,272 +0,0 @@ -/************************************************************************************* - * Copyright 2012, 2013 Daniel Vrátil * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - *************************************************************************************/ - -#include "xrandrxcbhelper.h" -#include "xrandr.h" -#include "xlibandxrandr.h" - -#include - -#include -#include - -Q_LOGGING_CATEGORY(KSCREEN_XCB_HELPER, "kscreen.xcb.helper") -XRandRXCBHelper::XRandRXCBHelper(): - QObject(), - m_isRandrPresent(false), - m_event11(false), - m_randrBase(0), - m_randrErrorBase(0), - m_majorOpcode(0), - m_eventType(0), - m_versionMajor(0), - m_versionMinor(0), - m_window(0) -{ - QLoggingCategory::setFilterRules(QStringLiteral("kscreen.xcb.helper = true")); - - xcb_connection_t* c = QX11Info::connection(); - xcb_prefetch_extension_data(c, &xcb_randr_id); - xcb_randr_query_version_cookie_t cookie = xcb_randr_query_version(c, - XCB_RANDR_MAJOR_VERSION, - XCB_RANDR_MINOR_VERSION - ); - const xcb_query_extension_reply_t *queryExtension = xcb_get_extension_data(c, &xcb_randr_id); - if (!queryExtension) { - qCDebug(KSCREEN_XCB_HELPER) << "Fail to query for xrandr extension"; - return; - } - if (!queryExtension->present) { - qCDebug(KSCREEN_XCB_HELPER) << "XRandR extension is not present at all"; - return; - } - - m_isRandrPresent = queryExtension->present; - m_randrBase = queryExtension->first_event; - m_randrErrorBase = queryExtension->first_error; - m_majorOpcode = queryExtension->major_opcode; - - xcb_generic_error_t *error = NULL; - xcb_randr_query_version_reply_t* versionReply = xcb_randr_query_version_reply(c, cookie, &error); - Q_ASSERT_X(versionReply, "xrandrxcbhelper", "Query to fetch xrandr version failed"); - if (error) { - qFatal("Error while querying for xrandr version: %d", error->error_code); - } - m_versionMajor = versionReply->major_version; - m_versionMinor = versionReply->minor_version; - free(versionReply); - - if (m_versionMajor == 1 && m_versionMinor <= 1) { - m_event11 = true; - } - qCDebug(KSCREEN_XCB_HELPER).nospace() << "Detected XRandR " << m_versionMajor << "." << m_versionMinor; - qCDebug(KSCREEN_XCB_HELPER) << "Event Base: " << m_randrBase; - qCDebug(KSCREEN_XCB_HELPER) << "Event Error: "<< m_randrErrorBase; - - uint32_t rWindow = QX11Info::appRootWindow(); - m_window = xcb_generate_id(c); - xcb_create_window(c, XCB_COPY_FROM_PARENT, m_window, - rWindow, - 0, 0, 1, 1, 0, XCB_COPY_FROM_PARENT, - XCB_COPY_FROM_PARENT, 0, NULL); - - xcb_randr_select_input(c, m_window, - XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE | - XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE | - XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE | - XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY - ); - - qApp->installNativeEventFilter(this); -} - -XRandRXCBHelper::~XRandRXCBHelper() -{ - if (m_window && QX11Info::connection()) { - xcb_destroy_window(QX11Info::connection(), m_window); - } -} - -QString XRandRXCBHelper::rotationToString(Rotation rotation) -{ - switch (rotation) { - case RR_Rotate_0: - return "RR_Rotate_0"; - case RR_Rotate_90: - return "RR_Rotate_90"; - case RR_Rotate_180: - return "RR_Rotate_180"; - case RR_Rotate_270: - return "RR_Rotate_270"; - } - - return QString("invalid value (%1)").arg(rotation); -} - -QString XRandRXCBHelper::connectionToString(Connection connection) -{ - switch (connection) { - case RR_Connected: - return "RR_Connected"; - case RR_Disconnected: - return "RR_Disconnected"; - case RR_UnknownConnection: - return "RR_UnknownConnection"; - } - - return QString("invalid value (%1)").arg(connection); -} - -bool XRandRXCBHelper::nativeEventFilter(const QByteArray& eventType, void* message, long int* result) -{ - Q_UNUSED(result); - - if (eventType != "xcb_generic_event_t") { - return false; - } - - xcb_generic_event_t* e = static_cast(message); - const uint8_t xEventType = e->response_type & ~0x80; - - //If this event is not xcb_randr_notify, we don't want it - if (xEventType == m_randrBase + XCB_RANDR_SCREEN_CHANGE_NOTIFY && m_event11) { - handleScreenChange(e); - } - if (xEventType == m_randrBase + XCB_RANDR_NOTIFY) { - handleXRandRNotify(e); - } - - return false; -} - -void XRandRXCBHelper::handleScreenChange(xcb_generic_event_t* e) -{ - xcb_randr_screen_change_notify_event_t *e2 = - (xcb_randr_screen_change_notify_event_t *) e; - qCDebug(KSCREEN_XCB_HELPER) << "Timestamp: " << e2->timestamp; - qCDebug(KSCREEN_XCB_HELPER) << "Window: " << e2->request_window; - qCDebug(KSCREEN_XCB_HELPER) << "Root: "<< e2->root; - qCDebug(KSCREEN_XCB_HELPER) << "Subpixel Order:" << e2->subpixel_order; - qCDebug(KSCREEN_XCB_HELPER) << "Rotation: " << rotationToString(e2->rotation); - qCDebug(KSCREEN_XCB_HELPER) << "Size: " << e2->width << e2->height; - qCDebug(KSCREEN_XCB_HELPER) << "SizeMM: " << e2->mwidth << e2->mheight; - - Q_EMIT outputsChanged(); -} - -void XRandRXCBHelper::handleXRandRNotify(xcb_generic_event_t* e) -{ - xcb_randr_notify_event_t* - randrEvent = reinterpret_cast(e); - - if (randrEvent->subCode == XCB_RANDR_NOTIFY_CRTC_CHANGE) { - xcb_randr_crtc_change_t crtc = randrEvent->u.cc; - qCDebug(KSCREEN_XCB_HELPER) << "CRTC CHANGE"; - qCDebug(KSCREEN_XCB_HELPER) << "CRTC: " << crtc.crtc; - qCDebug(KSCREEN_XCB_HELPER) << "Mode: " << crtc.mode; - qCDebug(KSCREEN_XCB_HELPER) << "Rotation: " << rotationToString(crtc.rotation); - qCDebug(KSCREEN_XCB_HELPER) << "Geometry: " << crtc.x << crtc.y << crtc.width << crtc.height; - - Q_EMIT crtcChanged(crtc.crtc); - } else if(randrEvent->subCode == XCB_RANDR_NOTIFY_OUTPUT_CHANGE) { - xcb_randr_output_change_t output = randrEvent->u.oc; - qCDebug(KSCREEN_XCB_HELPER) << "OUTPUT CHANGE"; - qCDebug(KSCREEN_XCB_HELPER) << "Output: " << output.output; - qCDebug(KSCREEN_XCB_HELPER) << "CRTC: " << output.crtc; - qCDebug(KSCREEN_XCB_HELPER) << "Mode: " << output.mode; - qCDebug(KSCREEN_XCB_HELPER) << "Rotation: " << rotationToString(output.rotation); - qCDebug(KSCREEN_XCB_HELPER) << "Connection: " << connectionToString(output.connection); - qCDebug(KSCREEN_XCB_HELPER) << "Subpixel Order: " << output.subpixel_order; - - Q_EMIT outputChanged(output.output); - } else if(randrEvent->subCode == XCB_RANDR_NOTIFY_OUTPUT_PROPERTY) { - xcb_randr_output_property_t property = randrEvent->u.op; - - xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(QX11Info::connection(), xcb_get_atom_name(QX11Info::connection(), property.atom), NULL) ; - - qCDebug(KSCREEN_XCB_HELPER) << "OUTPUT PROPERTY"; - qCDebug(KSCREEN_XCB_HELPER) << "Output: " << property.output; - qCDebug(KSCREEN_XCB_HELPER) << "Property: " << xcb_get_atom_name_name(reply); - qCDebug(KSCREEN_XCB_HELPER) << "State (newValue, Deleted): " << property.status; - free(reply); - } -} - - -bool XRandRXCBHelper::x11Event(XEvent *event) -{ - /* XRandR <= 1.1 */ - if (m_versionMajor == 1 && m_versionMinor <= 1) { - if (event->xany.type == m_randrBase + RRScreenChangeNotify) { - - XRRScreenChangeNotifyEvent* e2 = reinterpret_cast< XRRScreenChangeNotifyEvent* >(event); - - qCDebug(KSCREEN_XCB_HELPER) << "Timestamp: " << e2->timestamp; - qCDebug(KSCREEN_XCB_HELPER) << "Window: " << e2->window; - qCDebug(KSCREEN_XCB_HELPER) << "Root: "<< e2->root; - qCDebug(KSCREEN_XCB_HELPER) << "Size Index: " << e2->size_index; - qCDebug(KSCREEN_XCB_HELPER) << "Subpixel Order:" << e2->subpixel_order; - qCDebug(KSCREEN_XCB_HELPER) << "Rotation: " << rotationToString(e2->rotation); - qCDebug(KSCREEN_XCB_HELPER) << "Size: " << e2->width << e2->height; - qCDebug(KSCREEN_XCB_HELPER) << "SizeMM: " << e2->mwidth << e2->mheight; - - Q_EMIT outputsChanged(); - } - - return false; - } - - /* XRandR >= 1.2 */ - if (event->xany.type == m_randrBase + RRNotify) { - XRRNotifyEvent* e2 = reinterpret_cast< XRRNotifyEvent* >(event); - if (e2->subtype == RRNotify_CrtcChange) { - XRRCrtcChangeNotifyEvent* e2 = reinterpret_cast< XRRCrtcChangeNotifyEvent* >(event); - - qCDebug(KSCREEN_XCB_HELPER) << "CRTC: " << e2->crtc; - qCDebug(KSCREEN_XCB_HELPER) << "Mode: " << e2->mode; - qCDebug(KSCREEN_XCB_HELPER) << "Rotation: " << rotationToString(e2->rotation); - qCDebug(KSCREEN_XCB_HELPER) << "Geometry: " << e2->x << e2->y << e2->width << e2->height; - - Q_EMIT crtcChanged(e2->crtc); - - } else if (e2->subtype == RRNotify_OutputChange) { - XRROutputChangeNotifyEvent* e2 = reinterpret_cast< XRROutputChangeNotifyEvent* >(event); - - qCDebug(KSCREEN_XCB_HELPER) << "Output: " << e2->output; - qCDebug(KSCREEN_XCB_HELPER) << "CRTC: " << e2->crtc; - qCDebug(KSCREEN_XCB_HELPER) << "Mode: " << e2->mode; - qCDebug(KSCREEN_XCB_HELPER) << "Rotation: " << rotationToString(e2->rotation); - qCDebug(KSCREEN_XCB_HELPER) << "Connection: " << connectionToString(e2->connection); - qCDebug(KSCREEN_XCB_HELPER) << "Subpixel Order: " << e2->subpixel_order; - - Q_EMIT outputChanged(e2->output); - - } else if (e2->subtype == RRNotify_OutputProperty) { - XRROutputPropertyNotifyEvent* e2 = reinterpret_cast< XRROutputPropertyNotifyEvent* >(event); - - char *atom_name = XGetAtomName(QX11Info::display(), e2->property); - qCDebug(KSCREEN_XCB_HELPER) << "Timestamp: " << e2->timestamp; - qCDebug(KSCREEN_XCB_HELPER) << "Output: " << e2->output; - qCDebug(KSCREEN_XCB_HELPER) << "Property: " << XGetAtomName(QX11Info::display(), e2->property); - qCDebug(KSCREEN_XCB_HELPER) << "State (newValue, Deleted): " << e2->state; - XFree(atom_name); - } - } - - return false; -} diff -Nru libkscreen-5.2.2/backends/xrandr/xrandrxcbhelper.h libkscreen-5.3.0/backends/xrandr/xrandrxcbhelper.h --- libkscreen-5.2.2/backends/xrandr/xrandrxcbhelper.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr/xrandrxcbhelper.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -/************************************************************************************* - * Copyright 2012, 2013 Daniel Vrátil * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - *************************************************************************************/ - -#ifndef XRANDRX11HELPER_H -#define XRANDRX11HELPER_H - -#include -#include -#include -#include - -#include "xlibandxrandr.h" - -class XRandRXCBHelper : public QObject, public QAbstractNativeEventFilter -{ - Q_OBJECT - - public: - XRandRXCBHelper(); - virtual ~XRandRXCBHelper(); - - virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long int* result) Q_DECL_OVERRIDE; - Q_SIGNALS: - /* Emitted when only XRandR 1.1 or older is available */ - void outputsChanged(); - - /* Emitted only when XRandR 1.2 or newer is available */ - void crtcChanged(RRCrtc crtc); - void outputChanged(RROutput output); - void outputPropertyChanged(RROutput output); - - private: - QString rotationToString(Rotation rotation); - QString connectionToString(Connection connection); - void handleScreenChange(xcb_generic_event_t *e); - void handleXRandRNotify(xcb_generic_event_t *e); - inline xcb_window_t rootWindow(xcb_connection_t *c, int screen) - { - xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(c)); - for (xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(c)); - it.rem; - --screen, xcb_screen_next(&it)) { - if (screen == 0) { - return iter.data->root; - } - } - return XCB_WINDOW_NONE; - } - - protected: - virtual bool x11Event(XEvent *); - - bool m_isRandrPresent; - bool m_event11; - int m_randrBase; - int m_randrErrorBase; - int m_majorOpcode; - int m_eventType; - int m_versionMajor; - int m_versionMinor; - - uint32_t m_window; -}; - -Q_DECLARE_LOGGING_CATEGORY(KSCREEN_XCB_HELPER) -#endif // XRANDRX11HELPER_H diff -Nru libkscreen-5.2.2/backends/xrandr1.1/CMakeLists.txt libkscreen-5.3.0/backends/xrandr1.1/CMakeLists.txt --- libkscreen-5.2.2/backends/xrandr1.1/CMakeLists.txt 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr1.1/CMakeLists.txt 2015-04-23 10:04:35.000000000 +0000 @@ -4,12 +4,12 @@ ${KDE4_INCLUDES} ${CMAKE_BUILD_DIR} ${QT_INCLUDES} - ${X11_Xrandr_INCLUDE_PATH} ) set(xrandr11_SRCS xrandr11.cpp - ../xrandr/xrandrxcbhelper.cpp + ../xcbeventlistener.cpp + ../xcbwrapper.cpp ) add_library(KSC_XRandR11 MODULE ${xrandr11_SRCS}) @@ -18,8 +18,6 @@ target_link_libraries(KSC_XRandR11 Qt5::Core Qt5::Gui Qt5::X11Extras - ${X11_LIBRARIES} - ${X11_Xrandr_LIB} ${XCB_LIBRARIES} KF5::Screen ) diff -Nru libkscreen-5.2.2/backends/xrandr1.1/fixx11h.h libkscreen-5.3.0/backends/xrandr1.1/fixx11h.h --- libkscreen-5.2.2/backends/xrandr1.1/fixx11h.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr1.1/fixx11h.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,301 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2003 Lubos Lunak - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -****************************************************************************/ - -//#ifdef don't do this, this file is supposed to be included -//#define multiple times - -#include - -/* Usage: - - If you get compile errors caused by X11 includes (the line - where first error appears contains word like None, Unsorted, - Below, etc.), put #include in the .cpp file - (not .h file!) between the place where X11 headers are - included and the place where the file with compile - error is included (or the place where the compile error - in the .cpp file occurs). - - This file remaps X11 #defines to const variables or - inline functions. The side effect may be that these - symbols may now refer to different variables - (e.g. if X11 #defined NoButton, after this file - is included NoButton would no longer be X11's - NoButton, but Qt::NoButton instead). At this time, - there's no conflict known that could cause problems. - - The original X11 symbols are still accessible - (e.g. for None) as X::None, XNone, and also still - None, unless name lookup finds different None - first (in the current class, etc.) - - Use 'Unsorted', 'Bool' and 'index' as templates. - -*/ - -namespace X -{ - -// template ---> -// Affects: Should be without side effects. -#ifdef Unsorted -#ifndef FIXX11H_Unsorted -#define FIXX11H_Unsorted -const int XUnsorted = Unsorted; -#undef Unsorted -const int Unsorted = XUnsorted; -#endif -#undef Unsorted -#endif -// template <--- - -// Affects: Should be without side effects. -#ifdef None -#ifndef FIXX11H_None -#define FIXX11H_None -const XID XNone = None; -#undef None -const XID None = XNone; -#endif -#undef None -#endif - -// template ---> -// Affects: Should be without side effects. -#ifdef Bool -#ifndef FIXX11H_Bool -#define FIXX11H_Bool -#ifdef _XTYPEDEF_BOOL /* Xdefs.h has typedef'ed Bool already */ -#undef Bool -#else -typedef Bool XBool; -#undef Bool -typedef XBool Bool; -#endif -#endif -#undef Bool -#define _XTYPEDEF_BOOL -#endif -// template <--- - -// Affects: Should be without side effects. -#ifdef KeyPress -#ifndef FIXX11H_KeyPress -#define FIXX11H_KeyPress -const int XKeyPress = KeyPress; -#undef KeyPress -const int KeyPress = XKeyPress; -#endif -#undef KeyPress -#endif - -// Affects: Should be without side effects. -#ifdef KeyRelease -#ifndef FIXX11H_KeyRelease -#define FIXX11H_KeyRelease -const int XKeyRelease = KeyRelease; -#undef KeyRelease -const int KeyRelease = XKeyRelease; -#endif -#undef KeyRelease -#endif - -// Affects: Should be without side effects. -#ifdef Above -#ifndef FIXX11H_Above -#define FIXX11H_Above -const int XAbove = Above; -#undef Above -const int Above = XAbove; -#endif -#undef Above -#endif - -// Affects: Should be without side effects. -#ifdef Below -#ifndef FIXX11H_Below -#define FIXX11H_Below -const int XBelow = Below; -#undef Below -const int Below = XBelow; -#endif -#undef Below -#endif - -// Affects: Should be without side effects. -#ifdef FocusIn -#ifndef FIXX11H_FocusIn -#define FIXX11H_FocusIn -const int XFocusIn = FocusIn; -#undef FocusIn -const int FocusIn = XFocusIn; -#endif -#undef FocusIn -#endif - -// Affects: Should be without side effects. -#ifdef FocusOut -#ifndef FIXX11H_FocusOut -#define FIXX11H_FocusOut -const int XFocusOut = FocusOut; -#undef FocusOut -const int FocusOut = XFocusOut; -#endif -#undef FocusOut -#endif - -// Affects: Should be without side effects. -#ifdef Always -#ifndef FIXX11H_Always -#define FIXX11H_Always -const int XAlways = Always; -#undef Always -const int Always = XAlways; -#endif -#undef Always -#endif - -// Affects: Should be without side effects. -#ifdef Expose -#ifndef FIXX11H_Expose -#define FIXX11H_Expose -const int XExpose = Expose; -#undef Expose -const int Expose = XExpose; -#endif -#undef Expose -#endif - -// Affects: Should be without side effects. -#ifdef Success -#ifndef FIXX11H_Success -#define FIXX11H_Success -const int XSuccess = Success; -#undef Success -const int Success = XSuccess; -#endif -#undef Success -#endif - -// Affects: Should be without side effects. -#ifdef GrayScale -#ifndef FIXX11H_GrayScale -#define FIXX11H_GrayScale -const int XGrayScale = GrayScale; -#undef GrayScale -const int GrayScale = XGrayScale; -#endif -#undef GrayScale -#endif - -// Affects: Should be without side effects. -#ifdef Status -#ifndef FIXX11H_Status -#define FIXX11H_Status -typedef Status XStatus; -#undef Status -typedef XStatus Status; -#endif -#undef Status -#endif - -// template ---> -// Affects: Should be without side effects. -#ifdef CursorShape -#ifndef FIXX11H_CursorShape -#define FIXX11H_CursorShape -const int XCursorShape = CursorShape; -#undef CursorShape -const int CursorShape = XCursorShape; -#endif -#undef CursorShape -#endif -// template <--- - -// template ---> -// Affects: Should be without side effects. -#ifdef FontChange -#ifndef FIXX11H_FontChange -#define FIXX11H_FontChange -const int XFontChange = FontChange; -#undef FontChange -const int FontChange = XFontChange; -#endif -#undef FontChange -#endif -// template <--- - -// Affects: Should be without side effects. -#ifdef NormalState -#ifndef FIXX11H_NormalState -#define FIXX11H_NormalState -const int XNormalState = NormalState; -#undef NormalState -const int NormalState = XNormalState; -#endif -#undef NormalState -#endif - -// template ---> -// Affects: Should be without side effects. -#ifdef index -#ifndef FIXX11H_index -#define FIXX11H_index -inline -const char *Xindex(const char *s, int c) -{ - return index(s, c); -} -#undef index -inline -const char *index(const char *s, int c) -{ - return Xindex(s, c); -} -#endif -#undef index -#endif -// template <--- - -#ifdef rindex -// Affects: Should be without side effects. -#ifndef FIXX11H_rindex -#define FIXX11H_rindex -inline -const char *Xrindex(const char *s, int c) -{ - return rindex(s, c); -} -#undef rindex -inline -const char *rindex(const char *s, int c) -{ - return Xrindex(s, c); -} -#endif -#undef rindex -#endif -} - -using namespace X; diff -Nru libkscreen-5.2.2/backends/xrandr1.1/wrapper.h libkscreen-5.3.0/backends/xrandr1.1/wrapper.h --- libkscreen-5.2.2/backends/xrandr1.1/wrapper.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr1.1/wrapper.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,174 +0,0 @@ -/******************************************************************** - K Win - the KDE window manager - This file is part of the KDE project. - -Copyright (C) 2012, 2013 Martin Gräßlin - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*********************************************************************/ - -#include "xlibandxcb.h" - -#include -#include - -static xcb_connection_t *XRandR11XCBConnection = 0; - -xcb_connection_t *connection() -{ - // Use our own connection to make sure that we won't mess up Qt's connection - // if something goes wrong on our side. - if (XRandR11XCBConnection == 0) { - XRandR11XCBConnection = xcb_connect(0, 0); - } - return XRandR11XCBConnection; -} - -void closeConnection() -{ - xcb_disconnect(XRandR11XCBConnection); - XRandR11XCBConnection = 0; -} - -xcb_screen_t *screen_of_display (xcb_connection_t *c, int screen) -{ - xcb_screen_iterator_t iter; - - iter = xcb_setup_roots_iterator (xcb_get_setup (c)); - for (; iter.rem; --screen, xcb_screen_next (&iter)) - if (screen == 0) - return iter.data; - - return NULL; -} - -typedef xcb_window_t WindowId; - -template -class Wrapper -{ -public: - Wrapper() - : m_retrieved(false) - , m_window(XCB_WINDOW_NONE) - , m_reply(NULL) - { - m_cookie.sequence = 0; - } - explicit Wrapper(WindowId window) - : m_retrieved(false) - , m_cookie(requestFunc(connection(), window)) - , m_window(window) - , m_reply(NULL) - { - } - explicit Wrapper(const Wrapper &other) - : m_retrieved(other.m_retrieved) - , m_cookie(other.m_cookie) - , m_window(other.m_window) - , m_reply(NULL) - { - takeFromOther(const_cast(other)); - } - virtual ~Wrapper() { - cleanup(); - } - inline Wrapper &operator=(const Wrapper &other) { - if (this != &other) { - // if we had managed a reply, free it - cleanup(); - // copy members - m_retrieved = other.m_retrieved; - m_cookie = other.m_cookie; - m_window = other.m_window; - m_reply = other.m_reply; - // take over the responsibility for the reply pointer - takeFromOther(const_cast(other)); - } - return *this; - } - - inline const Reply *operator->() const { - getReply(); - return m_reply; - } - inline bool isNull() const { - getReply(); - return m_reply == NULL; - } - inline operator bool() const { - return !isNull(); - } - inline const Reply *data() const { - getReply(); - return m_reply; - } - inline WindowId window() const { - return m_window; - } - inline bool isRetrieved() const { - return m_retrieved; - } - /** - * Returns the value of the reply pointer referenced by this object. The reply pointer of - * this object will be reset to null. Calling any method which requires the reply to be valid - * will crash. - * - * Callers of this function take ownership of the pointer. - **/ - inline Reply *take() { - getReply(); - Reply *ret = m_reply; - m_reply = NULL; - m_window = XCB_WINDOW_NONE; - return ret; - } - -protected: - void getReply() const { - if (m_retrieved || !m_cookie.sequence) { - return; - } - m_reply = replyFunc(connection(), m_cookie, NULL); - m_retrieved = true; - } - -private: - inline void cleanup() { - if (!m_retrieved && m_cookie.sequence) { - xcb_discard_reply(connection(), m_cookie.sequence); - } else if (m_reply) { - free(m_reply); - } - } - inline void takeFromOther(Wrapper &other) { - if (m_retrieved) { - m_reply = other.take(); - } else { - //ensure that other object doesn't try to get the reply or discards it in the dtor - other.m_retrieved = true; - other.m_window = XCB_WINDOW_NONE; - } - } - mutable bool m_retrieved; - Cookie m_cookie; - WindowId m_window; - mutable Reply *m_reply; -}; - -typedef Wrapper ScreenSize; -typedef Wrapper ScreenInfo; diff -Nru libkscreen-5.2.2/backends/xrandr1.1/xlibandxcb.h libkscreen-5.3.0/backends/xrandr1.1/xlibandxcb.h --- libkscreen-5.2.2/backends/xrandr1.1/xlibandxcb.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr1.1/xlibandxcb.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/************************************************************************************* - * Copyright (C) 2012 by Alejandro Fiestas Olivares * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - *************************************************************************************/ - -#ifndef XLIBANDXCB_H -#define XLIBANDXCB_H - -extern "C" -{ - #include - #include - #include - #define INT8 _X11INT8 - #define INT32 _X11INT32 - #include - #undef INT8 - #undef INT32 - - #include -} - -#include "fixx11h.h" - -#endif // XLIBANDXCB_H diff -Nru libkscreen-5.2.2/backends/xrandr1.1/xrandr11.cpp libkscreen-5.3.0/backends/xrandr1.1/xrandr11.cpp --- libkscreen-5.2.2/backends/xrandr1.1/xrandr11.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr1.1/xrandr11.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -17,8 +17,7 @@ *************************************************************************************/ #include "xrandr11.h" -#include "wrapper.h" -#include "../xrandr/xrandrxcbhelper.h" +#include "../xcbeventlistener.h" #include "config.h" #include "edid.h" @@ -44,28 +43,32 @@ xcb_generic_error_t *error = 0; xcb_randr_query_version_reply_t* version; - version = xcb_randr_query_version_reply(connection(), xcb_randr_query_version(connection(), XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION), &error); + version = xcb_randr_query_version_reply(XCB::connection(), + xcb_randr_query_version(XCB::connection(), XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION), &error); if (!version || error) { free(error); + XCB::closeConnection(); qCDebug(KSCREEN_XRANDR11) << "Can't get XRandR version"; return; } if (version->major_version != 1 || version->minor_version != 1) { + XCB::closeConnection(); qCDebug(KSCREEN_XRANDR11) << "This backend is only for XRandR 1.1, your version is: " << version->major_version << "." << version->minor_version; return; } - m_x11Helper = new XRandRXCBHelper(); + m_x11Helper = new XCBEventListener(); - connect(m_x11Helper, SIGNAL(outputsChanged()), SLOT(updateConfig())); + connect(m_x11Helper, &XCBEventListener::outputsChanged, + this, &XRandR11::updateConfig); m_valid = true; } XRandR11::~XRandR11() { - closeConnection(); + XCB::closeConnection(); delete m_x11Helper; } @@ -90,9 +93,9 @@ KScreen::ConfigPtr config(new KScreen::Config); const int screenId = QX11Info::appScreen(); - xcb_screen_t* xcbScreen = screen_of_display(connection(), screenId); - const ScreenInfo info(xcbScreen->root); - const ScreenSize size(xcbScreen->root); + xcb_screen_t* xcbScreen = XCB::screenOfDisplay(XCB::connection(), screenId); + const XCB::ScreenInfo info(xcbScreen->root); + const XCB::ScreenSize size(xcbScreen->root); if (info->config_timestamp == m_currentTimestamp) { return m_currentConfig; @@ -130,26 +133,28 @@ KScreen::ModePtr mode; KScreen::ModeList modes; - xcb_randr_refresh_rates_iterator_t ite = xcb_randr_get_screen_info_rates_iterator(info.data()); - xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(info.data()); + auto iter = xcb_randr_get_screen_info_rates_iterator(info); + xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(info); for (int x = 0; x < info->nSizes; x++) { - const uint16_t* rates = xcb_randr_refresh_rates_rates(ite.data); - const int nrates = xcb_randr_refresh_rates_rates_length(ite.data); + const xcb_randr_screen_size_t size = sizes[x]; + const uint16_t* rates = xcb_randr_refresh_rates_rates(iter.data); + const int nrates = xcb_randr_refresh_rates_rates_length(iter.data); for (int j = 0; j < nrates; j++) { + float rate = rates[j]; mode = KScreen::ModePtr(new KScreen::Mode); - mode->setId(QString::number(x) + "-" + QString::number(j)); - mode->setSize(QSize(sizes[x].width, sizes[x].height)); - mode->setRefreshRate((float) rates[j]); - mode->setName(QString(QString::number(sizes[x].width) + "x" + QString::number(sizes[x].height))); + mode->setId(QString::fromLatin1("%1-%2").arg(x).arg(j)); + mode->setSize(QSize(size.width, size.height)); + mode->setRefreshRate(rate); + mode->setName(QString::fromLatin1("%1x%2").arg(size.width).arg(size.height)); - if (x == info->sizeID && rates[j] == info->rate) { + if (x == info->sizeID && rate == info->rate) { output->setCurrentModeId(mode->id()); } modes.insert(mode->id(), mode); } - xcb_randr_refresh_rates_next(&ite); + xcb_randr_refresh_rates_next(&iter); } output->setModes(modes); @@ -162,18 +167,19 @@ const KScreen::ModePtr mode = output->currentMode(); const int screenId = QX11Info::appScreen(); - xcb_screen_t* xcbScreen = screen_of_display(connection(), screenId); + xcb_screen_t* xcbScreen = XCB::screenOfDisplay(XCB::connection(), screenId); - const ScreenInfo info(xcbScreen->root); + const XCB::ScreenInfo info(xcbScreen->root); xcb_generic_error_t *err; - xcb_randr_set_screen_config_cookie_t cookie; - xcb_randr_set_screen_config_reply_t *result; const int sizeId = mode->id().split("-").first().toInt(); - cookie = xcb_randr_set_screen_config(connection(), xcbScreen->root, CurrentTime, info->config_timestamp, sizeId, + auto cookie = xcb_randr_set_screen_config(XCB::connection(), xcbScreen->root, + XCB_CURRENT_TIME, info->config_timestamp, sizeId, (short) output->rotation(), mode->refreshRate()); - result = xcb_randr_set_screen_config_reply(connection(), cookie, &err); - - delete result; + XCB::ScopedPointer reply( + xcb_randr_set_screen_config_reply(XCB::connection(), cookie, &err)); + if (err) { + free(err); + } } void XRandR11::updateConfig() diff -Nru libkscreen-5.2.2/backends/xrandr1.1/xrandr11.h libkscreen-5.3.0/backends/xrandr1.1/xrandr11.h --- libkscreen-5.2.2/backends/xrandr1.1/xrandr11.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/backends/xrandr1.1/xrandr11.h 2015-04-23 10:04:35.000000000 +0000 @@ -19,12 +19,13 @@ #ifndef XRANDR11_BACKEND_H #define XRANDR11_BACKEND_H -#include "xlibandxcb.h" #include "abstractbackend.h" +#include "../xcbwrapper.h" + #include #include -class XRandRXCBHelper; +class XCBEventListener; class XRandR11 : public KScreen::AbstractBackend { @@ -46,10 +47,11 @@ private: bool m_valid; - XRandRXCBHelper* m_x11Helper; + XCBEventListener* m_x11Helper; KScreen::ConfigPtr m_currentConfig; xcb_timestamp_t m_currentTimestamp; }; Q_DECLARE_LOGGING_CATEGORY(KSCREEN_XRANDR11) + #endif //FAKE_BACKEND_H diff -Nru libkscreen-5.2.2/debian/changelog libkscreen-5.3.0/debian/changelog --- libkscreen-5.2.2/debian/changelog 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/changelog 2015-04-28 17:29:05.000000000 +0000 @@ -1,9 +1,20 @@ -libkscreen (4:5.2.2-1) experimental; urgency=medium +libkscreen (4:5.3.0-0tanglu1) staging; urgency=medium - * New upstream release (5.2.1). - * New upstream release (5.2.2). + * Upload for Tanglu - -- Maximiliano Curia Wed, 25 Mar 2015 23:17:37 +0100 + -- Matthias Klumpp Tue, 28 Apr 2015 19:29:05 +0200 + +libkscreen (4:5.3.0-0ubuntu1~ubuntu15.04~ppa1) vivid; urgency=medium + + [ Scarlett Clark ] + * Manual merge kubuntu_stable. + + [ Jonathan Riddell ] + * Plasma 5.3 beta + * new upstream release + * PPA build + + -- Jonathan Riddell Thu, 23 Apr 2015 17:04:43 +0200 libkscreen (4:5.2.2-0ubuntu1) vivid; urgency=medium @@ -23,26 +34,6 @@ -- Scarlett Clark Mon, 23 Feb 2015 09:43:36 -0800 -libkscreen (4:5.2.0-1) experimental; urgency=medium - - [ Harald Sitter ] - * Use software transition flags for kscreen5->6 - Using versioned breaks/replaces instead of an unversioned - conflicts. - - [ Maximiliano Curia ] - * Prepare initial Debian release. - * Add myself as Uploader. - * Bump Standards-Version to 3.9.6, no changes needed. - * Update build dependencies to build against experimental and to - follow cmake. - * Update copyright information. - * Update install files. - * Update watch file. - * Add basic autopkgtests support. - - -- Maximiliano Curia Mon, 09 Feb 2015 17:18:18 +0100 - libkscreen (4:5.2.0-0ubuntu1) vivid; urgency=medium * New upstream release @@ -63,6 +54,12 @@ -- Jonathan Riddell Thu, 15 Jan 2015 01:32:51 +0100 +libkscreen (5.1.2-0ubuntu1) UNRELEASED; urgency=medium + + * New upstream release + + -- Jonathan Riddell Fri, 12 Dec 2014 14:37:52 +0100 + libkscreen (5.1.1-0ubuntu2) vivid; urgency=medium * Add symbols file @@ -72,18 +69,34 @@ libkscreen (5.1.1-0ubuntu1) vivid; urgency=medium * New upstream release. - * Add missing build depends for various xcb protocols. -- Scarlett Clark Mon, 10 Nov 2014 19:48:54 +0100 +libkscreen (5.1.0.1-0ubuntu1) UNRELEASED; urgency=medium + + [ Jonathan Riddell ] + * New upstream release + + [ Scarlett Clark ] + * Add missing build depends for various xcb protocols. + + -- Jonathan Riddell Wed, 01 Oct 2014 15:47:21 +0200 + libkscreen (5.0.93-0ubuntu1) utopic; urgency=medium * New upstream release + -- Scarlett Clark Thu, 18 Sep 2014 07:13:45 -0700 + +libkscreen (5.0.92-0ubuntu1) UNRELEASED; urgency=medium + + [ Jonathan Riddell ] + * New upstream bugfix release + [ Harald Sitter ] * switch to new pkg-kde-tools - -- Scarlett Clark Thu, 18 Sep 2014 07:13:45 -0700 + -- Jonathan Riddell Sun, 10 Aug 2014 16:57:26 +0200 libkscreen (5.0.91-0ubuntu1) utopic; urgency=medium diff -Nru libkscreen-5.2.2/debian/control libkscreen-5.3.0/debian/control --- libkscreen-5.2.2/debian/control 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/control 2015-04-28 17:29:04.000000000 +0000 @@ -1,34 +1,56 @@ Source: libkscreen -Section: libs -Priority: optional +Priority: extra Maintainer: Debian/Kubuntu Qt/KDE Maintainers -Uploaders: Maximiliano Curia -Build-Depends: cmake (>= 2.8.12), - debhelper (>= 9), +Build-Depends: cmake, + debhelper (>= 9.0.0), extra-cmake-modules (>= 1.3.0~), - libqt5x11extras5-dev (>= 5.2.0~), - libx11-dev, + libqjson-dev, + libqt5x11extras5-dev, libx11-xcb-dev, + libxcb-composite0-dev, + libxcb-cursor-dev, + libxcb-damage0-dev, + libxcb-dpms0-dev, + libxcb-ewmh-dev, + libxcb-icccm4-dev, + libxcb-image0-dev, + libxcb-keysyms1-dev, libxcb-randr0-dev, + libxcb-record0-dev, + libxcb-render-util0-dev, + libxcb-res0-dev, + libxcb-screensaver0-dev, + libxcb-shape0-dev, + libxcb-shm0-dev, + libxcb-sync-dev, + libxcb-util0-dev, + libxcb-xevie0-dev, + libxcb-xf86dri0-dev, + libxcb-xfixes0-dev, + libxcb-xinerama0-dev, + libxcb-xkb-dev, + libxcb-xprint0-dev, + libxcb-xtest0-dev, + libxcb-xv0-dev, + libxcb-xvmc0-dev, libxcb1-dev, libxrandr-dev, pkg-config, pkg-kde-tools (>= 0.15.15ubuntu1~), - qtbase5-dev (>= 5.2.0), + qtbase5-dev, xauth, + xcb-proto, xvfb -Standards-Version: 3.9.6 -XS-Testsuite: autopkgtest +Standards-Version: 3.9.5 +Section: libs Homepage: https://projects.kde.org/projects/kde/workspace/libkscreen -Vcs-Browser: http://anonscm.debian.org/cgit/pkg-kde/plasma/libkscreen.git +Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-kde/plasma/libkscreen.git Vcs-Git: git://anonscm.debian.org/pkg-kde/plasma/libkscreen.git Package: libkf5screen-dev Section: libdevel Architecture: any -Depends: libkf5screen6 (= ${binary:Version}), - qtbase5-dev (>= 5.2.0), - ${misc:Depends} +Depends: libkf5screen6 (= ${binary:Version}), ${misc:Depends} Description: library for screen management - development files The KDE multiple monitor support is trying be as smart as possible adapting the behavior of it to each use case making the configuration @@ -37,6 +59,7 @@ This package contains the files necessary for development. Package: libkf5screen6 +Section: libs Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends} Breaks: libkf5screen5 (<< 4:5.2.0) @@ -50,7 +73,6 @@ Package: libkscreen-dbg Section: debug -Priority: extra Architecture: any Recommends: qtbase5-dbg Depends: libkf5screen6 (= ${binary:Version}), ${misc:Depends} diff -Nru libkscreen-5.2.2/debian/copyright libkscreen-5.3.0/debian/copyright --- libkscreen-5.2.2/debian/copyright 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/copyright 2015-04-23 15:04:34.000000000 +0000 @@ -1,42 +1,37 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: libkscreen -Source: git://anongit.kde.org/libkscreen +Upstream-Name: libkscreen2 +Source: ftp://ftp.kde.org/pub/kde/unstable/plasma/ Files: * -Copyright: 2012-2014, Alejandro Fiestas Olivares - 2012, Daniel Nicoletti - 2012-2014, Daniel Vrátil - 2012-2014, Sebastian Kügler +Copyright: © 2012-2014 Alejandro Fiestas Olivares + © 2012-2013 Daniel Vrátil + © 2012 Daniel Nicoletti + © 2012 Fredrik Höglund + © 2007 Matthias Kretz + © 2008 Helio Chissini de Castro + © 2012-2013 Martin Gräßlin + © 2003 Lubos Lunak License: LGPL-2.1+ - -Files: COPYING - COPYING.LIB - backends/xrandr1.1/wrapper.h - tests/testplugandplay.cpp -Copyright: 1989-1991, Free Software Foundation, Inc - 2012-2013, Martin Gräßlin - 2014, Sebastian Kügler -License: GPL-2+ - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. . - This program is distributed in the hope that it will be useful, + This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. . - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA . - On Debian systems, the complete text of the GNU General Public License - version 2 can be found in "/usr/share/common-licenses/GPL-2". + On Debian systems, the complete text of the GNU Lesser General + Public License version 2 can be found in "/usr/share/common-licenses/LGPL-2.1". Files: backends/xrandr1.1/fixx11h.h -Copyright: 2003, Lubos Lunak -License: Expat +Copyright: 2003 Lubos Lunak +License: MIT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to @@ -54,24 +49,58 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Files: debian/* -Copyright: 2014 Scarlett Clark -License: LGPL-2.1+ +Files: cmake/modules/* +Copyright: 2012 Fredrik Höglund + 2008 Helio Chissini de Castro + 2007 Matthias Kretz +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. -License: LGPL-2.1+ - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. +Files: backends/xrandr1.1/wrapper.h + tests/* + debian/* +Copyright: 2012, 2013 Martin Gräßlin + 2013 by Alejandro Fiestas Olivares + 2014 Scarlett Clark +License: GPL-2.0+ + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. . - This library is distributed in the hope that it will be useful, + This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. . - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + You should have received a copy of the GNU General Public License + along with this program. If not, see . - On Debian systems, the complete text of the GNU Lesser General Public License - version 2.1 can be found in "/usr/share/common-licenses/LGPL-2.1". + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff -Nru libkscreen-5.2.2/debian/libkf5screen-dev.acc.in libkscreen-5.3.0/debian/libkf5screen-dev.acc.in --- libkscreen-5.2.2/debian/libkf5screen-dev.acc.in 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/libkf5screen-dev.acc.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ - - - - - 5.1.1 - - - - /usr/include/KF5/KScreen/ - - - - /usr/lib/@@DEB_HOST_MULTIARCH@@/libKF5Screen.so - - - - -fPIC - - - diff -Nru libkscreen-5.2.2/debian/libkf5screen-dev.install libkscreen-5.3.0/debian/libkf5screen-dev.install --- libkscreen-5.2.2/debian/libkf5screen-dev.install 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/libkf5screen-dev.install 2015-04-23 15:04:34.000000000 +0000 @@ -1,6 +1,5 @@ -usr/include/KF5/KScreen/ -usr/include/KF5/kscreen_version.h -usr/lib/*/cmake/KF5Screen/ -usr/lib/*/libKF5Screen.so -usr/lib/*/pkgconfig/kscreen2.pc +usr/include/* +usr/lib/*/*.so +usr/lib/*/cmake/* +usr/lib/*/pkgconfig/* usr/lib/*/qt5/mkspecs/modules/qt_KScreen.pri diff -Nru libkscreen-5.2.2/debian/libkf5screen6.install libkscreen-5.3.0/debian/libkf5screen6.install --- libkscreen-5.2.2/debian/libkf5screen6.install 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/libkf5screen6.install 2015-04-23 15:04:34.000000000 +0000 @@ -1,4 +1,4 @@ -usr/lib/*/libKF5Screen.so.5.* +usr/lib/*/libKF5Screen.so.5* usr/lib/*/libKF5Screen.so.6 usr/lib/*/libexec/kf5/kscreen_backend_launcher -usr/lib/*/qt5/plugins/kf5/kscreen/ +usr/lib/*/qt5/plugins/ diff -Nru libkscreen-5.2.2/debian/libkf5screen6.symbols libkscreen-5.3.0/debian/libkf5screen6.symbols --- libkscreen-5.2.2/debian/libkf5screen6.symbols 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/libkf5screen6.symbols 2015-04-23 15:04:34.000000000 +0000 @@ -1,4 +1,4 @@ -# SymbolsHelper-Confirmed: 5.1.1 amd64 +# SymbolsHelper-Confirmed: 4:5.2.2+git20150403.0042 amd64 i386 KSC_Fake.so libkf5screen6 #MINVER# qt_plugin_instance@Base 5.1.80 qt_plugin_query_metadata@Base 5.1.80 @@ -141,6 +141,7 @@ _ZN7KScreen6Config11outputAddedERK14QSharedPointerINS_6OutputEE@Base 5.1.1 _ZN7KScreen6Config11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.1.1 _ZN7KScreen6Config11qt_metacastEPKc@Base 5.1.1 + _ZN7KScreen6Config12canBeAppliedERK14QSharedPointerIS0_E6QFlagsINS0_12ValidityFlagEE@Base 4:5.2.1+git20150307.0128+15.04 _ZN7KScreen6Config12canBeAppliedERK14QSharedPointerIS0_E@Base 5.1.1 _ZN7KScreen6Config12removeOutputEi@Base 5.1.1 _ZN7KScreen6Config13outputRemovedEi@Base 5.1.1 @@ -148,12 +149,16 @@ _ZN7KScreen6Config16staticMetaObjectE@Base 5.1.1 _ZN7KScreen6Config20primaryOutputChangedERK14QSharedPointerINS_6OutputEE@Base 5.1.1 _ZN7KScreen6Config5applyERK14QSharedPointerIS0_E@Base 5.1.1 + _ZN7KScreen6Config7Private11qt_metacallEN11QMetaObject4CallEiPPv@Base 4:5.2.2+git20150403.0042 + _ZN7KScreen6Config7Private11qt_metacastEPKc@Base 4:5.2.2+git20150403.0042 + _ZN7KScreen6Config7Private16staticMetaObjectE@Base 4:5.2.2+git20150403.0042 + _ZN7KScreen6Config7PrivateD0Ev@Base 4:5.2.2+git20150403.0042 + _ZN7KScreen6Config7PrivateD1Ev@Base 4:5.2.2+git20150403.0042 + _ZN7KScreen6Config7PrivateD2Ev@Base 4:5.2.2+git20150403.0042 _ZN7KScreen6Config8setValidEb@Base 5.1.1 _ZN7KScreen6Config9addOutputERK14QSharedPointerINS_6OutputEE@Base 5.1.1 _ZN7KScreen6Config9setScreenERK14QSharedPointerINS_6ScreenEE@Base 5.1.1 - _ZN7KScreen6ConfigC1EPNS0_7PrivateE@Base 5.1.1 _ZN7KScreen6ConfigC1Ev@Base 5.1.1 - _ZN7KScreen6ConfigC2EPNS0_7PrivateE@Base 5.1.1 _ZN7KScreen6ConfigC2Ev@Base 5.1.1 _ZN7KScreen6ConfigD0Ev@Base 5.1.1 _ZN7KScreen6ConfigD1Ev@Base 5.1.1 @@ -255,6 +260,7 @@ _ZNK7KScreen6Config5cloneEv@Base 5.1.1 _ZNK7KScreen6Config6outputEi@Base 5.1.1 _ZNK7KScreen6Config6screenEv@Base 5.1.1 + _ZNK7KScreen6Config7Private10metaObjectEv@Base 4:5.2.2+git20150403.0042 _ZNK7KScreen6Config7isValidEv@Base 5.1.1 _ZNK7KScreen6Config7outputsEv@Base 5.1.1 _ZNK7KScreen6Output10metaObjectEv@Base 5.1.1 @@ -296,6 +302,7 @@ _ZTIN7KScreen18SetConfigOperationE@Base 5.1.1 _ZTIN7KScreen4EdidE@Base 5.1.1 _ZTIN7KScreen4ModeE@Base 5.1.1 + _ZTIN7KScreen6Config7PrivateE@Base 4:5.2.2+git20150403.0042 _ZTIN7KScreen6ConfigE@Base 5.1.1 _ZTIN7KScreen6OutputE@Base 5.1.1 _ZTIN7KScreen6ScreenE@Base 5.1.1 @@ -308,6 +315,7 @@ _ZTSN7KScreen18SetConfigOperationE@Base 5.1.1 _ZTSN7KScreen4EdidE@Base 5.1.1 _ZTSN7KScreen4ModeE@Base 5.1.1 + _ZTSN7KScreen6Config7PrivateE@Base 4:5.2.2+git20150403.0042 _ZTSN7KScreen6ConfigE@Base 5.1.1 _ZTSN7KScreen6OutputE@Base 5.1.1 _ZTSN7KScreen6ScreenE@Base 5.1.1 @@ -320,6 +328,7 @@ _ZTVN7KScreen18SetConfigOperationE@Base 5.1.1 _ZTVN7KScreen4EdidE@Base 5.1.1 _ZTVN7KScreen4ModeE@Base 5.1.1 + _ZTVN7KScreen6Config7PrivateE@Base 4:5.2.2+git20150403.0042 _ZTVN7KScreen6ConfigE@Base 5.1.1 _ZTVN7KScreen6OutputE@Base 5.1.1 _ZTVN7KScreen6ScreenE@Base 5.1.1 diff -Nru libkscreen-5.2.2/debian/meta/upstream_scm.json libkscreen-5.3.0/debian/meta/upstream_scm.json --- libkscreen-5.2.2/debian/meta/upstream_scm.json 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/meta/upstream_scm.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -{ - "type" : "git", - "branch" : "frameworks" -} diff -Nru libkscreen-5.2.2/debian/rules libkscreen-5.3.0/debian/rules --- libkscreen-5.2.2/debian/rules 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/rules 2015-04-23 15:04:34.000000000 +0000 @@ -7,4 +7,5 @@ $(overridden_command) --dbg-package=libkscreen-dbg override_dh_auto_test: - -xvfb-run -a dh_auto_test + dh_installwm openbox\ + xvfb-run -a dh_auto_test diff -Nru libkscreen-5.2.2/debian/source/lintian-overrides libkscreen-5.3.0/debian/source/lintian-overrides --- libkscreen-5.2.2/debian/source/lintian-overrides 1970-01-01 00:00:00.000000000 +0000 +++ libkscreen-5.3.0/debian/source/lintian-overrides 2015-04-23 15:04:34.000000000 +0000 @@ -0,0 +1 @@ +libkscreen source: no-human-maintainers diff -Nru libkscreen-5.2.2/debian/tests/acc libkscreen-5.3.0/debian/tests/acc --- libkscreen-5.2.2/debian/tests/acc 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/tests/acc 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -#!/bin/sh - -DEB_HOST_MULTIARCH=$(dpkg-architecture -qDEB_HOST_MULTIARCH) - -for in_file in debian/*.acc.in; do - out_file=${in_file%.in} - sed 's/@@DEB_HOST_MULTIARCH@@/'"${DEB_HOST_MULTIARCH}"'/' \ - "${in_file}" > "${out_file}" -done - -dh_acc diff -Nru libkscreen-5.2.2/debian/tests/control libkscreen-5.3.0/debian/tests/control --- libkscreen-5.2.2/debian/tests/control 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -# Tests: testsuite -# Depends: @, @builddeps@, build-essential -# Restrictions: build-needed - -Tests: acc -Depends: @, dh-acc, exuberant-ctags diff -Nru libkscreen-5.2.2/debian/tests/testsuite libkscreen-5.3.0/debian/tests/testsuite --- libkscreen-5.2.2/debian/tests/testsuite 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/tests/testsuite 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -#!/bin/sh - -dh_auto_test diff -Nru libkscreen-5.2.2/debian/watch libkscreen-5.3.0/debian/watch --- libkscreen-5.2.2/debian/watch 2015-03-25 22:17:37.000000000 +0000 +++ libkscreen-5.3.0/debian/watch 2015-04-23 15:04:34.000000000 +0000 @@ -1,3 +1,4 @@ version=3 -http://download.kde.org/unstable/plasma/([\d.]+)/libkscreen-([\d.]+)\.tar\.xz -http://download.kde.org/stable/plasma/([\d.]+)/libkscreen-([\d.]+)\.tar\.xz +http://download.kde.org/unstable/plasma/([\d\.]+)/libkscreen-(.*)\.tar\.xz + +http://download.kde.org/stable/plasma/([\d\.]+)/libkscreen-(.*)\.tar\.xz diff -Nru libkscreen-5.2.2/interfaces/org.kde.KScreen.FakeBackend.xml libkscreen-5.3.0/interfaces/org.kde.KScreen.FakeBackend.xml --- libkscreen-5.2.2/interfaces/org.kde.KScreen.FakeBackend.xml 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/interfaces/org.kde.KScreen.FakeBackend.xml 2015-04-23 10:04:35.000000000 +0000 @@ -21,5 +21,12 @@ + + + + + + + diff -Nru libkscreen-5.2.2/src/backendlauncher/backendloader.cpp libkscreen-5.3.0/src/backendlauncher/backendloader.cpp --- libkscreen-5.2.2/src/backendlauncher/backendloader.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/src/backendlauncher/backendloader.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -33,11 +33,13 @@ BackendLoader::BackendLoader() : QObject() + , mBackend(0) { } BackendLoader::~BackendLoader() { + delete mBackend; } bool BackendLoader::loadBackend(const QString& backend) @@ -47,7 +49,7 @@ const QStringList paths = QCoreApplication::libraryPaths(); qCDebug(KSCREEN_BACKEND_LAUNCHER) << "Lookup paths: " << paths; Q_FOREACH (const QString &path, paths) { - const QDir dir(path + QDir::separator() + QLatin1String("/kf5/kscreen/"), + const QDir dir(path + QLatin1String("/kf5/kscreen/"), backendFilter, QDir::SortFlags(QDir::QDir::NoSort), QDir::NoDotAndDotDot | QDir::Files); diff -Nru libkscreen-5.2.2/src/backendlauncher/main.cpp libkscreen-5.3.0/src/backendlauncher/main.cpp --- libkscreen-5.2.2/src/backendlauncher/main.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/src/backendlauncher/main.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -28,9 +28,10 @@ int main(int argc, char **argv) { + QGuiApplication::setDesktopSettingsAware(false); QGuiApplication app(argc, argv); - BackendLoader launcher; + BackendLoader *loader = new BackendLoader; QCommandLineOption backendOption(QLatin1String("backend"), QLatin1String("Backend to load. When not specified, BackendLauncher will " @@ -44,9 +45,9 @@ bool success = false; if (parser.isSet(backendOption)) { - success = launcher.loadBackend(parser.value(backendOption)); + success = loader->loadBackend(parser.value(backendOption)); } else { - success = launcher.loadBackend(); + success = loader->loadBackend(); } // We failed to load any backend: abort immediatelly @@ -56,15 +57,15 @@ // Create BackendDBusWrapper that takes implements the DBus interface and translates // DBus calls to backend implementations. It will also take care of terminating this - // launcher when no other KScreen-enabled processes are running - BackendDBusWrapper backendWrapper(launcher.backend()); + // loader when no other KScreen-enabled processes are running + BackendDBusWrapper backendWrapper(loader->backend()); if (!backendWrapper.init()) { // Loading failed, maybe it failed because another process is already running; if so we still want to print the path before we exit // Check if another Backend Launcher with this particular backend is already running - const bool alreadyRunning = launcher.checkIsAlreadyRunning(); + const bool alreadyRunning = loader->checkIsAlreadyRunning(); if (alreadyRunning) { // If it is, let caller now it's DBus service name and terminate - printf("%s", qPrintable(launcher.backend()->serviceName())); + printf("%s", qPrintable(loader->backend()->serviceName())); fflush(stdout); return BackendLoader::BackendAlreadyExists; } @@ -72,9 +73,14 @@ } // Now let caller now what's our DBus service name, so it can connect to us - printf("%s", qPrintable(launcher.backend()->serviceName())); + printf("%s", qPrintable(loader->backend()->serviceName())); fflush(stdout); // And go! - return app.exec(); + const int ret = app.exec(); + + // Make sure the backend is destroyed and unloaded before we return + delete loader; + + return ret; } diff -Nru libkscreen-5.2.2/src/config.cpp libkscreen-5.3.0/src/config.cpp --- libkscreen-5.2.2/src/config.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/src/config.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -28,31 +28,76 @@ using namespace KScreen; -class Config::Private +class Config::Private : public QObject { - public: - Private(): - valid(true) + Q_OBJECT +public: + Private(Config *parent) + : QObject(parent) + , valid(true) + , q(parent) { } - Private(const Private &other): - valid(other.valid), - primaryOutput(other.primaryOutput) + KScreen::OutputPtr findPrimaryOutput() const { - screen = other.screen->clone(); - Q_FOREACH (const OutputPtr &otherOutput, other.outputs) { - outputs.insert(otherOutput->id(), otherOutput->clone()); - } + auto iter = std::find_if(outputs.constBegin(), outputs.constEnd(), + [](const KScreen::OutputPtr &output) -> bool { + return output->isPrimary(); + }); + return iter == outputs.constEnd() ? KScreen::OutputPtr() : iter.value(); + } + + void onPrimaryOutputChanged() + { + const KScreen::OutputPtr output(qobject_cast(sender()), [](void *) {}); + Q_ASSERT(output); + if (output->isPrimary()) { + q->setPrimaryOutput(output); + } else { + q->setPrimaryOutput(findPrimaryOutput()); + } + } + + OutputList::Iterator removeOutput(OutputList::Iterator iter) + { + if (iter == outputs.end()) { + return iter; + } + + OutputPtr output = iter.value(); + if (!output) { + return outputs.erase(iter); + } + + const int outputId = iter.key(); + iter = outputs.erase(iter); + + if (primaryOutput == output) { + q->setPrimaryOutput(OutputPtr()); + } + output->disconnect(q); + + Q_EMIT q->outputRemoved(outputId); + + return iter; } bool valid; ScreenPtr screen; OutputPtr primaryOutput; OutputList outputs; + +private: + Config *q; }; bool Config::canBeApplied(const ConfigPtr &config) { + return canBeApplied(config, ValidityFlag::None); +} + +bool Config::canBeApplied(const ConfigPtr &config, ValidityFlags flags) +{ ConfigPtr currentConfig = BackendManager::instance()->config(); if (!currentConfig) { qCDebug(KSCREEN) << "canBeApplied: Current config not available, returning false"; @@ -93,7 +138,6 @@ return false; } - const ModePtr currentMode = output->currentMode(); const QSize outputSize = currentMode->size(); @@ -124,6 +168,11 @@ } } + if (flags & ValidityFlag::RequireAtLeastOneEnabledScreen && enabledOutputsCount == 0) { + qCDebug(KSCREEN) << "canBeAppled: There are no enabled screens, at least one required"; + return false; + } + const int maxEnabledOutputsCount = config->screen()->maxActiveOutputsCount(); if (enabledOutputsCount > maxEnabledOutputsCount) { qCDebug(KSCREEN) << "canBeApplied: Too many active screens. Requested: " << enabledOutputsCount << ", Max: " << maxEnabledOutputsCount; @@ -144,13 +193,7 @@ Config::Config() : QObject(0) - , d(new Private()) -{ -} - -Config::Config(Config::Private *dd) - : QObject() - , d(dd) + , d(new Private(this)) { } @@ -162,7 +205,14 @@ ConfigPtr Config::clone() const { - return ConfigPtr(new Config(new Private(*d))); + ConfigPtr newConfig(new Config()); + newConfig->d->screen = d->screen->clone(); + for (const OutputPtr &ourOutput : d->outputs) { + newConfig->addOutput(ourOutput->clone()); + } + newConfig->d->primaryOutput = newConfig->d->findPrimaryOutput(); + + return newConfig; } @@ -178,11 +228,7 @@ OutputPtr Config::output(int outputId) const { - if (!d->outputs.contains(outputId)) { - return OutputPtr(); - } - - return d->outputs[outputId]; + return d->outputs.value(outputId); } OutputList Config::outputs() const @@ -209,52 +255,62 @@ return d->primaryOutput; } - Q_FOREACH(const OutputPtr &output, d->outputs) { - if (output->isPrimary()) { - d->primaryOutput = output; - return d->primaryOutput; - } - } - - return OutputPtr(); + d->primaryOutput = d->findPrimaryOutput(); + return d->primaryOutput; } -void Config::setPrimaryOutput(const OutputPtr &output) +void Config::setPrimaryOutput(const OutputPtr &newPrimary) { - if (primaryOutput() == output) { + // Don't call primaryOutput(): at this point d->primaryOutput is either + // initialized, or we need to look for the primary anyway + if (d->primaryOutput == newPrimary) { return; } - qDebug(KSCREEN) << "Primary output changed from" << d->primaryOutput - << "(" << (d->primaryOutput.isNull() ? "none" : d->primaryOutput->name()) << ") to" - << output << "(" << (output.isNull() ? "none" : output->name()) << ")"; - d->primaryOutput = output; + qDebug(KSCREEN) << "Primary output changed from" << primaryOutput() + << "(" << (primaryOutput().isNull() ? "none" : primaryOutput()->name()) << ") to" + << newPrimary << "(" << (newPrimary.isNull() ? "none" : newPrimary->name()) << ")"; + + for (OutputPtr &output : d->outputs) { + disconnect(output.data(), &KScreen::Output::isPrimaryChanged, + d, &KScreen::Config::Private::onPrimaryOutputChanged); + output->setPrimary(output == newPrimary); + connect(output.data(), &KScreen::Output::isPrimaryChanged, + d, &KScreen::Config::Private::onPrimaryOutputChanged); + } - Q_EMIT primaryOutputChanged(output); + d->primaryOutput = newPrimary; + Q_EMIT primaryOutputChanged(newPrimary); } void Config::addOutput(const OutputPtr &output) { d->outputs.insert(output->id(), output); + connect(output.data(), &KScreen::Output::isPrimaryChanged, + d, &KScreen::Config::Private::onPrimaryOutputChanged); Q_EMIT outputAdded(output); + + if (output->isPrimary()) { + setPrimaryOutput(output); + } } void Config::removeOutput(int outputId) { - OutputPtr output = d->outputs.take(outputId); - if (output) { - if (d->primaryOutput == output) { - setPrimaryOutput(OutputPtr()); - } - } - - Q_EMIT outputRemoved(outputId); + d->removeOutput(d->outputs.find(outputId)); } void Config::setOutputs(OutputList outputs) { - d->outputs = outputs; + for (auto iter = d->outputs.begin(), end = d->outputs.end(); iter != end; ) { + iter = d->removeOutput(iter); + end = d->outputs.end(); + } + + for (const OutputPtr &output : outputs) { + addOutput(output); + } } bool Config::isValid() const @@ -288,19 +344,8 @@ } } - // Update primary output - bool matched = false; - Q_FOREACH (const OutputPtr &output, d->outputs) { - if (output->isPrimary()) { - setPrimaryOutput(output); - matched = true; - break; - } - } - if (!matched) { - setPrimaryOutput(OutputPtr()); - } - // Update validity setValid(other->isValid()); } + +#include "config.moc" \ No newline at end of file diff -Nru libkscreen-5.2.2/src/config.h libkscreen-5.3.0/src/config.h --- libkscreen-5.2.2/src/config.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/src/config.h 2015-04-23 10:04:35.000000000 +0000 @@ -50,6 +50,26 @@ Q_PROPERTY(OutputList outputs READ outputs) public: + enum class ValidityFlag { + None = 0x0, + RequireAtLeastOneEnabledScreen = 0x1 + }; + Q_DECLARE_FLAGS(ValidityFlags, ValidityFlag) + + /** + * Validates that a config can be applied in the current system + * + * Each system has different constrains, this method will test + * the given config with those constrains to see if it + * can be applied. + * + * @arg config to be checked + * @flags enable additional optional checks + * @return true if the configuration can be applied, false if not. + * @since 5.3.0 + */ + static bool canBeApplied(const ConfigPtr &config, ValidityFlags flags); + /** * Validates that a config can be applied in the current system * @@ -109,8 +129,6 @@ class Private; Private * const d; - - Config(Private *dd); }; } //KScreen namespace diff -Nru libkscreen-5.2.2/src/configoperation.cpp libkscreen-5.3.0/src/configoperation.cpp --- libkscreen-5.2.2/src/configoperation.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/src/configoperation.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -104,7 +104,7 @@ Q_UNUSED(op); loop.quit(); }); - loop.exec(); + loop.exec(QEventLoop::ExcludeUserInputEvents); return !hasError(); } diff -Nru libkscreen-5.2.2/src/getconfigoperation.cpp libkscreen-5.3.0/src/getconfigoperation.cpp --- libkscreen-5.2.2/src/getconfigoperation.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/src/getconfigoperation.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -103,6 +103,10 @@ pendingEDIDs = 0; org::kde::kscreen::Backend *backend = watcher->property("backend").value(); Q_FOREACH (const OutputPtr &output, config->outputs()) { + if (!output->isConnected()) { + continue; + } + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(backend->getEdid(output->id()), this); watcher->setProperty("outputId", output->id()); connect(watcher, &QDBusPendingCallWatcher::finished, @@ -126,10 +130,7 @@ const QByteArray edidData = reply.value(); const int outputId = watcher->property("outputId").toInt(); - OutputList outputs = config->outputs(); - outputs[outputId]->setEdid(edidData); - config->setOutputs(outputs); - + config->output(outputId)->setEdid(edidData); if (--pendingEDIDs == 0) { q->emitResult(); } diff -Nru libkscreen-5.2.2/src/output.cpp libkscreen-5.3.0/src/output.cpp --- libkscreen-5.2.2/src/output.cpp 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/src/output.cpp 2015-04-23 10:04:35.000000000 +0000 @@ -421,7 +421,11 @@ return QRect(); } - return QRect(pos(), currentMode()->size()); + if (isHorizontal()) { + return QRect(pos(), currentMode()->size()); + } else { + return QRect(pos(), QSize(currentMode()->size().height(), currentMode()->size().width())); + } } void Output::apply(const OutputPtr& other) diff -Nru libkscreen-5.2.2/src/output.h libkscreen-5.3.0/src/output.h --- libkscreen-5.2.2/src/output.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/src/output.h 2015-04-23 10:04:35.000000000 +0000 @@ -151,7 +151,10 @@ void setSizeMm(const QSize &size); /** - * @returns a rectangle containing the current output position and size. + * Returns a rectangle containing the current output position and size. + * + * The geometry takes rotation into account, so if an 1920x1200 output + * is rotated by 90 deg, the geometry will be (0, 0, 1200, 1920)! */ QRect geometry() const; @@ -173,7 +176,6 @@ Private * const d; Output(Private *dd); - }; } //KScreen namespace diff -Nru libkscreen-5.2.2/src/types.h libkscreen-5.3.0/src/types.h --- libkscreen-5.2.2/src/types.h 2015-03-19 11:47:04.000000000 +0000 +++ libkscreen-5.3.0/src/types.h 2015-04-23 10:04:35.000000000 +0000 @@ -26,16 +26,16 @@ { class Config; -typedef QSharedPointer ConfigPtr; +typedef QSharedPointer ConfigPtr; class Screen; -typedef QSharedPointer ScreenPtr; +typedef QSharedPointer ScreenPtr; class Output; -typedef QSharedPointer OutputPtr; -typedef QMap OutputList; +typedef QSharedPointer OutputPtr; +typedef QMap OutputList; class Mode; -typedef QSharedPointer ModePtr; -typedef QMap ModeList; +typedef QSharedPointer ModePtr; +typedef QMap ModeList; }