xref: /petsc/src/sys/classes/draw/impls/x/xinit.c (revision 5c6c1daec53e1d9ab0bec9db5309fd8fc7645b8d)
1*5c6c1daeSBarry Smith 
2*5c6c1daeSBarry Smith /*
3*5c6c1daeSBarry Smith    This file contains routines to open an X window display and window
4*5c6c1daeSBarry Smith    This consists of a number of routines that set the various
5*5c6c1daeSBarry Smith    fields in the Window structure, which is passed to
6*5c6c1daeSBarry Smith    all of these routines.
7*5c6c1daeSBarry Smith 
8*5c6c1daeSBarry Smith    Note that if you use the default visual and colormap, then you
9*5c6c1daeSBarry Smith    can use these routines with any X toolkit that will give you the
10*5c6c1daeSBarry Smith    Window id of the window that it is managing.  Use that instead of the
11*5c6c1daeSBarry Smith    call to PetscDrawXiCreateWindow .  Similarly for the Display.
12*5c6c1daeSBarry Smith */
13*5c6c1daeSBarry Smith 
14*5c6c1daeSBarry Smith #include <../src/sys/classes/draw/impls/x/ximpl.h>
15*5c6c1daeSBarry Smith 
16*5c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXiUniformHues(PetscDraw_X *,int);
17*5c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXi_wait_map(PetscDraw_X*);
18*5c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXiFontFixed(PetscDraw_X*,int,int,PetscDrawXiFont**);
19*5c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXiInitCmap(PetscDraw_X*);
20*5c6c1daeSBarry Smith extern PetscErrorCode PetscDrawSetColormap_X(PetscDraw_X*,char *,Colormap);
21*5c6c1daeSBarry Smith 
22*5c6c1daeSBarry Smith /*
23*5c6c1daeSBarry Smith   PetscDrawXiOpenDisplay - Open a display
24*5c6c1daeSBarry Smith */
25*5c6c1daeSBarry Smith #undef __FUNCT__
26*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiOpenDisplay"
27*5c6c1daeSBarry Smith PetscErrorCode PetscDrawXiOpenDisplay(PetscDraw_X* XiWin,char *display_name)
28*5c6c1daeSBarry Smith {
29*5c6c1daeSBarry Smith   PetscFunctionBegin;
30*5c6c1daeSBarry Smith   XiWin->disp = XOpenDisplay(display_name);
31*5c6c1daeSBarry Smith   if (!XiWin->disp) {
32*5c6c1daeSBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open display on %s\n.  Make sure your COMPUTE NODES are authorized to connect \n\
33*5c6c1daeSBarry Smith     to this X server and either your DISPLAY variable\n\
34*5c6c1daeSBarry Smith     is set or you use the -display name option\n",display_name);
35*5c6c1daeSBarry Smith   }
36*5c6c1daeSBarry Smith   XiWin->screen = DefaultScreen(XiWin->disp);
37*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
38*5c6c1daeSBarry Smith }
39*5c6c1daeSBarry Smith 
40*5c6c1daeSBarry Smith 
41*5c6c1daeSBarry Smith /*
42*5c6c1daeSBarry Smith    PetscDrawXiSetGC - set the GC structure in the base window
43*5c6c1daeSBarry Smith */
44*5c6c1daeSBarry Smith #undef __FUNCT__
45*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetGC"
46*5c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetGC(PetscDraw_X* XiWin,PetscDrawXiPixVal fg)
47*5c6c1daeSBarry Smith {
48*5c6c1daeSBarry Smith   XGCValues       gcvalues;       /* window graphics context values */
49*5c6c1daeSBarry Smith 
50*5c6c1daeSBarry Smith   PetscFunctionBegin;
51*5c6c1daeSBarry Smith   /* Set the graphics contexts */
52*5c6c1daeSBarry Smith   /* create a gc for the ROP_SET operation (writing the fg value to a pixel) */
53*5c6c1daeSBarry Smith   /* (do this with function GXcopy; GXset will automatically write 1) */
54*5c6c1daeSBarry Smith   gcvalues.function   = GXcopy;
55*5c6c1daeSBarry Smith   gcvalues.foreground = fg;
56*5c6c1daeSBarry Smith   XiWin->gc.cur_pix   = fg;
57*5c6c1daeSBarry Smith   XiWin->gc.set = XCreateGC(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),GCFunction | GCForeground,&gcvalues);
58*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
59*5c6c1daeSBarry Smith }
60*5c6c1daeSBarry Smith 
61*5c6c1daeSBarry Smith /*
62*5c6c1daeSBarry Smith     Actually display a window at [x,y] with sizes (w,h)
63*5c6c1daeSBarry Smith     If w and/or h are 0, use the sizes in the fields of XiWin
64*5c6c1daeSBarry Smith     (which may have been set by, for example, PetscDrawXiSetWindowSize)
65*5c6c1daeSBarry Smith */
66*5c6c1daeSBarry Smith #undef __FUNCT__
67*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiDisplayWindow"
68*5c6c1daeSBarry Smith PetscErrorCode PetscDrawXiDisplayWindow(PetscDraw_X* XiWin,char *label,int x,int y,int w,int h,PetscDrawXiPixVal backgnd_pixel)
69*5c6c1daeSBarry Smith {
70*5c6c1daeSBarry Smith   unsigned int            wavail,havail;
71*5c6c1daeSBarry Smith   XSizeHints              size_hints;
72*5c6c1daeSBarry Smith   XWindowAttributes       in_window_attributes;
73*5c6c1daeSBarry Smith   XSetWindowAttributes    window_attributes;
74*5c6c1daeSBarry Smith   int                     depth,border_width;
75*5c6c1daeSBarry Smith   unsigned long           wmask;
76*5c6c1daeSBarry Smith   PetscBool               flg;
77*5c6c1daeSBarry Smith   PetscErrorCode          ierr;
78*5c6c1daeSBarry Smith 
79*5c6c1daeSBarry Smith   PetscFunctionBegin;
80*5c6c1daeSBarry Smith   /* get the available widths */
81*5c6c1daeSBarry Smith   wavail              = DisplayWidth(XiWin->disp,XiWin->screen);
82*5c6c1daeSBarry Smith   havail              = DisplayHeight(XiWin->disp,XiWin->screen);
83*5c6c1daeSBarry Smith   if (w <= 0 || h <= 0)  SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"X Window display has invalid height or width");
84*5c6c1daeSBarry Smith   if ((unsigned int) w > wavail) w = wavail;
85*5c6c1daeSBarry Smith   if ((unsigned int) h > havail) h = havail;
86*5c6c1daeSBarry Smith 
87*5c6c1daeSBarry Smith   border_width   = 0;
88*5c6c1daeSBarry Smith   if (x < 0) x   = 0;
89*5c6c1daeSBarry Smith   if (y < 0) y   = 0;
90*5c6c1daeSBarry Smith   x   = ((unsigned int) x + w > wavail) ? wavail - w : x;
91*5c6c1daeSBarry Smith   y   = ((unsigned int) y + h > havail) ? havail - h : y;
92*5c6c1daeSBarry Smith 
93*5c6c1daeSBarry Smith   /* We need XCreateWindow since we may need an visual other than the default one */
94*5c6c1daeSBarry Smith   XGetWindowAttributes(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),&in_window_attributes);
95*5c6c1daeSBarry Smith   window_attributes.background_pixmap = None;
96*5c6c1daeSBarry Smith   window_attributes.background_pixel  = backgnd_pixel;
97*5c6c1daeSBarry Smith   /* No border for now */
98*5c6c1daeSBarry Smith   window_attributes.border_pixmap     = None;
99*5c6c1daeSBarry Smith   /*
100*5c6c1daeSBarry Smith   window_attributes.border_pixel      = border_pixel;
101*5c6c1daeSBarry Smith   */
102*5c6c1daeSBarry Smith   window_attributes.bit_gravity       = in_window_attributes.bit_gravity;
103*5c6c1daeSBarry Smith   window_attributes.win_gravity       = in_window_attributes.win_gravity;
104*5c6c1daeSBarry Smith         /* Backing store is too slow in color systems */
105*5c6c1daeSBarry Smith   window_attributes.backing_store     = 0;
106*5c6c1daeSBarry Smith   window_attributes.backing_pixel     = backgnd_pixel;
107*5c6c1daeSBarry Smith   window_attributes.save_under        = 1;
108*5c6c1daeSBarry Smith   window_attributes.event_mask        = 0;
109*5c6c1daeSBarry Smith   window_attributes.do_not_propagate_mask = 0;
110*5c6c1daeSBarry Smith   window_attributes.override_redirect = 0;
111*5c6c1daeSBarry Smith   window_attributes.colormap          = XiWin->cmap;
112*5c6c1daeSBarry Smith   /* None for cursor does NOT mean none, it means cursor of Parent */
113*5c6c1daeSBarry Smith   window_attributes.cursor            = None;
114*5c6c1daeSBarry Smith   wmask = CWBackPixmap | CWBackPixel    | CWBorderPixmap  | CWBitGravity |
115*5c6c1daeSBarry Smith           CWWinGravity | CWBackingStore |CWBackingPixel   |CWOverrideRedirect |
116*5c6c1daeSBarry Smith           CWSaveUnder  | CWEventMask    | CWDontPropagate |
117*5c6c1daeSBarry Smith           CWCursor     | CWColormap ;
118*5c6c1daeSBarry Smith   depth = XiWin->depth;
119*5c6c1daeSBarry Smith 
120*5c6c1daeSBarry Smith   XiWin->win  = XCreateWindow(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),x,y,w,h,border_width,depth,InputOutput,XiWin->vis,wmask,&window_attributes);
121*5c6c1daeSBarry Smith   if (!XiWin->win) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open X window");
122*5c6c1daeSBarry Smith 
123*5c6c1daeSBarry Smith   /* set window manager hints */
124*5c6c1daeSBarry Smith   {
125*5c6c1daeSBarry Smith     XWMHints      wm_hints;
126*5c6c1daeSBarry Smith     XClassHint    class_hints;
127*5c6c1daeSBarry Smith     XTextProperty windowname,iconname;
128*5c6c1daeSBarry Smith 
129*5c6c1daeSBarry Smith     if (label) { XStringListToTextProperty(&label,1,&windowname);}
130*5c6c1daeSBarry Smith     else       { XStringListToTextProperty(&label,0,&windowname);}
131*5c6c1daeSBarry Smith     if (label) { XStringListToTextProperty(&label,1,&iconname);}
132*5c6c1daeSBarry Smith     else       { XStringListToTextProperty(&label,0,&iconname);}
133*5c6c1daeSBarry Smith 
134*5c6c1daeSBarry Smith     wm_hints.initial_state  = NormalState;
135*5c6c1daeSBarry Smith     wm_hints.input          = True;
136*5c6c1daeSBarry Smith     wm_hints.flags          = StateHint|InputHint;
137*5c6c1daeSBarry Smith 
138*5c6c1daeSBarry Smith     /* These properties can be used by window managers to decide how to display a window */
139*5c6c1daeSBarry Smith     class_hints.res_name    = (char*)"petsc";
140*5c6c1daeSBarry Smith     class_hints.res_class   = (char*)"PETSc";
141*5c6c1daeSBarry Smith 
142*5c6c1daeSBarry Smith     size_hints.x            = x;
143*5c6c1daeSBarry Smith     size_hints.y            = y;
144*5c6c1daeSBarry Smith     size_hints.min_width    = 4*border_width;
145*5c6c1daeSBarry Smith     size_hints.min_height   = 4*border_width;
146*5c6c1daeSBarry Smith     size_hints.width        = w;
147*5c6c1daeSBarry Smith     size_hints.height       = h;
148*5c6c1daeSBarry Smith     size_hints.flags        = USPosition | USSize | PMinSize;
149*5c6c1daeSBarry Smith 
150*5c6c1daeSBarry Smith     XSetWMProperties(XiWin->disp,XiWin->win,&windowname,&iconname,0,0,&size_hints,&wm_hints,&class_hints);
151*5c6c1daeSBarry Smith     XFree((void*)windowname.value);
152*5c6c1daeSBarry Smith     XFree((void*)iconname.value);
153*5c6c1daeSBarry Smith   }
154*5c6c1daeSBarry Smith   /* make the window visible */
155*5c6c1daeSBarry Smith   XSelectInput(XiWin->disp,XiWin->win,ExposureMask | StructureNotifyMask);
156*5c6c1daeSBarry Smith   XMapWindow(XiWin->disp,XiWin->win);
157*5c6c1daeSBarry Smith 
158*5c6c1daeSBarry Smith 
159*5c6c1daeSBarry Smith   /* some window systems are cruel and interfere with the placement of
160*5c6c1daeSBarry Smith      windows.  We wait here for the window to be created or to die */
161*5c6c1daeSBarry Smith   if (PetscDrawXi_wait_map(XiWin)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Wait for X window failed");
162*5c6c1daeSBarry Smith 
163*5c6c1daeSBarry Smith   flg = PETSC_FALSE;
164*5c6c1daeSBarry Smith   ierr = PetscOptionsGetBool(PETSC_NULL,"-draw_virtual",&flg,PETSC_NULL);CHKERRQ(ierr);
165*5c6c1daeSBarry Smith   if (flg) {
166*5c6c1daeSBarry Smith     XiWin->drw = XCreatePixmap(XiWin->disp,XiWin->win,XiWin->w,XiWin->h,XiWin->depth);
167*5c6c1daeSBarry Smith     XDestroyWindow(XiWin->disp,XiWin->win);
168*5c6c1daeSBarry Smith     XiWin->win = 0;
169*5c6c1daeSBarry Smith     PetscFunctionReturn(0);
170*5c6c1daeSBarry Smith   }
171*5c6c1daeSBarry Smith 
172*5c6c1daeSBarry Smith   /* Initial values for the upper left corner */
173*5c6c1daeSBarry Smith   XiWin->x = 0;
174*5c6c1daeSBarry Smith   XiWin->y = 0;
175*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
176*5c6c1daeSBarry Smith }
177*5c6c1daeSBarry Smith 
178*5c6c1daeSBarry Smith #undef __FUNCT__
179*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindow"
180*5c6c1daeSBarry Smith PetscErrorCode PetscDrawXiQuickWindow(PetscDraw_X* w,char* host,char* name,int x,int y,int nx,int ny)
181*5c6c1daeSBarry Smith {
182*5c6c1daeSBarry Smith   PetscErrorCode ierr;
183*5c6c1daeSBarry Smith 
184*5c6c1daeSBarry Smith   PetscFunctionBegin;
185*5c6c1daeSBarry Smith   ierr = PetscDrawXiOpenDisplay(w,host);CHKERRQ(ierr);
186*5c6c1daeSBarry Smith 
187*5c6c1daeSBarry Smith   w->vis    = DefaultVisual(w->disp,w->screen);
188*5c6c1daeSBarry Smith   w->depth  = DefaultDepth(w->disp,w->screen);
189*5c6c1daeSBarry Smith 
190*5c6c1daeSBarry Smith   ierr = PetscDrawSetColormap_X(w,host,(Colormap)0);CHKERRQ(ierr);
191*5c6c1daeSBarry Smith 
192*5c6c1daeSBarry Smith   ierr = PetscDrawXiDisplayWindow(w,name,x,y,nx,ny,(PetscDrawXiPixVal)0);CHKERRQ(ierr);
193*5c6c1daeSBarry Smith   PetscDrawXiSetGC(w,w->cmapping[1]);
194*5c6c1daeSBarry Smith   PetscDrawXiSetPixVal(w,w->background);
195*5c6c1daeSBarry Smith 
196*5c6c1daeSBarry Smith   ierr = PetscDrawXiFontFixed(w,6,10,&w->font);CHKERRQ(ierr);
197*5c6c1daeSBarry Smith   if (w->win) {
198*5c6c1daeSBarry Smith     XSetWindowBackground(w->disp,w->win,w->cmapping[0]);
199*5c6c1daeSBarry Smith     XFillRectangle(w->disp,w->win,w->gc.set,0,0,nx,ny);
200*5c6c1daeSBarry Smith   }
201*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
202*5c6c1daeSBarry Smith }
203*5c6c1daeSBarry Smith 
204*5c6c1daeSBarry Smith /*
205*5c6c1daeSBarry Smith    A version from an already defined window
206*5c6c1daeSBarry Smith */
207*5c6c1daeSBarry Smith #undef __FUNCT__
208*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindowFromWindow"
209*5c6c1daeSBarry Smith PetscErrorCode PetscDrawXiQuickWindowFromWindow(PetscDraw_X* w,char *host,Window win)
210*5c6c1daeSBarry Smith {
211*5c6c1daeSBarry Smith   Window            root;
212*5c6c1daeSBarry Smith   PetscErrorCode    ierr;
213*5c6c1daeSBarry Smith   int               d;
214*5c6c1daeSBarry Smith   unsigned int      ud;
215*5c6c1daeSBarry Smith   XWindowAttributes attributes;
216*5c6c1daeSBarry Smith 
217*5c6c1daeSBarry Smith   PetscFunctionBegin;
218*5c6c1daeSBarry Smith   ierr = PetscDrawXiOpenDisplay(w,host);CHKERRQ(ierr);
219*5c6c1daeSBarry Smith   w->win = win;
220*5c6c1daeSBarry Smith   XGetWindowAttributes(w->disp,w->win,&attributes);
221*5c6c1daeSBarry Smith 
222*5c6c1daeSBarry Smith   w->vis    = DefaultVisual(w->disp,w->screen);
223*5c6c1daeSBarry Smith   w->depth  = DefaultDepth(w->disp,w->screen);
224*5c6c1daeSBarry Smith   ierr      = PetscDrawSetColormap_X(w,host,attributes.colormap);CHKERRQ(ierr);
225*5c6c1daeSBarry Smith 
226*5c6c1daeSBarry Smith   XGetGeometry(w->disp,w->win,&root,&d,&d,(unsigned int *)&w->w,(unsigned int *)&w->h,&ud,&ud);
227*5c6c1daeSBarry Smith   w->x = w->y = 0;
228*5c6c1daeSBarry Smith 
229*5c6c1daeSBarry Smith   PetscDrawXiSetGC(w,w->cmapping[1]);
230*5c6c1daeSBarry Smith   PetscDrawXiSetPixVal(w,w->background);
231*5c6c1daeSBarry Smith   XSetWindowBackground(w->disp,w->win,w->cmapping[0]);
232*5c6c1daeSBarry Smith   ierr = PetscDrawXiFontFixed(w,6,10,&w->font);CHKERRQ(ierr);
233*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
234*5c6c1daeSBarry Smith }
235*5c6c1daeSBarry Smith 
236*5c6c1daeSBarry Smith /*
237*5c6c1daeSBarry Smith       PetscDrawXiSetWindowLabel - Sets new label in open window.
238*5c6c1daeSBarry Smith */
239*5c6c1daeSBarry Smith #undef __FUNCT__
240*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetWindowLabel"
241*5c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetWindowLabel(PetscDraw_X* Xiwin,char *label)
242*5c6c1daeSBarry Smith {
243*5c6c1daeSBarry Smith   XTextProperty prop;
244*5c6c1daeSBarry Smith   size_t        len;
245*5c6c1daeSBarry Smith   PetscErrorCode ierr;
246*5c6c1daeSBarry Smith 
247*5c6c1daeSBarry Smith   PetscFunctionBegin;
248*5c6c1daeSBarry Smith   XGetWMName(Xiwin->disp,Xiwin->win,&prop);
249*5c6c1daeSBarry Smith   prop.value  = (unsigned char *)label;
250*5c6c1daeSBarry Smith   ierr        = PetscStrlen(label,&len);CHKERRQ(ierr);
251*5c6c1daeSBarry Smith   prop.nitems = (long) len;
252*5c6c1daeSBarry Smith   XSetWMName(Xiwin->disp,Xiwin->win,&prop);
253*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
254*5c6c1daeSBarry Smith }
255*5c6c1daeSBarry Smith 
256*5c6c1daeSBarry Smith #undef __FUNCT__
257*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetToBackground"
258*5c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetToBackground(PetscDraw_X* XiWin)
259*5c6c1daeSBarry Smith {
260*5c6c1daeSBarry Smith   PetscFunctionBegin;
261*5c6c1daeSBarry Smith   if (XiWin->gc.cur_pix != XiWin->background) {
262*5c6c1daeSBarry Smith     XSetForeground(XiWin->disp,XiWin->gc.set,XiWin->background);
263*5c6c1daeSBarry Smith     XiWin->gc.cur_pix   = XiWin->background;
264*5c6c1daeSBarry Smith   }
265*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
266*5c6c1daeSBarry Smith 
267*5c6c1daeSBarry Smith }
268*5c6c1daeSBarry Smith 
269*5c6c1daeSBarry Smith #undef __FUNCT__
270*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSetSave_X"
271*5c6c1daeSBarry Smith PetscErrorCode  PetscDrawSetSave_X(PetscDraw draw,const char *filename)
272*5c6c1daeSBarry Smith {
273*5c6c1daeSBarry Smith   PetscErrorCode ierr;
274*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN)
275*5c6c1daeSBarry Smith   PetscMPIInt    rank;
276*5c6c1daeSBarry Smith   char           command[PETSC_MAX_PATH_LEN];
277*5c6c1daeSBarry Smith   FILE           *fd;
278*5c6c1daeSBarry Smith #endif
279*5c6c1daeSBarry Smith 
280*5c6c1daeSBarry Smith   PetscFunctionBegin;
281*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
282*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN)
283*5c6c1daeSBarry Smith   ierr = MPI_Comm_rank(((PetscObject)draw)->comm,&rank);CHKERRQ(ierr);
284*5c6c1daeSBarry Smith   if (!rank) {
285*5c6c1daeSBarry Smith     ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"rm -f %s_[0-9]*.Gif %s.m4v",draw->savefilename,draw->savefilename);CHKERRQ(ierr);
286*5c6c1daeSBarry Smith     ierr = PetscPOpen(((PetscObject)draw)->comm,PETSC_NULL,command,"r",&fd);CHKERRQ(ierr);
287*5c6c1daeSBarry Smith     ierr = PetscPClose(((PetscObject)draw)->comm,fd,PETSC_NULL);CHKERRQ(ierr);
288*5c6c1daeSBarry Smith   }
289*5c6c1daeSBarry Smith #endif
290*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
291*5c6c1daeSBarry Smith }
292*5c6c1daeSBarry Smith 
293*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_AFTERIMAGE)
294*5c6c1daeSBarry Smith #include <afterimage.h>
295*5c6c1daeSBarry Smith #undef __FUNCT__
296*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSave_X"
297*5c6c1daeSBarry Smith PetscErrorCode PetscDrawSave_X(PetscDraw draw)
298*5c6c1daeSBarry Smith {
299*5c6c1daeSBarry Smith   PetscDraw_X              *drawx = (PetscDraw_X*)draw->data;
300*5c6c1daeSBarry Smith   XImage                   *image;
301*5c6c1daeSBarry Smith   ASImage                  *asimage;
302*5c6c1daeSBarry Smith   static struct  ASVisual  *asv = 0;
303*5c6c1daeSBarry Smith   char                     filename[PETSC_MAX_PATH_LEN];
304*5c6c1daeSBarry Smith   PetscErrorCode           ierr;
305*5c6c1daeSBarry Smith   PetscMPIInt              rank;
306*5c6c1daeSBarry Smith 
307*5c6c1daeSBarry Smith   PetscFunctionBegin;
308*5c6c1daeSBarry Smith   ierr = MPI_Comm_rank(((PetscObject)draw)->comm,&rank);CHKERRQ(ierr);
309*5c6c1daeSBarry Smith   if (rank) PetscFunctionReturn(0);
310*5c6c1daeSBarry Smith   if (!draw->savefilename) PetscFunctionReturn(0);
311*5c6c1daeSBarry Smith   if (draw->savefilecount == -1) {
312*5c6c1daeSBarry Smith     /* The first PetscDrawClear() should happen before any drawing has been done, hence do not save at the first PetscDrawClear() */
313*5c6c1daeSBarry Smith     draw->savefilecount++;
314*5c6c1daeSBarry Smith     PetscFunctionReturn(0);
315*5c6c1daeSBarry Smith   }
316*5c6c1daeSBarry Smith 
317*5c6c1daeSBarry Smith   if (!asv) {
318*5c6c1daeSBarry Smith     asv = create_asvisual(drawx->disp, 0, 0, 0);if (!asv) SETERRQ(((PetscObject)draw)->comm,PETSC_ERR_PLIB,"Cannot create AfterImage ASVisual");
319*5c6c1daeSBarry Smith   }
320*5c6c1daeSBarry Smith   if (drawx->drw) {
321*5c6c1daeSBarry Smith     image   = XGetImage(drawx->disp, drawx->drw, 0, 0, drawx->w, drawx->h, AllPlanes, ZPixmap);if (!image) SETERRQ(((PetscObject)draw)->comm,PETSC_ERR_PLIB,"Cannot XGetImage()");\
322*5c6c1daeSBarry Smith   } else {
323*5c6c1daeSBarry Smith     image   = XGetImage(drawx->disp, drawx->win, 0, 0, drawx->w, drawx->h, AllPlanes, ZPixmap);if (!image) SETERRQ(((PetscObject)draw)->comm,PETSC_ERR_PLIB,"Cannot XGetImage()");
324*5c6c1daeSBarry Smith   }
325*5c6c1daeSBarry Smith   asimage = picture_ximage2asimage (asv,image,0,0);if (!asimage) SETERRQ(((PetscObject)draw)->comm,PETSC_ERR_PLIB,"Cannot create AfterImage ASImage");
326*5c6c1daeSBarry Smith   ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s_%d.Gif",draw->savefilename,draw->savefilecount++);CHKERRQ(ierr);
327*5c6c1daeSBarry Smith   ASImage2file( asimage, 0, filename,ASIT_Gif,0);
328*5c6c1daeSBarry Smith 
329*5c6c1daeSBarry Smith   XDestroyImage(image);
330*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
331*5c6c1daeSBarry Smith }
332*5c6c1daeSBarry Smith /*
333*5c6c1daeSBarry Smith    There are routines wanted by AfterImage for PNG files
334*5c6c1daeSBarry Smith  */
335*5c6c1daeSBarry Smith void crc32(void) {;}
336*5c6c1daeSBarry Smith void inflateReset(void) {;}
337*5c6c1daeSBarry Smith void deflateReset(void) {;}
338*5c6c1daeSBarry Smith void deflateInit2(void) {;}
339*5c6c1daeSBarry Smith void deflateInit2_(void) {;}
340*5c6c1daeSBarry Smith void deflate(void) {;}
341*5c6c1daeSBarry Smith void deflateEnd(void) {;}
342*5c6c1daeSBarry Smith 
343*5c6c1daeSBarry Smith #endif
344*5c6c1daeSBarry Smith 
345*5c6c1daeSBarry Smith 
346*5c6c1daeSBarry Smith 
347