1 2 #include <petscdraw.h> /*I "petscdraw.h" I*/ 3 4 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X) 5 #include <X11/Xlib.h> 6 #include <X11/Xutil.h> 7 #include <setjmp.h> 8 static jmp_buf PetscXIOErrorJumpBuf; 9 static void PetscXIOHandler(Display *dpy) 10 { 11 longjmp(PetscXIOErrorJumpBuf, 1); 12 } 13 #endif 14 15 #undef __FUNCT__ 16 #define __FUNCT__ "PetscDrawZoom" 17 /*@C 18 PetscDrawZoom - Allows one to create a graphic that users may zoom into. 19 20 Collective on PetscDraw 21 22 Input Parameters: 23 + draw - the window where the graph will be made. 24 . func - users function that draws the graphic 25 - ctx - pointer to any user required data 26 27 Level: advanced 28 29 Concepts: graphics^zooming 30 Concepts: drawing^zooming 31 Concepts: zooming^in graphics 32 33 .seealso: 34 @*/ 35 PetscErrorCode PetscDrawZoom(PetscDraw draw,PetscErrorCode (*func)(PetscDraw,void*),void *ctx) 36 { 37 PetscErrorCode ierr; 38 PetscDrawButton button; 39 PetscReal dpause,xc,yc,scale = 1.0,w,h,xr,xl,yr,yl,xmin,xmax,ymin,ymax; 40 PetscBool isnull; 41 42 PetscFunctionBegin; 43 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 44 if (isnull) PetscFunctionReturn(0); 45 46 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X) 47 if (!setjmp(PetscXIOErrorJumpBuf)) XSetIOErrorHandler((XIOErrorHandler)PetscXIOHandler); 48 else { 49 XSetIOErrorHandler(NULL); 50 ierr = PetscDrawSetType(draw,PETSC_DRAW_NULL);CHKERRQ(ierr); 51 PetscFunctionReturn(0); 52 } 53 #endif 54 55 ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr); 56 ierr = PetscDrawSynchronizedClear(draw);CHKERRQ(ierr); 57 ierr = (*func)(draw,ctx);CHKERRQ(ierr); 58 ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); 59 60 ierr = PetscDrawGetPause(draw,&dpause);CHKERRQ(ierr); 61 if (dpause >= 0) { 62 ierr = PetscSleep(dpause);CHKERRQ(ierr); 63 goto theend; 64 } 65 if (dpause != -1) goto theend; 66 67 ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr); 68 ierr = PetscDrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0);CHKERRQ(ierr); 69 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 70 w = xr - xl; xmin = xl; ymin = yl; xmax = xr; ymax = yr; 71 h = yr - yl; 72 73 if (button != PETSC_BUTTON_NONE) { 74 while (button != PETSC_BUTTON_RIGHT) { 75 76 ierr = PetscDrawSynchronizedClear(draw);CHKERRQ(ierr); 77 if (button == PETSC_BUTTON_LEFT) scale = .5; 78 else if (button == PETSC_BUTTON_CENTER) scale = 2.; 79 xl = scale*(xl + w - xc) + xc - w*scale; 80 xr = scale*(xr - w - xc) + xc + w*scale; 81 yl = scale*(yl + h - yc) + yc - h*scale; 82 yr = scale*(yr - h - yc) + yc + h*scale; 83 w *= scale; h *= scale; 84 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 85 86 ierr = (*func)(draw,ctx);CHKERRQ(ierr); 87 ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); 88 ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr); 89 ierr = PetscDrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0);CHKERRQ(ierr); 90 } 91 } 92 ierr = PetscDrawSetCoordinates(draw,xmin,ymin,xmax,ymax);CHKERRQ(ierr); 93 theend: 94 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X) 95 XSetIOErrorHandler(NULL); 96 #endif 97 PetscFunctionReturn(0); 98 } 99 100