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" 10165d9662dSLisandro 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__ "PetscDrawSetSave_X" 2815c6c1daeSBarry Smith PetscErrorCode PetscDrawSetSave_X(PetscDraw draw,const char *filename) 2825c6c1daeSBarry Smith { 2835c6c1daeSBarry Smith PetscErrorCode ierr; 2845c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN) 2855c6c1daeSBarry Smith PetscMPIInt rank; 2865c6c1daeSBarry Smith #endif 2875c6c1daeSBarry Smith 2885c6c1daeSBarry Smith PetscFunctionBegin; 2895c6c1daeSBarry Smith PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 2905c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN) 291ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 2925c6c1daeSBarry Smith if (!rank) { 293d45a07a7SBarry Smith char command[PETSC_MAX_PATH_LEN]; 294d45a07a7SBarry Smith FILE *fd; 295d45a07a7SBarry Smith int err; 296d45a07a7SBarry Smith 297d45a07a7SBarry Smith ierr = PetscMemzero(command,sizeof(command));CHKERRQ(ierr); 2989982bd17SBarry Smith ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"rm -fr %s %s.m4v",draw->savefilename,draw->savefilename);CHKERRQ(ierr); 299e97f6855SBarry Smith ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr); 3000076e027SBarry Smith ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr); 3019982bd17SBarry Smith ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"mkdir %s",draw->savefilename);CHKERRQ(ierr); 302e97f6855SBarry Smith ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr); 3030076e027SBarry Smith ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr); 3045c6c1daeSBarry Smith } 3055c6c1daeSBarry Smith #endif 3065c6c1daeSBarry Smith PetscFunctionReturn(0); 3075c6c1daeSBarry Smith } 3085c6c1daeSBarry Smith 3091cda70a7SBarry Smith 3105c6c1daeSBarry Smith #if defined(PETSC_HAVE_AFTERIMAGE) 3115c6c1daeSBarry Smith #include <afterimage.h> 312aee23540SBarry Smith 31376f01e85SBarry Smith /* String names of possible Afterimage formats */ 31476f01e85SBarry Smith const char *PetscAfterImageFormats[] = { 31576f01e85SBarry Smith ".Xpm", 31676f01e85SBarry Smith ".Xpm.Z", 31776f01e85SBarry Smith ".Xpm.gz", 31876f01e85SBarry Smith ".Png", 31976f01e85SBarry Smith ".Jpeg", 320f140b876SBarry Smith ".Xcf", /* Gimp format */ 32176f01e85SBarry Smith ".Ppm", 32276f01e85SBarry Smith ".Pnm", 323f140b876SBarry Smith "MS Windows Bitmap", 324f140b876SBarry Smith "MS Windows Icon", 325f140b876SBarry Smith "MS Windows Cursor", 32676f01e85SBarry Smith ".Gif", 32776f01e85SBarry Smith ".Tiff", 328f140b876SBarry Smith "Afterstep XMLScript", 329f140b876SBarry Smith "Scalable Vector Graphics (SVG)", 33076f01e85SBarry Smith ".Xbm", 33176f01e85SBarry Smith "Targa", 33276f01e85SBarry Smith ".Pcx", 33376f01e85SBarry Smith ".HTML", 33476f01e85SBarry Smith "XML", 33576f01e85SBarry Smith "Unknown" 336aee23540SBarry Smith }; 337aee23540SBarry Smith 338aee23540SBarry Smith #undef __FUNCT__ 33976f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageStringToFormat" 34076f01e85SBarry Smith static PetscErrorCode PetscAfterimageStringToFormat(const char *ext,ASImageFileTypes *format) 341aee23540SBarry Smith { 34276f01e85SBarry Smith PetscInt i; 343aee23540SBarry Smith PetscErrorCode ierr; 34476f01e85SBarry Smith PetscBool flg; 345aee23540SBarry Smith 346aee23540SBarry Smith PetscFunctionBegin; 347f140b876SBarry Smith ierr = PetscStrcasecmp(".Jpg",ext,&flg);CHKERRQ(ierr); 348f140b876SBarry Smith if (flg) ext = ".Jpeg"; 34976f01e85SBarry Smith for (i=0; i<sizeof(PetscAfterImageFormats)/sizeof(char**); i++) { 35076f01e85SBarry Smith ierr = PetscStrcasecmp(PetscAfterImageFormats[i],ext,&flg);CHKERRQ(ierr); 35176f01e85SBarry Smith if (flg) { 35276f01e85SBarry Smith *format = (ASImageFileTypes)i; 35376f01e85SBarry Smith PetscFunctionReturn(0); 35476f01e85SBarry Smith } 35576f01e85SBarry Smith } 35676f01e85SBarry Smith *format = ASIT_Unknown; 35776f01e85SBarry Smith PetscFunctionReturn(0); 35876f01e85SBarry Smith } 35976f01e85SBarry Smith 36076f01e85SBarry Smith #if defined(PETSC_HAVE_SAWS) 36176f01e85SBarry Smith #include <petscviewersaws.h> 36276f01e85SBarry Smith /* 36376f01e85SBarry Smith The PetscAfterimage object and functions are used to maintain a list of file images created by Afterimage that can 36476f01e85SBarry Smith be displayed by the SAWs webserver. 36576f01e85SBarry Smith */ 36676f01e85SBarry Smith typedef struct _P_PetscAfterimage *PetscAfterimage; 36776f01e85SBarry Smith struct _P_PetscAfterimage { 36876f01e85SBarry Smith PetscAfterimage next; 36976f01e85SBarry Smith char *filename; 37076f01e85SBarry Smith char *ext; 37176f01e85SBarry Smith PetscInt cnt; 37276f01e85SBarry Smith } ; 37376f01e85SBarry Smith 37476f01e85SBarry Smith static PetscAfterimage afterimages = 0; 37576f01e85SBarry Smith 37676f01e85SBarry Smith #undef __FUNCT__ 37776f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageDestroy" 37876f01e85SBarry Smith static PetscErrorCode PetscAfterimageDestroy(void) 37976f01e85SBarry Smith { 38076f01e85SBarry Smith PetscErrorCode ierr; 38176f01e85SBarry Smith PetscAfterimage afterimage,oafterimage = afterimages; 38276f01e85SBarry Smith 38376f01e85SBarry Smith PetscFunctionBegin; 38476f01e85SBarry Smith while (oafterimage) { 38576f01e85SBarry Smith afterimage = oafterimage->next; 38676f01e85SBarry Smith ierr = PetscFree(oafterimage->filename);CHKERRQ(ierr); 38776f01e85SBarry Smith ierr = PetscFree(oafterimage->ext);CHKERRQ(ierr); 38876f01e85SBarry Smith ierr = PetscFree(oafterimage);CHKERRQ(ierr); 38976f01e85SBarry Smith oafterimage = afterimage; 390aee23540SBarry Smith } 391aee23540SBarry Smith PetscFunctionReturn(0); 392aee23540SBarry Smith } 393aee23540SBarry Smith 394aee23540SBarry Smith #undef __FUNCT__ 39576f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageAdd" 39676f01e85SBarry Smith static PetscErrorCode PetscAfterimageAdd(const char *filename,const char *ext,PetscInt cnt) 397aee23540SBarry Smith { 398aee23540SBarry Smith PetscErrorCode ierr; 39976f01e85SBarry Smith PetscAfterimage afterimage,oafterimage = afterimages; 400aee23540SBarry Smith PetscBool flg; 401aee23540SBarry Smith 402aee23540SBarry Smith PetscFunctionBegin; 40376f01e85SBarry Smith if (oafterimage){ 40476f01e85SBarry Smith ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr); 40576f01e85SBarry Smith if (flg) { 40676f01e85SBarry Smith oafterimage->cnt = cnt; 40776f01e85SBarry Smith PetscFunctionReturn(0); 408aee23540SBarry Smith } 40976f01e85SBarry Smith while (oafterimage->next) { 41076f01e85SBarry Smith oafterimage = oafterimage->next; 41176f01e85SBarry Smith ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr); 41276f01e85SBarry Smith if (flg) { 41376f01e85SBarry Smith oafterimage->cnt = cnt; 41476f01e85SBarry Smith PetscFunctionReturn(0); 41576f01e85SBarry Smith } 41676f01e85SBarry Smith } 41776f01e85SBarry Smith ierr = PetscNew(&afterimage);CHKERRQ(ierr); 41876f01e85SBarry Smith oafterimage->next = afterimage; 419aee23540SBarry Smith } else { 42076f01e85SBarry Smith ierr = PetscNew(&afterimage);CHKERRQ(ierr); 42176f01e85SBarry Smith afterimages = afterimage; 422aee23540SBarry Smith } 42376f01e85SBarry Smith ierr = PetscStrallocpy(filename,&afterimage->filename);CHKERRQ(ierr); 42476f01e85SBarry Smith ierr = PetscStrallocpy(ext,&afterimage->ext);CHKERRQ(ierr); 42576f01e85SBarry Smith afterimage->cnt = cnt; 42676f01e85SBarry Smith ierr = PetscRegisterFinalize(PetscAfterimageDestroy);CHKERRQ(ierr); 427aee23540SBarry Smith PetscFunctionReturn(0); 428aee23540SBarry Smith } 429aee23540SBarry Smith 430aee23540SBarry Smith #endif 431aee23540SBarry Smith 4325c6c1daeSBarry Smith #undef __FUNCT__ 4335c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSave_X" 4345c6c1daeSBarry Smith PetscErrorCode PetscDrawSave_X(PetscDraw draw) 4355c6c1daeSBarry Smith { 4365c6c1daeSBarry Smith PetscDraw_X *drawx = (PetscDraw_X*)draw->data; 4375c6c1daeSBarry Smith XImage *image; 4385c6c1daeSBarry Smith ASImage *asimage; 439681455b2SBarry Smith struct ASVisual *asv; 4405c6c1daeSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 4415c6c1daeSBarry Smith PetscErrorCode ierr; 4425c6c1daeSBarry Smith PetscMPIInt rank; 443681455b2SBarry Smith int depth; 44476f01e85SBarry Smith ASImageFileTypes format; 4455c6c1daeSBarry Smith 4465c6c1daeSBarry Smith PetscFunctionBegin; 4475c6c1daeSBarry Smith if (!draw->savefilename) PetscFunctionReturn(0); 448*5b399a63SLisandro Dalcin ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 449*5b399a63SLisandro Dalcin 450*5b399a63SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 451*5b399a63SLisandro Dalcin XSync(drawx->disp,True); 452*5b399a63SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 453*5b399a63SLisandro Dalcin ierr = MPI_Barrier(PetscObjectComm((PetscObject)draw));CHKERRQ(ierr); 454*5b399a63SLisandro Dalcin 455*5b399a63SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 456*5b399a63SLisandro Dalcin if (rank) goto finally; /* only process 0 handles the saving business */ 457681455b2SBarry Smith depth = DefaultDepth(drawx->disp,drawx->screen); 458681455b2SBarry Smith asv = create_asvisual(drawx->disp,drawx->screen,depth,NULL);if (!asv) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASVisual"); 459*5b399a63SLisandro Dalcin image = XGetImage(drawx->disp,PetscDrawXiDrawable(drawx),0,0,drawx->w,drawx->h,AllPlanes,ZPixmap); 46076f01e85SBarry Smith if (!image) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot XGetImage()"); 461ce94432eSBarry Smith asimage = picture_ximage2asimage(asv,image,0,0);if (!asimage) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASImage"); 4628b7fcac6SBarry Smith if (draw->savesinglefile) { 46376f01e85SBarry Smith ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s%s",draw->savefilename,draw->savefilename,draw->savefilenameext);CHKERRQ(ierr); 4648b7fcac6SBarry Smith } else { 46576f01e85SBarry Smith ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s_%d%s",draw->savefilename,draw->savefilename,draw->savefilecount++,draw->savefilenameext);CHKERRQ(ierr); 4668b7fcac6SBarry Smith } 46776f01e85SBarry Smith ierr = PetscAfterimageStringToFormat(draw->savefilenameext,&format);CHKERRQ(ierr); 46876f01e85SBarry Smith ASImage2file(asimage,0,filename,format,0); 4691cda70a7SBarry Smith #if defined(PETSC_HAVE_SAWS) 4701cda70a7SBarry Smith { 471aee23540SBarry Smith char body[4096]; 47276f01e85SBarry Smith PetscAfterimage afterimage; 473aee23540SBarry Smith size_t len = 0; 474aee23540SBarry Smith 47576f01e85SBarry Smith ierr = PetscAfterimageAdd(draw->savefilename,draw->savefilenameext,draw->savefilecount-1);CHKERRQ(ierr); 47676f01e85SBarry Smith afterimage = afterimages; 47776f01e85SBarry Smith while (afterimage) { 47876f01e85SBarry Smith if (draw->savesinglefile) { 47976f01e85SBarry Smith ierr = PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s%s\" alt=\"None\">",afterimage->filename,afterimage->filename,afterimage->ext);CHKERRQ(ierr); 48076f01e85SBarry Smith } else { 48176f01e85SBarry 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); 48276f01e85SBarry Smith } 483aee23540SBarry Smith ierr = PetscStrlen(body,&len);CHKERRQ(ierr); 48476f01e85SBarry Smith afterimage = afterimage->next; 485aee23540SBarry Smith } 486aee23540SBarry Smith ierr = PetscStrcat(body,"<br>\n");CHKERRQ(ierr); 48743da4ab2SBarry Smith if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1)); 48843da4ab2SBarry Smith PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body)); 4891cda70a7SBarry Smith } 4901cda70a7SBarry Smith #endif 491681455b2SBarry Smith destroy_asvisual(asv,0); 492*5b399a63SLisandro Dalcin XDestroyImage(image); 493*5b399a63SLisandro Dalcin finally: 494*5b399a63SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 4955c6c1daeSBarry Smith PetscFunctionReturn(0); 4965c6c1daeSBarry Smith } 497*5b399a63SLisandro Dalcin 4985c6c1daeSBarry Smith /* 4995c6c1daeSBarry Smith There are routines wanted by AfterImage for PNG files 5005c6c1daeSBarry Smith */ 5015c6c1daeSBarry Smith void crc32(void) {;} 5025c6c1daeSBarry Smith void inflateReset(void) {;} 5035c6c1daeSBarry Smith void deflateReset(void) {;} 5045c6c1daeSBarry Smith void deflateInit2(void) {;} 5055c6c1daeSBarry Smith void deflateInit2_(void) {;} 5065c6c1daeSBarry Smith void deflate(void) {;} 5075c6c1daeSBarry Smith void deflateEnd(void) {;} 5085c6c1daeSBarry Smith 5095c6c1daeSBarry Smith #endif 5105c6c1daeSBarry Smith 5115c6c1daeSBarry Smith 5125c6c1daeSBarry Smith 513