From 5343f6ebcd096bbcc0b131b7f9411b0e15642592 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Mon, 26 May 2025 00:35:40 -0400 Subject: [PATCH 1/4] avoid grabbing x server --- PltApp.H | 38 ++------------- PltApp.cpp | 127 +++++++++++++++++++++++--------------------------- ProfApp.cpp | 7 ++- XYPlotWin.cpp | 6 ++- 4 files changed, 69 insertions(+), 109 deletions(-) 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..b70072f 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,24 @@ 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 + Window activeWindow = amrPicturePtrArray[V]->PictureWindow(); + int bufferWidth = amrPicturePtrArray[V]->ImageSizeH(); + int bufferHeight = amrPicturePtrArray[V]->ImageSizeV(); + + 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); if(servingButton == 1) { if(bShiftDown) { @@ -3619,47 +3649,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 +3673,14 @@ 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); rectDrawn = true; oldX = newX; @@ -3702,41 +3698,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 +3748,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 +4050,19 @@ 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); + + XSync(display, False); } @@ -4152,7 +4143,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 +4309,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); From 8707f291bfb47cfd6529708aa43a06280d3f4f76 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Mon, 26 May 2025 00:57:45 -0400 Subject: [PATCH 2/4] rewrite rubber banding for 3D planes --- PltApp.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/PltApp.cpp b/PltApp.cpp index b70072f..cfd72dc 100644 --- a/PltApp.cpp +++ b/PltApp.cpp @@ -3613,11 +3613,12 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) OwnerGrabButtonMask, cursor, CurrentTime); XSync(display, False); - // Setup double buffering for rubber band + // 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, @@ -3630,6 +3631,33 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) XCopyArea(display, activeWindow, rubberBandBackup, copyGC, 0, 0, bufferWidth, bufferHeight, 0, 0); + // Declare 3D plane variables (needed for cleanup scope) + Pixmap planeBackup[amrex::Amrvis::NPLANES] = {None, None, None}; + Pixmap planeBuffer[amrex::Amrvis::NPLANES] = {None, None, None}; + GC planeGC[amrex::Amrvis::NPLANES] = {None, None, 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) { oldX = 0; @@ -3681,6 +3709,78 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) 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 + 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); + } +#endif rectDrawn = true; oldX = newX; @@ -4061,6 +4161,19 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) 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); } From 3fb49461d6393d2d5c5c569a2ce5c7e83b14d384 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Mon, 26 May 2025 01:01:24 -0400 Subject: [PATCH 3/4] initialize based on NPLANES --- PltApp.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/PltApp.cpp b/PltApp.cpp index cfd72dc..107c6c3 100644 --- a/PltApp.cpp +++ b/PltApp.cpp @@ -3632,9 +3632,16 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) 0, 0, bufferWidth, bufferHeight, 0, 0); // Declare 3D plane variables (needed for cleanup scope) - Pixmap planeBackup[amrex::Amrvis::NPLANES] = {None, None, None}; - Pixmap planeBuffer[amrex::Amrvis::NPLANES] = {None, None, None}; - GC planeGC[amrex::Amrvis::NPLANES] = {None, None, None}; + 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 From e2a846448b18ecc70b1959d381528ebee584278f Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Mon, 26 May 2025 01:10:38 -0400 Subject: [PATCH 4/4] fix case label error --- PltApp.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/PltApp.cpp b/PltApp.cpp index 107c6c3..6cd6947 100644 --- a/PltApp.cpp +++ b/PltApp.cpp @@ -3720,7 +3720,7 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) #if (BL_SPACEDIM == 3) // Double buffering for additional 3D planes switch (V) { - case Amrvis::ZPLANE: + 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); @@ -3742,8 +3742,9 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) 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: + 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); @@ -3764,10 +3765,11 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) 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 + default: { // Amrvis::XPLANE // Update ZPLANE - rStartPlane = (anchorX < newX) ? newX : anchorX; + 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)); @@ -3786,6 +3788,8 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) 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;