xref: /petsc/src/sys/classes/draw/utils/zoom.c (revision 9895aa37ac365bac650f6bd8bf977519f7222510)
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