132 { |
130 { |
133 IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer(); |
131 IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer(); |
134 if (!layer) |
132 if (!layer) |
135 qFatal("QDirectFBWindowSurface: Unable to get primary display layer!"); |
133 qFatal("QDirectFBWindowSurface: Unable to get primary display layer!"); |
136 |
134 |
|
135 updateIsOpaque(); |
|
136 |
137 DFBWindowDescription description; |
137 DFBWindowDescription description; |
138 memset(&description, 0, sizeof(DFBWindowDescription)); |
138 memset(&description, 0, sizeof(DFBWindowDescription)); |
139 |
139 |
|
140 description.flags = DWDESC_CAPS|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT; |
140 description.caps = DWCAPS_NODECORATION; |
141 description.caps = DWCAPS_NODECORATION; |
141 description.flags = DWDESC_CAPS|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY; |
142 description.surface_caps = DSCAPS_NONE; |
142 #if (Q_DIRECTFB_VERSION >= 0x010200) |
143 imageFormat = screen->pixelFormat(); |
143 description.flags |= DWDESC_OPTIONS; |
144 |
144 #endif |
145 if (!(surfaceFlags() & Opaque)) { |
145 |
146 imageFormat = screen->alphaPixmapFormat(); |
146 if (noSystemBackground) { |
|
147 description.caps |= DWCAPS_ALPHACHANNEL; |
147 description.caps |= DWCAPS_ALPHACHANNEL; |
148 #if (Q_DIRECTFB_VERSION >= 0x010200) |
148 #if (Q_DIRECTFB_VERSION >= 0x010200) |
|
149 description.flags |= DWDESC_OPTIONS; |
149 description.options |= DWOP_ALPHACHANNEL; |
150 description.options |= DWOP_ALPHACHANNEL; |
150 #endif |
151 #endif |
151 } |
152 } |
152 |
153 description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(imageFormat); |
153 description.posx = rect.x(); |
154 description.posx = rect.x(); |
154 description.posy = rect.y(); |
155 description.posy = rect.y(); |
155 description.width = rect.width(); |
156 description.width = rect.width(); |
156 description.height = rect.height(); |
157 description.height = rect.height(); |
157 description.surface_caps = DSCAPS_NONE; |
158 |
|
159 if (QDirectFBScreen::isPremultiplied(imageFormat)) |
|
160 description.surface_caps = DSCAPS_PREMULTIPLIED; |
|
161 |
158 if (screen->directFBFlags() & QDirectFBScreen::VideoOnly) |
162 if (screen->directFBFlags() & QDirectFBScreen::VideoOnly) |
159 description.surface_caps |= DSCAPS_VIDEOONLY; |
163 description.surface_caps |= DSCAPS_VIDEOONLY; |
160 const QImage::Format format = (noSystemBackground ? screen->alphaPixmapFormat() : screen->pixelFormat()); |
|
161 description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format); |
|
162 if (QDirectFBScreen::isPremultiplied(format)) |
|
163 description.surface_caps = DSCAPS_PREMULTIPLIED; |
|
164 |
164 |
165 DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow); |
165 DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow); |
166 |
166 |
167 if (result != DFB_OK) |
167 if (result != DFB_OK) |
168 DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result); |
168 DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result); |
265 rect.width(), rect.height() }; |
264 rect.width(), rect.height() }; |
266 result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); |
265 result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); |
267 } |
266 } |
268 } else { // mode == Offscreen |
267 } else { // mode == Offscreen |
269 if (!dfbSurface) { |
268 if (!dfbSurface) { |
270 dfbSurface = screen->createDFBSurface(rect.size(), screen->pixelFormat(), QDirectFBScreen::DontTrackSurface); |
269 dfbSurface = screen->createDFBSurface(rect.size(), surfaceFlags() & Opaque ? screen->pixelFormat() : screen->alphaPixmapFormat(), |
|
270 QDirectFBScreen::DontTrackSurface); |
271 } |
271 } |
272 } |
272 } |
273 if (result != DFB_OK) |
273 if (result != DFB_OK) |
274 DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result); |
274 DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result); |
275 #endif |
275 #endif |
276 } |
276 } |
277 if (oldSurface != dfbSurface) |
277 if (oldSurface != dfbSurface) { |
278 updateFormat(); |
278 imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid; |
|
279 } |
279 |
280 |
280 if (oldRect.size() != rect.size()) { |
281 if (oldRect.size() != rect.size()) { |
281 QWSWindowSurface::setGeometry(rect); |
282 QWSWindowSurface::setGeometry(rect); |
282 } else { |
283 } else { |
283 QWindowSurface::setGeometry(rect); |
284 QWindowSurface::setGeometry(rect); |
294 void QDirectFBWindowSurface::setPermanentState(const QByteArray &state) |
295 void QDirectFBWindowSurface::setPermanentState(const QByteArray &state) |
295 { |
296 { |
296 if (state.size() == sizeof(this)) { |
297 if (state.size() == sizeof(this)) { |
297 sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData()); |
298 sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData()); |
298 Q_ASSERT(sibling); |
299 Q_ASSERT(sibling); |
299 sibling->setSurfaceFlags(surfaceFlags()); |
300 setSurfaceFlags(sibling->surfaceFlags()); |
300 } |
301 } |
301 } |
302 } |
302 |
303 |
303 static inline void scrollSurface(IDirectFBSurface *surface, const QRect &r, int dx, int dy) |
304 bool QDirectFBWindowSurface::scroll(const QRegion ®ion, int dx, int dy) |
304 { |
305 { |
|
306 if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.rectCount() != 1) |
|
307 return false; |
|
308 if (flushPending) { |
|
309 dfbSurface->Flip(dfbSurface, 0, DSFLIP_BLIT); |
|
310 } else { |
|
311 flushPending = true; |
|
312 } |
|
313 dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); |
|
314 const QRect r = region.boundingRect(); |
305 const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() }; |
315 const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() }; |
306 surface->Blit(surface, surface, &rect, r.x() + dx, r.y() + dy); |
316 dfbSurface->Blit(dfbSurface, dfbSurface, &rect, r.x() + dx, r.y() + dy); |
307 const DFBRegion region = { rect.x + dx, rect.y + dy, r.right() + dx, r.bottom() + dy }; |
|
308 surface->Flip(surface, ®ion, DSFLIP_BLIT); |
|
309 } |
|
310 |
|
311 bool QDirectFBWindowSurface::scroll(const QRegion ®ion, int dx, int dy) |
|
312 { |
|
313 if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.isEmpty()) |
|
314 return false; |
|
315 dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); |
|
316 if (region.rectCount() == 1) { |
|
317 scrollSurface(dfbSurface, region.boundingRect(), dx, dy); |
|
318 } else { |
|
319 const QVector<QRect> rects = region.rects(); |
|
320 const int n = rects.size(); |
|
321 for (int i=0; i<n; ++i) { |
|
322 scrollSurface(dfbSurface, rects.at(i), dx, dy); |
|
323 } |
|
324 } |
|
325 return true; |
317 return true; |
326 } |
318 } |
327 |
319 |
328 bool QDirectFBWindowSurface::move(const QPoint &moveBy) |
320 bool QDirectFBWindowSurface::move(const QPoint &moveBy) |
329 { |
321 { |
357 return; |
349 return; |
358 |
350 |
359 const quint8 windowOpacity = quint8(win->windowOpacity() * 0xff); |
351 const quint8 windowOpacity = quint8(win->windowOpacity() * 0xff); |
360 const QRect windowGeometry = geometry(); |
352 const QRect windowGeometry = geometry(); |
361 #ifdef QT_DIRECTFB_WM |
353 #ifdef QT_DIRECTFB_WM |
362 const bool wasNoSystemBackground = noSystemBackground; |
|
363 noSystemBackground = win->testAttribute(Qt::WA_NoSystemBackground); |
|
364 quint8 currentOpacity; |
354 quint8 currentOpacity; |
365 Q_ASSERT(dfbWindow); |
355 Q_ASSERT(dfbWindow); |
366 dfbWindow->GetOpacity(dfbWindow, ¤tOpacity); |
356 dfbWindow->GetOpacity(dfbWindow, ¤tOpacity); |
367 if (currentOpacity != windowOpacity) { |
357 if (currentOpacity != windowOpacity) { |
368 dfbWindow->SetOpacity(dfbWindow, windowOpacity); |
358 dfbWindow->SetOpacity(dfbWindow, windowOpacity); |
369 } |
359 } |
370 |
360 |
371 setOpaque(noSystemBackground || windowOpacity != 0xff); |
|
372 if (wasNoSystemBackground != noSystemBackground) { |
|
373 releaseSurface(); |
|
374 dfbWindow->Release(dfbWindow); |
|
375 dfbWindow = 0; |
|
376 createWindow(windowGeometry); |
|
377 win->update(); |
|
378 return; |
|
379 } |
|
380 screen->flipSurface(dfbSurface, flipFlags, region, offset); |
361 screen->flipSurface(dfbSurface, flipFlags, region, offset); |
381 #else |
362 #else |
382 setOpaque(windowOpacity != 0xff); |
363 setOpaque(windowOpacity == 0xff); |
383 if (mode == Offscreen) { |
364 if (mode == Offscreen) { |
384 screen->exposeRegion(region.translated(offset + geometry().topLeft()), 0); |
365 screen->exposeRegion(region.translated(offset + geometry().topLeft()), 0); |
385 } else { |
366 } else { |
386 screen->flipSurface(dfbSurface, flipFlags, region, offset); |
367 screen->flipSurface(dfbSurface, flipFlags, region, offset); |
387 } |
368 } |
463 dfbSurface->Release(dfbSurface); |
441 dfbSurface->Release(dfbSurface); |
464 dfbSurface = 0; |
442 dfbSurface = 0; |
465 } |
443 } |
466 } |
444 } |
467 |
445 |
|
446 void QDirectFBWindowSurface::updateIsOpaque() |
|
447 { |
|
448 const QWidget *win = window(); |
|
449 Q_ASSERT(win); |
|
450 if (win->testAttribute(Qt::WA_OpaquePaintEvent) || win->testAttribute(Qt::WA_PaintOnScreen)) { |
|
451 setOpaque(true); |
|
452 return; |
|
453 } |
|
454 |
|
455 if (qFuzzyCompare(static_cast<float>(win->windowOpacity()), 1.0f)) { |
|
456 const QPalette &pal = win->palette(); |
|
457 |
|
458 if (win->autoFillBackground()) { |
|
459 const QBrush &autoFillBrush = pal.brush(win->backgroundRole()); |
|
460 if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) { |
|
461 setOpaque(true); |
|
462 return; |
|
463 } |
|
464 } |
|
465 |
|
466 if (win->isWindow() && !win->testAttribute(Qt::WA_NoSystemBackground)) { |
|
467 const QBrush &windowBrush = win->palette().brush(QPalette::Window); |
|
468 if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) { |
|
469 setOpaque(true); |
|
470 return; |
|
471 } |
|
472 } |
|
473 } |
|
474 setOpaque(false); |
|
475 } |
468 |
476 |
469 QT_END_NAMESPACE |
477 QT_END_NAMESPACE |
470 |
478 |
471 #endif // QT_NO_QWS_DIRECTFB |
479 #endif // QT_NO_QWS_DIRECTFB |
472 |
|
473 |
|