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