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