xref: /petsc/src/sys/classes/draw/impls/x/xinit.c (revision 65d9662d86c761487b3875c99d02cb2e87b4df42)
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*);
1915d5bc79SLisandro Dalcin extern PetscErrorCode PetscDrawSetColormap_X(PetscDraw_X*,Colormap);
205c6c1daeSBarry Smith 
215c6c1daeSBarry Smith /*
2215d5bc79SLisandro Dalcin   PetscDrawXiOpenDisplay - Open and setup a display
235c6c1daeSBarry Smith */
245c6c1daeSBarry Smith #undef __FUNCT__
255c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiOpenDisplay"
2615d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiOpenDisplay(PetscDraw_X *XiWin,const char display[])
275c6c1daeSBarry Smith {
285c6c1daeSBarry Smith   PetscFunctionBegin;
2915d5bc79SLisandro Dalcin   XiWin->disp = XOpenDisplay(display);
305c6c1daeSBarry Smith   if (!XiWin->disp) {
3115d5bc79SLisandro Dalcin     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open display on %s\n\
3215d5bc79SLisandro Dalcin     Make sure your COMPUTE NODES are authorized to connect \n\
335c6c1daeSBarry Smith     to this X server and either your DISPLAY variable\n\
3415d5bc79SLisandro 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);
3915d5bc79SLisandro Dalcin   XiWin->cmap       = DefaultColormap(XiWin->disp,XiWin->screen);
4015d5bc79SLisandro Dalcin   XiWin->background = WhitePixel(XiWin->disp,XiWin->screen);
4115d5bc79SLisandro Dalcin   XiWin->foreground = BlackPixel(XiWin->disp,XiWin->screen);
425c6c1daeSBarry Smith   PetscFunctionReturn(0);
435c6c1daeSBarry Smith }
445c6c1daeSBarry Smith 
45815f00f0SLisandro Dalcin #undef __FUNCT__
46815f00f0SLisandro Dalcin #define __FUNCT__ "PetscDrawXiClose"
47815f00f0SLisandro Dalcin PetscErrorCode PetscDrawXiClose(PetscDraw_X *XiWin)
48815f00f0SLisandro Dalcin {
49815f00f0SLisandro Dalcin   PetscErrorCode ierr;
50815f00f0SLisandro Dalcin 
51815f00f0SLisandro Dalcin   PetscFunctionBegin;
52815f00f0SLisandro Dalcin   if (!XiWin) PetscFunctionReturn(0);
53815f00f0SLisandro Dalcin   ierr = PetscFree(XiWin->font);CHKERRQ(ierr);
54815f00f0SLisandro Dalcin   if (XiWin->disp) {
55815f00f0SLisandro Dalcin #if defined(PETSC_HAVE_SETJMP_H)
56815f00f0SLisandro Dalcin     jmp_buf              jmpbuf;
57815f00f0SLisandro Dalcin     PetscXIOErrorHandler xioerrhdl;
58815f00f0SLisandro Dalcin     ierr = PetscMemcpy(&jmpbuf,&PetscXIOErrorHandlerJumpBuf,sizeof(jmpbuf));CHKERRQ(ierr);
59815f00f0SLisandro Dalcin     xioerrhdl = PetscSetXIOErrorHandler(PetscXIOErrorHandlerJump);
60815f00f0SLisandro Dalcin     if (!setjmp(PetscXIOErrorHandlerJumpBuf))
61815f00f0SLisandro Dalcin #endif
62815f00f0SLisandro Dalcin     {
63815f00f0SLisandro Dalcin       XFreeGC(XiWin->disp,XiWin->gc.set);
64815f00f0SLisandro Dalcin       XCloseDisplay(XiWin->disp);
65815f00f0SLisandro Dalcin     }
66815f00f0SLisandro Dalcin     XiWin->disp = NULL;
67815f00f0SLisandro Dalcin #if defined(PETSC_HAVE_SETJMP_H)
68815f00f0SLisandro Dalcin     (void)PetscSetXIOErrorHandler(xioerrhdl);
69815f00f0SLisandro Dalcin     ierr = PetscMemcpy(&PetscXIOErrorHandlerJumpBuf,&jmpbuf,sizeof(jmpbuf));CHKERRQ(ierr);
70815f00f0SLisandro Dalcin #endif
71815f00f0SLisandro Dalcin   }
72815f00f0SLisandro Dalcin   PetscFunctionReturn(0);
73815f00f0SLisandro Dalcin }
74815f00f0SLisandro Dalcin 
755c6c1daeSBarry Smith /*
7615d5bc79SLisandro Dalcin    PetscDrawXiSetGC - setup the GC structure
775c6c1daeSBarry Smith */
785c6c1daeSBarry Smith #undef __FUNCT__
795c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetGC"
805c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetGC(PetscDraw_X *XiWin,PetscDrawXiPixVal fg)
815c6c1daeSBarry Smith {
825c6c1daeSBarry Smith   XGCValues gcvalues;             /* window graphics context values */
835c6c1daeSBarry Smith 
845c6c1daeSBarry Smith   PetscFunctionBegin;
855c6c1daeSBarry Smith   /* Set the graphics contexts */
865c6c1daeSBarry Smith   /* create a gc for the ROP_SET operation (writing the fg value to a pixel) */
875c6c1daeSBarry Smith   /* (do this with function GXcopy; GXset will automatically write 1) */
885c6c1daeSBarry Smith   gcvalues.function   = GXcopy;
895c6c1daeSBarry Smith   gcvalues.foreground = fg;
905c6c1daeSBarry Smith   XiWin->gc.cur_pix   = fg;
915c6c1daeSBarry Smith   XiWin->gc.set       = XCreateGC(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),GCFunction|GCForeground,&gcvalues);
9215d5bc79SLisandro Dalcin   if (!XiWin->gc.set) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to create X graphics context");
9315d5bc79SLisandro Dalcin   PetscFunctionReturn(0);
9415d5bc79SLisandro Dalcin }
9515d5bc79SLisandro Dalcin 
9615d5bc79SLisandro Dalcin /*
97815f00f0SLisandro Dalcin    PetscDrawXiInit - basic setup the draw (display, graphics context, font)
9815d5bc79SLisandro Dalcin */
9915d5bc79SLisandro Dalcin #undef __FUNCT__
100815f00f0SLisandro Dalcin #define __FUNCT__ "PetscDrawXiInit"
101*65d9662dSLisandro Dalcin PetscErrorCode PetscDrawXiInit(PetscDraw_X *XiWin,const char display[])
10215d5bc79SLisandro Dalcin {
10315d5bc79SLisandro Dalcin   PetscErrorCode ierr;
10415d5bc79SLisandro Dalcin   PetscFunctionBegin;
10515d5bc79SLisandro Dalcin   ierr = PetscDrawXiOpenDisplay(XiWin,display);CHKERRQ(ierr);
10615d5bc79SLisandro Dalcin   ierr = PetscDrawXiSetGC(XiWin,XiWin->foreground);CHKERRQ(ierr);
10715d5bc79SLisandro Dalcin   ierr = PetscDrawXiFontFixed(XiWin,6,10,&XiWin->font);CHKERRQ(ierr);
1085c6c1daeSBarry Smith   PetscFunctionReturn(0);
1095c6c1daeSBarry Smith }
1105c6c1daeSBarry Smith 
1115c6c1daeSBarry Smith /*
1125c6c1daeSBarry Smith     Actually display a window at [x,y] with sizes (w,h)
1135c6c1daeSBarry Smith */
1145c6c1daeSBarry Smith #undef __FUNCT__
1155c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiDisplayWindow"
11615d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiDisplayWindow(PetscDraw_X *XiWin,char *label,int x,int y,int w,int h)
1175c6c1daeSBarry Smith {
1185c6c1daeSBarry Smith   unsigned int         wavail,havail;
1195c6c1daeSBarry Smith   XSizeHints           size_hints;
1205c6c1daeSBarry Smith   XWindowAttributes    in_window_attributes;
1215c6c1daeSBarry Smith   XSetWindowAttributes window_attributes;
12215d5bc79SLisandro Dalcin   unsigned int         border_width = 0;
12315d5bc79SLisandro Dalcin   unsigned long        backgnd_pixel = WhitePixel(XiWin->disp,XiWin->screen);
1245c6c1daeSBarry Smith   unsigned long        wmask;
1255c6c1daeSBarry Smith 
1265c6c1daeSBarry Smith   PetscFunctionBegin;
1275c6c1daeSBarry Smith   /* get the available widths */
1285c6c1daeSBarry Smith   wavail = DisplayWidth(XiWin->disp,XiWin->screen);
1295c6c1daeSBarry Smith   havail = DisplayHeight(XiWin->disp,XiWin->screen);
1305c6c1daeSBarry Smith   if (w <= 0 || h <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"X Window display has invalid height or width");
1315c6c1daeSBarry Smith   if ((unsigned int)w > wavail) w = wavail;
1325c6c1daeSBarry Smith   if ((unsigned int)h > havail) h = havail;
1335c6c1daeSBarry Smith 
13415d5bc79SLisandro Dalcin   if (x < 0) x = (int)(wavail - (unsigned int)w + (unsigned int)x);
13515d5bc79SLisandro Dalcin   if (y < 0) y = (int)(havail - (unsigned int)h + (unsigned int)y);
13615d5bc79SLisandro Dalcin   x = ((unsigned int)x + w > wavail) ? (int)(wavail - (unsigned int)w) : x;
13715d5bc79SLisandro Dalcin   y = ((unsigned int)y + h > havail) ? (int)(havail - (unsigned int)h) : y;
1385c6c1daeSBarry Smith 
1395c6c1daeSBarry Smith   /* We need XCreateWindow since we may need an visual other than the default one */
1405c6c1daeSBarry Smith   XGetWindowAttributes(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),&in_window_attributes);
1415c6c1daeSBarry Smith   window_attributes.background_pixmap = None;
1425c6c1daeSBarry Smith   window_attributes.background_pixel  = backgnd_pixel;
1435c6c1daeSBarry Smith   /* No border for now */
1445c6c1daeSBarry Smith   window_attributes.border_pixmap     = None;
1455c6c1daeSBarry Smith   /*
1465c6c1daeSBarry Smith   window_attributes.border_pixel      = border_pixel;
1475c6c1daeSBarry Smith   */
1485c6c1daeSBarry Smith   window_attributes.bit_gravity       = in_window_attributes.bit_gravity;
1495c6c1daeSBarry Smith   window_attributes.win_gravity       = in_window_attributes.win_gravity;
1505c6c1daeSBarry Smith   /* Backing store is too slow in color systems */
15115d5bc79SLisandro Dalcin   window_attributes.backing_store     = NotUseful;
1525c6c1daeSBarry Smith   window_attributes.backing_pixel     = backgnd_pixel;
1535c6c1daeSBarry Smith   window_attributes.save_under        = 1;
1545c6c1daeSBarry Smith   window_attributes.event_mask        = 0;
1555c6c1daeSBarry Smith   window_attributes.do_not_propagate_mask = 0;
1565c6c1daeSBarry Smith   window_attributes.override_redirect = 0;
1575c6c1daeSBarry Smith   window_attributes.colormap          = XiWin->cmap;
1585c6c1daeSBarry Smith   /* None for cursor does NOT mean none, it means cursor of Parent */
1595c6c1daeSBarry Smith   window_attributes.cursor            = None;
160a297a907SKarl Rupp 
1615c6c1daeSBarry Smith   wmask = CWBackPixmap | CWBackPixel    | CWBorderPixmap  | CWBitGravity |
1625c6c1daeSBarry Smith           CWWinGravity | CWBackingStore | CWBackingPixel  | CWOverrideRedirect |
1635c6c1daeSBarry Smith           CWSaveUnder  | CWEventMask    | CWDontPropagate |
1645c6c1daeSBarry Smith           CWCursor     | CWColormap;
1655c6c1daeSBarry Smith 
16615d5bc79SLisandro 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);
1675c6c1daeSBarry Smith   if (!XiWin->win) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open X window");
1685c6c1daeSBarry Smith 
1695c6c1daeSBarry Smith   /* set window manager hints */
1705c6c1daeSBarry Smith   {
1715c6c1daeSBarry Smith     XWMHints      wm_hints;
1725c6c1daeSBarry Smith     XClassHint    class_hints;
1735c6c1daeSBarry Smith     XTextProperty windowname,iconname;
1745c6c1daeSBarry Smith 
175a297a907SKarl Rupp     if (label) XStringListToTextProperty(&label,1,&windowname);
176a297a907SKarl Rupp     else       XStringListToTextProperty(&label,0,&windowname);
177a297a907SKarl Rupp     if (label) XStringListToTextProperty(&label,1,&iconname);
178a297a907SKarl Rupp     else       XStringListToTextProperty(&label,0,&iconname);
1795c6c1daeSBarry Smith 
1805c6c1daeSBarry Smith     wm_hints.initial_state = NormalState;
1815c6c1daeSBarry Smith     wm_hints.input         = True;
1825c6c1daeSBarry Smith     wm_hints.flags         = StateHint|InputHint;
1835c6c1daeSBarry Smith 
1845c6c1daeSBarry Smith     /* These properties can be used by window managers to decide how to display a window */
1855c6c1daeSBarry Smith     class_hints.res_name  = (char*)"petsc";
1865c6c1daeSBarry Smith     class_hints.res_class = (char*)"PETSc";
1875c6c1daeSBarry Smith 
1885c6c1daeSBarry Smith     size_hints.x          = x;
1895c6c1daeSBarry Smith     size_hints.y          = y;
1905c6c1daeSBarry Smith     size_hints.min_width  = 4*border_width;
1915c6c1daeSBarry Smith     size_hints.min_height = 4*border_width;
1925c6c1daeSBarry Smith     size_hints.width      = w;
1935c6c1daeSBarry Smith     size_hints.height     = h;
1945c6c1daeSBarry Smith     size_hints.flags      = USPosition | USSize | PMinSize;
1955c6c1daeSBarry Smith 
1965c6c1daeSBarry Smith     XSetWMProperties(XiWin->disp,XiWin->win,&windowname,&iconname,0,0,&size_hints,&wm_hints,&class_hints);
1975c6c1daeSBarry Smith     XFree((void*)windowname.value);
1985c6c1daeSBarry Smith     XFree((void*)iconname.value);
1995c6c1daeSBarry Smith   }
200481cee7bSLisandro Dalcin 
2015c6c1daeSBarry Smith   /* make the window visible */
2025c6c1daeSBarry Smith   XSelectInput(XiWin->disp,XiWin->win,ExposureMask|StructureNotifyMask);
2035c6c1daeSBarry Smith   XMapWindow(XiWin->disp,XiWin->win);
2045c6c1daeSBarry Smith 
2055c6c1daeSBarry Smith   /* some window systems are cruel and interfere with the placement of
2065c6c1daeSBarry Smith      windows.  We wait here for the window to be created or to die */
2075c6c1daeSBarry Smith   if (PetscDrawXi_wait_map(XiWin)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Wait for X window failed");
2085c6c1daeSBarry Smith   PetscFunctionReturn(0);
2095c6c1daeSBarry Smith }
2105c6c1daeSBarry Smith 
2115c6c1daeSBarry Smith #undef __FUNCT__
2125c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindow"
21315d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiQuickWindow(PetscDraw_X *XiWin,char *name,int x,int y,int nx,int ny)
2145c6c1daeSBarry Smith {
21515d5bc79SLisandro Dalcin   Window         root;
21615d5bc79SLisandro Dalcin   unsigned int   w,h,dummy;
2175c6c1daeSBarry Smith   PetscErrorCode ierr;
2185c6c1daeSBarry Smith 
2195c6c1daeSBarry Smith   PetscFunctionBegin;
22015d5bc79SLisandro Dalcin   ierr = PetscDrawSetColormap_X(XiWin,(Colormap)0);CHKERRQ(ierr);
22115d5bc79SLisandro Dalcin   ierr = PetscDrawXiDisplayWindow(XiWin,name,x,y,nx,ny);CHKERRQ(ierr);
22215d5bc79SLisandro Dalcin   XSetWindowBackground(XiWin->disp,XiWin->win,XiWin->background);
22315d5bc79SLisandro Dalcin   XClearWindow(XiWin->disp,XiWin->win);
2245c6c1daeSBarry Smith 
22515d5bc79SLisandro Dalcin   XGetGeometry(XiWin->disp,XiWin->win,&root,&x,&y,&w,&h,&dummy,&dummy);
22615d5bc79SLisandro Dalcin   XiWin->x = x;
22715d5bc79SLisandro Dalcin   XiWin->y = y;
22815d5bc79SLisandro Dalcin   XiWin->w = (int)w;
22915d5bc79SLisandro Dalcin   XiWin->h = (int)h;
2305c6c1daeSBarry Smith   PetscFunctionReturn(0);
2315c6c1daeSBarry Smith }
2325c6c1daeSBarry Smith 
2335c6c1daeSBarry Smith /*
2345c6c1daeSBarry Smith    A version from an already defined window
2355c6c1daeSBarry Smith */
2365c6c1daeSBarry Smith #undef __FUNCT__
2375c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindowFromWindow"
23815d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiQuickWindowFromWindow(PetscDraw_X *XiWin,Window win)
2395c6c1daeSBarry Smith {
2405c6c1daeSBarry Smith   Window            root;
24115d5bc79SLisandro Dalcin   int               x,y;
24215d5bc79SLisandro Dalcin   unsigned int      w,h,dummy;
2435c6c1daeSBarry Smith   XWindowAttributes attributes;
24415d5bc79SLisandro Dalcin   PetscErrorCode    ierr;
2455c6c1daeSBarry Smith 
2465c6c1daeSBarry Smith   PetscFunctionBegin;
24715d5bc79SLisandro Dalcin   XiWin->win = win;
24815d5bc79SLisandro Dalcin   XGetWindowAttributes(XiWin->disp,XiWin->win,&attributes);
24915d5bc79SLisandro Dalcin   ierr = PetscDrawSetColormap_X(XiWin,attributes.colormap);CHKERRQ(ierr);
250481cee7bSLisandro Dalcin 
25115d5bc79SLisandro Dalcin   XGetGeometry(XiWin->disp,XiWin->win,&root,&x,&y,&w,&h,&dummy,&dummy);
25215d5bc79SLisandro Dalcin   XiWin->x = x;
25315d5bc79SLisandro Dalcin   XiWin->y = y;
25415d5bc79SLisandro Dalcin   XiWin->w = (int)w;
25515d5bc79SLisandro Dalcin   XiWin->h = (int)h;
2565c6c1daeSBarry Smith   PetscFunctionReturn(0);
2575c6c1daeSBarry Smith }
2585c6c1daeSBarry Smith 
2595c6c1daeSBarry Smith /*
2605c6c1daeSBarry Smith       PetscDrawXiSetWindowLabel - Sets new label in open window.
2615c6c1daeSBarry Smith */
2625c6c1daeSBarry Smith #undef __FUNCT__
2635c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetWindowLabel"
26415d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiSetWindowLabel(PetscDraw_X *XiWin,char *label)
2655c6c1daeSBarry Smith {
2665c6c1daeSBarry Smith   XTextProperty  prop;
2675c6c1daeSBarry Smith   size_t         len;
2685c6c1daeSBarry Smith   PetscErrorCode ierr;
2695c6c1daeSBarry Smith 
2705c6c1daeSBarry Smith   PetscFunctionBegin;
2715c6c1daeSBarry Smith   ierr = PetscStrlen(label,&len);CHKERRQ(ierr);
27215d5bc79SLisandro Dalcin   XGetWMName(XiWin->disp,XiWin->win,&prop);
27315d5bc79SLisandro Dalcin   prop.value  = (unsigned char*)label;
2745c6c1daeSBarry Smith   prop.nitems = (long)len;
27515d5bc79SLisandro Dalcin   XSetWMName(XiWin->disp,XiWin->win,&prop);
2765c6c1daeSBarry Smith   PetscFunctionReturn(0);
2775c6c1daeSBarry Smith }
2785c6c1daeSBarry Smith 
2795c6c1daeSBarry Smith #undef __FUNCT__
2805c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetToBackground"
2815c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetToBackground(PetscDraw_X *XiWin)
2825c6c1daeSBarry Smith {
2835c6c1daeSBarry Smith   PetscFunctionBegin;
2845c6c1daeSBarry Smith   if (XiWin->gc.cur_pix != XiWin->background) {
2855c6c1daeSBarry Smith     XSetForeground(XiWin->disp,XiWin->gc.set,XiWin->background);
2865c6c1daeSBarry Smith     XiWin->gc.cur_pix = XiWin->background;
2875c6c1daeSBarry Smith   }
2885c6c1daeSBarry Smith   PetscFunctionReturn(0);
2895c6c1daeSBarry Smith 
2905c6c1daeSBarry Smith }
2915c6c1daeSBarry Smith 
2925c6c1daeSBarry Smith #undef __FUNCT__
2935c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSetSave_X"
2945c6c1daeSBarry Smith PetscErrorCode  PetscDrawSetSave_X(PetscDraw draw,const char *filename)
2955c6c1daeSBarry Smith {
2965c6c1daeSBarry Smith   PetscErrorCode ierr;
2975c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN)
2985c6c1daeSBarry Smith   PetscMPIInt    rank;
2995c6c1daeSBarry Smith #endif
3005c6c1daeSBarry Smith 
3015c6c1daeSBarry Smith   PetscFunctionBegin;
3025c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
3035c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN)
304ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
3055c6c1daeSBarry Smith   if (!rank) {
306d45a07a7SBarry Smith     char  command[PETSC_MAX_PATH_LEN];
307d45a07a7SBarry Smith     FILE  *fd;
308d45a07a7SBarry Smith     int   err;
309d45a07a7SBarry Smith 
310d45a07a7SBarry Smith     ierr = PetscMemzero(command,sizeof(command));CHKERRQ(ierr);
3119982bd17SBarry Smith     ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"rm -fr %s %s.m4v",draw->savefilename,draw->savefilename);CHKERRQ(ierr);
312e97f6855SBarry Smith     ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr);
3130076e027SBarry Smith     ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr);
3149982bd17SBarry Smith     ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"mkdir %s",draw->savefilename);CHKERRQ(ierr);
315e97f6855SBarry Smith     ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr);
3160076e027SBarry Smith     ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr);
3175c6c1daeSBarry Smith   }
3185c6c1daeSBarry Smith #endif
3195c6c1daeSBarry Smith   PetscFunctionReturn(0);
3205c6c1daeSBarry Smith }
3215c6c1daeSBarry Smith 
3221cda70a7SBarry Smith 
3235c6c1daeSBarry Smith #if defined(PETSC_HAVE_AFTERIMAGE)
3245c6c1daeSBarry Smith #include <afterimage.h>
325aee23540SBarry Smith 
32676f01e85SBarry Smith /* String names of possible Afterimage formats */
32776f01e85SBarry Smith const char *PetscAfterImageFormats[] = {
32876f01e85SBarry Smith         ".Xpm",
32976f01e85SBarry Smith 	".Xpm.Z",
33076f01e85SBarry Smith 	".Xpm.gz",
33176f01e85SBarry Smith 	".Png",
33276f01e85SBarry Smith 	".Jpeg",
333f140b876SBarry Smith 	".Xcf", /* Gimp format */
33476f01e85SBarry Smith 	".Ppm",
33576f01e85SBarry Smith 	".Pnm",
336f140b876SBarry Smith 	"MS Windows Bitmap",
337f140b876SBarry Smith 	"MS Windows Icon",
338f140b876SBarry Smith 	"MS Windows Cursor",
33976f01e85SBarry Smith 	".Gif",
34076f01e85SBarry Smith 	".Tiff",
341f140b876SBarry Smith 	"Afterstep XMLScript",
342f140b876SBarry Smith 	"Scalable Vector Graphics (SVG)",
34376f01e85SBarry Smith 	".Xbm",
34476f01e85SBarry Smith 	"Targa",
34576f01e85SBarry Smith 	".Pcx",
34676f01e85SBarry Smith 	".HTML",
34776f01e85SBarry Smith 	"XML",
34876f01e85SBarry Smith 	"Unknown"
349aee23540SBarry Smith };
350aee23540SBarry Smith 
351aee23540SBarry Smith #undef __FUNCT__
35276f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageStringToFormat"
35376f01e85SBarry Smith static PetscErrorCode PetscAfterimageStringToFormat(const char *ext,ASImageFileTypes *format)
354aee23540SBarry Smith {
35576f01e85SBarry Smith   PetscInt       i;
356aee23540SBarry Smith   PetscErrorCode ierr;
35776f01e85SBarry Smith   PetscBool      flg;
358aee23540SBarry Smith 
359aee23540SBarry Smith   PetscFunctionBegin;
360f140b876SBarry Smith   ierr = PetscStrcasecmp(".Jpg",ext,&flg);CHKERRQ(ierr);
361f140b876SBarry Smith   if (flg) ext = ".Jpeg";
36276f01e85SBarry Smith   for (i=0; i<sizeof(PetscAfterImageFormats)/sizeof(char**); i++) {
36376f01e85SBarry Smith     ierr = PetscStrcasecmp(PetscAfterImageFormats[i],ext,&flg);CHKERRQ(ierr);
36476f01e85SBarry Smith     if (flg) {
36576f01e85SBarry Smith       *format = (ASImageFileTypes)i;
36676f01e85SBarry Smith       PetscFunctionReturn(0);
36776f01e85SBarry Smith     }
36876f01e85SBarry Smith   }
36976f01e85SBarry Smith   *format = ASIT_Unknown;
37076f01e85SBarry Smith   PetscFunctionReturn(0);
37176f01e85SBarry Smith }
37276f01e85SBarry Smith 
37376f01e85SBarry Smith #if defined(PETSC_HAVE_SAWS)
37476f01e85SBarry Smith #include <petscviewersaws.h>
37576f01e85SBarry Smith /*
37676f01e85SBarry Smith   The PetscAfterimage object and functions are used to maintain a list of file images created by Afterimage that can
37776f01e85SBarry Smith   be displayed by the SAWs webserver.
37876f01e85SBarry Smith */
37976f01e85SBarry Smith typedef struct _P_PetscAfterimage *PetscAfterimage;
38076f01e85SBarry Smith struct _P_PetscAfterimage {
38176f01e85SBarry Smith   PetscAfterimage next;
38276f01e85SBarry Smith   char            *filename;
38376f01e85SBarry Smith   char            *ext;
38476f01e85SBarry Smith   PetscInt        cnt;
38576f01e85SBarry Smith } ;
38676f01e85SBarry Smith 
38776f01e85SBarry Smith static PetscAfterimage afterimages = 0;
38876f01e85SBarry Smith 
38976f01e85SBarry Smith #undef __FUNCT__
39076f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageDestroy"
39176f01e85SBarry Smith static PetscErrorCode PetscAfterimageDestroy(void)
39276f01e85SBarry Smith {
39376f01e85SBarry Smith   PetscErrorCode ierr;
39476f01e85SBarry Smith   PetscAfterimage       afterimage,oafterimage = afterimages;
39576f01e85SBarry Smith 
39676f01e85SBarry Smith   PetscFunctionBegin;
39776f01e85SBarry Smith   while (oafterimage) {
39876f01e85SBarry Smith     afterimage = oafterimage->next;
39976f01e85SBarry Smith     ierr = PetscFree(oafterimage->filename);CHKERRQ(ierr);
40076f01e85SBarry Smith     ierr = PetscFree(oafterimage->ext);CHKERRQ(ierr);
40176f01e85SBarry Smith     ierr = PetscFree(oafterimage);CHKERRQ(ierr);
40276f01e85SBarry Smith     oafterimage = afterimage;
403aee23540SBarry Smith   }
404aee23540SBarry Smith   PetscFunctionReturn(0);
405aee23540SBarry Smith }
406aee23540SBarry Smith 
407aee23540SBarry Smith #undef __FUNCT__
40876f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageAdd"
40976f01e85SBarry Smith static PetscErrorCode PetscAfterimageAdd(const char *filename,const char *ext,PetscInt cnt)
410aee23540SBarry Smith {
411aee23540SBarry Smith   PetscErrorCode   ierr;
41276f01e85SBarry Smith   PetscAfterimage  afterimage,oafterimage = afterimages;
413aee23540SBarry Smith   PetscBool        flg;
414aee23540SBarry Smith 
415aee23540SBarry Smith   PetscFunctionBegin;
41676f01e85SBarry Smith   if (oafterimage){
41776f01e85SBarry Smith     ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr);
41876f01e85SBarry Smith     if (flg) {
41976f01e85SBarry Smith       oafterimage->cnt = cnt;
42076f01e85SBarry Smith       PetscFunctionReturn(0);
421aee23540SBarry Smith     }
42276f01e85SBarry Smith     while (oafterimage->next) {
42376f01e85SBarry Smith       oafterimage = oafterimage->next;
42476f01e85SBarry Smith       ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr);
42576f01e85SBarry Smith       if (flg) {
42676f01e85SBarry Smith         oafterimage->cnt = cnt;
42776f01e85SBarry Smith         PetscFunctionReturn(0);
42876f01e85SBarry Smith       }
42976f01e85SBarry Smith     }
43076f01e85SBarry Smith     ierr = PetscNew(&afterimage);CHKERRQ(ierr);
43176f01e85SBarry Smith     oafterimage->next = afterimage;
432aee23540SBarry Smith   } else {
43376f01e85SBarry Smith     ierr = PetscNew(&afterimage);CHKERRQ(ierr);
43476f01e85SBarry Smith     afterimages = afterimage;
435aee23540SBarry Smith   }
43676f01e85SBarry Smith   ierr = PetscStrallocpy(filename,&afterimage->filename);CHKERRQ(ierr);
43776f01e85SBarry Smith   ierr = PetscStrallocpy(ext,&afterimage->ext);CHKERRQ(ierr);
43876f01e85SBarry Smith   afterimage->cnt = cnt;
43976f01e85SBarry Smith   ierr = PetscRegisterFinalize(PetscAfterimageDestroy);CHKERRQ(ierr);
440aee23540SBarry Smith   PetscFunctionReturn(0);
441aee23540SBarry Smith }
442aee23540SBarry Smith 
443aee23540SBarry Smith #endif
444aee23540SBarry Smith 
4455c6c1daeSBarry Smith #undef __FUNCT__
4465c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSave_X"
4475c6c1daeSBarry Smith PetscErrorCode PetscDrawSave_X(PetscDraw draw)
4485c6c1daeSBarry Smith {
4495c6c1daeSBarry Smith   PetscDraw_X      *drawx = (PetscDraw_X*)draw->data;
4505c6c1daeSBarry Smith   XImage           *image;
4515c6c1daeSBarry Smith   ASImage          *asimage;
452681455b2SBarry Smith   struct  ASVisual *asv;
4535c6c1daeSBarry Smith   char             filename[PETSC_MAX_PATH_LEN];
4545c6c1daeSBarry Smith   PetscErrorCode   ierr;
4555c6c1daeSBarry Smith   PetscMPIInt      rank;
456681455b2SBarry Smith   int              depth;
45776f01e85SBarry Smith   ASImageFileTypes format;
4585c6c1daeSBarry Smith 
4595c6c1daeSBarry Smith   PetscFunctionBegin;
460ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
4615c6c1daeSBarry Smith   if (rank) PetscFunctionReturn(0);
4625c6c1daeSBarry Smith   if (!draw->savefilename) PetscFunctionReturn(0);
4635c6c1daeSBarry Smith   if (draw->savefilecount == -1) {
4645c6c1daeSBarry Smith     /* The first PetscDrawClear() should happen before any drawing has been done, hence do not save at the first PetscDrawClear() */
4655c6c1daeSBarry Smith     draw->savefilecount++;
4665c6c1daeSBarry Smith     PetscFunctionReturn(0);
4675c6c1daeSBarry Smith   }
468681455b2SBarry Smith   XSynchronize(drawx->disp, True);
469681455b2SBarry Smith   depth = DefaultDepth( drawx->disp, drawx->screen );
470681455b2SBarry Smith   asv   = create_asvisual(drawx->disp, drawx->screen, depth, NULL);if (!asv) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASVisual");
4715c6c1daeSBarry Smith 
4729982bd17SBarry Smith   image   = XGetImage(drawx->disp, drawx->drw ? drawx->drw : drawx->win, 0, 0, drawx->w, drawx->h, AllPlanes, ZPixmap);
47376f01e85SBarry Smith   if (!image) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot XGetImage()");
474ce94432eSBarry Smith   asimage = picture_ximage2asimage (asv,image,0,0);if (!asimage) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASImage");
4758b7fcac6SBarry Smith   if (draw->savesinglefile) {
47676f01e85SBarry Smith     ierr    = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s%s",draw->savefilename,draw->savefilename,draw->savefilenameext);CHKERRQ(ierr);
4778b7fcac6SBarry Smith   } else {
47876f01e85SBarry Smith     ierr    = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s_%d%s",draw->savefilename,draw->savefilename,draw->savefilecount++,draw->savefilenameext);CHKERRQ(ierr);
4798b7fcac6SBarry Smith   }
48076f01e85SBarry Smith   ierr = PetscAfterimageStringToFormat(draw->savefilenameext,&format);CHKERRQ(ierr);
48176f01e85SBarry Smith   ASImage2file(asimage, 0, filename,format,0);
4821cda70a7SBarry Smith #if defined(PETSC_HAVE_SAWS)
4831cda70a7SBarry Smith   {
484aee23540SBarry Smith     char     body[4096];
48576f01e85SBarry Smith     PetscAfterimage afterimage;
486aee23540SBarry Smith     size_t   len = 0;
487aee23540SBarry Smith 
48876f01e85SBarry Smith     ierr = PetscAfterimageAdd(draw->savefilename,draw->savefilenameext,draw->savefilecount-1);CHKERRQ(ierr);
48976f01e85SBarry Smith     afterimage  = afterimages;
49076f01e85SBarry Smith     while (afterimage) {
49176f01e85SBarry Smith       if (draw->savesinglefile) {
49276f01e85SBarry Smith         ierr = PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s%s\" alt=\"None\">",afterimage->filename,afterimage->filename,afterimage->ext);CHKERRQ(ierr);
49376f01e85SBarry Smith       } else {
49476f01e85SBarry 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);
49576f01e85SBarry Smith       }
496aee23540SBarry Smith       ierr = PetscStrlen(body,&len);CHKERRQ(ierr);
49776f01e85SBarry Smith       afterimage  = afterimage->next;
498aee23540SBarry Smith     }
499aee23540SBarry Smith     ierr = PetscStrcat(body,"<br>\n");CHKERRQ(ierr);
50043da4ab2SBarry Smith     if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1));
50143da4ab2SBarry Smith     PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body));
5021cda70a7SBarry Smith   }
5031cda70a7SBarry Smith #endif
5045c6c1daeSBarry Smith 
5055c6c1daeSBarry Smith   XDestroyImage(image);
506681455b2SBarry Smith   destroy_asvisual(asv,0);
5075c6c1daeSBarry Smith   PetscFunctionReturn(0);
5085c6c1daeSBarry Smith }
5095c6c1daeSBarry Smith /*
5105c6c1daeSBarry Smith    There are routines wanted by AfterImage for PNG files
5115c6c1daeSBarry Smith  */
5125c6c1daeSBarry Smith void crc32(void) {;}
5135c6c1daeSBarry Smith void inflateReset(void) {;}
5145c6c1daeSBarry Smith void deflateReset(void) {;}
5155c6c1daeSBarry Smith void deflateInit2(void) {;}
5165c6c1daeSBarry Smith void deflateInit2_(void) {;}
5175c6c1daeSBarry Smith void deflate(void) {;}
5185c6c1daeSBarry Smith void deflateEnd(void) {;}
5195c6c1daeSBarry Smith 
5205c6c1daeSBarry Smith #endif
5215c6c1daeSBarry Smith 
5225c6c1daeSBarry Smith 
5235c6c1daeSBarry Smith 
524