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