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