Changeset 751
- Timestamp:
- Jun 15, 2010, 5:00:46 PM (15 years ago)
- Location:
- trunk/src/gui/painting
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gui/painting/qwindowsurface_pm.cpp
r746 r751 58 58 #include <qt_os2.h> 59 59 #include <qlibrary.h> 60 61 60 62 61 63 #include "qwindowsurface_pm_p.h" … … 323 325 QPMDiveWindowSurfaceFB(QWidget *widget); 324 326 ~QPMDiveWindowSurfaceFB(); 325 void doFlush( const QRect &from, const QPoint &to);327 void doFlush(const QRect &from, const QPoint &to); 326 328 }; 327 329 328 struct QPMDiveWindowSurfacePrivate 329 { 330 struct QPMDiveWindowSurfacePrivate : public QObject, private QWidget::PmEventFilter 331 { 332 QPMDiveWindowSurface *that; 333 330 334 QImage *image; 331 335 HDIVE hDive; … … 333 337 ULONG bufNum; 334 338 bool posDirty; 335 bool vrnDirty;336 339 bool vrnDisabled; 337 340 bool inDrag; 338 int windowHeight;339 341 SETUP_BLITTER setup; 340 QVector<RECTL> rcls;341 342 342 343 struct FlushArgs 343 344 { 345 344 346 QRect from; 345 347 QPoint to; 346 348 }; 347 349 QList<FlushArgs> pending; 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 348 377 }; 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 349 485 350 486 QPMDiveWindowSurface::QPMDiveWindowSurface(QWidget* widget) 351 487 : QWindowSurface(widget), d(new QPMDiveWindowSurfacePrivate) 352 488 { 489 353 490 d->image = 0; 354 491 d->hDive = NULLHANDLE; … … 356 493 d->bufNum = 0; 357 494 d->posDirty = true; 358 d->vrnDirty = true;359 495 d->vrnDisabled = false; 360 496 d->inDrag = false; 361 d-> windowHeight= 0;497 d-> = 0; 362 498 363 499 memset(&d->setup, 0, sizeof(SETUP_BLITTER)); … … 369 505 d->setup.fccDstColorFormat = FOURCC_SCRN; 370 506 371 window()->addPmEventFilter(this);372 WinSetVisibleRegionNotify(window()->winId(), TRUE);507 508 ); 373 509 374 510 setStaticContentsSupport(true); … … 377 513 QPMDiveWindowSurface::~QPMDiveWindowSurface() 378 514 { 379 WinSetVisibleRegionNotify(window()->winId(), FALSE); 380 window()->removePmEventFilter(this); 515 if (d->subWidgets) { 516 foreach(HWND hwnd, d->subWidgets->keys()) 517 d->removeWidget((*d->subWidgets)[hwnd].widget); 518 Q_ASSERT(d->subWidgets->count() == 0); 519 delete d->subWidgets; 520 } 521 522 d->removeWidget(window()); 381 523 382 524 if (d->bufNum) … … 400 542 if (!d->image || rgn.rectCount() == 0) 401 543 return; 544 545 546 547 402 548 403 549 QRect br = rgn.boundingRect(); … … 465 611 if (d->vrnDisabled) { 466 612 // defer the flush 467 QPMDiveWindowSurfacePrivate::FlushArgs args = { br, wbr.topLeft() }; 613 QPMDiveWindowSurfacePrivate::FlushArgs args = { widget, 614 br, wbr.topLeft() }; 468 615 d->pending.append(args); 469 616 return; 470 617 } 471 618 472 doFlush( br, wbr.topLeft());473 } 474 475 bool QPMDiveWindowSurface::adjustSetup( )619 doFlush(br, wbr.topLeft()); 620 } 621 622 bool QPMDiveWindowSurface::adjustSetup() 476 623 { 477 624 HWND hwnd = window()->winId(); … … 481 628 bool setupDirty = false; 482 629 483 if (d->posDirty || d->vrnDirty) { 630 QPMDiveWindowSurfacePrivate::WidgetData *wd = d->widgetData(widget); 631 Q_ASSERT(wd); 632 633 if (d->posDirty || wd->vrnDirty) { 484 634 setupDirty = true; 485 635 d->posDirty = false; 636 486 637 POINTL ptl = { 0, 0 }; 487 638 WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptl, 1); … … 494 645 } 495 646 496 if (d->vrnDirty) { 647 bool wasVrnDirty = wd->vrnDirty; 648 649 if (wd->vrnDirty) { 497 650 setupDirty = true; 498 d->vrnDirty = false;651 d->vrnDirty = false; 499 652 500 653 HPS hps = window()->getPS(); 501 654 HRGN hrgn = GpiCreateRegion(hps, 0L, NULL); 502 655 503 RGNRECT rgnCtl;504 rgnCtl.ircStart = 1;505 rgnCtl.crc = rgnCtl.crcReturned = 0;506 rgnCtl.ulDirection = RECTDIR_LFRT_TOPBOT;507 508 656 ULONG rc = WinQueryVisibleRegion(hwnd, hrgn); 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 509 677 if (rc == RGN_RECT || rc == RGN_COMPLEX) { 678 679 680 681 510 682 if (GpiQueryRegionRects(hps, hrgn, NULL, &rgnCtl, NULL) && 511 683 rgnCtl.crcReturned) { … … 513 685 rgnCtl.crc = rgnCtl.crcReturned; 514 686 rgnCtl.ulDirection = RECTDIR_LFRT_TOPBOT; 515 if (d->rcls.size() < (int)rgnCtl.crc) 516 d->rcls.resize((int)rgnCtl.crc); 517 GpiQueryRegionRects(hps, hrgn, NULL, &rgnCtl, d->rcls.data()); 687 if (wd->rcls.size() < (int)rgnCtl.crc) 688 wd->rcls.resize((int)rgnCtl.crc); 689 wd->rclCount = rgnCtl.crc; 690 GpiQueryRegionRects(hps, hrgn, NULL, &rgnCtl, wd->rcls.data()); 518 691 } 519 } 520 521 d->setup.ulNumDstRects = rgnCtl.crcReturned; 522 d->setup.pVisDstRects = rgnCtl.crcReturned ? d->rcls.data() : NULL; 523 d->setup.ulStructLen = sizeof(SETUP_BLITTER); 692 } else if (rc == RGN_NULL) { 693 wd->rclCount = 0; 694 } 524 695 525 696 GpiDestroyRegion(hps, hrgn); … … 528 699 // memorize the window height used for the additional visible region 529 700 // validation in doFlush() 530 d->windowHeight = window()->height();701 ->height(); 531 702 532 703 #if defined(QDIVE_DEBUG) 533 704 DEBUG(() << "QPMDiveWindowSurface::adjustSetup:" << "vrnDirty"); 534 for (size_t i = 0; i < d->setup.ulNumDstRects; ++i)535 DEBUG(() << " " << i << ":" << d->setup.pVisDstRects[i]);705 for (size_t i = 0; i < ; ++i) 706 DEBUG(() << " " << i << ":" << s[i]); 536 707 #endif 537 708 } 538 709 710 711 712 713 714 715 716 717 718 719 720 539 721 return setupDirty; 540 722 } 541 723 542 void QPMDiveWindowSurface::doFlush( const QRect &from, const QPoint &to)543 { 544 DEBUG(() << "QPMDiveWindowSurface::doFlush:" << window() 724 void QPMDiveWindowSurface::doFlush(const QRect &from, const QPoint &to) 725 { 726 DEBUG(() << "QPMDiveWindowSurface::doFlush:" << window() 545 727 << "from" << from << "to" << to); 546 728 … … 550 732 QPoint dst = to + (src.topLeft() - from.topLeft()); 551 733 552 bool setupDirty = adjustSetup( );734 bool setupDirty = adjustSetup(); 553 735 554 736 // note that the source image is expected to be top-left oriented … … 578 760 579 761 DiveBlitImage(d->hDive, d->bufNum, DIVE_BUFFER_SCREEN); 580 }581 582 bool QPMDiveWindowSurface::pmEventFilter(QMSG *msg, MRESULT *result)583 {584 switch (msg->msg) {585 case WM_VRNDISABLED: {586 if (!d->useFB)587 DiveSetupBlitter(d->hDive, NULL);588 d->vrnDisabled = true;589 *result = 0;590 return true;591 }592 case DM_DRAGOVER: {593 d->inDrag = true;594 break;595 }596 case DM_DRAGLEAVE:597 case DM_DROP: {598 d->inDrag = false;599 break;600 }601 case WM_VRNENABLED: {602 d->vrnDisabled = false;603 // Note that when an overlapping window of *other* process is moved604 // over this window, PM still sends WM_VRNENABLED to it but with605 // ffVisRgnChanged set to FALSE although the visible region *does*606 // actually change (it doesn't seem to be the case for windows of607 // the same process). The solution is to ignore this flag and always608 // assume that the visible region was changed when we get this msg609 #if 0610 if (LONGFROMMP(msg->mp1)) // window's visible region changed611 #endif612 d->vrnDirty = true;613 d->posDirty = true;614 615 // process pending flush events616 foreach(const QPMDiveWindowSurfacePrivate::FlushArgs &args, d->pending)617 doFlush(args.from, args.to);618 d->pending.clear();619 620 *result = 0;621 return true;622 }623 default:624 break;625 }626 627 return false;628 762 } 629 763 … … 934 1068 } 935 1069 936 void QPMDiveWindowSurfaceFB::doFlush( const QRect &from, const QPoint &to)937 { 938 DEBUG(() << "QPMDiveWindowSurfaceFB::doFlush:" << window() 1070 void QPMDiveWindowSurfaceFB::doFlush(const QRect &from, const QPoint &to) 1071 { 1072 DEBUG(() << "QPMDiveWindowSurfaceFB::doFlush:" << window() 939 1073 << "from" << from << "to" << to); 940 1074 … … 946 1080 QPoint dstDelta = from.topLeft() - to; 947 1081 948 const int windowHeight = window()->height(); 1082 QPMDiveWindowSurfacePrivate::WidgetData *wd = d->widgetData(widget); 1083 Q_ASSERT(wd); 1084 1085 int widgetHeight = widget->height(); 949 1086 950 1087 // sometimes PM does not send WM_VRNENABLED although the window size has … … 952 1089 // application) which leads to screen corruption due to outdated visible 953 1090 // regions. A fix is to memorize the window height and check it here 954 if (wi ndowHeight != d->windowHeight)955 d->vrnDirty = true;1091 if (wiHeight) 1092 d->vrnDirty = true; 956 1093 957 1094 bool wasPosDirty = d->posDirty; 958 bool wasVrnDirty = d->vrnDirty; 959 960 adjustSetup(); 1095 bool wasVrnDirty = wd->vrnDirty; 1096 1097 adjustSetup(widget); 1098 1099 int windowHeight = window()->height(); 961 1100 962 1101 if (wasVrnDirty) { -
trunk/src/gui/painting/qwindowsurface_pm_p.h
r713 r751 63 63 struct QPMDiveWindowSurfacePrivate; 64 64 65 class QPMDiveWindowSurface : public QWindowSurface , private QWidget::PmEventFilter65 class QPMDiveWindowSurface : public QWindowSurface 66 66 { 67 67 public: … … 77 77 78 78 protected: 79 bool adjustSetup(); 80 virtual void doFlush(const QRect &from, const QPoint &to); 81 bool pmEventFilter(QMSG *msg, MRESULT *result); 79 bool adjustSetup(QWidget *widget); 80 virtual void doFlush(QWidget *widget, const QRect &from, const QPoint &to); 82 81 83 82 QScopedPointer<QPMDiveWindowSurfacePrivate> d; 83 84 84 }; 85 85
Note:
See TracChangeset
for help on using the changeset viewer.