Implement the orientationChanged signal.
[qt:qtsystems-staging.git] / src / systeminfo / qdisplayinfo_linux.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtSystems module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qdisplayinfo_linux_p.h"
43
44 #include <QtCore/qdir.h>
45 #include <QtGui/qapplication.h>
46 #include <QtGui/qdesktopwidget.h>
47 #include <QtGui/qpixmap.h>
48
49 #if defined(Q_WS_X11)
50 #include <QtGui/qx11info_x11.h>
51 #include <X11/extensions/Xrandr.h>
52 #endif // Q_WS_X11
53
54 QT_BEGIN_NAMESPACE
55
56 QDisplayInfoPrivate::QDisplayInfoPrivate(QDisplayInfo *parent)
57     : QObject(parent)
58     , q_ptr(parent)
59     , watchOrientation(false)
60 {
61 }
62
63 int QDisplayInfoPrivate::brightness(int screen)
64 {
65     QString sysfsPath(QString::fromAscii("/sys/class/backlight/"));
66     const QStringList dirs = QDir(sysfsPath).entryList(QDir::Dirs | QDir::NoDotAndDotDot);
67     if (dirs.size() < screen + 1)
68         return -1;
69
70     bool ok = false;
71     int max = 0;
72     int actual = 0;
73     sysfsPath += dirs.at(screen);
74     QFile brightness(sysfsPath + QString::fromAscii("/max_brightness"));
75     if (brightness.open(QIODevice::ReadOnly)) {
76         max = brightness.readAll().simplified().toInt(&ok);
77         if (!ok || max == 0)
78             return -1;
79         brightness.close();
80
81         brightness.setFileName(sysfsPath + QString::fromAscii("/actual_brightness"));
82         if (brightness.open(QIODevice::ReadOnly)) {
83             actual = brightness.readAll().simplified().toInt(&ok);
84             if (!ok)
85                 return -1;
86
87             return actual * 100 / max;
88         }
89     }
90
91     return -1;
92 }
93
94 int QDisplayInfoPrivate::colorDepth(int screen)
95 {
96 #if defined(Q_WS_X11)
97     return QX11Info::appDepth(screen);
98 #else
99     Q_UNUSED(screen)
100 #endif // Q_WS_X11
101
102     return QPixmap::defaultDepth();
103 }
104
105 int QDisplayInfoPrivate::contrast(int screen)
106 {
107     Q_UNUSED(screen)
108     return -1;
109 }
110
111 int QDisplayInfoPrivate::dpiX(int screen)
112 {
113 #if defined(Q_WS_X11)
114     return QX11Info::appDpiX(screen);
115 #else
116     Q_UNUSED(screen)
117     return -1;
118 #endif
119 }
120
121 int QDisplayInfoPrivate::dpiY(int screen)
122 {
123 #if defined(Q_WS_X11)
124     return QX11Info::appDpiY(screen);
125 #else
126     Q_UNUSED(screen)
127     return -1;
128 #endif
129 }
130
131 int QDisplayInfoPrivate::physicalHeight(int screen)
132 {
133 #if defined(Q_WS_X11)
134     int height = -1;
135     XRRScreenResources *sr = XRRGetScreenResources(QX11Info::display(), RootWindow(QX11Info::display(), screen));
136     for (int i = 0; i < sr->noutput; ++i) {
137         XRROutputInfo *output = XRRGetOutputInfo(QX11Info::display(), sr, sr->outputs[i]);
138         if (output->crtc) {
139            height = output->mm_height;
140            XRRFreeOutputInfo(output);
141            break;
142         }
143         XRRFreeOutputInfo(output);
144     }
145     XRRFreeScreenResources(sr);
146     return height;
147 #else
148     Q_UNUSED(screen)
149     return -1;
150 #endif
151 }
152
153 int QDisplayInfoPrivate::physicalWidth(int screen)
154 {
155 #if defined(Q_WS_X11)
156     int width = -1;
157     XRRScreenResources *sr = XRRGetScreenResources(QX11Info::display(), RootWindow(QX11Info::display(), screen));
158     for (int i = 0; i < sr->noutput; ++i) {
159         XRROutputInfo *output = XRRGetOutputInfo(QX11Info::display(), sr, sr->outputs[i]);
160         if (output->crtc) {
161            width = output->mm_width;
162            XRRFreeOutputInfo(output);
163            break;
164         }
165         XRRFreeOutputInfo(output);
166     }
167     XRRFreeScreenResources(sr);
168     return width;
169 #else
170     Q_UNUSED(screen)
171     return -1;
172 #endif
173 }
174
175 QDisplayInfo::BacklightState QDisplayInfoPrivate::backlightState(int screen)
176 {
177     Q_UNUSED(screen);
178     return QDisplayInfo::BacklightUnknown;
179 }
180
181 QDisplayInfo::Orientation QDisplayInfoPrivate::orientation(int screen)
182 {
183     if (watchOrientation)
184         return currentOrientation[screen];
185     return getOrientation(screen);
186 }
187
188 void QDisplayInfoPrivate::connectNotify(const char *signal)
189 {
190     if (strcmp(signal, SIGNAL(thermalStateChanged(QDeviceInfo::ThermalState))) == 0) {
191         watchOrientation = true;
192         int count = qApp->desktop()->screenCount();
193         for (int i = 0; i < count; ++i)
194             currentOrientation[i] = getOrientation(i);
195         connect(qApp->desktop(), SIGNAL(resized(int)), this, SLOT(onDesktopWidgetResized(int)));
196     }
197 }
198
199 void QDisplayInfoPrivate::disconnectNotify(const char *signal)
200 {
201     if (strcmp(signal, SIGNAL(thermalStateChanged(QDeviceInfo::ThermalState))) == 0) {
202         watchOrientation = false;
203         currentOrientation.clear();
204         disconnect(qApp->desktop(), SIGNAL(resized(int)), this, SLOT(onDesktopWidgetResized(int)));
205     }
206 }
207
208 void QDisplayInfoPrivate::onDesktopWidgetResized(int screen)
209 {
210     QDisplayInfo::Orientation current = getOrientation(screen);
211     if (currentOrientation[screen] != current) {
212         currentOrientation[screen] = current;
213         Q_EMIT orientationChanged(screen, current);
214     }
215 }
216
217 QDisplayInfo::Orientation QDisplayInfoPrivate::getOrientation(int screen)
218 {
219 #if defined(Q_WS_X11)
220     Rotation rotation;
221     XRRRotations(QX11Info::display(), screen, &rotation);
222     switch (rotation) {
223     case RR_Rotate_0:
224         return QDisplayInfo::Landscape;
225     case RR_Rotate_90:
226         return QDisplayInfo::Portrait;
227     case RR_Rotate_180:
228         return QDisplayInfo::InvertedLandscape;
229     case RR_Rotate_270:
230         return QDisplayInfo::InvertedPortrait;
231     default:
232         return QDisplayInfo::OrientationUnknown;
233     }
234 #else
235     Q_UNUSED(screen)
236     return QDisplayInfo::OrientationUnknown;
237 #endif
238 }
239
240 QT_END_NAMESPACE