12#include <QtCore/QThread>
13#include <QtCore/QDebug>
14#include <qpa/qwindowsysteminterface.h>
18#if defined(QQNX_PHYSICAL_SCREEN_WIDTH) && QQNX_PHYSICAL_SCREEN_WIDTH > 0
19 && defined(QQNX_PHYSICAL_SCREEN_HEIGHT) && QQNX_PHYSICAL_SCREEN_HEIGHT > 0
20#define QQNX_PHYSICAL_SCREEN_SIZE_DEFINED
21#elif defined(QQNX_PHYSICAL_SCREEN_WIDTH) || defined(QQNX_PHYSICAL_SCREEN_HEIGHT)
22#error Please define QQNX_PHYSICAL_SCREEN_WIDTH and QQNX_PHYSICAL_SCREEN_HEIGHT to values greater than zero
36 const int result = screen_get_display_property_iv(display, SCREEN_PROPERTY_PHYSICAL_SIZE, val);
39 return QSize(150, 90);
42 if (val[0] > 0 && val[1] > 0)
43 return QSize(val[0], val[1]);
45 qCDebug(lcQpaScreen,
"QQnxScreen: screen_get_display_property_iv() reported an invalid "
46 "physical screen size (%dx%d). Falling back to QQNX_PHYSICAL_SCREEN_SIZE "
47 "environment variable.", val[0], val[1]);
49 const QString envPhySizeStr = qgetenv(
"QQNX_PHYSICAL_SCREEN_SIZE");
50 if (!envPhySizeStr.isEmpty()) {
51 const auto envPhySizeStrList = QStringView{envPhySizeStr}.split(u',');
52 const int envWidth = envPhySizeStrList.size() == 2 ? envPhySizeStrList[0].toInt() : -1;
53 const int envHeight = envPhySizeStrList.size() == 2 ? envPhySizeStrList[1].toInt() : -1;
55 if (envWidth <= 0 || envHeight <= 0) {
56 qWarning(
"QQnxScreen: The value of QQNX_PHYSICAL_SCREEN_SIZE must be in the format "
57 "\"width,height\" in mm, with width, height > 0. Defaulting to 150x90. "
58 "Example: QQNX_PHYSICAL_SCREEN_SIZE=150,90");
59 return QSize(150, 90);
62 return QSize(envWidth, envHeight);
65#if defined(QQNX_PHYSICAL_SCREEN_SIZE_DEFINED)
66 const QSize defSize(QQNX_PHYSICAL_SCREEN_WIDTH, QQNX_PHYSICAL_SCREEN_HEIGHT);
67 qWarning(
"QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. Falling back to defines "
68 "QQNX_PHYSICAL_SCREEN_WIDTH/QQNX_PHYSICAL_SCREEN_HEIGHT (%dx%d)",
69 defSize.width(), defSize.height());
73 qWarning(
"QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. "
74 "Could not determine physical screen size. Defaulting to 150x90.");
75 return QSize(150, 90);
79QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display,
bool primaryScreen)
80 : m_screenContext(screenContext),
83 m_primaryScreen(primaryScreen),
85 m_nativeOrientation(Qt::PrimaryOrientation),
87 m_cursor(
new QQnxCursor())
89 qCDebug(lcQpaScreen) << Q_FUNC_INFO;
91 int result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_ROTATION,
95 m_currentRotation = m_initialRotation;
100 "Failed to query display size");
102 m_currentGeometry = m_initialGeometry = QRect(0, 0, val[0], val[1]);
105 Q_SCREEN_CHECKERROR(screen_get_display_property_cv(m_display, SCREEN_PROPERTY_ID_STRING, 100,
106 name),
"Failed to query display name");
107 m_name = QString::fromUtf8(name);
113 const QSize screenSize = determineScreenSize(m_display, primaryScreen);
115 m_nativeOrientation = screenSize.width() >= screenSize.height() ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
117 const int angle = screen()->angleBetween(m_nativeOrientation, orientation());
118 if (angle == 0 || angle == 180)
119 m_currentPhysicalSize = m_initialPhysicalSize = screenSize;
121 m_currentPhysicalSize = m_initialPhysicalSize = screenSize.transposed();
126 qCDebug(lcQpaScreen) << Q_FUNC_INFO;
127 Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
128 childWindow->setScreen(0);
138 QQnxWindow *qnxWin = findWindow(
reinterpret_cast<screen_window_t>(window));
140 qWarning(
"grabWindow: unknown window");
144 QRect bound = qnxWin->geometry();
147 width = bound.width();
149 height = bound.height();
151 bound &= QRect(x + bound.x(), y + bound.y(), width, height);
153 if (bound.width() <= 0 || bound.height() <= 0) {
154 qWarning(
"grabWindow: size is null");
159 screen_context_t context;
160 if (screen_create_context(&context, SCREEN_DISPLAY_MANAGER_CONTEXT)) {
162 qWarning(
"grabWindow: root privileges required");
164 qWarning(
"grabWindow: cannot create context");
170 screen_display_t display = 0;
171 screen_get_context_property_iv(context, SCREEN_PROPERTY_DISPLAY_COUNT, &count);
173 const size_t idLen = 30;
178 screen_display_t *displays =
static_cast<screen_display_t*>
179 (calloc(count,
sizeof(screen_display_t)));
180 screen_get_context_property_pv(context, SCREEN_PROPERTY_DISPLAYS, (
void **)displays);
181 screen_get_display_property_cv(m_display, SCREEN_PROPERTY_ID_STRING, idLen, matchId);
183 while (count && !found) {
185 screen_get_display_property_cv(displays[count], SCREEN_PROPERTY_ID_STRING, idLen, id);
186 found = !strncmp(id, matchId, idLen);
190 display = displays[count];
196 screen_pixmap_t pixmap;
198 if (display && !screen_create_pixmap(&pixmap, context)) {
199 screen_buffer_t buffer;
202 const int rect[4] = { bound.x(), bound.y(), bound.width(), bound.height() };
204 int val = SCREEN_USAGE_READ | SCREEN_USAGE_NATIVE;
205 screen_set_pixmap_property_iv(pixmap, SCREEN_PROPERTY_USAGE, &val);
206 val = SCREEN_FORMAT_RGBA8888;
207 screen_set_pixmap_property_iv(pixmap, SCREEN_PROPERTY_FORMAT, &val);
209 int err = screen_set_pixmap_property_iv(pixmap, SCREEN_PROPERTY_BUFFER_SIZE, rect+2);
210 err = err || screen_create_pixmap_buffer(pixmap);
211 err = err || screen_get_pixmap_property_pv(pixmap, SCREEN_PROPERTY_RENDER_BUFFERS,
212 reinterpret_cast<
void**>(&buffer));
213 err = err || screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, &pointer);
214 err = err || screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE, &stride);
215 err = err || screen_read_display(display, buffer, 1, rect, 0);
218 const QImage img(
static_cast<
unsigned char*>(pointer),
219 bound.width(), bound.height(), stride, QImage::Format_ARGB32);
220 result = QPixmap::fromImage(img);
222 qWarning(
"grabWindow: capture error");
224 screen_destroy_pixmap(pixmap);
226 qWarning(
"grabWindow: display/pixmap error ");
228 screen_destroy_context(context);
235 qCDebug(lcQpaScreen) << Q_FUNC_INFO;
236 static int defaultDepth = 0;
237 if (defaultDepth == 0) {
240 defaultDepth = qEnvironmentVariableIntValue(
"QQNX_DISPLAY_DEPTH");
241 if (defaultDepth != 16 && defaultDepth != 32)
249 qCDebug(lcQpaScreen) << Q_FUNC_INFO;
251 return QRect(m_currentGeometry.x(), m_currentGeometry.y(),
252 m_currentGeometry.width(), m_currentGeometry.height() - m_keyboardHeight);
262 screen_display_mode_t displayMode;
263 int result = screen_get_display_property_pv(m_display, SCREEN_PROPERTY_MODE,
reinterpret_cast<
void **>(&displayMode));
265 if (result != 0 || displayMode.refresh == 0) {
266 qWarning(
"QQnxScreen: Failed to query screen mode. Using default value of 60Hz");
269 qCDebug(lcQpaScreen,
"screen mode:\n"
274 uint(displayMode.width), uint(displayMode.height), uint(displayMode.refresh), uint(displayMode.interlaced));
275 return static_cast<qreal>(displayMode.refresh);
280 return m_nativeOrientation;
285 Qt::ScreenOrientation orient;
286 if (m_nativeOrientation == Qt::LandscapeOrientation) {
288 if (m_currentRotation == 0)
289 orient = Qt::LandscapeOrientation;
290 else if (m_currentRotation == 90)
291 orient = Qt::PortraitOrientation;
292 else if (m_currentRotation == 180)
293 orient = Qt::InvertedLandscapeOrientation;
295 orient = Qt::InvertedPortraitOrientation;
299 if (m_currentRotation == 0)
300 orient = Qt::PortraitOrientation;
301 else if (m_currentRotation == 90)
302 orient = Qt::LandscapeOrientation;
303 else if (m_currentRotation == 180)
304 orient = Qt::InvertedPortraitOrientation;
306 orient = Qt::InvertedLandscapeOrientation;
308 qCDebug(lcQpaScreen) << Q_FUNC_INFO <<
"Orientation =" << orient;
314 for (
auto it = m_childWindows.rbegin(), end = m_childWindows.rend(); it != end; ++it) {
315 QWindow *win = (*it)->window();
316 if (win->geometry().contains(point))
323
324
327 return ((angle1 - angle2) % 180) != 0;
332 qCDebug(lcQpaScreen) << Q_FUNC_INFO <<
"orientation =" << rotation;
340 const QRect previousScreenGeometry = geometry();
344 m_currentGeometry = QRect(0, 0, m_initialGeometry.height(), m_initialGeometry.width());
345 m_currentPhysicalSize = QSize(m_initialPhysicalSize.height(), m_initialPhysicalSize.width());
347 m_currentGeometry = QRect(0, 0, m_initialGeometry.width(), m_initialGeometry.height());
348 m_currentPhysicalSize = m_initialPhysicalSize;
353 qCDebug(lcQpaScreen) << Q_FUNC_INFO <<
"resize, size =" << m_currentGeometry.size();
355 rootWindow()->setGeometry(QRect(QPoint(0,0), m_currentGeometry.size()));
357 resizeWindows(previousScreenGeometry);
361 screen_flush_context(nativeContext(), 0);
365 m_currentRotation = rotation;
370 if (m_primaryScreen) {
371 QWindowSystemInterface::handleScreenOrientationChange(screen(), orientation());
372 QWindowSystemInterface::handleScreenGeometryChange(screen(), m_currentGeometry, availableGeometry());
377 screen_flush_context( m_screenContext, 0 );
382
383
384void QQnxScreen::resizeNativeWidgetWindow(
QQnxWindow *w,
const QRect &previousScreenGeometry)
const
386 const qreal relativeX =
static_cast<qreal>(w->geometry().topLeft().x()) / previousScreenGeometry.width();
387 const qreal relativeY =
static_cast<qreal>(w->geometry().topLeft().y()) / previousScreenGeometry.height();
388 const qreal relativeWidth =
static_cast<qreal>(w->geometry().width()) / previousScreenGeometry.width();
389 const qreal relativeHeight =
static_cast<qreal>(w->geometry().height()) / previousScreenGeometry.height();
391 const QRect windowGeometry(relativeX * geometry().width(), relativeY * geometry().height(),
392 relativeWidth * geometry().width(), relativeHeight * geometry().height());
394 w->setGeometry(windowGeometry);
398
399
402 QRect windowGeometry = w->geometry();
404 const qreal relativeCenterX =
static_cast<qreal>(w->geometry().center().x()) / previousScreenGeometry.width();
405 const qreal relativeCenterY =
static_cast<qreal>(w->geometry().center().y()) / previousScreenGeometry.height();
406 const QPoint newCenter(relativeCenterX * geometry().width(), relativeCenterY * geometry().height());
408 windowGeometry.moveCenter(newCenter);
412 if (!geometry().contains(windowGeometry)) {
413 const int x1 = windowGeometry.x();
414 const int y1 = windowGeometry.y();
415 const int x2 = x1 + windowGeometry.width();
416 const int y2 = y1 + windowGeometry.height();
419 const int centerX = qMin(qAbs(x1) + windowGeometry.center().x(),
420 geometry().center().x());
422 windowGeometry.moveCenter(QPoint(centerX, windowGeometry.center().y()));
426 const int centerY = qMin(qAbs(y1) + windowGeometry.center().y(),
427 geometry().center().y());
429 windowGeometry.moveCenter(QPoint(windowGeometry.center().x(), centerY));
432 if (x2 > geometry().width()) {
433 const int centerX = qMax(windowGeometry.center().x() - (x2 - geometry().width()),
434 geometry().center().x());
436 windowGeometry.moveCenter(QPoint(centerX, windowGeometry.center().y()));
439 if (y2 > geometry().height()) {
440 const int centerY = qMax(windowGeometry.center().y() - (y2 - geometry().height()),
441 geometry().center().y());
443 windowGeometry.moveCenter(QPoint(windowGeometry.center().x(), centerY));
450 if (!geometry().contains(windowGeometry)) {
451 QSize newSize = windowGeometry.size();
452 newSize.scale(geometry().size(), Qt::KeepAspectRatio);
453 windowGeometry.setSize(newSize);
455 if (windowGeometry.x() < 0)
456 windowGeometry.moveCenter(QPoint(geometry().center().x(), windowGeometry.center().y()));
458 if (windowGeometry.y() < 0)
459 windowGeometry.moveCenter(QPoint(windowGeometry.center().x(), geometry().center().y()));
462 w->setGeometry(windowGeometry);
466
467
468void QQnxScreen::resizeWindows(
const QRect &previousScreenGeometry)
470 resizeMaximizedWindows();
472 Q_FOREACH (QQnxWindow *w, m_childWindows) {
474 if (w->window()->windowState() & Qt::WindowFullScreen || w->window()->windowState() & Qt::WindowMaximized)
479 resizeNativeWidgetWindow(w, previousScreenGeometry);
482 resizeTopLevelWindow(w, previousScreenGeometry);
489 Q_FOREACH (QQnxWindow *window, m_childWindows) {
490 QQnxWindow *
const result = window->findWindow(windowHandle);
500 qCDebug(lcQpaScreen) << Q_FUNC_INFO <<
"Window =" << window;
502 if (m_childWindows.contains(window))
505 if (window->window()->type() != Qt::CoverWindow) {
506 m_childWindows.push_back(window);
513 qCDebug(lcQpaScreen) << Q_FUNC_INFO <<
"Window =" << window;
515 if (window != m_coverWindow) {
516 const int numWindowsRemoved = m_childWindows.removeAll(window);
517 if (window == m_rootWindow)
519 if (numWindowsRemoved > 0)
528 qCDebug(lcQpaScreen) << Q_FUNC_INFO <<
"Window =" << window;
530 if (window != m_coverWindow) {
532 m_childWindows.push_back(window);
538 qCDebug(lcQpaScreen) << Q_FUNC_INFO <<
"Window =" << window;
540 if (window != m_coverWindow) {
542 m_childWindows.push_front(window);
548 qCDebug(lcQpaScreen) << Q_FUNC_INFO;
550 QList<QQnxWindow*>::const_iterator it;
556 result = screen_get_window_property_iv(rootWindow()->nativeHandle(), SCREEN_PROPERTY_ZORDER, &topZorder);
559 qWarning(
"QQnxScreen: failed to query root window z-order, errno=%d", errno);
568 int underlayZorder = -1;
570 Q_FOREACH (screen_window_t underlay, m_underlays) {
574 screen_set_window_property_iv(underlay, SCREEN_PROPERTY_ZORDER, &underlayZorder);
579 for (it = m_childWindows.constBegin(); it != m_childWindows.constEnd(); ++it)
580 (*it)->updateZorder(topZorder);
583 Q_FOREACH (screen_window_t overlay, m_overlays) {
585 screen_set_window_property_iv(overlay, SCREEN_PROPERTY_ZORDER, &topZorder);
591 screen_flush_context(m_screenContext, 0);
596 if (!m_primaryScreen)
600 const int rotation = qEnvironmentVariableIntValue(
"ORIENTATION", &ok);
603 setRotation(rotation);
611void QQnxScreen::keyboardHeightChanged(
int height)
613 if (height == m_keyboardHeight)
616 m_keyboardHeight = height;
618 QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
621void QQnxScreen::addOverlayWindow(screen_window_t window)
623 m_overlays.append(window);
627void QQnxScreen::addUnderlayWindow(screen_window_t window)
629 m_underlays.append(window);
633void QQnxScreen::removeOverlayOrUnderlayWindow(screen_window_t window)
635 const int numRemoved = m_overlays.removeAll(window) + m_underlays.removeAll(window);
636 if (numRemoved > 0) {
638 Q_EMIT foreignWindowClosed(window);
644 Q_ASSERT(thread() == QThread::currentThread());
645 const screen_window_t windowHandle =
reinterpret_cast<screen_window_t>(window);
646 screen_display_t display = 0;
647 if (screen_get_window_property_pv(windowHandle, SCREEN_PROPERTY_DISPLAY, (
void**)&display) != 0) {
648 qWarning(
"QQnx: Failed to get screen for window, errno=%d", errno);
653 if (screen_get_window_property_iv(windowHandle, SCREEN_PROPERTY_ZORDER, &zorder) != 0) {
654 qWarning(
"QQnx: Failed to get z-order for window, errno=%d", errno);
658 char windowNameBuffer[256] = { 0 };
659 QByteArray windowName;
661 if (screen_get_window_property_cv(windowHandle, SCREEN_PROPERTY_ID_STRING,
662 sizeof(windowNameBuffer) - 1, windowNameBuffer) != 0) {
663 qWarning(
"QQnx: Failed to get id for window, errno=%d", errno);
666 windowName = QByteArray(windowNameBuffer);
668 if (display != nativeDisplay())
677 if (findWindow(windowHandle))
680 if (zorder <= MAX_UNDERLAY_ZORDER)
681 addUnderlayWindow(windowHandle);
683 addOverlayWindow(windowHandle);
685 Q_EMIT foreignWindowCreated(windowHandle);
690 Q_ASSERT(thread() == QThread::currentThread());
691 const screen_window_t windowHandle =
reinterpret_cast<screen_window_t>(window);
693 removeOverlayOrUnderlayWindow(windowHandle);
698 qCDebug(lcQpaScreen) << Q_FUNC_INFO;
708 QWindowSystemInterface::handleWindowStateChanged(window, state);
713 qCDebug(lcQpaScreen) << Q_FUNC_INFO;
723 Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
724 childWindow->setExposed(
true);
732 qCDebug(lcQpaScreen) << Q_FUNC_INFO;
740 Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
741 childWindow->setExposed(
false);
753 const int disablePowerSave = qEnvironmentVariableIntValue(
"QQNX_DISABLE_POWER_SAVE", &ok);
754 if (ok && disablePowerSave) {
755 const int mode = SCREEN_IDLE_MODE_KEEP_AWAKE;
756 int result = screen_set_window_property_iv(window->nativeHandle(), SCREEN_PROPERTY_IDLE_MODE, &mode);
758 qWarning(
"QQnxRootWindow: failed to disable power saving mode");
760 m_rootWindow = window;
void windowClosed(void *window)
Qt::ScreenOrientation nativeOrientation() const override
Reimplement this function in subclass to return the native orientation of the screen,...
QPlatformCursor * cursor() const override
Reimplement this function in subclass to return the cursor of the screen.
Qt::ScreenOrientation orientation() const override
Reimplement this function in subclass to return the current orientation of the screen,...
QWindow * topLevelAt(const QPoint &point) const override
Return the given top level window for a given position.
void lowerWindow(QQnxWindow *window)
bool isPrimaryScreen() const
void raiseWindow(QQnxWindow *window)
void activateWindowGroup(const QByteArray &id)
void removeWindow(QQnxWindow *child)
void addWindow(QQnxWindow *child)
QRect availableGeometry() const override
Reimplement in subclass to return the pixel geometry of the available space This normally is the desk...
void deactivateWindowGroup(const QByteArray &id)
QPixmap grabWindow(WId window, int x, int y, int width, int height) const override
This function is called when Qt needs to be able to grab the content of a window.
QQnxWindow * findWindow(screen_window_t windowHandle) const
void setRootWindow(QQnxWindow *)
int depth() const override
Reimplement in subclass to return current depth of the screen.
QQnxWindow * rootWindow() const
void newWindowCreated(void *window)
qreal refreshRate() const override
Reimplement this function in subclass to return the vertical refresh rate of the screen,...
void windowGroupStateChanged(const QByteArray &id, Qt::WindowState state)
The QQnxWindow is the base class of the various classes used as instances of QPlatformWindow in the Q...
void setExposed(bool exposed)
void setScreen(QQnxScreen *platformScreen)
void setRotation(int rotation)
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
#define Q_SCREEN_CRITICALERROR(x, message)
#define Q_SCREEN_CHECKERROR(x, message)
static const int MAX_UNDERLAY_ZORDER
static bool isOrthogonal(int angle1, int angle2)
Check if the supplied angles are perpendicular to each other.
static int defaultDepth()
static QSize determineScreenSize(screen_display_t display, bool primaryScreen)