diff options
Diffstat (limited to 'src/plugins/platforms/qnx/qqnxscreen.cpp')
-rw-r--r-- | src/plugins/platforms/qnx/qqnxscreen.cpp | 131 |
1 files changed, 110 insertions, 21 deletions
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index add45ecbe5..f3f93e7f64 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -5,36 +5,28 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -209,6 +201,103 @@ QQnxScreen::~QQnxScreen() 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"); + return QPixmap(); + } + + 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"); + return QPixmap(); + } + + // 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"); + else + qWarning("grabWindow: cannot create context"); + return QPixmap(); + } + + // Find corresponding display in SCREEN_DISPLAY_MANAGER_CONTEXT + int 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 int defaultDepth() { qScreenDebug() << Q_FUNC_INFO; @@ -348,7 +437,7 @@ void QQnxScreen::setRotation(int rotation) // Rotating only the primary screen is what we had in the navigator event handler before refactoring if (m_primaryScreen) { QWindowSystemInterface::handleScreenOrientationChange(screen(), orientation()); - QWindowSystemInterface::handleScreenGeometryChange(screen(), m_currentGeometry); + QWindowSystemInterface::handleScreenGeometryChange(screen(), m_currentGeometry, availableGeometry()); } // Flush everything, so that the windows rotations are applied properly. @@ -463,7 +552,7 @@ void QQnxScreen::resizeWindows(const QRect &previousScreenGeometry) } } -QQnxWindow *QQnxScreen::findWindow(screen_window_t windowHandle) +QQnxWindow *QQnxScreen::findWindow(screen_window_t windowHandle) const { Q_FOREACH (QQnxWindow *window, m_childWindows) { QQnxWindow * const result = window->findWindow(windowHandle); @@ -608,7 +697,7 @@ void QQnxScreen::keyboardHeightChanged(int height) m_keyboardHeight = height; - QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), availableGeometry()); + QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); } void QQnxScreen::addOverlayWindow(screen_window_t window) |