📄 qscreen_qws.cpp
字号:
driver.truncate(colon); driver = driver.trimmed(); bool foundDriver = false; QString driverName = driver; QStringList driverList; if (!driver.isEmpty()) driverList << driver; else driverList = QScreenDriverFactory::keys(); for (int i = 0; i < driverList.size(); ++i) { const QString driverName = driverList.at(i); qt_screen = QScreenDriverFactory::create(driverName, display_id); if (qt_screen) { foundDriver = true; if (qt_screen->connect(displaySpec)) { return qt_screen; } else { delete qt_screen; qt_screen = 0; } } } if (driver.isNull()) qFatal("No suitable driver found"); else if (foundDriver) qFatal("%s: driver cannot connect", driver.toLatin1().constData()); else qFatal("%s: driver not found", driver.toLatin1().constData()); return 0;}/*! \fn void QScreen::exposeRegion(QRegion region, int windowIndex) This function is called by the \l {Qtopia Core} server whenever a screen update is required. \a region is the area on the screen that must be updated, and \a windowIndex is the index into QWSServer::clientWindows() of the window that required the update. QWSWindow::state() gives more information about the cause. The default implementation composes the affected windows and paints the given \a region on screen by calling the blit() and solidFill() functions This function can be reimplemented to perform composition in hardware, or to perform transition effects. For simpler hardware acceleration, or to interface with this is typically done by reimplementing the blit() and solidFill() functions instead. Note that there is no need to call this function explicitly. \sa blit(), solidFill(), blank()*/void QScreen::exposeRegion(QRegion r, int windowIndex){ r &= region(); if (r.isEmpty()) return; int changing = windowIndex; // when we have just lowered a window, we have to expose all the windows below where the // window used to be. if (changing && qwsServer->clientWindows().at(changing)->state() == QWSWindow::Lowering) changing = 0;#ifdef QTOPIA_PERFTEST static enum { PerfTestUnknown, PerfTestOn, PerfTestOff } perfTestState = PerfTestUnknown; if(PerfTestUnknown == perfTestState) { if(::getenv("QTOPIA_PERFTEST")) perfTestState = PerfTestOn; else perfTestState = PerfTestOff; } if(PerfTestOn == perfTestState) { QWSWindow *changed = qwsServer->clientWindows().at(changing); if(!changed->client()->identity().isEmpty()) qDebug() << "Performance : expose_region :" << changed->client()->identity() << r.boundingRect() << ": " << qPrintable( QTime::currentTime().toString( "h:mm:ss.zzz" ) ); }#endif const QRect bounds = r.boundingRect(); QRegion blendRegion; QImage blendBuffer;#ifndef QT_NO_QWS_CURSOR if (qt_screencursor && !qt_screencursor->isAccelerated()) { blendRegion = r & qt_screencursor->boundingRect(); }#endif compose(0, r, blendRegion, blendBuffer, changing);#ifdef QT_EXPERIMENTAL_REGIONS if (!blendBuffer.isNull()) { const QPoint offset = blendRegion.boundingRect().topLeft();#ifndef QT_NO_QWS_CURSOR if (qt_screencursor && !qt_screencursor->isAccelerated()) { const QRect cursorRect = qt_screencursor->boundingRect(); if (blendRegion.intersects(cursorRect)) { //### can be optimized... QPainter p(&blendBuffer); p.drawImage(cursorRect.topLeft() - offset, qt_screencursor->image()); } }#endif // QT_NO_QWS_CURSOR blit(blendBuffer, offset, blendRegion); }#else#ifndef QT_NO_QWS_CURSOR if (qt_screencursor && !qt_screencursor->isAccelerated() && !blendBuffer.isNull()) { //### can be optimized... QPainter p(&blendBuffer); p.drawImage(qt_screencursor->boundingRect().topLeft() - blendRegion.boundingRect().topLeft(), qt_screencursor->image()); }#endif if (!blendBuffer.isNull()) { //bltToScreen QPoint topLeft = blendRegion.boundingRect().topLeft(); blit(blendBuffer, topLeft, blendRegion); }#endif // QT_EXPERIMENTAL_REGIONS const QVector<QRect> rects = r.rects(); for (int i = 0; i < rects.size(); ++i) setDirty(rects.at(i));}/*! \fn void QScreen::blit(const QImage &image, const QPoint &topLeft, const QRegion ®ion) Copies the given \a region in the given \a image to the point specified by \a topLeft using device coordinates. This function is called from the exposeRegion() function; it is not intended to be called explicitly. Reimplement this function to make use of \l {Adding an Accelerated Graphics Driver in Qtopia Core}{accelerated hardware}. Note that this function must be reimplemented if the framebuffer format is not supported by \l {Qtopia Core} (See the \l {Qtopia Core Display Management}{Display Management} documentation for more details). \sa exposeRegion(), solidFill(), blank()*/void QScreen::blit(const QImage &img, const QPoint &topLeft, const QRegion ®){ const QRect bound = (region() & QRect(topLeft, img.size())).boundingRect(); QWSDisplay::grab(); d_ptr->blit(this, img, topLeft - offset(), (reg & bound).translated(-topLeft)); QWSDisplay::ungrab();}/*! \internal*/void QScreen::blit(QWSWindow *win, const QRegion &clip){ QWSWindowSurface *surface = win->windowSurface(); if (!surface) return; const QImage &img = surface->image(); if (img == QImage()) return; const QRegion rgn = clip & win->paintedRegion(); if (rgn.isEmpty()) return; surface->lock(); blit(img, win->requestedRegion().boundingRect().topLeft(), rgn); surface->unlock();}struct fill_data { quint32 color; uchar *data; int lineStep; int x; int y; int w; int h;};/*! Fills the given \a region of the screen with the specified \a color. This function is called from the exposeRegion() function; it is not intended to be called explicitly. Reimplement this function to make use of \l {Adding an Accelerated Graphics Driver in Qtopia Core}{accelerated hardware}. Note that this function must be reimplemented if the framebuffer format is not supported by \l {Qtopia Core} (See the \l {Qtopia Core Display Management}{Display Management} documentation for more details). \sa exposeRegion(), blit(), blank()*/// the base class implementation works in device coordinates, so that transformed drivers can use itvoid QScreen::solidFill(const QColor &color, const QRegion ®ion){ QWSDisplay::grab(); d_ptr->solidFill(this, color, region.translated(-offset()) & QRect(0, 0, dw, dh)); QWSDisplay::ungrab();}/*! \since 4.2 Creates and returns a new window surface matching the given \a key. Possible keys include \e OnScreen for an on-screen surface, \e mem for a surface constructed from local memory, \e shm for a surface constructed from shared memory, \e Yellow for a yellow surface, and \e DirectPainter for a direct painter surface. The server application will call this function whenever it needs to create a server side representation of a window, e.g. when copying the content of memory to the screen using the screen driver. Note that this function must be reimplemented when adding an accelerated graphics driver. See the \l {Adding an Accelerated Graphics Driver in Qtopia Core}{Adding an Accelerated Graphics Driver} documentation for details. \sa {Qtopia Core Architecture}*/QWSWindowSurface* QScreen::createSurface(const QString &key) const{#ifndef QT_NO_PAINTONSCREEN if (key == QLatin1String("OnScreen")) return new QWSOnScreenSurface; else#endif if (key == QLatin1String("mem")) return new QWSLocalMemSurface;#ifndef QT_NO_QWS_MULTIPROCESS else if (key == QLatin1String("shm")) return new QWSSharedMemSurface;#endif#ifndef QT_NO_PAINT_DEBUG else if (key == QLatin1String("Yellow")) return new QWSYellowSurface;#endif#ifndef QT_NO_DIRECTPAINTER else if (key == QLatin1String("DirectPainter")) return new QWSDirectPainterSurface;#endif return 0;}#ifndef QT_NO_PAINTONSCREENbool QScreen::isWidgetPaintOnScreen(const QWidget *w){ static int doOnScreen = -1; if (doOnScreen == -1) { const QByteArray env = qgetenv("QT_ONSCREEN_PAINT"); if (env == "force") doOnScreen = 2; else doOnScreen = (env.toInt() > 0 ? 1 : 0); } if (doOnScreen == 2) // force return true; if (doOnScreen == 0 && !w->testAttribute(Qt::WA_PaintOnScreen)) return false; return w->d_func()->isOpaque();}#endif/*! \overload Creates and returns a new window surface for the given \a widget.*/QWSWindowSurface* QScreen::createSurface(QWidget *widget) const{#ifndef QT_NO_PAINTONSCREEN if (isWidgetPaintOnScreen(widget) && base()) return new QWSOnScreenSurface(widget); else#endif if (QApplication::type() == QApplication::GuiServer) return new QWSLocalMemSurface(widget);#ifndef QT_NO_QWS_MULTIPROCESS else return new QWSSharedMemSurface(widget);#endif return 0;}void QScreen::compose(int level, const QRegion &exposed, QRegion &blend, QImage &blendbuffer, int changing_level){ QRect exposed_bounds = exposed.boundingRect(); QWSWindow *win = 0; do { win = qwsServer->clientWindows().value(level); // null is background ++level; } while (win && !win->paintedRegion().boundingRect().intersects(exposed_bounds)); QWSWindowSurface *surface = (win ? win->windowSurface() : 0); bool above_changing = level <= changing_level; // 0 is topmost QRegion exposedBelow = exposed; bool opaque = true; if (win) { opaque = win->isOpaque() || !surface->isBuffered(); if (opaque) { exposedBelow -= win->paintedRegion(); if (above_changing || !surface->isBuffered()) blend -= exposed & win->paintedRegion(); } else { blend += exposed & win->paintedRegion(); } } if (win && !exposedBelow.isEmpty()) { compose(level, exposedBelow, blend, blendbuffer, changing_level); } else { QSize blendSize = blend.boundingRect().size(); if (!blendSize.isNull()) { blendbuffer = QImage(blendSize, depth() <= 16 ? QImage::Format_RGB16 : QImage::Format_ARGB32_Premultiplied); } } const QRegion blitRegion = exposed - blend; if (!win) paintBackground(blitRegion); else if (!above_changing && surface->isBuffered()) blit(win, blitRegion); QRegion blendRegion = exposed & blend; if (win) blendRegion &= win->paintedRegion(); if (!blendRegion.isEmpty()) { QPoint off = blend.boundingRect().topLeft(); QRasterBuffer rb; rb.prepare(&blendbuffer); QSpanData spanData; spanData.init(&rb); if (!win) { if (blendbuffer.format() == QImage::Format_ARGB32_Premultiplied) spanData.rasterBuffer->compositionMode = QPainter::CompositionMode_Source; spanData.setup(qwsServer->backgroundBrush(), 256); spanData.dx = off.x(); spanData.dy = off.y(); } else if (!surface->isBuffered()) { return; } else { const QImage &img = surface->image(); QPoint winoff = off - win->requestedRegion().boundingRect().topLeft(); // convert win->opacity() from scale [0..255] to [0..256] int const_alpha = win->opacity(); const_alpha += (const_alpha >> 7); spanData.type = QSpanData::Texture; spanData.initTexture(&img, const_alpha); spanData.dx = winoff.x(); spanData.dy = winoff.y(); } if (!spanData.blend) return; if (surface) surface->lock(); const QVector<QRect> rects = blendRegion.rects(); const int nspans = 256; QT_FT_Span spans[nspans]; for (int i = 0; i < rects.size(); ++i) { int y = rects.at(i).y() - off.y(); int ye = y + rects.at(i).height(); int x = rects.at(i).x() - off.x(); int len = rects.at(i).width(); while (y < ye) { int n = qMin(nspans, ye - y); int i = 0; while (i < n) { spans[i].x = x; spans[i].len = len; spans[i].y = y + i; spans[i].coverage = 255; ++i; } spanData.blend(n, spans, &spanData); y += n; } } if (surface) surface->unlock(); }}void QScreen::paintBackground(const QRegion &r){ const QBrush &bg = qwsServer->backgroundBrush(); Qt::BrushStyle bs = bg.style(); if (bs == Qt::NoBrush || r.isEmpty()) return; if (bs == Qt::SolidPattern) { solidFill(bg.color(), r); } else { const QRect br = r.boundingRect(); QImage img(br.size(), d_ptr->preferredImageFormat()); QPoint off = br.topLeft(); QRasterBuffer rb; rb.prepare(&img); QSpanData spanData; spanData.init(&rb); spanData.setup(bg, 256); spanData.dx = off.x(); spanData.dy = off.y(); Q_ASSERT(spanData.blend); const QVector<QRect> rects = r.rects(); const int nspans = 256; QT_FT_Span spans[nspans]; for (int i = 0; i < rects.size(); ++i) { int y = rects.at(i).y() - off.y(); int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -