1dfb45d7ff46fee70700ad629d6bdc85804ea441
[profile/ivi/qtbase.git] / src / plugins / platforms / qnx / qqnxwindow.cpp
1 /***************************************************************************
2 **
3 ** Copyright (C) 2011 - 2012 Research In Motion
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qqnxwindow.h"
43 #ifndef QT_NO_OPENGL
44 #include "qqnxglcontext.h"
45 #endif
46 #include "qqnxintegration.h"
47 #include "qqnxscreen.h"
48
49 #include <QtGui/QWindow>
50 #include <QtGui/QWindowSystemInterface>
51
52 #include <QtCore/QDebug>
53
54 #include <errno.h>
55
56 #ifdef QQNXWINDOW_DEBUG
57 #define qWindowDebug qDebug
58 #else
59 #define qWindowDebug QT_NO_QDEBUG_MACRO
60 #endif
61
62 QT_BEGIN_NAMESPACE
63
64 QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context)
65     : QPlatformWindow(window),
66       m_screenContext(context),
67       m_window(0),
68       m_currentBufferIndex(-1),
69       m_previousBufferIndex(-1),
70 #ifndef QT_NO_OPENGL
71       m_platformOpenGLContext(0),
72 #endif
73       m_screen(0),
74       m_parentWindow(0),
75       m_visible(true),
76       m_windowState(Qt::WindowNoState)
77 {
78     qWindowDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size();
79     int result;
80
81     // Create child QNX window
82     errno = 0;
83     result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW);
84     if (result != 0) {
85         qFatal("QQnxWindow: failed to create window, errno=%d", errno);
86     }
87
88     // Set window buffer usage based on rendering API
89     int val;
90     QSurface::SurfaceType surfaceType = window->surfaceType();
91     switch (surfaceType) {
92     case QSurface::RasterSurface:
93         val = SCREEN_USAGE_NATIVE | SCREEN_USAGE_READ | SCREEN_USAGE_WRITE;
94         break;
95     case QSurface::OpenGLSurface:
96         val = SCREEN_USAGE_OPENGL_ES2;
97         break;
98     default:
99         qFatal("QQnxWindow: unsupported window API");
100         break;
101     }
102
103     errno = 0;
104     result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_USAGE, &val);
105     if (result != 0) {
106         qFatal("QQnxWindow: failed to set window buffer usage, errno=%d", errno);
107     }
108
109     // Alpha channel is always pre-multiplied if present
110     errno = 0;
111     val = SCREEN_PRE_MULTIPLIED_ALPHA;
112     result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val);
113     if (result != 0) {
114         qFatal("QQnxWindow: failed to set window alpha mode, errno=%d", errno);
115     }
116
117     // Make the window opaque
118     errno = 0;
119     val = SCREEN_TRANSPARENCY_NONE;
120     result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, &val);
121     if (result != 0) {
122         qFatal("QQnxWindow: failed to set window transparency, errno=%d", errno);
123     }
124
125     // Set the window swap interval
126     errno = 0;
127     val = 1;
128     result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val);
129     if (result != 0) {
130         qFatal("QQnxWindow: failed to set window swap interval, errno=%d", errno);
131     }
132
133     setScreen(static_cast<QQnxScreen *>(window->screen()->handle()));
134
135     // Add window to plugin's window mapper
136     QQnxIntegration::addWindow(m_window, window);
137
138     // setWindowState() does not get called when the platform window hasn't been created yet, so
139     // make sure to apply the inital window state here
140     setWindowState(window->windowState());
141 }
142
143 QQnxWindow::~QQnxWindow()
144 {
145     qWindowDebug() << Q_FUNC_INFO << "window =" << window();
146     // Remove from plugin's window mapper
147     QQnxIntegration::removeWindow(m_window);
148
149     // Remove from parent's Hierarchy.
150     removeFromParent();
151     m_screen->updateHierarchy();
152
153     // We shouldn't allow this case unless QT allows it. Does it? Or should we send the
154     // handleCloseEvent on all children when this window is deleted?
155     if (m_childWindows.size() > 0)
156         qFatal("QQnxWindow: window destroyed before children!");
157
158     // Cleanup QNX window and its buffers
159     screen_destroy_window(m_window);
160 }
161
162 void QQnxWindow::setGeometry(const QRect &rect)
163 {
164     qWindowDebug() << Q_FUNC_INFO << "window =" << window()
165                    << ", (" << rect.x() << "," << rect.y()
166                    << "," << rect.width() << "," << rect.height() << ")";
167
168     QRect oldGeometry = geometry();
169
170     // Call base class method
171     QPlatformWindow::setGeometry(rect);
172
173     // Set window geometry equal to widget geometry
174     errno = 0;
175     int val[2];
176     val[0] = rect.x();
177     val[1] = rect.y();
178     int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val);
179     if (result != 0) {
180         qFatal("QQnxWindow: failed to set window position, errno=%d", errno);
181     }
182
183     errno = 0;
184     val[0] = rect.width();
185     val[1] = rect.height();
186     result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val);
187     if (result != 0) {
188         qFatal("QQnxWindow: failed to set window size, errno=%d", errno);
189     }
190
191     // Set viewport size equal to window size
192     errno = 0;
193     result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val);
194     if (result != 0) {
195         qFatal("QQnxWindow: failed to set window source size, errno=%d", errno);
196     }
197
198     if (m_platformOpenGLContext != 0 && bufferSize() != rect.size()) {
199         bool restoreCurrent = false;
200
201         if (m_platformOpenGLContext->isCurrent()) {
202             m_platformOpenGLContext->doneCurrent();
203             restoreCurrent = true;
204         }
205
206         m_platformOpenGLContext->destroySurface();
207         setBufferSize(rect.size());
208         m_platformOpenGLContext->createSurface(this);
209
210         if (restoreCurrent)
211             m_platformOpenGLContext->makeCurrent(this);
212     }
213
214     QWindowSystemInterface::handleSynchronousGeometryChange(window(), rect);
215
216     // Now move all children.
217     if (!oldGeometry.isEmpty()) {
218         const QPoint offset = rect.topLeft() - oldGeometry.topLeft();
219         Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
220             childWindow->setOffset(offset);
221     }
222 }
223
224 void QQnxWindow::setOffset(const QPoint &offset)
225 {
226     qWindowDebug() << Q_FUNC_INFO << "window =" << window();
227     // Move self and then children.
228     QRect newGeometry = geometry();
229     newGeometry.translate(offset);
230
231     // Call the base class
232     QPlatformWindow::setGeometry(newGeometry);
233
234     int val[2];
235
236     errno = 0;
237     val[0] = newGeometry.x();
238     val[1] = newGeometry.y();
239     int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val);
240     if (result != 0) {
241         qFatal("QQnxWindow: failed to set window position, errno=%d", errno);
242     }
243
244     Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
245         childWindow->setOffset(offset);
246 }
247
248 void QQnxWindow::setVisible(bool visible)
249 {
250     qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "visible =" << visible;
251
252     m_visible = visible;
253
254     QQnxWindow *root = this;
255     while (root->m_parentWindow)
256         root = root->m_parentWindow;
257
258     root->updateVisibility(root->m_visible);
259
260     window()->requestActivateWindow();
261
262     if (window()->isTopLevel() && visible)
263         QWindowSystemInterface::handleExposeEvent(window(), window()->geometry());
264 }
265
266 void QQnxWindow::updateVisibility(bool parentVisible)
267 {
268     qWindowDebug() << Q_FUNC_INFO << "parentVisible =" << parentVisible << "window =" << window();
269     // Set window visibility
270     errno = 0;
271     int val = (m_visible && parentVisible) ? 1 : 0;
272     int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val);
273     if (result != 0) {
274         qFatal("QQnxWindow: failed to set window visibility, errno=%d", errno);
275     }
276
277     Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
278         childWindow->updateVisibility(m_visible && parentVisible);
279 }
280
281 void QQnxWindow::setOpacity(qreal level)
282 {
283     qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "opacity =" << level;
284     // Set window global alpha
285     errno = 0;
286     int val = (int)(level * 255);
287     int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val);
288     if (result != 0) {
289         qFatal("QQnxWindow: failed to set window global alpha, errno=%d", errno);
290     }
291
292     // TODO: How to handle children of this window? If we change all the visibilities, then
293     //       the transparency will look wrong...
294 }
295
296 bool QQnxWindow::isExposed() const
297 {
298     return m_visible;
299 }
300
301 void QQnxWindow::setBufferSize(const QSize &size)
302 {
303     qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size;
304     // Set window buffer size
305     errno = 0;
306     int val[2] = { size.width(), size.height() };
307     int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val);
308     if (result != 0) {
309         qFatal("QQnxWindow: failed to set window buffer size, errno=%d", errno);
310     }
311
312     // Create window buffers if they do not exist
313     if (!hasBuffers()) {
314 #ifndef QT_NO_OPENGL
315         // Get pixel format from EGL config if using OpenGL;
316         // otherwise inherit pixel format of window's screen
317         if (m_platformOpenGLContext != 0) {
318             val[0] = platformWindowFormatToNativeFormat(m_platformOpenGLContext->format());
319         } else {
320             val[0] = m_screen->nativeFormat();
321         }
322 #endif
323
324         errno = 0;
325         result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val);
326         if (result != 0) {
327             qFatal("QQnxWindow: failed to set window pixel format, errno=%d", errno);
328         }
329
330         errno = 0;
331         result = screen_create_window_buffers(m_window, MAX_BUFFER_COUNT);
332         if (result != 0) {
333             qFatal("QQnxWindow: failed to create window buffers, errno=%d", errno);
334         }
335     }
336
337     // Cache new buffer size
338     m_bufferSize = size;
339
340     // Buffers were destroyed; reacquire them
341     m_currentBufferIndex = -1;
342     m_previousDirty = QRegion();
343     m_scrolled = QRegion();
344 }
345
346 QQnxBuffer &QQnxWindow::renderBuffer()
347 {
348     qWindowDebug() << Q_FUNC_INFO << "window =" << window();
349     // Check if render buffer is invalid
350     if (m_currentBufferIndex == -1) {
351         // Get all buffers available for rendering
352         errno = 0;
353         screen_buffer_t buffers[MAX_BUFFER_COUNT];
354         int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers);
355         if (result != 0) {
356             qFatal("QQnxWindow: failed to query window buffers, errno=%d", errno);
357         }
358
359         // Wrap each buffer
360         for (int i = 0; i < MAX_BUFFER_COUNT; ++i) {
361             m_buffers[i] = QQnxBuffer(buffers[i]);
362         }
363
364         // Use the first available render buffer
365         m_currentBufferIndex = 0;
366         m_previousBufferIndex = -1;
367     }
368
369     return m_buffers[m_currentBufferIndex];
370 }
371
372 void QQnxWindow::scroll(const QRegion &region, int dx, int dy, bool flush)
373 {
374     qWindowDebug() << Q_FUNC_INFO << "window =" << window();
375     copyBack(region, dx, dy, flush);
376     m_scrolled += region;
377 }
378
379 void QQnxWindow::post(const QRegion &dirty)
380 {
381     // Check if render buffer exists and something was rendered
382     if (m_currentBufferIndex != -1 && !dirty.isEmpty()) {
383         qWindowDebug() << Q_FUNC_INFO << "window =" << window();
384         QQnxBuffer &currentBuffer = m_buffers[m_currentBufferIndex];
385
386         // Copy unmodified region from old render buffer to new render buffer;
387         // required to allow partial updates
388         QRegion preserve = m_previousDirty - dirty - m_scrolled;
389         copyBack(preserve, 0, 0);
390
391         // Calculate region that changed
392         QRegion modified = preserve + dirty + m_scrolled;
393         QRect rect = modified.boundingRect();
394         int dirtyRect[4] = { rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height() };
395
396         // Update the display with contents of render buffer
397         errno = 0;
398         int result = screen_post_window(m_window, currentBuffer.nativeBuffer(), 1, dirtyRect, 0);
399         if (result != 0) {
400             qFatal("QQnxWindow: failed to post window buffer, errno=%d", errno);
401         }
402
403         // Advance to next nender buffer
404         m_previousBufferIndex = m_currentBufferIndex++;
405         if (m_currentBufferIndex >= MAX_BUFFER_COUNT) {
406             m_currentBufferIndex = 0;
407         }
408
409         // Save modified region and clear scrolled region
410         m_previousDirty = dirty;
411         m_scrolled = QRegion();
412
413         // Notify screen that window posted
414         if (m_screen != 0) {
415             m_screen->onWindowPost(this);
416         }
417     }
418 }
419
420 void QQnxWindow::setScreen(QQnxScreen *platformScreen)
421 {
422     qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "platformScreen =" << platformScreen;
423
424     if (m_screen == platformScreen)
425         return;
426
427     if (m_screen)
428         m_screen->removeWindow(this);
429     platformScreen->addWindow(this);
430     m_screen = platformScreen;
431
432     // Move window to proper screen/display
433     errno = 0;
434     screen_display_t display = platformScreen->nativeDisplay();
435     int result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display);
436     if (result != 0) {
437         qFatal("QQnxWindow: failed to set window display, errno=%d", errno);
438     }
439
440     // Add window to display's window group
441     errno = 0;
442     result = screen_join_window_group(m_window, platformScreen->windowGroupName());
443     if (result != 0) {
444         qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
445     }
446
447     Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
448         // Only subwindows and tooltips need necessarily be moved to another display with the window.
449         if ((window()->windowType() & Qt::WindowType_Mask) == Qt::SubWindow ||
450             (window()->windowType() & Qt::WindowType_Mask) == Qt::ToolTip)
451             childWindow->setScreen(platformScreen);
452     }
453
454     m_screen->updateHierarchy();
455 }
456
457 void QQnxWindow::removeFromParent()
458 {
459     qWindowDebug() << Q_FUNC_INFO << "window =" << window();
460     // Remove from old Hierarchy position
461     if (m_parentWindow) {
462         if (m_parentWindow->m_childWindows.removeAll(this))
463             m_parentWindow = 0;
464         else
465             qFatal("QQnxWindow: Window Hierarchy broken; window has parent, but parent hasn't got child.");
466     } else {
467         m_screen->removeWindow(this);
468     }
469 }
470
471 void QQnxWindow::setParent(const QPlatformWindow *window)
472 {
473     qWindowDebug() << Q_FUNC_INFO << "window =" << this->window() << "platformWindow =" << window;
474     // Cast away the const, we need to modify the hierarchy.
475     QQnxWindow *newParent = 0;
476
477     if (window)
478         newParent = static_cast<QQnxWindow*>((QPlatformWindow *)window);
479
480     if (newParent == m_parentWindow)
481         return;
482
483     removeFromParent();
484     m_parentWindow = newParent;
485
486     // Add to new hierarchy position.
487     if (m_parentWindow) {
488         if (m_parentWindow->m_screen != m_screen)
489             setScreen(m_parentWindow->m_screen);
490
491         m_parentWindow->m_childWindows.push_back(this);
492     } else {
493         m_screen->addWindow(this);
494     }
495
496     m_screen->updateHierarchy();
497 }
498
499 void QQnxWindow::raise()
500 {
501     qWindowDebug() << Q_FUNC_INFO << "window =" << window();
502
503     QQnxWindow *oldParent = m_parentWindow;
504     if (oldParent) {
505         removeFromParent();
506         oldParent->m_childWindows.push_back(this);
507     } else {
508         m_screen->raiseWindow(this);
509     }
510
511     m_screen->updateHierarchy();
512 }
513
514 void QQnxWindow::lower()
515 {
516     qWindowDebug() << Q_FUNC_INFO << "window =" << window();
517
518     QQnxWindow *oldParent = m_parentWindow;
519     if (oldParent) {
520         removeFromParent();
521         oldParent->m_childWindows.push_front(this);
522     } else {
523         m_screen->lowerWindow(this);
524     }
525
526     m_screen->updateHierarchy();
527 }
528
529 void QQnxWindow::requestActivateWindow()
530 {
531     qWindowDebug() << Q_FUNC_INFO << "window =" << window();
532
533     // TODO: Tell screen to set keyboard focus to this window.
534
535     // Notify that we gained focus.
536     gainedFocus();
537 }
538
539
540 Qt::WindowState QQnxWindow::setWindowState(Qt::WindowState state)
541 {
542     qWindowDebug() << Q_FUNC_INFO << "state =" << state;
543
544     // Prevent two calls with Qt::WindowFullScreen from changing m_unmaximizedGeometry
545     if (m_windowState == state)
546         return state;
547
548     switch (state) {
549
550     // WindowMinimized is not supported - navigator does not have an API to minimize a window
551     // WindowActive is not an accepted parameter according to the docs
552     case Qt::WindowMinimized:
553     case Qt::WindowActive:
554         return m_windowState;
555
556     case Qt::WindowMaximized:
557     case Qt::WindowFullScreen:
558         m_unmaximizedGeometry = geometry();
559         setGeometry(state == Qt::WindowMaximized ? m_screen->availableGeometry() : m_screen->geometry());
560         break;
561
562     case Qt::WindowNoState:
563         if (m_unmaximizedGeometry.isValid())
564             setGeometry(m_unmaximizedGeometry);
565         break;
566     }
567
568     m_windowState = state;
569     return state;
570 }
571
572 void QQnxWindow::gainedFocus()
573 {
574     qWindowDebug() << Q_FUNC_INFO << "window =" << window();
575
576     // Got focus
577     QWindowSystemInterface::handleWindowActivated(window());
578 }
579
580 #ifndef QT_NO_OPENGL
581 void QQnxWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext)
582 {
583     // This function does not take ownership of the platform gl context.
584     // It is owned by the frontend QOpenGLContext
585     m_platformOpenGLContext = platformOpenGLContext;
586 }
587 #endif
588
589 QQnxWindow *QQnxWindow::findWindow(screen_window_t windowHandle)
590 {
591     if (m_window == windowHandle)
592         return this;
593
594     Q_FOREACH (QQnxWindow *window, m_childWindows) {
595         QQnxWindow * const result = window->findWindow(windowHandle);
596         if (result)
597             return result;
598     }
599
600     return 0;
601 }
602
603 void QQnxWindow::updateZorder(int &topZorder)
604 {
605     errno = 0;
606     int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ZORDER, &topZorder);
607     topZorder++;
608
609     if (result != 0)
610         qFatal("QQnxWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, m_window);
611
612     Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
613         childWindow->updateZorder(topZorder);
614 }
615
616 void QQnxWindow::copyBack(const QRegion &region, int dx, int dy, bool flush)
617 {
618     qWindowDebug() << Q_FUNC_INFO << "window =" << window();
619     int result;
620
621     // Abort if previous buffer is invalid
622     if (m_previousBufferIndex == -1) {
623         return;
624     }
625
626     // Abort if nothing to copy
627     if (region.isEmpty()) {
628         return;
629     }
630
631     QQnxBuffer &currentBuffer = m_buffers[m_currentBufferIndex];
632     QQnxBuffer &previousBuffer = m_buffers[m_previousBufferIndex];
633
634     // Break down region into non-overlapping rectangles
635     QVector<QRect> rects = region.rects();
636     for (int i = rects.size() - 1; i >= 0; i--) {
637         // Clip rectangle to bounds of target
638         QRect rect = rects[i].intersected( currentBuffer.rect() );
639
640         if (rect.isEmpty())
641             continue;
642
643         // Setup blit operation
644         int attribs[] = { SCREEN_BLIT_SOURCE_X, rect.x(),
645                           SCREEN_BLIT_SOURCE_Y, rect.y(),
646                           SCREEN_BLIT_SOURCE_WIDTH, rect.width(),
647                           SCREEN_BLIT_SOURCE_HEIGHT, rect.height(),
648                           SCREEN_BLIT_DESTINATION_X, rect.x() + dx,
649                           SCREEN_BLIT_DESTINATION_Y, rect.y() + dy,
650                           SCREEN_BLIT_DESTINATION_WIDTH, rect.width(),
651                           SCREEN_BLIT_DESTINATION_HEIGHT, rect.height(),
652                           SCREEN_BLIT_END };
653
654         // Queue blit operation
655         errno = 0;
656         result = screen_blit(m_screenContext, currentBuffer.nativeBuffer(), previousBuffer.nativeBuffer(), attribs);
657         if (result != 0) {
658             qFatal("QQnxWindow: failed to blit buffers, errno=%d", errno);
659         }
660     }
661
662     // Check if flush requested
663     if (flush) {
664         // Wait for all blits to complete
665         errno = 0;
666         result = screen_flush_blits(m_screenContext, SCREEN_WAIT_IDLE);
667         if (result != 0) {
668             qFatal("QQnxWindow: failed to flush blits, errno=%d", errno);
669         }
670
671         // Buffer was modified outside the CPU
672         currentBuffer.invalidateInCache();
673     }
674 }
675
676 int QQnxWindow::platformWindowFormatToNativeFormat(const QSurfaceFormat &format)
677 {
678     qWindowDebug() << Q_FUNC_INFO;
679     // Extract size of colour channels from window format
680     int redSize = format.redBufferSize();
681     if (redSize == -1) {
682         qFatal("QQnxWindow: red size not defined");
683     }
684
685     int greenSize = format.greenBufferSize();
686     if (greenSize == -1) {
687         qFatal("QQnxWindow: green size not defined");
688     }
689
690     int blueSize = format.blueBufferSize();
691     if (blueSize == -1) {
692         qFatal("QQnxWindow: blue size not defined");
693     }
694
695     // select matching native format
696     if (redSize == 5 && greenSize == 6 && blueSize == 5) {
697         return SCREEN_FORMAT_RGB565;
698     } else if (redSize == 8 && greenSize == 8 && blueSize == 8) {
699         return SCREEN_FORMAT_RGBA8888;
700     } else {
701         qFatal("QQnxWindow: unsupported pixel format");
702         return 0;
703     }
704 }
705
706 QT_END_NAMESPACE