123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773 | // Copyright (C) 2011 - 2013 BlackBerry Limited. All rights reserved.// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#undef QT_NO_FOREACH// this file contains unported legacy Q_FOREACH uses#include"qqnxglobal.h"#include"qqnxscreen.h"#include"qqnxwindow.h"#include"qqnxcursor.h"#include <QtCore/QThread>#include <QtCore/QDebug>#include <qpa/qwindowsysteminterface.h>#include <errno.h>#if defined(QQNX_PHYSICAL_SCREEN_WIDTH) && QQNX_PHYSICAL_SCREEN_WIDTH > 0 \ && defined(QQNX_PHYSICAL_SCREEN_HEIGHT) && QQNX_PHYSICAL_SCREEN_HEIGHT > 0#define QQNX_PHYSICAL_SCREEN_SIZE_DEFINED#elif defined(QQNX_PHYSICAL_SCREEN_WIDTH) || defined(QQNX_PHYSICAL_SCREEN_HEIGHT)#error Please define QQNX_PHYSICAL_SCREEN_WIDTH and QQNX_PHYSICAL_SCREEN_HEIGHT to values greater than zero#endif// The maximum z-order at which a foreign window will be considered// an underlay.static const int MAX_UNDERLAY_ZORDER = -1; QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaScreen,"qt.qpa.screen");static QSize determineScreenSize(screen_display_t display,bool primaryScreen) {int val[2];const int result =screen_get_display_property_iv(display, SCREEN_PROPERTY_PHYSICAL_SIZE, val);Q_SCREEN_CHECKERROR(result,"Failed to query display physical size");if(result !=0) {returnQSize(150,90);}if(val[0] >0&& val[1] >0)returnQSize(val[0], val[1]);qCDebug(lcQpaScreen,"QQnxScreen: screen_get_display_property_iv() reported an invalid ""physical screen size (%dx%d). Falling back to QQNX_PHYSICAL_SCREEN_SIZE ""environment variable.", val[0], val[1]);const QString envPhySizeStr =qgetenv("QQNX_PHYSICAL_SCREEN_SIZE");if(!envPhySizeStr.isEmpty()) {constauto envPhySizeStrList = QStringView{envPhySizeStr}.split(u',');const int envWidth = envPhySizeStrList.size() ==2? envPhySizeStrList[0].toInt() : -1;const int envHeight = envPhySizeStrList.size() ==2? envPhySizeStrList[1].toInt() : -1;if(envWidth <=0|| envHeight <=0) {qWarning("QQnxScreen: The value of QQNX_PHYSICAL_SCREEN_SIZE must be in the format ""\"width,height\"in mm, with width, height > 0. Defaulting to 150x90. ""Example: QQNX_PHYSICAL_SCREEN_SIZE=150,90");returnQSize(150,90);}returnQSize(envWidth, envHeight);}#if defined(QQNX_PHYSICAL_SCREEN_SIZE_DEFINED)const QSize defSize(QQNX_PHYSICAL_SCREEN_WIDTH, QQNX_PHYSICAL_SCREEN_HEIGHT);qWarning("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. Falling back to defines ""QQNX_PHYSICAL_SCREEN_WIDTH/QQNX_PHYSICAL_SCREEN_HEIGHT (%dx%d)", defSize.width(), defSize.height());return defSize;#elseif(primaryScreen)qWarning("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. ""Could not determine physical screen size. Defaulting to 150x90.");returnQSize(150,90);#endif}QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display,bool primaryScreen):m_screenContext(screenContext),m_display(display),m_rootWindow(0),m_primaryScreen(primaryScreen),m_keyboardHeight(0),m_nativeOrientation(Qt::PrimaryOrientation),m_coverWindow(0),m_cursor(newQQnxCursor()){qCDebug(lcQpaScreen) << Q_FUNC_INFO;// Cache initial orientation of this displayint result =screen_get_display_property_iv(m_display, SCREEN_PROPERTY_ROTATION,&m_initialRotation);Q_SCREEN_CHECKERROR(result,"Failed to query display rotation"); m_currentRotation = m_initialRotation;// Cache size of this display in pixelsint val[2];Q_SCREEN_CRITICALERROR(screen_get_display_property_iv(m_display, SCREEN_PROPERTY_SIZE, val),"Failed to query display size"); m_currentGeometry = m_initialGeometry =QRect(0,0, val[0], val[1]);char name[100];Q_SCREEN_CHECKERROR(screen_get_display_property_cv(m_display, SCREEN_PROPERTY_ID_STRING,100, name),"Failed to query display name"); m_name =QString::fromUtf8(name);// Cache size of this display in millimeters. We have to take care of the orientation.// libscreen always reports the physical size dimensions as width and height in the// native orientation. Contrary to this, QPlatformScreen::physicalSize() expects the// returned dimensions to follow the current orientation.const QSize screenSize =determineScreenSize(m_display, primaryScreen); m_nativeOrientation = screenSize.width() >= screenSize.height() ?Qt::LandscapeOrientation :Qt::PortraitOrientation;const int angle =screen()->angleBetween(m_nativeOrientation,orientation());if(angle ==0|| angle ==180) m_currentPhysicalSize = m_initialPhysicalSize = screenSize;else m_currentPhysicalSize = m_initialPhysicalSize = screenSize.transposed();}QQnxScreen::~QQnxScreen(){qCDebug(lcQpaScreen) << Q_FUNC_INFO;Q_FOREACH(QQnxWindow *childWindow, m_childWindows) childWindow->setScreen(0);if(m_coverWindow) m_coverWindow->setScreen(0);delete m_cursor;} QPixmap QQnxScreen::grabWindow(WId window,int x,int y,int width,int height)const{ QQnxWindow *qnxWin =findWindow(reinterpret_cast<screen_window_t>(window));if(!qnxWin) {qWarning("grabWindow: unknown window");returnQPixmap();} QRect bound = qnxWin->geometry();if(width <0) width = bound.width();if(height <0) height = bound.height(); bound &=QRect(x + bound.x(), y + bound.y(), width, height);if(bound.width() <=0|| bound.height() <=0) {qWarning("grabWindow: size is null");returnQPixmap();}// Create new context, only SCREEN_DISPLAY_MANAGER_CONTEXT can read from screen screen_context_t context;if(screen_create_context(&context, SCREEN_DISPLAY_MANAGER_CONTEXT)) {if(errno == EPERM)qWarning("grabWindow: root privileges required");elseqWarning("grabWindow: cannot create context");returnQPixmap();}// Find corresponding display in SCREEN_DISPLAY_MANAGER_CONTEXTint count =0; screen_display_t display =0;screen_get_context_property_iv(context, SCREEN_PROPERTY_DISPLAY_COUNT, &count);if(count >0) {const size_t idLen =30;char matchId[idLen];char id[idLen];bool found =false; screen_display_t *displays =static_cast<screen_display_t*>(calloc(count,sizeof(screen_display_t)));screen_get_context_property_pv(context, SCREEN_PROPERTY_DISPLAYS, (void**)displays);screen_get_display_property_cv(m_display, SCREEN_PROPERTY_ID_STRING, idLen, matchId);while(count && !found) {--count;screen_get_display_property_cv(displays[count], SCREEN_PROPERTY_ID_STRING, idLen, id); found = !strncmp(id, matchId, idLen);}if(found) display = displays[count];free(displays);}// Create screen and Qt pixmap screen_pixmap_t pixmap; QPixmap result;if(display && !screen_create_pixmap(&pixmap, context)) { screen_buffer_t buffer;void*pointer;int stride;const int rect[4] = { bound.x(), bound.y(), bound.width(), bound.height() };int val = SCREEN_USAGE_READ | SCREEN_USAGE_NATIVE;screen_set_pixmap_property_iv(pixmap, SCREEN_PROPERTY_USAGE, &val); val = SCREEN_FORMAT_RGBA8888;screen_set_pixmap_property_iv(pixmap, SCREEN_PROPERTY_FORMAT, &val);int err =screen_set_pixmap_property_iv(pixmap, SCREEN_PROPERTY_BUFFER_SIZE, rect+2); err = err ||screen_create_pixmap_buffer(pixmap); err = err ||screen_get_pixmap_property_pv(pixmap, SCREEN_PROPERTY_RENDER_BUFFERS,reinterpret_cast<void**>(&buffer)); err = err ||screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, &pointer); err = err ||screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE, &stride); err = err ||screen_read_display(display, buffer,1, rect,0);if(!err) {const QImage img(static_cast<unsigned char*>(pointer), bound.width(), bound.height(), stride,QImage::Format_ARGB32); result =QPixmap::fromImage(img);}else{qWarning("grabWindow: capture error");}screen_destroy_pixmap(pixmap);}else{qWarning("grabWindow: display/pixmap error ");}screen_destroy_context(context);return result;}static intdefaultDepth(){qCDebug(lcQpaScreen) << Q_FUNC_INFO;static int defaultDepth =0;if(defaultDepth ==0) {// check if display depth was specified in environment variable;// use default value if no valid value found defaultDepth =qEnvironmentVariableIntValue("QQNX_DISPLAY_DEPTH");if(defaultDepth !=16&& defaultDepth !=32) defaultDepth =32;}return defaultDepth;} QRect QQnxScreen::availableGeometry()const{qCDebug(lcQpaScreen) << Q_FUNC_INFO;// available geometry = total geometry - keyboardreturnQRect(m_currentGeometry.x(), m_currentGeometry.y(), m_currentGeometry.width(), m_currentGeometry.height() - m_keyboardHeight);}intQQnxScreen::depth()const{returndefaultDepth();} qreal QQnxScreen::refreshRate()const{ screen_display_mode_t displayMode;int result =screen_get_display_property_pv(m_display, SCREEN_PROPERTY_MODE,reinterpret_cast<void**>(&displayMode));// Screen shouldn't really return 0 but it does so default to 60 or things break.if(result !=0|| displayMode.refresh ==0) {qWarning("QQnxScreen: Failed to query screen mode. Using default value of 60Hz");return60.0;}qCDebug(lcQpaScreen,"screen mode:\n"" width = %u\n"" height = %u\n"" refresh = %u\n"" interlaced = %u",uint(displayMode.width),uint(displayMode.height),uint(displayMode.refresh),uint(displayMode.interlaced));return static_cast<qreal>(displayMode.refresh);}Qt::ScreenOrientation QQnxScreen::nativeOrientation()const{return m_nativeOrientation;}Qt::ScreenOrientation QQnxScreen::orientation()const{Qt::ScreenOrientation orient;if(m_nativeOrientation ==Qt::LandscapeOrientation) {// Landscape devices e.g. PlayBookif(m_currentRotation ==0) orient =Qt::LandscapeOrientation;else if(m_currentRotation ==90) orient =Qt::PortraitOrientation;else if(m_currentRotation ==180) orient =Qt::InvertedLandscapeOrientation;else orient =Qt::InvertedPortraitOrientation;}else{// Portrait devices e.g. Phones// ###TODO Check these on an actual phone deviceif(m_currentRotation ==0) orient =Qt::PortraitOrientation;else if(m_currentRotation ==90) orient =Qt::LandscapeOrientation;else if(m_currentRotation ==180) orient =Qt::InvertedPortraitOrientation;else orient =Qt::InvertedLandscapeOrientation;}qCDebug(lcQpaScreen) << Q_FUNC_INFO <<"Orientation ="<< orient;return orient;} QWindow *QQnxScreen::topLevelAt(const QPoint &point)const{for(auto it = m_childWindows.rbegin(), end = m_childWindows.rend(); it != end; ++it) { QWindow *win = (*it)->window();if(win->geometry().contains(point))return win;}return0;}/*! Check if the supplied angles are perpendicular to each other.*/static boolisOrthogonal(int angle1,int angle2){return((angle1 - angle2) %180) !=0;}voidQQnxScreen::setRotation(int rotation){qCDebug(lcQpaScreen) << Q_FUNC_INFO <<"orientation ="<< rotation;// Check if rotation changed// We only want to rotate if we are the primary screenif(m_currentRotation != rotation &&isPrimaryScreen()) {// Update rotation of root windowif(rootWindow())rootWindow()->setRotation(rotation);const QRect previousScreenGeometry =geometry();// Swap dimensions if we've rotated 90 or 270 from initial orientationif(isOrthogonal(m_initialRotation, rotation)) { m_currentGeometry =QRect(0,0, m_initialGeometry.height(), m_initialGeometry.width()); m_currentPhysicalSize =QSize(m_initialPhysicalSize.height(), m_initialPhysicalSize.width());}else{ m_currentGeometry =QRect(0,0, m_initialGeometry.width(), m_initialGeometry.height()); m_currentPhysicalSize = m_initialPhysicalSize;}// Resize root window if we've rotated 90 or 270 from previous orientationif(isOrthogonal(m_currentRotation, rotation)) {qCDebug(lcQpaScreen) << Q_FUNC_INFO <<"resize, size ="<< m_currentGeometry.size();if(rootWindow())rootWindow()->setGeometry(QRect(QPoint(0,0), m_currentGeometry.size()));resizeWindows(previousScreenGeometry);}else{// TODO: Find one global place to flush display updates// Force immediate display update if no geometry changes requiredscreen_flush_context(nativeContext(),0);}// Save new rotation m_currentRotation = rotation;// TODO: check if other screens are supposed to rotate as well and/or whether this depends// on if clone mode is being used.// Rotating only the primary screen is what we had in the navigator event handler before refactoringif(m_primaryScreen) {QWindowSystemInterface::handleScreenOrientationChange(screen(),orientation());QWindowSystemInterface::handleScreenGeometryChange(screen(), m_currentGeometry,availableGeometry());}// Flush everything, so that the windows rotations are applied properly.// Needed for non-maximized windowsscreen_flush_context( m_screenContext,0);}}/*! Resize the given window proportionally to the screen geometry*/voidQQnxScreen::resizeNativeWidgetWindow(QQnxWindow *w,const QRect &previousScreenGeometry)const{const qreal relativeX =static_cast<qreal>(w->geometry().topLeft().x()) / previousScreenGeometry.width();const qreal relativeY =static_cast<qreal>(w->geometry().topLeft().y()) / previousScreenGeometry.height();const qreal relativeWidth =static_cast<qreal>(w->geometry().width()) / previousScreenGeometry.width();const qreal relativeHeight =static_cast<qreal>(w->geometry().height()) / previousScreenGeometry.height();const QRect windowGeometry(relativeX *geometry().width(), relativeY *geometry().height(), relativeWidth *geometry().width(), relativeHeight *geometry().height()); w->setGeometry(windowGeometry);}/*! Resize the given window to fit the screen geometry*/voidQQnxScreen::resizeTopLevelWindow(QQnxWindow *w,const QRect &previousScreenGeometry)const{ QRect windowGeometry = w->geometry();const qreal relativeCenterX =static_cast<qreal>(w->geometry().center().x()) / previousScreenGeometry.width();const qreal relativeCenterY =static_cast<qreal>(w->geometry().center().y()) / previousScreenGeometry.height();const QPoint newCenter(relativeCenterX *geometry().width(), relativeCenterY *geometry().height()); windowGeometry.moveCenter(newCenter);// adjust center position in case the window// is clippedif(!geometry().contains(windowGeometry)) {const int x1 = windowGeometry.x();const int y1 = windowGeometry.y();const int x2 = x1 + windowGeometry.width();const int y2 = y1 + windowGeometry.height();if(x1 <0) {const int centerX =qMin(qAbs(x1) + windowGeometry.center().x(),geometry().center().x()); windowGeometry.moveCenter(QPoint(centerX, windowGeometry.center().y()));}if(y1 <0) {const int centerY =qMin(qAbs(y1) + windowGeometry.center().y(),geometry().center().y()); windowGeometry.moveCenter(QPoint(windowGeometry.center().x(), centerY));}if(x2 >geometry().width()) {const int centerX =qMax(windowGeometry.center().x() - (x2 -geometry().width()),geometry().center().x()); windowGeometry.moveCenter(QPoint(centerX, windowGeometry.center().y()));}if(y2 >geometry().height()) {const int centerY =qMax(windowGeometry.center().y() - (y2 -geometry().height()),geometry().center().y()); windowGeometry.moveCenter(QPoint(windowGeometry.center().x(), centerY));}}// at this point, if the window is still clipped,// it means that it's too big to fit on the screen,// so we need to proportionally shrink itif(!geometry().contains(windowGeometry)) { QSize newSize = windowGeometry.size(); newSize.scale(geometry().size(),Qt::KeepAspectRatio); windowGeometry.setSize(newSize);if(windowGeometry.x() <0) windowGeometry.moveCenter(QPoint(geometry().center().x(), windowGeometry.center().y()));if(windowGeometry.y() <0) windowGeometry.moveCenter(QPoint(windowGeometry.center().x(),geometry().center().y()));} w->setGeometry(windowGeometry);}/*! Adjust windows to the new screen geometry.*/voidQQnxScreen::resizeWindows(const QRect &previousScreenGeometry){resizeMaximizedWindows();Q_FOREACH(QQnxWindow *w, m_childWindows) {if(w->window()->windowState() &Qt::WindowFullScreen || w->window()->windowState() &Qt::WindowMaximized)continue;if(w->parent()) {// This is a native (non-alien) widget windowresizeNativeWidgetWindow(w, previousScreenGeometry);}else{// This is a toplevel windowresizeTopLevelWindow(w, previousScreenGeometry);}}} QQnxWindow *QQnxScreen::findWindow(screen_window_t windowHandle)const{Q_FOREACH(QQnxWindow *window, m_childWindows) { QQnxWindow *const result = window->findWindow(windowHandle);if(result)return result;}return0;}voidQQnxScreen::addWindow(QQnxWindow *window){qCDebug(lcQpaScreen) << Q_FUNC_INFO <<"Window ="<< window;if(m_childWindows.contains(window))return;if(window->window()->type() !=Qt::CoverWindow) {// Ensure that the desktop window is at the bottom of the zorder.// If we do not do this then we may end up activating the desktop// when the navigator service gets an event that our window group// has been activated (see QQnxScreen::activateWindowGroup()).// Such a situation would strangely break focus handling due to the// invisible desktop widget window being layered on top of normal// windowsif(window->window()->type() ==Qt::Desktop) m_childWindows.push_front(window);else m_childWindows.push_back(window);updateHierarchy();}}voidQQnxScreen::removeWindow(QQnxWindow *window){qCDebug(lcQpaScreen) << Q_FUNC_INFO <<"Window ="<< window;if(window != m_coverWindow) {const int numWindowsRemoved = m_childWindows.removeAll(window);if(window == m_rootWindow)//We just removed the root window m_rootWindow =0;//TODO we need a new root window ;)if(numWindowsRemoved >0)updateHierarchy();}else{ m_coverWindow =0;}}voidQQnxScreen::raiseWindow(QQnxWindow *window){qCDebug(lcQpaScreen) << Q_FUNC_INFO <<"Window ="<< window;if(window != m_coverWindow) {removeWindow(window); m_childWindows.push_back(window);}}voidQQnxScreen::lowerWindow(QQnxWindow *window){qCDebug(lcQpaScreen) << Q_FUNC_INFO <<"Window ="<< window;if(window != m_coverWindow) {removeWindow(window); m_childWindows.push_front(window);}}voidQQnxScreen::updateHierarchy(){qCDebug(lcQpaScreen) << Q_FUNC_INFO; QList<QQnxWindow*>::const_iterator it;int result;int topZorder =0; errno =0;if(rootWindow()) { result =screen_get_window_property_iv(rootWindow()->nativeHandle(), SCREEN_PROPERTY_ZORDER, &topZorder);if(result !=0) {//This can happen if we use winId in QWidgets topZorder =10;qWarning("QQnxScreen: failed to query root window z-order, errno=%d", errno);}}else{ topZorder =0;//We do not need z ordering on the secondary screen, because only one window//is supported there} topZorder++;// root window has the lowest z-order in the windowgroupint underlayZorder = -1;// Underlays sit immediately above the root window in the z-orderingQ_FOREACH(screen_window_t underlay, m_underlays) {// Do nothing when this fails. This can happen if we have stale windows in m_underlays,// which in turn can happen because a window was removed but we didn't get a notification// yet.screen_set_window_property_iv(underlay, SCREEN_PROPERTY_ZORDER, &underlayZorder); underlayZorder--;}// Normal Qt windows come next above the root window z-orderingfor(it = m_childWindows.constBegin(); it != m_childWindows.constEnd(); ++it)(*it)->updateZorder(topZorder);// Finally overlays sit above all else in the z-orderingQ_FOREACH(screen_window_t overlay, m_overlays) {// No error handling, see underlay logic abovescreen_set_window_property_iv(overlay, SCREEN_PROPERTY_ZORDER, &topZorder); topZorder++;}// After a hierarchy update, we need to force a flush on all screens.// Right now, all screens share a context.screen_flush_context(m_screenContext,0);}voidQQnxScreen::adjustOrientation(){if(!m_primaryScreen)return;bool ok =false;const int rotation =qEnvironmentVariableIntValue("ORIENTATION", &ok);if(ok)setRotation(rotation);} QPlatformCursor *QQnxScreen::cursor()const{return m_cursor;}voidQQnxScreen::keyboardHeightChanged(int height){if(height == m_keyboardHeight)return; m_keyboardHeight = height;QWindowSystemInterface::handleScreenGeometryChange(screen(),geometry(),availableGeometry());}voidQQnxScreen::addOverlayWindow(screen_window_t window){ m_overlays.append(window);updateHierarchy();}voidQQnxScreen::addUnderlayWindow(screen_window_t window){ m_underlays.append(window);updateHierarchy();}voidQQnxScreen::removeOverlayOrUnderlayWindow(screen_window_t window){const int numRemoved = m_overlays.removeAll(window) + m_underlays.removeAll(window);if(numRemoved >0) {updateHierarchy(); Q_EMIT foreignWindowClosed(window);}}voidQQnxScreen::newWindowCreated(void*window){Q_ASSERT(thread() ==QThread::currentThread());const screen_window_t windowHandle =reinterpret_cast<screen_window_t>(window); screen_display_t display =0;if(screen_get_window_property_pv(windowHandle, SCREEN_PROPERTY_DISPLAY, (void**)&display) !=0) {qWarning("QQnx: Failed to get screen for window, errno=%d", errno);return;}int zorder;if(screen_get_window_property_iv(windowHandle, SCREEN_PROPERTY_ZORDER, &zorder) !=0) {qWarning("QQnx: Failed to get z-order for window, errno=%d", errno); zorder =0;}char windowNameBuffer[256] = {0}; QByteArray windowName;if(screen_get_window_property_cv(windowHandle, SCREEN_PROPERTY_ID_STRING,sizeof(windowNameBuffer) -1, windowNameBuffer) !=0) {qWarning("QQnx: Failed to get id for window, errno=%d", errno);} windowName =QByteArray(windowNameBuffer);if(display !=nativeDisplay())return;// A window was created on this screen. If we don't know about this window yet, it means// it was not created by Qt, but by some foreign library.//// Treat all foreign windows as overlays or underlays. A window will// be treated as an underlay if its Z-order is less or equal than// MAX_UNDERLAY_ZORDER. Otherwise, it will be treated as an overlay.if(findWindow(windowHandle))return;if(zorder <= MAX_UNDERLAY_ZORDER)addUnderlayWindow(windowHandle);elseaddOverlayWindow(windowHandle); Q_EMIT foreignWindowCreated(windowHandle);}voidQQnxScreen::windowClosed(void*window){Q_ASSERT(thread() ==QThread::currentThread());const screen_window_t windowHandle =reinterpret_cast<screen_window_t>(window);removeOverlayOrUnderlayWindow(windowHandle);}voidQQnxScreen::windowGroupStateChanged(const QByteArray &id,Qt::WindowState state){qCDebug(lcQpaScreen) << Q_FUNC_INFO;if(!rootWindow() || id !=rootWindow()->groupName())return; QWindow *const window =rootWindow()->window();if(!window)return;QWindowSystemInterface::handleWindowStateChanged(window, state);}voidQQnxScreen::activateWindowGroup(const QByteArray &id){qCDebug(lcQpaScreen) << Q_FUNC_INFO;if(!rootWindow() || id !=rootWindow()->groupName())return; QWindow *const window =rootWindow()->window();if(!window)return;Q_FOREACH(QQnxWindow *childWindow, m_childWindows) childWindow->setExposed(true);if(m_coverWindow) m_coverWindow->setExposed(false);}voidQQnxScreen::deactivateWindowGroup(const QByteArray &id){qCDebug(lcQpaScreen) << Q_FUNC_INFO;if(!rootWindow() || id !=rootWindow()->groupName())return;if(m_coverWindow) m_coverWindow->setExposed(true);Q_FOREACH(QQnxWindow *childWindow, m_childWindows) childWindow->setExposed(false);} QQnxWindow *QQnxScreen::rootWindow()const{return m_rootWindow;}voidQQnxScreen::setRootWindow(QQnxWindow *window){// Optionally disable the screen power savebool ok =false;const int disablePowerSave =qEnvironmentVariableIntValue("QQNX_DISABLE_POWER_SAVE", &ok);if(ok && disablePowerSave) {const int mode = SCREEN_IDLE_MODE_KEEP_AWAKE;int result =screen_set_window_property_iv(window->nativeHandle(), SCREEN_PROPERTY_IDLE_MODE, &mode);if(result !=0)qWarning("QQnxRootWindow: failed to disable power saving mode");} m_rootWindow = window;} QT_END_NAMESPACE
|