xref: /petsc/src/sys/classes/draw/impls/x/xinit.c (revision 481cee7b9d2ba1ac12db554daff76ad6aa1c27eb)
15c6c1daeSBarry Smith 
25c6c1daeSBarry Smith /*
35c6c1daeSBarry Smith    This file contains routines to open an X window display and window
45c6c1daeSBarry Smith    This consists of a number of routines that set the various
55c6c1daeSBarry Smith    fields in the Window structure, which is passed to
65c6c1daeSBarry Smith    all of these routines.
75c6c1daeSBarry Smith 
85c6c1daeSBarry Smith    Note that if you use the default visual and colormap, then you
95c6c1daeSBarry Smith    can use these routines with any X toolkit that will give you the
105c6c1daeSBarry Smith    Window id of the window that it is managing.  Use that instead of the
115c6c1daeSBarry Smith    call to PetscDrawXiCreateWindow .  Similarly for the Display.
125c6c1daeSBarry Smith */
135c6c1daeSBarry Smith 
145c6c1daeSBarry Smith #include <../src/sys/classes/draw/impls/x/ximpl.h>
155c6c1daeSBarry Smith 
165c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXiUniformHues(PetscDraw_X*,int);
175c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXi_wait_map(PetscDraw_X*);
185c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXiFontFixed(PetscDraw_X*,int,int,PetscDrawXiFont**);
195c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXiInitCmap(PetscDraw_X*);
205c6c1daeSBarry Smith extern PetscErrorCode PetscDrawSetColormap_X(PetscDraw_X*,char*,Colormap);
215c6c1daeSBarry Smith 
225c6c1daeSBarry Smith /*
235c6c1daeSBarry Smith   PetscDrawXiOpenDisplay - Open a display
245c6c1daeSBarry Smith */
255c6c1daeSBarry Smith #undef __FUNCT__
265c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiOpenDisplay"
275c6c1daeSBarry Smith PetscErrorCode PetscDrawXiOpenDisplay(PetscDraw_X *XiWin,char *display_name)
285c6c1daeSBarry Smith {
295c6c1daeSBarry Smith   PetscFunctionBegin;
305c6c1daeSBarry Smith   XiWin->disp = XOpenDisplay(display_name);
315c6c1daeSBarry Smith   if (!XiWin->disp) {
325c6c1daeSBarry 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\
335c6c1daeSBarry Smith     to this X server and either your DISPLAY variable\n\
345c6c1daeSBarry Smith     is set or you use the -display name option\n",display_name);
355c6c1daeSBarry Smith   }
365c6c1daeSBarry Smith   XiWin->screen = DefaultScreen(XiWin->disp);
37*481cee7bSLisandro Dalcin   XiWin->vis = DefaultVisual(XiWin->disp,XiWin->screen);
38*481cee7bSLisandro Dalcin   XiWin->depth = DefaultDepth(XiWin->disp,XiWin->screen);
395c6c1daeSBarry Smith   PetscFunctionReturn(0);
405c6c1daeSBarry Smith }
415c6c1daeSBarry Smith 
425c6c1daeSBarry Smith 
435c6c1daeSBarry Smith /*
445c6c1daeSBarry Smith    PetscDrawXiSetGC - set the GC structure in the base window
455c6c1daeSBarry Smith */
465c6c1daeSBarry Smith #undef __FUNCT__
475c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetGC"
485c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetGC(PetscDraw_X *XiWin,PetscDrawXiPixVal fg)
495c6c1daeSBarry Smith {
505c6c1daeSBarry Smith   XGCValues gcvalues;             /* window graphics context values */
515c6c1daeSBarry Smith 
525c6c1daeSBarry Smith   PetscFunctionBegin;
535c6c1daeSBarry Smith   /* Set the graphics contexts */
545c6c1daeSBarry Smith   /* create a gc for the ROP_SET operation (writing the fg value to a pixel) */
555c6c1daeSBarry Smith   /* (do this with function GXcopy; GXset will automatically write 1) */
565c6c1daeSBarry Smith   gcvalues.function   = GXcopy;
575c6c1daeSBarry Smith   gcvalues.foreground = fg;
585c6c1daeSBarry Smith   XiWin->gc.cur_pix   = fg;
595c6c1daeSBarry Smith   XiWin->gc.set       = XCreateGC(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),GCFunction | GCForeground,&gcvalues);
605c6c1daeSBarry Smith   PetscFunctionReturn(0);
615c6c1daeSBarry Smith }
625c6c1daeSBarry Smith 
635c6c1daeSBarry Smith /*
645c6c1daeSBarry Smith     Actually display a window at [x,y] with sizes (w,h)
655c6c1daeSBarry Smith     If w and/or h are 0, use the sizes in the fields of XiWin
665c6c1daeSBarry Smith     (which may have been set by, for example, PetscDrawXiSetWindowSize)
675c6c1daeSBarry Smith */
685c6c1daeSBarry Smith #undef __FUNCT__
695c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiDisplayWindow"
705c6c1daeSBarry Smith PetscErrorCode PetscDrawXiDisplayWindow(PetscDraw_X *XiWin,char *label,int x,int y,int w,int h,PetscDrawXiPixVal backgnd_pixel)
715c6c1daeSBarry Smith {
725c6c1daeSBarry Smith   unsigned int         wavail,havail;
735c6c1daeSBarry Smith   XSizeHints           size_hints;
745c6c1daeSBarry Smith   XWindowAttributes    in_window_attributes;
755c6c1daeSBarry Smith   XSetWindowAttributes window_attributes;
765c6c1daeSBarry Smith   int                  depth,border_width;
775c6c1daeSBarry Smith   unsigned long        wmask;
785c6c1daeSBarry Smith   PetscBool            flg;
795c6c1daeSBarry Smith   PetscErrorCode       ierr;
805c6c1daeSBarry Smith 
815c6c1daeSBarry Smith   PetscFunctionBegin;
825c6c1daeSBarry Smith   /* get the available widths */
835c6c1daeSBarry Smith   wavail = DisplayWidth(XiWin->disp,XiWin->screen);
845c6c1daeSBarry Smith   havail = DisplayHeight(XiWin->disp,XiWin->screen);
855c6c1daeSBarry Smith   if (w <= 0 || h <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"X Window display has invalid height or width");
865c6c1daeSBarry Smith   if ((unsigned int) w > wavail) w = wavail;
875c6c1daeSBarry Smith   if ((unsigned int) h > havail) h = havail;
885c6c1daeSBarry Smith 
895c6c1daeSBarry Smith   border_width = 0;
905c6c1daeSBarry Smith   if (x < 0) x = 0;
915c6c1daeSBarry Smith   if (y < 0) y = 0;
923964eb88SJed Brown   x = ((unsigned int) x + w > wavail) ? wavail - w : (unsigned int)x;
933964eb88SJed Brown   y = ((unsigned int) y + h > havail) ? havail - h : (unsigned int)y;
945c6c1daeSBarry Smith 
955c6c1daeSBarry Smith   /* We need XCreateWindow since we may need an visual other than the default one */
965c6c1daeSBarry Smith   XGetWindowAttributes(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),&in_window_attributes);
975c6c1daeSBarry Smith   window_attributes.background_pixmap = None;
985c6c1daeSBarry Smith   window_attributes.background_pixel  = backgnd_pixel;
995c6c1daeSBarry Smith   /* No border for now */
1005c6c1daeSBarry Smith   window_attributes.border_pixmap     = None;
1015c6c1daeSBarry Smith   /*
1025c6c1daeSBarry Smith   window_attributes.border_pixel      = border_pixel;
1035c6c1daeSBarry Smith   */
1045c6c1daeSBarry Smith   window_attributes.bit_gravity       = in_window_attributes.bit_gravity;
1055c6c1daeSBarry Smith   window_attributes.win_gravity       = in_window_attributes.win_gravity;
1065c6c1daeSBarry Smith   /* Backing store is too slow in color systems */
1075c6c1daeSBarry Smith   window_attributes.backing_store     = 0;
1085c6c1daeSBarry Smith   window_attributes.backing_pixel     = backgnd_pixel;
1095c6c1daeSBarry Smith   window_attributes.save_under        = 1;
1105c6c1daeSBarry Smith   window_attributes.event_mask        = 0;
1115c6c1daeSBarry Smith   window_attributes.do_not_propagate_mask = 0;
1125c6c1daeSBarry Smith   window_attributes.override_redirect = 0;
1135c6c1daeSBarry Smith   window_attributes.colormap          = XiWin->cmap;
1145c6c1daeSBarry Smith   /* None for cursor does NOT mean none, it means cursor of Parent */
1155c6c1daeSBarry Smith   window_attributes.cursor            = None;
116a297a907SKarl Rupp 
1175c6c1daeSBarry Smith   wmask = CWBackPixmap | CWBackPixel    | CWBorderPixmap  | CWBitGravity |
1185c6c1daeSBarry Smith           CWWinGravity | CWBackingStore |CWBackingPixel   |CWOverrideRedirect |
1195c6c1daeSBarry Smith           CWSaveUnder  | CWEventMask    | CWDontPropagate |
1205c6c1daeSBarry Smith           CWCursor     | CWColormap;
1215c6c1daeSBarry Smith   depth = XiWin->depth;
1225c6c1daeSBarry Smith 
1235c6c1daeSBarry Smith   XiWin->win = XCreateWindow(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),x,y,w,h,border_width,depth,InputOutput,XiWin->vis,wmask,&window_attributes);
1245c6c1daeSBarry Smith   if (!XiWin->win) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open X window");
1255c6c1daeSBarry Smith 
1265c6c1daeSBarry Smith   /* set window manager hints */
1275c6c1daeSBarry Smith   {
1285c6c1daeSBarry Smith     XWMHints      wm_hints;
1295c6c1daeSBarry Smith     XClassHint    class_hints;
1305c6c1daeSBarry Smith     XTextProperty windowname,iconname;
1315c6c1daeSBarry Smith 
132a297a907SKarl Rupp     if (label) XStringListToTextProperty(&label,1,&windowname);
133a297a907SKarl Rupp     else       XStringListToTextProperty(&label,0,&windowname);
134a297a907SKarl Rupp     if (label) XStringListToTextProperty(&label,1,&iconname);
135a297a907SKarl Rupp     else       XStringListToTextProperty(&label,0,&iconname);
1365c6c1daeSBarry Smith 
1375c6c1daeSBarry Smith     wm_hints.initial_state = NormalState;
1385c6c1daeSBarry Smith     wm_hints.input         = True;
1395c6c1daeSBarry Smith     wm_hints.flags         = StateHint|InputHint;
1405c6c1daeSBarry Smith 
1415c6c1daeSBarry Smith     /* These properties can be used by window managers to decide how to display a window */
1425c6c1daeSBarry Smith     class_hints.res_name  = (char*)"petsc";
1435c6c1daeSBarry Smith     class_hints.res_class = (char*)"PETSc";
1445c6c1daeSBarry Smith 
1455c6c1daeSBarry Smith     size_hints.x          = x;
1465c6c1daeSBarry Smith     size_hints.y          = y;
1475c6c1daeSBarry Smith     size_hints.min_width  = 4*border_width;
1485c6c1daeSBarry Smith     size_hints.min_height = 4*border_width;
1495c6c1daeSBarry Smith     size_hints.width      = w;
1505c6c1daeSBarry Smith     size_hints.height     = h;
1515c6c1daeSBarry Smith     size_hints.flags      = USPosition | USSize | PMinSize;
1525c6c1daeSBarry Smith 
1535c6c1daeSBarry Smith     XSetWMProperties(XiWin->disp,XiWin->win,&windowname,&iconname,0,0,&size_hints,&wm_hints,&class_hints);
1545c6c1daeSBarry Smith     XFree((void*)windowname.value);
1555c6c1daeSBarry Smith     XFree((void*)iconname.value);
1565c6c1daeSBarry Smith   }
157*481cee7bSLisandro Dalcin 
1585c6c1daeSBarry Smith   /* make the window visible */
1595c6c1daeSBarry Smith   XSelectInput(XiWin->disp,XiWin->win,ExposureMask|StructureNotifyMask);
1605c6c1daeSBarry Smith   XMapWindow(XiWin->disp,XiWin->win);
1615c6c1daeSBarry Smith 
1625c6c1daeSBarry Smith   /* some window systems are cruel and interfere with the placement of
1635c6c1daeSBarry Smith      windows.  We wait here for the window to be created or to die */
1645c6c1daeSBarry Smith   if (PetscDrawXi_wait_map(XiWin)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Wait for X window failed");
1655c6c1daeSBarry Smith 
1665c6c1daeSBarry Smith   flg  = PETSC_FALSE;
167c5929fdfSBarry Smith   ierr = PetscOptionsGetBool(NULL,NULL,"-draw_virtual",&flg,NULL);CHKERRQ(ierr);
1685c6c1daeSBarry Smith   if (flg) {
1695c6c1daeSBarry Smith     XiWin->drw = XCreatePixmap(XiWin->disp,XiWin->win,XiWin->w,XiWin->h,XiWin->depth);
1705c6c1daeSBarry Smith     XDestroyWindow(XiWin->disp,XiWin->win);
1715c6c1daeSBarry Smith     XiWin->win = 0;
1725c6c1daeSBarry Smith     PetscFunctionReturn(0);
1735c6c1daeSBarry Smith   }
1745c6c1daeSBarry Smith 
1755c6c1daeSBarry Smith   /* Initial values for the upper left corner */
1765c6c1daeSBarry Smith   XiWin->x = 0;
1775c6c1daeSBarry Smith   XiWin->y = 0;
1785c6c1daeSBarry Smith   PetscFunctionReturn(0);
1795c6c1daeSBarry Smith }
1805c6c1daeSBarry Smith 
1815c6c1daeSBarry Smith #undef __FUNCT__
1825c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindow"
1835c6c1daeSBarry Smith PetscErrorCode PetscDrawXiQuickWindow(PetscDraw_X *w,char *host,char *name,int x,int y,int nx,int ny)
1845c6c1daeSBarry Smith {
1855c6c1daeSBarry Smith   PetscErrorCode ierr;
1865c6c1daeSBarry Smith 
1875c6c1daeSBarry Smith   PetscFunctionBegin;
1885c6c1daeSBarry Smith   ierr = PetscDrawXiOpenDisplay(w,host);CHKERRQ(ierr);
1895c6c1daeSBarry Smith 
1905c6c1daeSBarry Smith   ierr = PetscDrawSetColormap_X(w,host,(Colormap)0);CHKERRQ(ierr);
1915c6c1daeSBarry Smith 
1925c6c1daeSBarry Smith   ierr = PetscDrawXiDisplayWindow(w,name,x,y,nx,ny,(PetscDrawXiPixVal)0);CHKERRQ(ierr);
19300d931feSLisandro Dalcin   PetscDrawXiSetGC(w,w->cmapping[PETSC_DRAW_BLACK]);
1945c6c1daeSBarry Smith   PetscDrawXiSetPixVal(w,w->background);
1955c6c1daeSBarry Smith 
1965c6c1daeSBarry Smith   ierr = PetscDrawXiFontFixed(w,6,10,&w->font);CHKERRQ(ierr);
1975c6c1daeSBarry Smith   if (w->win) {
19800d931feSLisandro Dalcin     XSetWindowBackground(w->disp,w->win,w->cmapping[PETSC_DRAW_WHITE]);
1995c6c1daeSBarry Smith     XFillRectangle(w->disp,w->win,w->gc.set,0,0,nx,ny);
2005c6c1daeSBarry Smith   }
2015c6c1daeSBarry Smith   PetscFunctionReturn(0);
2025c6c1daeSBarry Smith }
2035c6c1daeSBarry Smith 
2045c6c1daeSBarry Smith /*
2055c6c1daeSBarry Smith    A version from an already defined window
2065c6c1daeSBarry Smith */
2075c6c1daeSBarry Smith #undef __FUNCT__
2085c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindowFromWindow"
2095c6c1daeSBarry Smith PetscErrorCode PetscDrawXiQuickWindowFromWindow(PetscDraw_X *w,char *host,Window win)
2105c6c1daeSBarry Smith {
2115c6c1daeSBarry Smith   Window            root;
2125c6c1daeSBarry Smith   PetscErrorCode    ierr;
2135c6c1daeSBarry Smith   int               d;
2145c6c1daeSBarry Smith   unsigned int      ud;
2155c6c1daeSBarry Smith   XWindowAttributes attributes;
2165c6c1daeSBarry Smith 
2175c6c1daeSBarry Smith   PetscFunctionBegin;
2185c6c1daeSBarry Smith   ierr = PetscDrawXiOpenDisplay(w,host);CHKERRQ(ierr);
219*481cee7bSLisandro Dalcin 
2205c6c1daeSBarry Smith   w->win = win;
2215c6c1daeSBarry Smith   XGetWindowAttributes(w->disp,w->win,&attributes);
2225c6c1daeSBarry Smith   XGetGeometry(w->disp,w->win,&root,&d,&d,(unsigned int*)&w->w,(unsigned int*)&w->h,&ud,&ud);
2235c6c1daeSBarry Smith   w->x = w->y = 0;
2245c6c1daeSBarry Smith 
225*481cee7bSLisandro Dalcin   ierr = PetscDrawSetColormap_X(w,host,attributes.colormap);CHKERRQ(ierr);
226*481cee7bSLisandro Dalcin 
22700d931feSLisandro Dalcin   PetscDrawXiSetGC(w,w->cmapping[PETSC_DRAW_BLACK]);
2285c6c1daeSBarry Smith   PetscDrawXiSetPixVal(w,w->background);
22900d931feSLisandro Dalcin   XSetWindowBackground(w->disp,w->win,w->cmapping[PETSC_DRAW_WHITE]);
2305c6c1daeSBarry Smith   ierr = PetscDrawXiFontFixed(w,6,10,&w->font);CHKERRQ(ierr);
2315c6c1daeSBarry Smith   PetscFunctionReturn(0);
2325c6c1daeSBarry Smith }
2335c6c1daeSBarry Smith 
2345c6c1daeSBarry Smith /*
2355c6c1daeSBarry Smith       PetscDrawXiSetWindowLabel - Sets new label in open window.
2365c6c1daeSBarry Smith */
2375c6c1daeSBarry Smith #undef __FUNCT__
2385c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetWindowLabel"
2395c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetWindowLabel(PetscDraw_X *Xiwin,char *label)
2405c6c1daeSBarry Smith {
2415c6c1daeSBarry Smith   XTextProperty  prop;
2425c6c1daeSBarry Smith   size_t         len;
2435c6c1daeSBarry Smith   PetscErrorCode ierr;
2445c6c1daeSBarry Smith 
2455c6c1daeSBarry Smith   PetscFunctionBegin;
2465c6c1daeSBarry Smith   XGetWMName(Xiwin->disp,Xiwin->win,&prop);
2475c6c1daeSBarry Smith   prop.value  = (unsigned char*)label;
2485c6c1daeSBarry Smith   ierr        = PetscStrlen(label,&len);CHKERRQ(ierr);
2495c6c1daeSBarry Smith   prop.nitems = (long) len;
2505c6c1daeSBarry Smith   XSetWMName(Xiwin->disp,Xiwin->win,&prop);
2515c6c1daeSBarry Smith   PetscFunctionReturn(0);
2525c6c1daeSBarry Smith }
2535c6c1daeSBarry Smith 
2545c6c1daeSBarry Smith #undef __FUNCT__
2555c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetToBackground"
2565c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetToBackground(PetscDraw_X *XiWin)
2575c6c1daeSBarry Smith {
2585c6c1daeSBarry Smith   PetscFunctionBegin;
2595c6c1daeSBarry Smith   if (XiWin->gc.cur_pix != XiWin->background) {
2605c6c1daeSBarry Smith     XSetForeground(XiWin->disp,XiWin->gc.set,XiWin->background);
2615c6c1daeSBarry Smith     XiWin->gc.cur_pix = XiWin->background;
2625c6c1daeSBarry Smith   }
2635c6c1daeSBarry Smith   PetscFunctionReturn(0);
2645c6c1daeSBarry Smith 
2655c6c1daeSBarry Smith }
2665c6c1daeSBarry Smith 
2675c6c1daeSBarry Smith #undef __FUNCT__
2685c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSetSave_X"
2695c6c1daeSBarry Smith PetscErrorCode  PetscDrawSetSave_X(PetscDraw draw,const char *filename)
2705c6c1daeSBarry Smith {
2715c6c1daeSBarry Smith   PetscErrorCode ierr;
2725c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN)
2735c6c1daeSBarry Smith   PetscMPIInt    rank;
2745c6c1daeSBarry Smith #endif
2755c6c1daeSBarry Smith 
2765c6c1daeSBarry Smith   PetscFunctionBegin;
2775c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
2785c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN)
279ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
2805c6c1daeSBarry Smith   if (!rank) {
281d45a07a7SBarry Smith     char  command[PETSC_MAX_PATH_LEN];
282d45a07a7SBarry Smith     FILE  *fd;
283d45a07a7SBarry Smith     int   err;
284d45a07a7SBarry Smith 
285d45a07a7SBarry Smith     ierr = PetscMemzero(command,sizeof(command));CHKERRQ(ierr);
2869982bd17SBarry Smith     ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"rm -fr %s %s.m4v",draw->savefilename,draw->savefilename);CHKERRQ(ierr);
287e97f6855SBarry Smith     ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr);
2880076e027SBarry Smith     ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr);
2899982bd17SBarry Smith     ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"mkdir %s",draw->savefilename);CHKERRQ(ierr);
290e97f6855SBarry Smith     ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr);
2910076e027SBarry Smith     ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr);
2925c6c1daeSBarry Smith   }
2935c6c1daeSBarry Smith #endif
2945c6c1daeSBarry Smith   PetscFunctionReturn(0);
2955c6c1daeSBarry Smith }
2965c6c1daeSBarry Smith 
2971cda70a7SBarry Smith 
2985c6c1daeSBarry Smith #if defined(PETSC_HAVE_AFTERIMAGE)
2995c6c1daeSBarry Smith #include <afterimage.h>
300aee23540SBarry Smith 
30176f01e85SBarry Smith /* String names of possible Afterimage formats */
30276f01e85SBarry Smith const char *PetscAfterImageFormats[] = {
30376f01e85SBarry Smith         ".Xpm",
30476f01e85SBarry Smith 	".Xpm.Z",
30576f01e85SBarry Smith 	".Xpm.gz",
30676f01e85SBarry Smith 	".Png",
30776f01e85SBarry Smith 	".Jpeg",
308f140b876SBarry Smith 	".Xcf", /* Gimp format */
30976f01e85SBarry Smith 	".Ppm",
31076f01e85SBarry Smith 	".Pnm",
311f140b876SBarry Smith 	"MS Windows Bitmap",
312f140b876SBarry Smith 	"MS Windows Icon",
313f140b876SBarry Smith 	"MS Windows Cursor",
31476f01e85SBarry Smith 	".Gif",
31576f01e85SBarry Smith 	".Tiff",
316f140b876SBarry Smith 	"Afterstep XMLScript",
317f140b876SBarry Smith 	"Scalable Vector Graphics (SVG)",
31876f01e85SBarry Smith 	".Xbm",
31976f01e85SBarry Smith 	"Targa",
32076f01e85SBarry Smith 	".Pcx",
32176f01e85SBarry Smith 	".HTML",
32276f01e85SBarry Smith 	"XML",
32376f01e85SBarry Smith 	"Unknown"
324aee23540SBarry Smith };
325aee23540SBarry Smith 
326aee23540SBarry Smith #undef __FUNCT__
32776f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageStringToFormat"
32876f01e85SBarry Smith static PetscErrorCode PetscAfterimageStringToFormat(const char *ext,ASImageFileTypes *format)
329aee23540SBarry Smith {
33076f01e85SBarry Smith   PetscInt       i;
331aee23540SBarry Smith   PetscErrorCode ierr;
33276f01e85SBarry Smith   PetscBool      flg;
333aee23540SBarry Smith 
334aee23540SBarry Smith   PetscFunctionBegin;
335f140b876SBarry Smith   ierr = PetscStrcasecmp(".Jpg",ext,&flg);CHKERRQ(ierr);
336f140b876SBarry Smith   if (flg) ext = ".Jpeg";
33776f01e85SBarry Smith   for (i=0; i<sizeof(PetscAfterImageFormats)/sizeof(char**); i++) {
33876f01e85SBarry Smith     ierr = PetscStrcasecmp(PetscAfterImageFormats[i],ext,&flg);CHKERRQ(ierr);
33976f01e85SBarry Smith     if (flg) {
34076f01e85SBarry Smith       *format = (ASImageFileTypes)i;
34176f01e85SBarry Smith       PetscFunctionReturn(0);
34276f01e85SBarry Smith     }
34376f01e85SBarry Smith   }
34476f01e85SBarry Smith   *format = ASIT_Unknown;
34576f01e85SBarry Smith   PetscFunctionReturn(0);
34676f01e85SBarry Smith }
34776f01e85SBarry Smith 
34876f01e85SBarry Smith #if defined(PETSC_HAVE_SAWS)
34976f01e85SBarry Smith #include <petscviewersaws.h>
35076f01e85SBarry Smith /*
35176f01e85SBarry Smith   The PetscAfterimage object and functions are used to maintain a list of file images created by Afterimage that can
35276f01e85SBarry Smith   be displayed by the SAWs webserver.
35376f01e85SBarry Smith */
35476f01e85SBarry Smith typedef struct _P_PetscAfterimage *PetscAfterimage;
35576f01e85SBarry Smith struct _P_PetscAfterimage {
35676f01e85SBarry Smith   PetscAfterimage next;
35776f01e85SBarry Smith   char            *filename;
35876f01e85SBarry Smith   char            *ext;
35976f01e85SBarry Smith   PetscInt        cnt;
36076f01e85SBarry Smith } ;
36176f01e85SBarry Smith 
36276f01e85SBarry Smith static PetscAfterimage afterimages = 0;
36376f01e85SBarry Smith 
36476f01e85SBarry Smith #undef __FUNCT__
36576f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageDestroy"
36676f01e85SBarry Smith static PetscErrorCode PetscAfterimageDestroy(void)
36776f01e85SBarry Smith {
36876f01e85SBarry Smith   PetscErrorCode ierr;
36976f01e85SBarry Smith   PetscAfterimage       afterimage,oafterimage = afterimages;
37076f01e85SBarry Smith 
37176f01e85SBarry Smith   PetscFunctionBegin;
37276f01e85SBarry Smith   while (oafterimage) {
37376f01e85SBarry Smith     afterimage = oafterimage->next;
37476f01e85SBarry Smith     ierr = PetscFree(oafterimage->filename);CHKERRQ(ierr);
37576f01e85SBarry Smith     ierr = PetscFree(oafterimage->ext);CHKERRQ(ierr);
37676f01e85SBarry Smith     ierr = PetscFree(oafterimage);CHKERRQ(ierr);
37776f01e85SBarry Smith     oafterimage = afterimage;
378aee23540SBarry Smith   }
379aee23540SBarry Smith   PetscFunctionReturn(0);
380aee23540SBarry Smith }
381aee23540SBarry Smith 
382aee23540SBarry Smith #undef __FUNCT__
38376f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageAdd"
38476f01e85SBarry Smith static PetscErrorCode PetscAfterimageAdd(const char *filename,const char *ext,PetscInt cnt)
385aee23540SBarry Smith {
386aee23540SBarry Smith   PetscErrorCode   ierr;
38776f01e85SBarry Smith   PetscAfterimage  afterimage,oafterimage = afterimages;
388aee23540SBarry Smith   PetscBool        flg;
389aee23540SBarry Smith 
390aee23540SBarry Smith   PetscFunctionBegin;
39176f01e85SBarry Smith   if (oafterimage){
39276f01e85SBarry Smith     ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr);
39376f01e85SBarry Smith     if (flg) {
39476f01e85SBarry Smith       oafterimage->cnt = cnt;
39576f01e85SBarry Smith       PetscFunctionReturn(0);
396aee23540SBarry Smith     }
39776f01e85SBarry Smith     while (oafterimage->next) {
39876f01e85SBarry Smith       oafterimage = oafterimage->next;
39976f01e85SBarry Smith       ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr);
40076f01e85SBarry Smith       if (flg) {
40176f01e85SBarry Smith         oafterimage->cnt = cnt;
40276f01e85SBarry Smith         PetscFunctionReturn(0);
40376f01e85SBarry Smith       }
40476f01e85SBarry Smith     }
40576f01e85SBarry Smith     ierr = PetscNew(&afterimage);CHKERRQ(ierr);
40676f01e85SBarry Smith     oafterimage->next = afterimage;
407aee23540SBarry Smith   } else {
40876f01e85SBarry Smith     ierr = PetscNew(&afterimage);CHKERRQ(ierr);
40976f01e85SBarry Smith     afterimages = afterimage;
410aee23540SBarry Smith   }
41176f01e85SBarry Smith   ierr = PetscStrallocpy(filename,&afterimage->filename);CHKERRQ(ierr);
41276f01e85SBarry Smith   ierr = PetscStrallocpy(ext,&afterimage->ext);CHKERRQ(ierr);
41376f01e85SBarry Smith   afterimage->cnt = cnt;
41476f01e85SBarry Smith   ierr = PetscRegisterFinalize(PetscAfterimageDestroy);CHKERRQ(ierr);
415aee23540SBarry Smith   PetscFunctionReturn(0);
416aee23540SBarry Smith }
417aee23540SBarry Smith 
418aee23540SBarry Smith #endif
419aee23540SBarry Smith 
4205c6c1daeSBarry Smith #undef __FUNCT__
4215c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSave_X"
4225c6c1daeSBarry Smith PetscErrorCode PetscDrawSave_X(PetscDraw draw)
4235c6c1daeSBarry Smith {
4245c6c1daeSBarry Smith   PetscDraw_X      *drawx = (PetscDraw_X*)draw->data;
4255c6c1daeSBarry Smith   XImage           *image;
4265c6c1daeSBarry Smith   ASImage          *asimage;
427681455b2SBarry Smith   struct  ASVisual *asv;
4285c6c1daeSBarry Smith   char             filename[PETSC_MAX_PATH_LEN];
4295c6c1daeSBarry Smith   PetscErrorCode   ierr;
4305c6c1daeSBarry Smith   PetscMPIInt      rank;
431681455b2SBarry Smith   int              depth;
43276f01e85SBarry Smith   ASImageFileTypes format;
4335c6c1daeSBarry Smith 
4345c6c1daeSBarry Smith   PetscFunctionBegin;
435ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
4365c6c1daeSBarry Smith   if (rank) PetscFunctionReturn(0);
4375c6c1daeSBarry Smith   if (!draw->savefilename) PetscFunctionReturn(0);
4385c6c1daeSBarry Smith   if (draw->savefilecount == -1) {
4395c6c1daeSBarry Smith     /* The first PetscDrawClear() should happen before any drawing has been done, hence do not save at the first PetscDrawClear() */
4405c6c1daeSBarry Smith     draw->savefilecount++;
4415c6c1daeSBarry Smith     PetscFunctionReturn(0);
4425c6c1daeSBarry Smith   }
443681455b2SBarry Smith   XSynchronize(drawx->disp, True);
444681455b2SBarry Smith   depth = DefaultDepth( drawx->disp, drawx->screen );
445681455b2SBarry Smith   asv   = create_asvisual(drawx->disp, drawx->screen, depth, NULL);if (!asv) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASVisual");
4465c6c1daeSBarry Smith 
4479982bd17SBarry Smith   image   = XGetImage(drawx->disp, drawx->drw ? drawx->drw : drawx->win, 0, 0, drawx->w, drawx->h, AllPlanes, ZPixmap);
44876f01e85SBarry Smith   if (!image) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot XGetImage()");
449ce94432eSBarry Smith   asimage = picture_ximage2asimage (asv,image,0,0);if (!asimage) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASImage");
4508b7fcac6SBarry Smith   if (draw->savesinglefile) {
45176f01e85SBarry Smith     ierr    = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s%s",draw->savefilename,draw->savefilename,draw->savefilenameext);CHKERRQ(ierr);
4528b7fcac6SBarry Smith   } else {
45376f01e85SBarry Smith     ierr    = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s_%d%s",draw->savefilename,draw->savefilename,draw->savefilecount++,draw->savefilenameext);CHKERRQ(ierr);
4548b7fcac6SBarry Smith   }
45576f01e85SBarry Smith   ierr = PetscAfterimageStringToFormat(draw->savefilenameext,&format);CHKERRQ(ierr);
45676f01e85SBarry Smith   ASImage2file(asimage, 0, filename,format,0);
4571cda70a7SBarry Smith #if defined(PETSC_HAVE_SAWS)
4581cda70a7SBarry Smith   {
459aee23540SBarry Smith     char     body[4096];
46076f01e85SBarry Smith     PetscAfterimage afterimage;
461aee23540SBarry Smith     size_t   len = 0;
462aee23540SBarry Smith 
46376f01e85SBarry Smith     ierr = PetscAfterimageAdd(draw->savefilename,draw->savefilenameext,draw->savefilecount-1);CHKERRQ(ierr);
46476f01e85SBarry Smith     afterimage  = afterimages;
46576f01e85SBarry Smith     while (afterimage) {
46676f01e85SBarry Smith       if (draw->savesinglefile) {
46776f01e85SBarry Smith         ierr = PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s%s\" alt=\"None\">",afterimage->filename,afterimage->filename,afterimage->ext);CHKERRQ(ierr);
46876f01e85SBarry Smith       } else {
46976f01e85SBarry Smith         ierr = PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s_%d%s\" alt=\"None\">",afterimage->filename,afterimage->filename,afterimage->cnt,afterimage->ext);CHKERRQ(ierr);
47076f01e85SBarry Smith       }
471aee23540SBarry Smith       ierr = PetscStrlen(body,&len);CHKERRQ(ierr);
47276f01e85SBarry Smith       afterimage  = afterimage->next;
473aee23540SBarry Smith     }
474aee23540SBarry Smith     ierr = PetscStrcat(body,"<br>\n");CHKERRQ(ierr);
47543da4ab2SBarry Smith     if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1));
47643da4ab2SBarry Smith     PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body));
4771cda70a7SBarry Smith   }
4781cda70a7SBarry Smith #endif
4795c6c1daeSBarry Smith 
4805c6c1daeSBarry Smith   XDestroyImage(image);
481681455b2SBarry Smith   destroy_asvisual(asv,0);
4825c6c1daeSBarry Smith   PetscFunctionReturn(0);
4835c6c1daeSBarry Smith }
4845c6c1daeSBarry Smith /*
4855c6c1daeSBarry Smith    There are routines wanted by AfterImage for PNG files
4865c6c1daeSBarry Smith  */
4875c6c1daeSBarry Smith void crc32(void) {;}
4885c6c1daeSBarry Smith void inflateReset(void) {;}
4895c6c1daeSBarry Smith void deflateReset(void) {;}
4905c6c1daeSBarry Smith void deflateInit2(void) {;}
4915c6c1daeSBarry Smith void deflateInit2_(void) {;}
4925c6c1daeSBarry Smith void deflate(void) {;}
4935c6c1daeSBarry Smith void deflateEnd(void) {;}
4945c6c1daeSBarry Smith 
4955c6c1daeSBarry Smith #endif
4965c6c1daeSBarry Smith 
4975c6c1daeSBarry Smith 
4985c6c1daeSBarry Smith 
499