Changeset 112


Ignore:
Timestamp:
Aug 14, 2009, 5:13:16 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: Paint event translation.

Location:
trunk/src/gui/kernel
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/gui/kernel/qapplication_pm.cpp

    r109 r112  
    127127#endif
    128128    bool        translatePaintEvent(const QMSG &qmsg);
    129 //  bool        translateConfigEvent(const QMSG &msg);
     129    bool        translateConfigEvent(const QMSG &qmsg);
    130130    bool        translateCloseEvent(const QMSG &qmsg);
    131131//  void        repolishStyle(QStyle &style);
     
    556556        } else {
    557557            switch(msg) {
     558
     559            case WM_PAINT: { // paint event
     560                if (widget->translatePaintEvent(qmsg))
     561                    return (MRESULT)TRUE;
     562                break;
     563            }
     564
     565            case WM_ERASEBACKGROUND: { // erase window background
     566                // flush WM_PAINT messages here to update window contents
     567                // instantly while tracking the resize frame (normally these
     568                // messages are delivered after the user has stopped resizing
     569                // for some time). this slows down resizing slightly but gives a
     570                // better look (no invalid window contents can be seen during
     571                // resize). the alternative could be to erase the background only,
     572                // but we need to do it for every non-toplevel window, which can
     573                // also be time-consuming (WM_ERASEBACKGROUND is sent to WC_FRAME
     574                // clients only, so we would have to do all calculations ourselves).
     575                WinUpdateWindow(widget->effectiveWinId());
     576                return FALSE;
     577            }
     578
     579            case WM_CALCVALIDRECTS: {
     580                // we must always return this value here to cause PM to reposition
     581                // our children accordingly (othwerwise we would have to do it
     582                // ourselves to keep them top-left aligned).
     583                return (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
     584            }
     585
     586            case WM_MOVE:   // move window
     587            case WM_SIZE: { // resize window
     588                if (widget->translateConfigEvent(qmsg))
     589                    return (MRESULT)TRUE;
     590                break;
     591            }
    558592
    559593            case WM_SHOW: {
     
    14001434
    14011435//
     1436// Paint event translation
     1437//
     1438bool QETWidget::translatePaintEvent(const QMSG &qmsg)
     1439{
     1440    if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
     1441        Q_ASSERT(internalWinId());
     1442
     1443    HPS displayPS = qt_display_ps();
     1444
     1445    // Since we don't use WS_CLIPSIBLINGS and WS_CLIPCHILDREN bits (see
     1446    // qwidget_pm.cpp), we have to validate areas that intersect with our
     1447    // children and siblings, taking their clip regions into account.
     1448//    validateObstacles();
     1449
     1450    Q_ASSERT(testAttribute(Qt::WA_WState_Created));
     1451
     1452    HRGN hrgn = GpiCreateRegion(displayPS, 0, NULL);
     1453    LONG rc = WinQueryUpdateRegion(internalWinId(), hrgn);
     1454    if (rc == RGN_ERROR) { // The update bounding rect is invalid
     1455        GpiDestroyRegion(displayPS, hrgn);
     1456        d_func()->hd = NULLHANDLE;
     1457        setAttribute(Qt::WA_PendingUpdate, false);
     1458        return false;
     1459    }
     1460
     1461    setAttribute(Qt::WA_PendingUpdate, false);
     1462
     1463    // @todo not sure we need it
     1464//  const QRegion dirtyInBackingStore(qt_dirtyRegion(this));
     1465//  // Make sure the invalidated region contains the region we're about to repaint.
     1466//  // BeginPaint will set the clip to the invalidated region and it is impossible
     1467//  // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient
     1468//  // as it may return an invalid context (especially on Windows Vista).
     1469//  if (!dirtyInBackingStore.isEmpty())
     1470//      InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false);
     1471
     1472    RECTL rcl;
     1473    d_func()->hd = WinBeginPaint(internalWinId(), 0, &rcl);
     1474
     1475    // it's possible that the update rectangle is empty
     1476    if (rcl.xRight <= rcl.xLeft || rcl.yTop <= rcl.yBottom) {
     1477        WinEndPaint(d_func()->hd);
     1478        GpiDestroyRegion(displayPS, hrgn);
     1479        d_func()->hd = NULLHANDLE;
     1480        setAttribute(Qt::WA_PendingUpdate, false);
     1481        return true;
     1482    }
     1483
     1484    if (WinQueryClipRegion( internalWinId(), 0) != QCRGN_NO_CLIP_REGION) {
     1485        // Correct the update region by intersecting it with the clip
     1486        // region (PM doesn't do that itself). It is necessary
     1487        // to have a correct QRegion in QPaintEvent.
     1488        HRGN hcrgn = GpiCreateRegion(displayPS, 0, NULL);
     1489        WinQueryClipRegion(internalWinId(), hcrgn);
     1490        GpiCombineRegion(displayPS, hrgn, hrgn, hcrgn, CRGN_AND);
     1491        GpiDestroyRegion(displayPS, hcrgn);
     1492    }
     1493
     1494    // flip y coordinate
     1495    rcl.yBottom = height() - (rcl.yBottom + 1);
     1496    rcl.yTop = height() - (rcl.yTop + 1);
     1497
     1498    const QRect updateRect(QPoint(rcl.xLeft, rcl.yBottom),
     1499                           QPoint(rcl.xRight, rcl.yTop));
     1500
     1501    // Mapping region from system to qt (32 bit) coordinate system.
     1502    // @todo use hrgn here once we implement QRegion<->HRGN relationship
     1503    d_func()->syncBackingStore(updateRect.translated(data->wrect.topLeft()));
     1504
     1505    WinEndPaint(d_func()->hd);
     1506    d_func()->hd = NULLHANDLE;
     1507
     1508    return true;
     1509}
     1510
     1511//
     1512// Window move and resize (configure) events
     1513//
     1514
     1515bool QETWidget::translateConfigEvent(const QMSG &qmsg)
     1516{
     1517    // @todo implement
     1518    return false;
     1519}
     1520
     1521//
    14021522// Close window event translation.
    14031523//
  • TabularUnified trunk/src/gui/kernel/qwidget.cpp

    r95 r112  
    184184        ,isScrolled(0)
    185185        ,isMoved(0)
    186 #ifdef Q_WS_WIN
     186#if defined(Q_WS_WIN) || defined(Q_WS_PM)
    187187        ,noPaintOnScreen(0)
    188188#endif
     
    96759675               "QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute");
    96769676
    9677 #ifdef Q_WS_WIN
     9677#if defined(Q_WS_WIN) || defined(Q_WS_PM)
    96789678    if (attribute == Qt::WA_PaintOnScreen && on) {
    9679         // see qwidget_win.cpp, ::paintEngine for details
     9679        // see qwidget_[win|pm].cpp, ::paintEngine for details
    96809680        paintEngine();
    96819681        if (d->noPaintOnScreen)
  • TabularUnified trunk/src/gui/kernel/qwidget_p.h

    r100 r112  
    551551    uint isMoved : 1;
    552552
    553 #ifdef Q_WS_WIN
    554     uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine()
     553#if defined(Q_WS_WIN) || defined(Q_WS_PM)
     554    uint noPaintOnScreen : 1; // see qwidget_[win|pm].cpp ::paintEngine()
    555555#endif
    556556
  • TabularUnified trunk/src/gui/kernel/qwidget_pm.cpp

    r110 r112  
    14671467    fs.setCoords(cswp.x, cswp.y, swp.cx - cswp.x - cswp.cx,
    14681468                                 swp.cy - cswp.y - cswp.cy);
    1469     // @todo need this??
     1469    // @todo do we really need to update crect here??
    14701470    //data.crect.setRect(swp.x + cswp.x, swp.y + cswp.y, cswp.cx, cswp.cy);
    14711471
     
    14801480QPaintEngine *QWidget::paintEngine() const
    14811481{
    1482     // @todo implement
     1482    // @todo this is a place to return some direct on-screen PaintEngine once
     1483    // we decide to support it
     1484
     1485    // We set this bit which is checked in setAttribute for
     1486    // Qt::WA_PaintOnScreen. We do this to allow these two scenarios:
     1487    //
     1488    // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to
     1489    // OS/2 which would mean suddenly their widgets stop working.
     1490    //
     1491    // 2. Users set paint on screen and subclass paintEngine() to
     1492    // return 0, in which case we have a "hole" in the backingstore
     1493    // allowing use of GPI directly.
     1494    //
     1495    // 1 is WRONG, but to minimize silent failures, we have set this
     1496    // bit to ignore the setAttribute call. 2. needs to be
     1497    // supported because its our only means of embeddeding native
     1498    // graphics stuff.
     1499    const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1;
     1500
    14831501    return 0;
    14841502}
Note: See TracChangeset for help on using the changeset viewer.