xref: /petsc/src/sys/classes/draw/impls/x/xinit.c (revision 15d5bc7987684e36335e48c93f0d6e15cde33d97)
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 PetscDrawXi_wait_map(PetscDraw_X*);
175c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXiFontFixed(PetscDraw_X*,int,int,PetscDrawXiFont**);
185c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXiInitCmap(PetscDraw_X*);
19*15d5bc79SLisandro Dalcin extern PetscErrorCode PetscDrawSetColormap_X(PetscDraw_X*,Colormap);
205c6c1daeSBarry Smith 
215c6c1daeSBarry Smith /*
22*15d5bc79SLisandro Dalcin   PetscDrawXiOpenDisplay - Open and setup a display
235c6c1daeSBarry Smith */
245c6c1daeSBarry Smith #undef __FUNCT__
255c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiOpenDisplay"
26*15d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiOpenDisplay(PetscDraw_X *XiWin,const char display[])
275c6c1daeSBarry Smith {
285c6c1daeSBarry Smith   PetscFunctionBegin;
29*15d5bc79SLisandro Dalcin   XiWin->disp = XOpenDisplay(display);
305c6c1daeSBarry Smith   if (!XiWin->disp) {
31*15d5bc79SLisandro Dalcin     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open display on %s\n\
32*15d5bc79SLisandro Dalcin     Make sure your COMPUTE NODES are authorized to connect \n\
335c6c1daeSBarry Smith     to this X server and either your DISPLAY variable\n\
34*15d5bc79SLisandro Dalcin     is set or you use the -display name option\n",display);
355c6c1daeSBarry Smith   }
365c6c1daeSBarry Smith   XiWin->screen     = DefaultScreen(XiWin->disp);
37481cee7bSLisandro Dalcin   XiWin->vis        = DefaultVisual(XiWin->disp,XiWin->screen);
38481cee7bSLisandro Dalcin   XiWin->depth      = DefaultDepth(XiWin->disp,XiWin->screen);
39*15d5bc79SLisandro Dalcin   XiWin->cmap       = DefaultColormap(XiWin->disp,XiWin->screen);
40*15d5bc79SLisandro Dalcin   XiWin->background = WhitePixel(XiWin->disp,XiWin->screen);
41*15d5bc79SLisandro Dalcin   XiWin->foreground = BlackPixel(XiWin->disp,XiWin->screen);
425c6c1daeSBarry Smith   PetscFunctionReturn(0);
435c6c1daeSBarry Smith }
445c6c1daeSBarry Smith 
455c6c1daeSBarry Smith /*
46*15d5bc79SLisandro Dalcin    PetscDrawXiSetGC - setup the GC structure
475c6c1daeSBarry Smith */
485c6c1daeSBarry Smith #undef __FUNCT__
495c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetGC"
505c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetGC(PetscDraw_X *XiWin,PetscDrawXiPixVal fg)
515c6c1daeSBarry Smith {
525c6c1daeSBarry Smith   XGCValues gcvalues;             /* window graphics context values */
535c6c1daeSBarry Smith 
545c6c1daeSBarry Smith   PetscFunctionBegin;
555c6c1daeSBarry Smith   /* Set the graphics contexts */
565c6c1daeSBarry Smith   /* create a gc for the ROP_SET operation (writing the fg value to a pixel) */
575c6c1daeSBarry Smith   /* (do this with function GXcopy; GXset will automatically write 1) */
585c6c1daeSBarry Smith   gcvalues.function   = GXcopy;
595c6c1daeSBarry Smith   gcvalues.foreground = fg;
605c6c1daeSBarry Smith   XiWin->gc.cur_pix   = fg;
615c6c1daeSBarry Smith   XiWin->gc.set       = XCreateGC(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),GCFunction|GCForeground,&gcvalues);
62*15d5bc79SLisandro Dalcin   if (!XiWin->gc.set) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to create X graphics context");
63*15d5bc79SLisandro Dalcin   PetscFunctionReturn(0);
64*15d5bc79SLisandro Dalcin }
65*15d5bc79SLisandro Dalcin 
66*15d5bc79SLisandro Dalcin /*
67*15d5bc79SLisandro Dalcin    PetscDrawXiInitialize - basic setup the draw (display, graphics context, font)
68*15d5bc79SLisandro Dalcin */
69*15d5bc79SLisandro Dalcin #undef __FUNCT__
70*15d5bc79SLisandro Dalcin #define __FUNCT__ "PetscDrawXiInitialize"
71*15d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiInitialize(PetscDraw_X *XiWin,char display[])
72*15d5bc79SLisandro Dalcin {
73*15d5bc79SLisandro Dalcin   PetscErrorCode ierr;
74*15d5bc79SLisandro Dalcin   PetscFunctionBegin;
75*15d5bc79SLisandro Dalcin   ierr = PetscDrawXiOpenDisplay(XiWin,display);CHKERRQ(ierr);
76*15d5bc79SLisandro Dalcin   ierr = PetscDrawXiSetGC(XiWin,XiWin->foreground);CHKERRQ(ierr);
77*15d5bc79SLisandro Dalcin   ierr = PetscDrawXiFontFixed(XiWin,6,10,&XiWin->font);CHKERRQ(ierr);
785c6c1daeSBarry Smith   PetscFunctionReturn(0);
795c6c1daeSBarry Smith }
805c6c1daeSBarry Smith 
815c6c1daeSBarry Smith /*
825c6c1daeSBarry Smith     Actually display a window at [x,y] with sizes (w,h)
835c6c1daeSBarry Smith */
845c6c1daeSBarry Smith #undef __FUNCT__
855c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiDisplayWindow"
86*15d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiDisplayWindow(PetscDraw_X *XiWin,char *label,int x,int y,int w,int h)
875c6c1daeSBarry Smith {
885c6c1daeSBarry Smith   unsigned int         wavail,havail;
895c6c1daeSBarry Smith   XSizeHints           size_hints;
905c6c1daeSBarry Smith   XWindowAttributes    in_window_attributes;
915c6c1daeSBarry Smith   XSetWindowAttributes window_attributes;
92*15d5bc79SLisandro Dalcin   unsigned int         border_width = 0;
93*15d5bc79SLisandro Dalcin   unsigned long        backgnd_pixel = WhitePixel(XiWin->disp,XiWin->screen);
945c6c1daeSBarry Smith   unsigned long        wmask;
955c6c1daeSBarry Smith 
965c6c1daeSBarry Smith   PetscFunctionBegin;
975c6c1daeSBarry Smith   /* get the available widths */
985c6c1daeSBarry Smith   wavail = DisplayWidth(XiWin->disp,XiWin->screen);
995c6c1daeSBarry Smith   havail = DisplayHeight(XiWin->disp,XiWin->screen);
1005c6c1daeSBarry Smith   if (w <= 0 || h <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"X Window display has invalid height or width");
1015c6c1daeSBarry Smith   if ((unsigned int)w > wavail) w = wavail;
1025c6c1daeSBarry Smith   if ((unsigned int)h > havail) h = havail;
1035c6c1daeSBarry Smith 
104*15d5bc79SLisandro Dalcin   if (x < 0) x = (int)(wavail - (unsigned int)w + (unsigned int)x);
105*15d5bc79SLisandro Dalcin   if (y < 0) y = (int)(havail - (unsigned int)h + (unsigned int)y);
106*15d5bc79SLisandro Dalcin   x = ((unsigned int)x + w > wavail) ? (int)(wavail - (unsigned int)w) : x;
107*15d5bc79SLisandro Dalcin   y = ((unsigned int)y + h > havail) ? (int)(havail - (unsigned int)h) : y;
1085c6c1daeSBarry Smith 
1095c6c1daeSBarry Smith   /* We need XCreateWindow since we may need an visual other than the default one */
1105c6c1daeSBarry Smith   XGetWindowAttributes(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),&in_window_attributes);
1115c6c1daeSBarry Smith   window_attributes.background_pixmap = None;
1125c6c1daeSBarry Smith   window_attributes.background_pixel  = backgnd_pixel;
1135c6c1daeSBarry Smith   /* No border for now */
1145c6c1daeSBarry Smith   window_attributes.border_pixmap     = None;
1155c6c1daeSBarry Smith   /*
1165c6c1daeSBarry Smith   window_attributes.border_pixel      = border_pixel;
1175c6c1daeSBarry Smith   */
1185c6c1daeSBarry Smith   window_attributes.bit_gravity       = in_window_attributes.bit_gravity;
1195c6c1daeSBarry Smith   window_attributes.win_gravity       = in_window_attributes.win_gravity;
1205c6c1daeSBarry Smith   /* Backing store is too slow in color systems */
121*15d5bc79SLisandro Dalcin   window_attributes.backing_store     = NotUseful;
1225c6c1daeSBarry Smith   window_attributes.backing_pixel     = backgnd_pixel;
1235c6c1daeSBarry Smith   window_attributes.save_under        = 1;
1245c6c1daeSBarry Smith   window_attributes.event_mask        = 0;
1255c6c1daeSBarry Smith   window_attributes.do_not_propagate_mask = 0;
1265c6c1daeSBarry Smith   window_attributes.override_redirect = 0;
1275c6c1daeSBarry Smith   window_attributes.colormap          = XiWin->cmap;
1285c6c1daeSBarry Smith   /* None for cursor does NOT mean none, it means cursor of Parent */
1295c6c1daeSBarry Smith   window_attributes.cursor            = None;
130a297a907SKarl Rupp 
1315c6c1daeSBarry Smith   wmask = CWBackPixmap | CWBackPixel    | CWBorderPixmap  | CWBitGravity |
1325c6c1daeSBarry Smith           CWWinGravity | CWBackingStore | CWBackingPixel  | CWOverrideRedirect |
1335c6c1daeSBarry Smith           CWSaveUnder  | CWEventMask    | CWDontPropagate |
1345c6c1daeSBarry Smith           CWCursor     | CWColormap;
1355c6c1daeSBarry Smith 
136*15d5bc79SLisandro Dalcin   XiWin->win = XCreateWindow(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),x,y,w,h,border_width,XiWin->depth,InputOutput,XiWin->vis,wmask,&window_attributes);
1375c6c1daeSBarry Smith   if (!XiWin->win) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open X window");
1385c6c1daeSBarry Smith 
1395c6c1daeSBarry Smith   /* set window manager hints */
1405c6c1daeSBarry Smith   {
1415c6c1daeSBarry Smith     XWMHints      wm_hints;
1425c6c1daeSBarry Smith     XClassHint    class_hints;
1435c6c1daeSBarry Smith     XTextProperty windowname,iconname;
1445c6c1daeSBarry Smith 
145a297a907SKarl Rupp     if (label) XStringListToTextProperty(&label,1,&windowname);
146a297a907SKarl Rupp     else       XStringListToTextProperty(&label,0,&windowname);
147a297a907SKarl Rupp     if (label) XStringListToTextProperty(&label,1,&iconname);
148a297a907SKarl Rupp     else       XStringListToTextProperty(&label,0,&iconname);
1495c6c1daeSBarry Smith 
1505c6c1daeSBarry Smith     wm_hints.initial_state = NormalState;
1515c6c1daeSBarry Smith     wm_hints.input         = True;
1525c6c1daeSBarry Smith     wm_hints.flags         = StateHint|InputHint;
1535c6c1daeSBarry Smith 
1545c6c1daeSBarry Smith     /* These properties can be used by window managers to decide how to display a window */
1555c6c1daeSBarry Smith     class_hints.res_name  = (char*)"petsc";
1565c6c1daeSBarry Smith     class_hints.res_class = (char*)"PETSc";
1575c6c1daeSBarry Smith 
1585c6c1daeSBarry Smith     size_hints.x          = x;
1595c6c1daeSBarry Smith     size_hints.y          = y;
1605c6c1daeSBarry Smith     size_hints.min_width  = 4*border_width;
1615c6c1daeSBarry Smith     size_hints.min_height = 4*border_width;
1625c6c1daeSBarry Smith     size_hints.width      = w;
1635c6c1daeSBarry Smith     size_hints.height     = h;
1645c6c1daeSBarry Smith     size_hints.flags      = USPosition | USSize | PMinSize;
1655c6c1daeSBarry Smith 
1665c6c1daeSBarry Smith     XSetWMProperties(XiWin->disp,XiWin->win,&windowname,&iconname,0,0,&size_hints,&wm_hints,&class_hints);
1675c6c1daeSBarry Smith     XFree((void*)windowname.value);
1685c6c1daeSBarry Smith     XFree((void*)iconname.value);
1695c6c1daeSBarry Smith   }
170481cee7bSLisandro Dalcin 
1715c6c1daeSBarry Smith   /* make the window visible */
1725c6c1daeSBarry Smith   XSelectInput(XiWin->disp,XiWin->win,ExposureMask|StructureNotifyMask);
1735c6c1daeSBarry Smith   XMapWindow(XiWin->disp,XiWin->win);
1745c6c1daeSBarry Smith 
1755c6c1daeSBarry Smith   /* some window systems are cruel and interfere with the placement of
1765c6c1daeSBarry Smith      windows.  We wait here for the window to be created or to die */
1775c6c1daeSBarry Smith   if (PetscDrawXi_wait_map(XiWin)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Wait for X window failed");
1785c6c1daeSBarry Smith   PetscFunctionReturn(0);
1795c6c1daeSBarry Smith }
1805c6c1daeSBarry Smith 
1815c6c1daeSBarry Smith #undef __FUNCT__
1825c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindow"
183*15d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiQuickWindow(PetscDraw_X *XiWin,char *name,int x,int y,int nx,int ny)
1845c6c1daeSBarry Smith {
185*15d5bc79SLisandro Dalcin   Window         root;
186*15d5bc79SLisandro Dalcin   unsigned int   w,h,dummy;
1875c6c1daeSBarry Smith   PetscErrorCode ierr;
1885c6c1daeSBarry Smith 
1895c6c1daeSBarry Smith   PetscFunctionBegin;
190*15d5bc79SLisandro Dalcin   ierr = PetscDrawSetColormap_X(XiWin,(Colormap)0);CHKERRQ(ierr);
191*15d5bc79SLisandro Dalcin   ierr = PetscDrawXiDisplayWindow(XiWin,name,x,y,nx,ny);CHKERRQ(ierr);
192*15d5bc79SLisandro Dalcin   XSetWindowBackground(XiWin->disp,XiWin->win,XiWin->background);
193*15d5bc79SLisandro Dalcin   XClearWindow(XiWin->disp,XiWin->win);
1945c6c1daeSBarry Smith 
195*15d5bc79SLisandro Dalcin   XGetGeometry(XiWin->disp,XiWin->win,&root,&x,&y,&w,&h,&dummy,&dummy);
196*15d5bc79SLisandro Dalcin   XiWin->x = x;
197*15d5bc79SLisandro Dalcin   XiWin->y = y;
198*15d5bc79SLisandro Dalcin   XiWin->w = (int)w;
199*15d5bc79SLisandro Dalcin   XiWin->h = (int)h;
2005c6c1daeSBarry Smith   PetscFunctionReturn(0);
2015c6c1daeSBarry Smith }
2025c6c1daeSBarry Smith 
2035c6c1daeSBarry Smith /*
2045c6c1daeSBarry Smith    A version from an already defined window
2055c6c1daeSBarry Smith */
2065c6c1daeSBarry Smith #undef __FUNCT__
2075c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindowFromWindow"
208*15d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiQuickWindowFromWindow(PetscDraw_X *XiWin,Window win)
2095c6c1daeSBarry Smith {
2105c6c1daeSBarry Smith   Window            root;
211*15d5bc79SLisandro Dalcin   int               x,y;
212*15d5bc79SLisandro Dalcin   unsigned int      w,h,dummy;
2135c6c1daeSBarry Smith   XWindowAttributes attributes;
214*15d5bc79SLisandro Dalcin   PetscErrorCode    ierr;
2155c6c1daeSBarry Smith 
2165c6c1daeSBarry Smith   PetscFunctionBegin;
217*15d5bc79SLisandro Dalcin   XiWin->win = win;
218*15d5bc79SLisandro Dalcin   XGetWindowAttributes(XiWin->disp,XiWin->win,&attributes);
219*15d5bc79SLisandro Dalcin   ierr = PetscDrawSetColormap_X(XiWin,attributes.colormap);CHKERRQ(ierr);
220481cee7bSLisandro Dalcin 
221*15d5bc79SLisandro Dalcin   XGetGeometry(XiWin->disp,XiWin->win,&root,&x,&y,&w,&h,&dummy,&dummy);
222*15d5bc79SLisandro Dalcin   XiWin->x = x;
223*15d5bc79SLisandro Dalcin   XiWin->y = y;
224*15d5bc79SLisandro Dalcin   XiWin->w = (int)w;
225*15d5bc79SLisandro Dalcin   XiWin->h = (int)h;
2265c6c1daeSBarry Smith   PetscFunctionReturn(0);
2275c6c1daeSBarry Smith }
2285c6c1daeSBarry Smith 
2295c6c1daeSBarry Smith /*
2305c6c1daeSBarry Smith       PetscDrawXiSetWindowLabel - Sets new label in open window.
2315c6c1daeSBarry Smith */
2325c6c1daeSBarry Smith #undef __FUNCT__
2335c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetWindowLabel"
234*15d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiSetWindowLabel(PetscDraw_X *XiWin,char *label)
2355c6c1daeSBarry Smith {
2365c6c1daeSBarry Smith   XTextProperty  prop;
2375c6c1daeSBarry Smith   size_t         len;
2385c6c1daeSBarry Smith   PetscErrorCode ierr;
2395c6c1daeSBarry Smith 
2405c6c1daeSBarry Smith   PetscFunctionBegin;
2415c6c1daeSBarry Smith   ierr = PetscStrlen(label,&len);CHKERRQ(ierr);
242*15d5bc79SLisandro Dalcin   XGetWMName(XiWin->disp,XiWin->win,&prop);
243*15d5bc79SLisandro Dalcin   prop.value  = (unsigned char*)label;
2445c6c1daeSBarry Smith   prop.nitems = (long)len;
245*15d5bc79SLisandro Dalcin   XSetWMName(XiWin->disp,XiWin->win,&prop);
2465c6c1daeSBarry Smith   PetscFunctionReturn(0);
2475c6c1daeSBarry Smith }
2485c6c1daeSBarry Smith 
2495c6c1daeSBarry Smith #undef __FUNCT__
2505c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetToBackground"
2515c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetToBackground(PetscDraw_X *XiWin)
2525c6c1daeSBarry Smith {
2535c6c1daeSBarry Smith   PetscFunctionBegin;
2545c6c1daeSBarry Smith   if (XiWin->gc.cur_pix != XiWin->background) {
2555c6c1daeSBarry Smith     XSetForeground(XiWin->disp,XiWin->gc.set,XiWin->background);
2565c6c1daeSBarry Smith     XiWin->gc.cur_pix = XiWin->background;
2575c6c1daeSBarry Smith   }
2585c6c1daeSBarry Smith   PetscFunctionReturn(0);
2595c6c1daeSBarry Smith 
2605c6c1daeSBarry Smith }
2615c6c1daeSBarry Smith 
2625c6c1daeSBarry Smith #undef __FUNCT__
2635c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSetSave_X"
2645c6c1daeSBarry Smith PetscErrorCode  PetscDrawSetSave_X(PetscDraw draw,const char *filename)
2655c6c1daeSBarry Smith {
2665c6c1daeSBarry Smith   PetscErrorCode ierr;
2675c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN)
2685c6c1daeSBarry Smith   PetscMPIInt    rank;
2695c6c1daeSBarry Smith #endif
2705c6c1daeSBarry Smith 
2715c6c1daeSBarry Smith   PetscFunctionBegin;
2725c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
2735c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN)
274ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
2755c6c1daeSBarry Smith   if (!rank) {
276d45a07a7SBarry Smith     char  command[PETSC_MAX_PATH_LEN];
277d45a07a7SBarry Smith     FILE  *fd;
278d45a07a7SBarry Smith     int   err;
279d45a07a7SBarry Smith 
280d45a07a7SBarry Smith     ierr = PetscMemzero(command,sizeof(command));CHKERRQ(ierr);
2819982bd17SBarry Smith     ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"rm -fr %s %s.m4v",draw->savefilename,draw->savefilename);CHKERRQ(ierr);
282e97f6855SBarry Smith     ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr);
2830076e027SBarry Smith     ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr);
2849982bd17SBarry Smith     ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"mkdir %s",draw->savefilename);CHKERRQ(ierr);
285e97f6855SBarry Smith     ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr);
2860076e027SBarry Smith     ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr);
2875c6c1daeSBarry Smith   }
2885c6c1daeSBarry Smith #endif
2895c6c1daeSBarry Smith   PetscFunctionReturn(0);
2905c6c1daeSBarry Smith }
2915c6c1daeSBarry Smith 
2921cda70a7SBarry Smith 
2935c6c1daeSBarry Smith #if defined(PETSC_HAVE_AFTERIMAGE)
2945c6c1daeSBarry Smith #include <afterimage.h>
295aee23540SBarry Smith 
29676f01e85SBarry Smith /* String names of possible Afterimage formats */
29776f01e85SBarry Smith const char *PetscAfterImageFormats[] = {
29876f01e85SBarry Smith         ".Xpm",
29976f01e85SBarry Smith 	".Xpm.Z",
30076f01e85SBarry Smith 	".Xpm.gz",
30176f01e85SBarry Smith 	".Png",
30276f01e85SBarry Smith 	".Jpeg",
303f140b876SBarry Smith 	".Xcf", /* Gimp format */
30476f01e85SBarry Smith 	".Ppm",
30576f01e85SBarry Smith 	".Pnm",
306f140b876SBarry Smith 	"MS Windows Bitmap",
307f140b876SBarry Smith 	"MS Windows Icon",
308f140b876SBarry Smith 	"MS Windows Cursor",
30976f01e85SBarry Smith 	".Gif",
31076f01e85SBarry Smith 	".Tiff",
311f140b876SBarry Smith 	"Afterstep XMLScript",
312f140b876SBarry Smith 	"Scalable Vector Graphics (SVG)",
31376f01e85SBarry Smith 	".Xbm",
31476f01e85SBarry Smith 	"Targa",
31576f01e85SBarry Smith 	".Pcx",
31676f01e85SBarry Smith 	".HTML",
31776f01e85SBarry Smith 	"XML",
31876f01e85SBarry Smith 	"Unknown"
319aee23540SBarry Smith };
320aee23540SBarry Smith 
321aee23540SBarry Smith #undef __FUNCT__
32276f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageStringToFormat"
32376f01e85SBarry Smith static PetscErrorCode PetscAfterimageStringToFormat(const char *ext,ASImageFileTypes *format)
324aee23540SBarry Smith {
32576f01e85SBarry Smith   PetscInt       i;
326aee23540SBarry Smith   PetscErrorCode ierr;
32776f01e85SBarry Smith   PetscBool      flg;
328aee23540SBarry Smith 
329aee23540SBarry Smith   PetscFunctionBegin;
330f140b876SBarry Smith   ierr = PetscStrcasecmp(".Jpg",ext,&flg);CHKERRQ(ierr);
331f140b876SBarry Smith   if (flg) ext = ".Jpeg";
33276f01e85SBarry Smith   for (i=0; i<sizeof(PetscAfterImageFormats)/sizeof(char**); i++) {
33376f01e85SBarry Smith     ierr = PetscStrcasecmp(PetscAfterImageFormats[i],ext,&flg);CHKERRQ(ierr);
33476f01e85SBarry Smith     if (flg) {
33576f01e85SBarry Smith       *format = (ASImageFileTypes)i;
33676f01e85SBarry Smith       PetscFunctionReturn(0);
33776f01e85SBarry Smith     }
33876f01e85SBarry Smith   }
33976f01e85SBarry Smith   *format = ASIT_Unknown;
34076f01e85SBarry Smith   PetscFunctionReturn(0);
34176f01e85SBarry Smith }
34276f01e85SBarry Smith 
34376f01e85SBarry Smith #if defined(PETSC_HAVE_SAWS)
34476f01e85SBarry Smith #include <petscviewersaws.h>
34576f01e85SBarry Smith /*
34676f01e85SBarry Smith   The PetscAfterimage object and functions are used to maintain a list of file images created by Afterimage that can
34776f01e85SBarry Smith   be displayed by the SAWs webserver.
34876f01e85SBarry Smith */
34976f01e85SBarry Smith typedef struct _P_PetscAfterimage *PetscAfterimage;
35076f01e85SBarry Smith struct _P_PetscAfterimage {
35176f01e85SBarry Smith   PetscAfterimage next;
35276f01e85SBarry Smith   char            *filename;
35376f01e85SBarry Smith   char            *ext;
35476f01e85SBarry Smith   PetscInt        cnt;
35576f01e85SBarry Smith } ;
35676f01e85SBarry Smith 
35776f01e85SBarry Smith static PetscAfterimage afterimages = 0;
35876f01e85SBarry Smith 
35976f01e85SBarry Smith #undef __FUNCT__
36076f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageDestroy"
36176f01e85SBarry Smith static PetscErrorCode PetscAfterimageDestroy(void)
36276f01e85SBarry Smith {
36376f01e85SBarry Smith   PetscErrorCode ierr;
36476f01e85SBarry Smith   PetscAfterimage       afterimage,oafterimage = afterimages;
36576f01e85SBarry Smith 
36676f01e85SBarry Smith   PetscFunctionBegin;
36776f01e85SBarry Smith   while (oafterimage) {
36876f01e85SBarry Smith     afterimage = oafterimage->next;
36976f01e85SBarry Smith     ierr = PetscFree(oafterimage->filename);CHKERRQ(ierr);
37076f01e85SBarry Smith     ierr = PetscFree(oafterimage->ext);CHKERRQ(ierr);
37176f01e85SBarry Smith     ierr = PetscFree(oafterimage);CHKERRQ(ierr);
37276f01e85SBarry Smith     oafterimage = afterimage;
373aee23540SBarry Smith   }
374aee23540SBarry Smith   PetscFunctionReturn(0);
375aee23540SBarry Smith }
376aee23540SBarry Smith 
377aee23540SBarry Smith #undef __FUNCT__
37876f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageAdd"
37976f01e85SBarry Smith static PetscErrorCode PetscAfterimageAdd(const char *filename,const char *ext,PetscInt cnt)
380aee23540SBarry Smith {
381aee23540SBarry Smith   PetscErrorCode   ierr;
38276f01e85SBarry Smith   PetscAfterimage  afterimage,oafterimage = afterimages;
383aee23540SBarry Smith   PetscBool        flg;
384aee23540SBarry Smith 
385aee23540SBarry Smith   PetscFunctionBegin;
38676f01e85SBarry Smith   if (oafterimage){
38776f01e85SBarry Smith     ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr);
38876f01e85SBarry Smith     if (flg) {
38976f01e85SBarry Smith       oafterimage->cnt = cnt;
39076f01e85SBarry Smith       PetscFunctionReturn(0);
391aee23540SBarry Smith     }
39276f01e85SBarry Smith     while (oafterimage->next) {
39376f01e85SBarry Smith       oafterimage = oafterimage->next;
39476f01e85SBarry Smith       ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr);
39576f01e85SBarry Smith       if (flg) {
39676f01e85SBarry Smith         oafterimage->cnt = cnt;
39776f01e85SBarry Smith         PetscFunctionReturn(0);
39876f01e85SBarry Smith       }
39976f01e85SBarry Smith     }
40076f01e85SBarry Smith     ierr = PetscNew(&afterimage);CHKERRQ(ierr);
40176f01e85SBarry Smith     oafterimage->next = afterimage;
402aee23540SBarry Smith   } else {
40376f01e85SBarry Smith     ierr = PetscNew(&afterimage);CHKERRQ(ierr);
40476f01e85SBarry Smith     afterimages = afterimage;
405aee23540SBarry Smith   }
40676f01e85SBarry Smith   ierr = PetscStrallocpy(filename,&afterimage->filename);CHKERRQ(ierr);
40776f01e85SBarry Smith   ierr = PetscStrallocpy(ext,&afterimage->ext);CHKERRQ(ierr);
40876f01e85SBarry Smith   afterimage->cnt = cnt;
40976f01e85SBarry Smith   ierr = PetscRegisterFinalize(PetscAfterimageDestroy);CHKERRQ(ierr);
410aee23540SBarry Smith   PetscFunctionReturn(0);
411aee23540SBarry Smith }
412aee23540SBarry Smith 
413aee23540SBarry Smith #endif
414aee23540SBarry Smith 
4155c6c1daeSBarry Smith #undef __FUNCT__
4165c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSave_X"
4175c6c1daeSBarry Smith PetscErrorCode PetscDrawSave_X(PetscDraw draw)
4185c6c1daeSBarry Smith {
4195c6c1daeSBarry Smith   PetscDraw_X      *drawx = (PetscDraw_X*)draw->data;
4205c6c1daeSBarry Smith   XImage           *image;
4215c6c1daeSBarry Smith   ASImage          *asimage;
422681455b2SBarry Smith   struct  ASVisual *asv;
4235c6c1daeSBarry Smith   char             filename[PETSC_MAX_PATH_LEN];
4245c6c1daeSBarry Smith   PetscErrorCode   ierr;
4255c6c1daeSBarry Smith   PetscMPIInt      rank;
426681455b2SBarry Smith   int              depth;
42776f01e85SBarry Smith   ASImageFileTypes format;
4285c6c1daeSBarry Smith 
4295c6c1daeSBarry Smith   PetscFunctionBegin;
430ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
4315c6c1daeSBarry Smith   if (rank) PetscFunctionReturn(0);
4325c6c1daeSBarry Smith   if (!draw->savefilename) PetscFunctionReturn(0);
4335c6c1daeSBarry Smith   if (draw->savefilecount == -1) {
4345c6c1daeSBarry Smith     /* The first PetscDrawClear() should happen before any drawing has been done, hence do not save at the first PetscDrawClear() */
4355c6c1daeSBarry Smith     draw->savefilecount++;
4365c6c1daeSBarry Smith     PetscFunctionReturn(0);
4375c6c1daeSBarry Smith   }
438681455b2SBarry Smith   XSynchronize(drawx->disp, True);
439681455b2SBarry Smith   depth = DefaultDepth( drawx->disp, drawx->screen );
440681455b2SBarry Smith   asv   = create_asvisual(drawx->disp, drawx->screen, depth, NULL);if (!asv) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASVisual");
4415c6c1daeSBarry Smith 
4429982bd17SBarry Smith   image   = XGetImage(drawx->disp, drawx->drw ? drawx->drw : drawx->win, 0, 0, drawx->w, drawx->h, AllPlanes, ZPixmap);
44376f01e85SBarry Smith   if (!image) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot XGetImage()");
444ce94432eSBarry Smith   asimage = picture_ximage2asimage (asv,image,0,0);if (!asimage) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASImage");
4458b7fcac6SBarry Smith   if (draw->savesinglefile) {
44676f01e85SBarry Smith     ierr    = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s%s",draw->savefilename,draw->savefilename,draw->savefilenameext);CHKERRQ(ierr);
4478b7fcac6SBarry Smith   } else {
44876f01e85SBarry Smith     ierr    = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s_%d%s",draw->savefilename,draw->savefilename,draw->savefilecount++,draw->savefilenameext);CHKERRQ(ierr);
4498b7fcac6SBarry Smith   }
45076f01e85SBarry Smith   ierr = PetscAfterimageStringToFormat(draw->savefilenameext,&format);CHKERRQ(ierr);
45176f01e85SBarry Smith   ASImage2file(asimage, 0, filename,format,0);
4521cda70a7SBarry Smith #if defined(PETSC_HAVE_SAWS)
4531cda70a7SBarry Smith   {
454aee23540SBarry Smith     char     body[4096];
45576f01e85SBarry Smith     PetscAfterimage afterimage;
456aee23540SBarry Smith     size_t   len = 0;
457aee23540SBarry Smith 
45876f01e85SBarry Smith     ierr = PetscAfterimageAdd(draw->savefilename,draw->savefilenameext,draw->savefilecount-1);CHKERRQ(ierr);
45976f01e85SBarry Smith     afterimage  = afterimages;
46076f01e85SBarry Smith     while (afterimage) {
46176f01e85SBarry Smith       if (draw->savesinglefile) {
46276f01e85SBarry Smith         ierr = PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s%s\" alt=\"None\">",afterimage->filename,afterimage->filename,afterimage->ext);CHKERRQ(ierr);
46376f01e85SBarry Smith       } else {
46476f01e85SBarry 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);
46576f01e85SBarry Smith       }
466aee23540SBarry Smith       ierr = PetscStrlen(body,&len);CHKERRQ(ierr);
46776f01e85SBarry Smith       afterimage  = afterimage->next;
468aee23540SBarry Smith     }
469aee23540SBarry Smith     ierr = PetscStrcat(body,"<br>\n");CHKERRQ(ierr);
47043da4ab2SBarry Smith     if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1));
47143da4ab2SBarry Smith     PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body));
4721cda70a7SBarry Smith   }
4731cda70a7SBarry Smith #endif
4745c6c1daeSBarry Smith 
4755c6c1daeSBarry Smith   XDestroyImage(image);
476681455b2SBarry Smith   destroy_asvisual(asv,0);
4775c6c1daeSBarry Smith   PetscFunctionReturn(0);
4785c6c1daeSBarry Smith }
4795c6c1daeSBarry Smith /*
4805c6c1daeSBarry Smith    There are routines wanted by AfterImage for PNG files
4815c6c1daeSBarry Smith  */
4825c6c1daeSBarry Smith void crc32(void) {;}
4835c6c1daeSBarry Smith void inflateReset(void) {;}
4845c6c1daeSBarry Smith void deflateReset(void) {;}
4855c6c1daeSBarry Smith void deflateInit2(void) {;}
4865c6c1daeSBarry Smith void deflateInit2_(void) {;}
4875c6c1daeSBarry Smith void deflate(void) {;}
4885c6c1daeSBarry Smith void deflateEnd(void) {;}
4895c6c1daeSBarry Smith 
4905c6c1daeSBarry Smith #endif
4915c6c1daeSBarry Smith 
4925c6c1daeSBarry Smith 
4935c6c1daeSBarry Smith 
494