diff --git a/PltApp.H b/PltApp.H index 9cabf91..16bc94d 100644 --- a/PltApp.H +++ b/PltApp.H @@ -214,6 +214,10 @@ private: XEvent nextEvent; int rWidth, rHeight, rStartX, rStartY; Cursor cursor; + + // double buffering for rubber band + Pixmap rubberBandBackup; + Pixmap rubberBandBuffer; static string defaultPaletteString, initialDerived, initialFormatString; static string defaultLightingFilename; @@ -343,40 +347,6 @@ private: }; -// ------------------------------------------------------------------- -class AVXGrab { - public: - AVXGrab(Display *display) : bIsGrabbed(true), cachedDisplay(display) { - XSync(cachedDisplay, False); - XGrabServer(display); - XSync(cachedDisplay, False); - } - - ~AVXGrab() { - if(bIsGrabbed) { - std::cout << "_______in ~AVXGrab: implicit ungrab." << std::endl; - } - XUngrabServer(cachedDisplay); - XSync(cachedDisplay, False); - bIsGrabbed = false; - } - - void ExplicitUngrab() { - if(bIsGrabbed == false) { - std::cout << "_______in AVXGrab::ExplicitUngrab: server not grabbed." - << std::endl; - } - XUngrabServer(cachedDisplay); - XSync(cachedDisplay, False); - bIsGrabbed = false; - } - - private: - AVXGrab(); // not implemented - bool bIsGrabbed; - Display *cachedDisplay; -}; -// ------------------------------------------------------------------- void SubregionPltApp(Widget toplevel, const amrex::Box ®ion, const amrex::IntVect &offset, diff --git a/PltApp.cpp b/PltApp.cpp index 1b1cd4b..6cd6947 100644 --- a/PltApp.cpp +++ b/PltApp.cpp @@ -95,6 +95,15 @@ PltApp::~PltApp() { if(datasetShowing) { delete datasetPtr; } + + // Cleanup double buffering resources + if(rubberBandBackup != None) { + XFreePixmap(XtDisplay(wTopLevel), rubberBandBackup); + } + if(rubberBandBuffer != None) { + XFreePixmap(XtDisplay(wTopLevel), rubberBandBuffer); + } + XtDestroyWidget(wAmrVisTopLevel); // delete all the call back parameter structs @@ -832,6 +841,10 @@ void PltApp::PltAppInit(bool bSubVolume) { rbgc = XCreateGC(display, gaPtr->PRoot(), 0, NULL); XSetFunction(display, rbgc, GXxor); cursor = XCreateFontCursor(display, XC_left_ptr); + + // Initialize double buffering variables + rubberBandBackup = None; + rubberBandBuffer = None; // No need to store these widgets in the class after this function is called. Widget wMainArea, wPalFrame, wPlotFrame, wPalForm; @@ -3598,7 +3611,59 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) XChangeActivePointerGrab(display, PointerMotionHintMask | ButtonMotionMask | ButtonReleaseMask | OwnerGrabButtonMask, cursor, CurrentTime); - AVXGrab avxGrab(display); + XSync(display, False); + + // Setup double buffering for rubber band - handle all 3D planes + Window activeWindow = amrPicturePtrArray[V]->PictureWindow(); + int bufferWidth = amrPicturePtrArray[V]->ImageSizeH(); + int bufferHeight = amrPicturePtrArray[V]->ImageSizeV(); + + // Create double buffering for main active plane + rubberBandBackup = XCreatePixmap(display, activeWindow, bufferWidth, bufferHeight, + DefaultDepth(display, DefaultScreen(display))); + rubberBandBuffer = XCreatePixmap(display, activeWindow, bufferWidth, bufferHeight, + DefaultDepth(display, DefaultScreen(display))); + + // Create GC for copying (always create fresh for this operation) + GC copyGC = XCreateGC(display, activeWindow, 0, NULL); + + // Copy original window contents to backup + XCopyArea(display, activeWindow, rubberBandBackup, copyGC, + 0, 0, bufferWidth, bufferHeight, 0, 0); + + // Declare 3D plane variables (needed for cleanup scope) + Pixmap planeBackup[amrex::Amrvis::NPLANES]; + Pixmap planeBuffer[amrex::Amrvis::NPLANES]; + GC planeGC[amrex::Amrvis::NPLANES]; + + // Initialize arrays to None + for(int i = 0; i < amrex::Amrvis::NPLANES; ++i) { + planeBackup[i] = None; + planeBuffer[i] = None; + planeGC[i] = None; + } + +#if (BL_SPACEDIM == 3) + // Create double buffering for additional 3D planes + + for(int plane = 0; plane < amrex::Amrvis::NPLANES; ++plane) { + if(plane != V) { // Skip the main plane, already handled above + Window planeWindow = amrPicturePtrArray[plane]->PictureWindow(); + int planeWidth = amrPicturePtrArray[plane]->ImageSizeH(); + int planeHeight = amrPicturePtrArray[plane]->ImageSizeV(); + + planeBackup[plane] = XCreatePixmap(display, planeWindow, planeWidth, planeHeight, + DefaultDepth(display, DefaultScreen(display))); + planeBuffer[plane] = XCreatePixmap(display, planeWindow, planeWidth, planeHeight, + DefaultDepth(display, DefaultScreen(display))); + planeGC[plane] = XCreateGC(display, planeWindow, 0, NULL); + + // Copy original contents to backup + XCopyArea(display, planeWindow, planeBackup[plane], planeGC[plane], + 0, 0, planeWidth, planeHeight, 0, 0); + } + } +#endif if(servingButton == 1) { if(bShiftDown) { @@ -3619,47 +3684,7 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) case MotionNotify: - if(rectDrawn) { // undraw the old rectangle(s) - rWidth = std::abs(oldX-anchorX); - rHeight = std::abs(oldY-anchorY); - rStartX = (anchorX < oldX) ? anchorX : oldX; - rStartY = (anchorY < oldY) ? anchorY : oldY; - XDrawRectangle(display, amrPicturePtrArray[V]->PictureWindow(), - rbgc, rStartX, rStartY, rWidth, rHeight); -#if (BL_SPACEDIM == 3) - // 3D sub domain selecting - switch (V) { - case Amrvis::ZPLANE: - XDrawRectangle(display, amrPicturePtrArray[Amrvis::YPLANE]->PictureWindow(), - rbgc, rStartX, startcutY[Amrvis::YPLANE], rWidth, - std::abs(finishcutY[Amrvis::YPLANE]-startcutY[Amrvis::YPLANE])); - rStartPlane = (anchorY < oldY) ? oldY : anchorY; - XDrawRectangle(display, amrPicturePtrArray[Amrvis::XPLANE]->PictureWindow(), - rbgc, imageHeight-rStartPlane, startcutY[Amrvis::XPLANE], - rHeight, - std::abs(finishcutY[Amrvis::XPLANE]-startcutY[Amrvis::XPLANE])); - break; - case Amrvis::YPLANE: - XDrawRectangle(display, amrPicturePtrArray[Amrvis::ZPLANE]->PictureWindow(), - rbgc, rStartX, startcutY[Amrvis::ZPLANE], rWidth, - std::abs(finishcutY[Amrvis::ZPLANE]-startcutY[Amrvis::ZPLANE])); - XDrawRectangle(display, amrPicturePtrArray[Amrvis::XPLANE]->PictureWindow(), - rbgc, startcutX[Amrvis::XPLANE], rStartY, - std::abs(finishcutX[Amrvis::XPLANE]-startcutX[Amrvis::XPLANE]), - rHeight); - break; - default: // Amrvis::XPLANE - rStartPlane = (anchorX < oldX) ? oldX : anchorX; - XDrawRectangle(display, amrPicturePtrArray[Amrvis::ZPLANE]->PictureWindow(), - rbgc, startcutX[Amrvis::ZPLANE], imageWidth-rStartPlane, - std::abs(finishcutX[Amrvis::ZPLANE]-startcutX[Amrvis::ZPLANE]), rWidth); - XDrawRectangle(display, amrPicturePtrArray[Amrvis::YPLANE]->PictureWindow(), - rbgc, startcutX[Amrvis::YPLANE], rStartY, - std::abs(finishcutX[Amrvis::YPLANE]-startcutX[Amrvis::YPLANE]), - rHeight); - } -#endif - } + // Double buffering approach - no need to "undraw" old rectangles DoDrawPointerLocation(None, (XtPointer) static_cast(V), &nextEvent); @@ -3683,8 +3708,90 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) rHeight = std::abs(newY-anchorY); rStartX = (anchorX < newX) ? anchorX : newX; rStartY = (anchorY < newY) ? anchorY : newY; - XDrawRectangle(display, amrPicturePtrArray[V]->PictureWindow(), - rbgc, rStartX, rStartY, rWidth, rHeight); + + // Double buffering: restore original, draw rectangle, copy to window + XCopyArea(display, rubberBandBackup, rubberBandBuffer, copyGC, + 0, 0, bufferWidth, bufferHeight, 0, 0); + XSetForeground(display, copyGC, pltPaletteptr->makePixel(120)); + XDrawRectangle(display, rubberBandBuffer, copyGC, rStartX, rStartY, rWidth, rHeight); + XCopyArea(display, rubberBandBuffer, amrPicturePtrArray[V]->PictureWindow(), copyGC, + 0, 0, bufferWidth, bufferHeight, 0, 0); + +#if (BL_SPACEDIM == 3) + // Double buffering for additional 3D planes + switch (V) { + case Amrvis::ZPLANE: { + // Update YPLANE + XCopyArea(display, planeBackup[Amrvis::YPLANE], planeBuffer[Amrvis::YPLANE], planeGC[Amrvis::YPLANE], + 0, 0, amrPicturePtrArray[Amrvis::YPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::YPLANE]->ImageSizeV(), 0, 0); + XSetForeground(display, planeGC[Amrvis::YPLANE], pltPaletteptr->makePixel(120)); + XDrawRectangle(display, planeBuffer[Amrvis::YPLANE], planeGC[Amrvis::YPLANE], + rStartX, startcutY[Amrvis::YPLANE], rWidth, + std::abs(finishcutY[Amrvis::YPLANE]-startcutY[Amrvis::YPLANE])); + XCopyArea(display, planeBuffer[Amrvis::YPLANE], amrPicturePtrArray[Amrvis::YPLANE]->PictureWindow(), planeGC[Amrvis::YPLANE], + 0, 0, amrPicturePtrArray[Amrvis::YPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::YPLANE]->ImageSizeV(), 0, 0); + + // Update XPLANE + int rStartPlane = (anchorY < newY) ? newY : anchorY; + XCopyArea(display, planeBackup[Amrvis::XPLANE], planeBuffer[Amrvis::XPLANE], planeGC[Amrvis::XPLANE], + 0, 0, amrPicturePtrArray[Amrvis::XPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::XPLANE]->ImageSizeV(), 0, 0); + XSetForeground(display, planeGC[Amrvis::XPLANE], pltPaletteptr->makePixel(120)); + XDrawRectangle(display, planeBuffer[Amrvis::XPLANE], planeGC[Amrvis::XPLANE], + imageHeight-rStartPlane, startcutY[Amrvis::XPLANE], rHeight, + std::abs(finishcutY[Amrvis::XPLANE]-startcutY[Amrvis::XPLANE])); + XCopyArea(display, planeBuffer[Amrvis::XPLANE], amrPicturePtrArray[Amrvis::XPLANE]->PictureWindow(), planeGC[Amrvis::XPLANE], + 0, 0, amrPicturePtrArray[Amrvis::XPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::XPLANE]->ImageSizeV(), 0, 0); + break; + } + + case Amrvis::YPLANE: { + // Update ZPLANE + XCopyArea(display, planeBackup[Amrvis::ZPLANE], planeBuffer[Amrvis::ZPLANE], planeGC[Amrvis::ZPLANE], + 0, 0, amrPicturePtrArray[Amrvis::ZPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::ZPLANE]->ImageSizeV(), 0, 0); + XSetForeground(display, planeGC[Amrvis::ZPLANE], pltPaletteptr->makePixel(120)); + XDrawRectangle(display, planeBuffer[Amrvis::ZPLANE], planeGC[Amrvis::ZPLANE], + rStartX, startcutY[Amrvis::ZPLANE], rWidth, + std::abs(finishcutY[Amrvis::ZPLANE]-startcutY[Amrvis::ZPLANE])); + XCopyArea(display, planeBuffer[Amrvis::ZPLANE], amrPicturePtrArray[Amrvis::ZPLANE]->PictureWindow(), planeGC[Amrvis::ZPLANE], + 0, 0, amrPicturePtrArray[Amrvis::ZPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::ZPLANE]->ImageSizeV(), 0, 0); + + // Update XPLANE + XCopyArea(display, planeBackup[Amrvis::XPLANE], planeBuffer[Amrvis::XPLANE], planeGC[Amrvis::XPLANE], + 0, 0, amrPicturePtrArray[Amrvis::XPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::XPLANE]->ImageSizeV(), 0, 0); + XSetForeground(display, planeGC[Amrvis::XPLANE], pltPaletteptr->makePixel(120)); + XDrawRectangle(display, planeBuffer[Amrvis::XPLANE], planeGC[Amrvis::XPLANE], + startcutX[Amrvis::XPLANE], rStartY, + std::abs(finishcutX[Amrvis::XPLANE]-startcutX[Amrvis::XPLANE]), rHeight); + XCopyArea(display, planeBuffer[Amrvis::XPLANE], amrPicturePtrArray[Amrvis::XPLANE]->PictureWindow(), planeGC[Amrvis::XPLANE], + 0, 0, amrPicturePtrArray[Amrvis::XPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::XPLANE]->ImageSizeV(), 0, 0); + break; + } + + default: { // Amrvis::XPLANE + // Update ZPLANE + int rStartPlane = (anchorX < newX) ? newX : anchorX; + XCopyArea(display, planeBackup[Amrvis::ZPLANE], planeBuffer[Amrvis::ZPLANE], planeGC[Amrvis::ZPLANE], + 0, 0, amrPicturePtrArray[Amrvis::ZPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::ZPLANE]->ImageSizeV(), 0, 0); + XSetForeground(display, planeGC[Amrvis::ZPLANE], pltPaletteptr->makePixel(120)); + XDrawRectangle(display, planeBuffer[Amrvis::ZPLANE], planeGC[Amrvis::ZPLANE], + startcutX[Amrvis::ZPLANE], imageWidth-rStartPlane, + std::abs(finishcutX[Amrvis::ZPLANE]-startcutX[Amrvis::ZPLANE]), rWidth); + XCopyArea(display, planeBuffer[Amrvis::ZPLANE], amrPicturePtrArray[Amrvis::ZPLANE]->PictureWindow(), planeGC[Amrvis::ZPLANE], + 0, 0, amrPicturePtrArray[Amrvis::ZPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::ZPLANE]->ImageSizeV(), 0, 0); + + // Update YPLANE + XCopyArea(display, planeBackup[Amrvis::YPLANE], planeBuffer[Amrvis::YPLANE], planeGC[Amrvis::YPLANE], + 0, 0, amrPicturePtrArray[Amrvis::YPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::YPLANE]->ImageSizeV(), 0, 0); + XSetForeground(display, planeGC[Amrvis::YPLANE], pltPaletteptr->makePixel(120)); + XDrawRectangle(display, planeBuffer[Amrvis::YPLANE], planeGC[Amrvis::YPLANE], + startcutX[Amrvis::YPLANE], rStartY, + std::abs(finishcutX[Amrvis::YPLANE]-startcutX[Amrvis::YPLANE]), rHeight); + XCopyArea(display, planeBuffer[Amrvis::YPLANE], amrPicturePtrArray[Amrvis::YPLANE]->PictureWindow(), planeGC[Amrvis::YPLANE], + 0, 0, amrPicturePtrArray[Amrvis::YPLANE]->ImageSizeH(), amrPicturePtrArray[Amrvis::YPLANE]->ImageSizeV(), 0, 0); + break; + } + } +#endif rectDrawn = true; oldX = newX; @@ -3702,41 +3809,24 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) finishcutX[Amrvis::YPLANE] = finishcutX[V]; startcutX[Amrvis::XPLANE] = imageHeight - startcutY[V]; finishcutX[Amrvis::XPLANE] = imageHeight - finishcutY[V]; - // draw in other planes - XDrawRectangle(display, amrPicturePtrArray[Amrvis::YPLANE]->PictureWindow(), - rbgc, rStartX, startcutY[Amrvis::YPLANE], rWidth, - std::abs(finishcutY[Amrvis::YPLANE]-startcutY[Amrvis::YPLANE])); - rStartPlane = (anchorY < newY) ? newY : anchorY; - XDrawRectangle(display, amrPicturePtrArray[Amrvis::XPLANE]->PictureWindow(), - rbgc, imageHeight-rStartPlane, startcutY[Amrvis::XPLANE], - rHeight, - std::abs(finishcutY[Amrvis::XPLANE]-startcutY[Amrvis::XPLANE])); + // 3D planes handled by double buffering now + // XDrawRectangle calls removed - double buffering handles all drawing break; case Amrvis::YPLANE: startcutX[Amrvis::ZPLANE] = startcutX[V]; finishcutX[Amrvis::ZPLANE] = finishcutX[V]; startcutY[Amrvis::XPLANE] = startcutY[V]; finishcutY[Amrvis::XPLANE] = finishcutY[V]; - XDrawRectangle(display, amrPicturePtrArray[Amrvis::ZPLANE]->PictureWindow(), - rbgc, rStartX, startcutY[Amrvis::ZPLANE], rWidth, - std::abs(finishcutY[Amrvis::ZPLANE]-startcutY[Amrvis::ZPLANE])); - XDrawRectangle(display, amrPicturePtrArray[Amrvis::XPLANE]->PictureWindow(), - rbgc, startcutX[Amrvis::XPLANE], rStartY, - std::abs(finishcutX[Amrvis::XPLANE]-startcutX[Amrvis::XPLANE]), rHeight); + // 3D planes handled by double buffering now break; default: // Amrvis::XPLANE startcutY[Amrvis::YPLANE] = startcutY[V]; finishcutY[Amrvis::YPLANE] = finishcutY[V]; startcutY[Amrvis::ZPLANE] = imageWidth - startcutX[V]; finishcutY[Amrvis::ZPLANE] = imageWidth - finishcutX[V]; - rStartPlane = (anchorX < newX) ? newX : anchorX; - XDrawRectangle(display, amrPicturePtrArray[Amrvis::ZPLANE]->PictureWindow(), - rbgc, startcutX[Amrvis::ZPLANE], imageWidth-rStartPlane, - std::abs(finishcutX[Amrvis::ZPLANE]-startcutX[Amrvis::ZPLANE]), rWidth); - XDrawRectangle(display, amrPicturePtrArray[Amrvis::YPLANE]->PictureWindow(), - rbgc, startcutX[Amrvis::YPLANE], rStartY, - std::abs(finishcutX[Amrvis::YPLANE]-startcutX[Amrvis::YPLANE]), rHeight); + // 3D planes handled by double buffering now } + XSync(display, False); #if defined(BL_VOLUMERENDER) || defined(BL_PARALLELVOLUMERENDER) if( ! XmToggleButtonGetState(wAutoDraw)) @@ -3769,7 +3859,6 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) break; case ButtonRelease: { - avxGrab.ExplicitUngrab(); startX = (max(0, min(imageWidth, anchorX))) / scale; startY = (max(0, min(imageHeight, anchorY))) / scale; @@ -4072,6 +4161,32 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) break; } // end switch } // end while(true) + + // Cleanup double buffering resources + if(rubberBandBackup != None) { + XFreePixmap(display, rubberBandBackup); + rubberBandBackup = None; + } + if(rubberBandBuffer != None) { + XFreePixmap(display, rubberBandBuffer); + rubberBandBuffer = None; + } + XFreeGC(display, copyGC); + + // Cleanup additional 3D plane resources + for(int plane = 0; plane < amrex::Amrvis::NPLANES; ++plane) { + if(planeBackup[plane] != None) { + XFreePixmap(display, planeBackup[plane]); + } + if(planeBuffer[plane] != None) { + XFreePixmap(display, planeBuffer[plane]); + } + if(planeGC[plane] != None) { + XFreeGC(display, planeGC[plane]); + } + } + + XSync(display, False); } @@ -4152,7 +4267,6 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) break; case ButtonRelease: - avxGrab.ExplicitUngrab(); tempi = max(0, min(imageHeight, nextEvent.xbutton.y)); amrPicturePtrArray[V]->SetHLine(tempi); #if (BL_SPACEDIM == 3) @@ -4319,7 +4433,6 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) break; case ButtonRelease: - avxGrab.ExplicitUngrab(); tempi = max(0, min(imageWidth, nextEvent.xbutton.x)); amrPicturePtrArray[V]->SetVLine(tempi); #if (BL_SPACEDIM == 3) diff --git a/ProfApp.cpp b/ProfApp.cpp index d53429c..dcd20f6 100644 --- a/ProfApp.cpp +++ b/ProfApp.cpp @@ -1350,7 +1350,7 @@ void ProfApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data XChangeActivePointerGrab(display, PointerMotionHintMask | ButtonMotionMask | ButtonReleaseMask | OwnerGrabButtonMask, cursor, CurrentTime); - AVXGrab avxGrab(display); + XSync(display, False); if(servingButton == 1) { if(bShiftDown) { @@ -1378,6 +1378,7 @@ void ProfApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data rStartY = (anchorY < oldY) ? anchorY : oldY; XDrawRectangle(display, regionPicturePtr->PictureWindow(), rbgc, rStartX, rStartY, rWidth, rHeight); + XSync(display, False); } while(XCheckTypedEvent(display, MotionNotify, &nextEvent)) { @@ -1402,6 +1403,7 @@ void ProfApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data rStartY = (anchorY < newY) ? anchorY : newY; XDrawRectangle(display, regionPicturePtr->PictureWindow(), rbgc, rStartX, rStartY, rWidth, rHeight); + XSync(display, False); rectDrawn = true; oldX = newX; @@ -1410,7 +1412,6 @@ void ProfApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data break; case ButtonRelease: { - avxGrab.ExplicitUngrab(); startX = (max(0, min(imageWidth, anchorX))) / scale; startY = (max(0, min(imageHeight, anchorY))) / scale; @@ -1512,7 +1513,6 @@ void ProfApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data break; case ButtonRelease: - avxGrab.ExplicitUngrab(); if(saveOldX == nextEvent.xbutton.x && saveOldY == nextEvent.xbutton.y) { // ---- turn region off @@ -1576,7 +1576,6 @@ void ProfApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data break; case ButtonRelease: - avxGrab.ExplicitUngrab(); if(saveOldX == nextEvent.xbutton.x && saveOldY == nextEvent.xbutton.y) { // ---- turn region on diff --git a/XYPlotWin.cpp b/XYPlotWin.cpp index 7e99f67..950acdd 100644 --- a/XYPlotWin.cpp +++ b/XYPlotWin.cpp @@ -2292,7 +2292,7 @@ void XYPlotWin::CBdoRubberBanding(Widget, XtPointer, XtPointer call_data) { ButtonPressMask | ButtonReleaseMask | PointerMotionMask | PointerMotionHintMask, zoomCursor, CurrentTime); - AVXGrab avxGrab(disp); + XSync(disp, False); lowX = TRANX(anchorX); lowY = TRANY(anchorY); @@ -2325,6 +2325,7 @@ void XYPlotWin::CBdoRubberBanding(Widget, XtPointer, XtPointer call_data) { rStartY = (anchorY < oldY) ? anchorY : oldY; XDrawRectangle(disp, pWindow, rbGC, rStartX, rStartY, rWidth, rHeight); + XSync(disp, False); } // get rid of those pesky extra MotionNotify events @@ -2341,6 +2342,7 @@ void XYPlotWin::CBdoRubberBanding(Widget, XtPointer, XtPointer call_data) { rStartY = (anchorY < newY) ? anchorY : newY; XDrawRectangle(disp, pWindow, rbGC, rStartX, rStartY, rWidth, rHeight); + XSync(disp, False); rectDrawn = true; oldX = newX; @@ -2349,7 +2351,6 @@ void XYPlotWin::CBdoRubberBanding(Widget, XtPointer, XtPointer call_data) { break; case ButtonRelease: - avxGrab.ExplicitUngrab(); // giveitawaynow // undraw rectangle rWidth = std::abs(oldX-anchorX); @@ -2358,6 +2359,7 @@ void XYPlotWin::CBdoRubberBanding(Widget, XtPointer, XtPointer call_data) { rStartY = (anchorY < oldY) ? anchorY : oldY; XDrawRectangle(disp, pWindow, rbGC, rStartX, rStartY, rWidth, rHeight); + XSync(disp, False); highX = TRANX(newX); highY = TRANY(newY);