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 1615d5bc79SLisandro Dalcin extern PetscErrorCode PetscDrawSetColormap_X(PetscDraw_X*,Colormap); 175c6c1daeSBarry Smith 185c6c1daeSBarry Smith /* 1915d5bc79SLisandro Dalcin PetscDrawXiOpenDisplay - Open and setup a display 205c6c1daeSBarry Smith */ 215c6c1daeSBarry Smith #undef __FUNCT__ 225c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiOpenDisplay" 23*09440f25SLisandro Dalcin static PetscErrorCode PetscDrawXiOpenDisplay(PetscDraw_X *XiWin,const char display[]) 245c6c1daeSBarry Smith { 255c6c1daeSBarry Smith PetscFunctionBegin; 2615d5bc79SLisandro Dalcin XiWin->disp = XOpenDisplay(display); 275c6c1daeSBarry Smith if (!XiWin->disp) { 2815d5bc79SLisandro Dalcin SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open display on %s\n\ 2915d5bc79SLisandro Dalcin Make sure your COMPUTE NODES are authorized to connect \n\ 305c6c1daeSBarry Smith to this X server and either your DISPLAY variable\n\ 3115d5bc79SLisandro Dalcin is set or you use the -display name option\n",display); 325c6c1daeSBarry Smith } 335c6c1daeSBarry Smith XiWin->screen = DefaultScreen(XiWin->disp); 34481cee7bSLisandro Dalcin XiWin->vis = DefaultVisual(XiWin->disp,XiWin->screen); 35481cee7bSLisandro Dalcin XiWin->depth = DefaultDepth(XiWin->disp,XiWin->screen); 3615d5bc79SLisandro Dalcin XiWin->cmap = DefaultColormap(XiWin->disp,XiWin->screen); 3715d5bc79SLisandro Dalcin XiWin->background = WhitePixel(XiWin->disp,XiWin->screen); 3815d5bc79SLisandro Dalcin XiWin->foreground = BlackPixel(XiWin->disp,XiWin->screen); 395c6c1daeSBarry Smith PetscFunctionReturn(0); 405c6c1daeSBarry Smith } 415c6c1daeSBarry Smith 42815f00f0SLisandro Dalcin #undef __FUNCT__ 43815f00f0SLisandro Dalcin #define __FUNCT__ "PetscDrawXiClose" 44815f00f0SLisandro Dalcin PetscErrorCode PetscDrawXiClose(PetscDraw_X *XiWin) 45815f00f0SLisandro Dalcin { 46815f00f0SLisandro Dalcin PetscErrorCode ierr; 47815f00f0SLisandro Dalcin 48815f00f0SLisandro Dalcin PetscFunctionBegin; 49815f00f0SLisandro Dalcin if (!XiWin) PetscFunctionReturn(0); 50815f00f0SLisandro Dalcin ierr = PetscFree(XiWin->font);CHKERRQ(ierr); 51815f00f0SLisandro Dalcin if (XiWin->disp) { 52815f00f0SLisandro Dalcin #if defined(PETSC_HAVE_SETJMP_H) 53815f00f0SLisandro Dalcin jmp_buf jmpbuf; 54815f00f0SLisandro Dalcin PetscXIOErrorHandler xioerrhdl; 55815f00f0SLisandro Dalcin ierr = PetscMemcpy(&jmpbuf,&PetscXIOErrorHandlerJumpBuf,sizeof(jmpbuf));CHKERRQ(ierr); 56815f00f0SLisandro Dalcin xioerrhdl = PetscSetXIOErrorHandler(PetscXIOErrorHandlerJump); 57815f00f0SLisandro Dalcin if (!setjmp(PetscXIOErrorHandlerJumpBuf)) 58815f00f0SLisandro Dalcin #endif 59815f00f0SLisandro Dalcin { 60815f00f0SLisandro Dalcin XFreeGC(XiWin->disp,XiWin->gc.set); 61815f00f0SLisandro Dalcin XCloseDisplay(XiWin->disp); 62815f00f0SLisandro Dalcin } 63815f00f0SLisandro Dalcin XiWin->disp = NULL; 64815f00f0SLisandro Dalcin #if defined(PETSC_HAVE_SETJMP_H) 65815f00f0SLisandro Dalcin (void)PetscSetXIOErrorHandler(xioerrhdl); 66815f00f0SLisandro Dalcin ierr = PetscMemcpy(&PetscXIOErrorHandlerJumpBuf,&jmpbuf,sizeof(jmpbuf));CHKERRQ(ierr); 67815f00f0SLisandro Dalcin #endif 68815f00f0SLisandro Dalcin } 69815f00f0SLisandro Dalcin PetscFunctionReturn(0); 70815f00f0SLisandro Dalcin } 71815f00f0SLisandro Dalcin 725c6c1daeSBarry Smith /* 73*09440f25SLisandro Dalcin PetscDrawXiCreateGC - setup the GC structure 745c6c1daeSBarry Smith */ 755c6c1daeSBarry Smith #undef __FUNCT__ 76*09440f25SLisandro Dalcin #define __FUNCT__ "PetscDrawXiCreateGC" 77*09440f25SLisandro Dalcin static PetscErrorCode PetscDrawXiCreateGC(PetscDraw_X *XiWin,PetscDrawXiPixVal fg) 785c6c1daeSBarry Smith { 795c6c1daeSBarry Smith XGCValues gcvalues; /* window graphics context values */ 805c6c1daeSBarry Smith 815c6c1daeSBarry Smith PetscFunctionBegin; 825c6c1daeSBarry Smith /* Set the graphics contexts */ 835c6c1daeSBarry Smith /* create a gc for the ROP_SET operation (writing the fg value to a pixel) */ 845c6c1daeSBarry Smith /* (do this with function GXcopy; GXset will automatically write 1) */ 855c6c1daeSBarry Smith gcvalues.function = GXcopy; 865c6c1daeSBarry Smith gcvalues.foreground = fg; 875c6c1daeSBarry Smith XiWin->gc.cur_pix = fg; 885c6c1daeSBarry Smith XiWin->gc.set = XCreateGC(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),GCFunction|GCForeground,&gcvalues); 8915d5bc79SLisandro Dalcin if (!XiWin->gc.set) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to create X graphics context"); 9015d5bc79SLisandro Dalcin PetscFunctionReturn(0); 9115d5bc79SLisandro Dalcin } 9215d5bc79SLisandro Dalcin 9315d5bc79SLisandro Dalcin /* 94815f00f0SLisandro Dalcin PetscDrawXiInit - basic setup the draw (display, graphics context, font) 9515d5bc79SLisandro Dalcin */ 9615d5bc79SLisandro Dalcin #undef __FUNCT__ 97815f00f0SLisandro Dalcin #define __FUNCT__ "PetscDrawXiInit" 9865d9662dSLisandro Dalcin PetscErrorCode PetscDrawXiInit(PetscDraw_X *XiWin,const char display[]) 9915d5bc79SLisandro Dalcin { 10015d5bc79SLisandro Dalcin PetscErrorCode ierr; 10115d5bc79SLisandro Dalcin PetscFunctionBegin; 10215d5bc79SLisandro Dalcin ierr = PetscDrawXiOpenDisplay(XiWin,display);CHKERRQ(ierr); 103*09440f25SLisandro Dalcin ierr = PetscDrawXiCreateGC(XiWin,XiWin->foreground);CHKERRQ(ierr); 10415d5bc79SLisandro Dalcin ierr = PetscDrawXiFontFixed(XiWin,6,10,&XiWin->font);CHKERRQ(ierr); 1055c6c1daeSBarry Smith PetscFunctionReturn(0); 1065c6c1daeSBarry Smith } 1075c6c1daeSBarry Smith 1085c6c1daeSBarry Smith /* 109*09440f25SLisandro Dalcin This routine waits until the window is actually created or destroyed 110*09440f25SLisandro Dalcin Returns 0 if window is mapped; 1 if window is destroyed. 111*09440f25SLisandro Dalcin */ 112*09440f25SLisandro Dalcin #undef __FUNCT__ 113*09440f25SLisandro Dalcin #define __FUNCT__ "PetscDrawXiWaitMap" 114*09440f25SLisandro Dalcin static PetscErrorCode PetscDrawXiWaitMap(PetscDraw_X *XiWin) 115*09440f25SLisandro Dalcin { 116*09440f25SLisandro Dalcin XEvent event; 117*09440f25SLisandro Dalcin 118*09440f25SLisandro Dalcin PetscFunctionBegin; 119*09440f25SLisandro Dalcin while (1) { 120*09440f25SLisandro Dalcin XMaskEvent(XiWin->disp,ExposureMask|StructureNotifyMask,&event); 121*09440f25SLisandro Dalcin if (event.xany.window != XiWin->win) break; 122*09440f25SLisandro Dalcin else { 123*09440f25SLisandro Dalcin switch (event.type) { 124*09440f25SLisandro Dalcin case ConfigureNotify: 125*09440f25SLisandro Dalcin /* window has been moved or resized */ 126*09440f25SLisandro Dalcin XiWin->w = event.xconfigure.width - 2 * event.xconfigure.border_width; 127*09440f25SLisandro Dalcin XiWin->h = event.xconfigure.height - 2 * event.xconfigure.border_width; 128*09440f25SLisandro Dalcin break; 129*09440f25SLisandro Dalcin case DestroyNotify: 130*09440f25SLisandro Dalcin PetscFunctionReturn(1); 131*09440f25SLisandro Dalcin case Expose: 132*09440f25SLisandro Dalcin PetscFunctionReturn(0); 133*09440f25SLisandro Dalcin /* else ignore event */ 134*09440f25SLisandro Dalcin } 135*09440f25SLisandro Dalcin } 136*09440f25SLisandro Dalcin } 137*09440f25SLisandro Dalcin PetscFunctionReturn(0); 138*09440f25SLisandro Dalcin } 139*09440f25SLisandro Dalcin 140*09440f25SLisandro Dalcin /* 1415c6c1daeSBarry Smith Actually display a window at [x,y] with sizes (w,h) 1425c6c1daeSBarry Smith */ 1435c6c1daeSBarry Smith #undef __FUNCT__ 1445c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiDisplayWindow" 145*09440f25SLisandro Dalcin static PetscErrorCode PetscDrawXiDisplayWindow(PetscDraw_X *XiWin,char *label,int x,int y,int w,int h) 1465c6c1daeSBarry Smith { 1475c6c1daeSBarry Smith unsigned int wavail,havail; 1485c6c1daeSBarry Smith XSizeHints size_hints; 1495c6c1daeSBarry Smith XWindowAttributes in_window_attributes; 1505c6c1daeSBarry Smith XSetWindowAttributes window_attributes; 15115d5bc79SLisandro Dalcin unsigned int border_width = 0; 15215d5bc79SLisandro Dalcin unsigned long backgnd_pixel = WhitePixel(XiWin->disp,XiWin->screen); 1535c6c1daeSBarry Smith unsigned long wmask; 1545c6c1daeSBarry Smith 1555c6c1daeSBarry Smith PetscFunctionBegin; 1565c6c1daeSBarry Smith /* get the available widths */ 1575c6c1daeSBarry Smith wavail = DisplayWidth(XiWin->disp,XiWin->screen); 1585c6c1daeSBarry Smith havail = DisplayHeight(XiWin->disp,XiWin->screen); 1595c6c1daeSBarry Smith if (w <= 0 || h <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"X Window display has invalid height or width"); 1605c6c1daeSBarry Smith if ((unsigned int)w > wavail) w = wavail; 1615c6c1daeSBarry Smith if ((unsigned int)h > havail) h = havail; 1625c6c1daeSBarry Smith 16315d5bc79SLisandro Dalcin if (x < 0) x = (int)(wavail - (unsigned int)w + (unsigned int)x); 16415d5bc79SLisandro Dalcin if (y < 0) y = (int)(havail - (unsigned int)h + (unsigned int)y); 16515d5bc79SLisandro Dalcin x = ((unsigned int)x + w > wavail) ? (int)(wavail - (unsigned int)w) : x; 16615d5bc79SLisandro Dalcin y = ((unsigned int)y + h > havail) ? (int)(havail - (unsigned int)h) : y; 1675c6c1daeSBarry Smith 1685c6c1daeSBarry Smith /* We need XCreateWindow since we may need an visual other than the default one */ 1695c6c1daeSBarry Smith XGetWindowAttributes(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),&in_window_attributes); 1705c6c1daeSBarry Smith window_attributes.background_pixmap = None; 1715c6c1daeSBarry Smith window_attributes.background_pixel = backgnd_pixel; 1725c6c1daeSBarry Smith /* No border for now */ 1735c6c1daeSBarry Smith window_attributes.border_pixmap = None; 1745c6c1daeSBarry Smith /* 1755c6c1daeSBarry Smith window_attributes.border_pixel = border_pixel; 1765c6c1daeSBarry Smith */ 1775c6c1daeSBarry Smith window_attributes.bit_gravity = in_window_attributes.bit_gravity; 1785c6c1daeSBarry Smith window_attributes.win_gravity = in_window_attributes.win_gravity; 1795c6c1daeSBarry Smith /* Backing store is too slow in color systems */ 18015d5bc79SLisandro Dalcin window_attributes.backing_store = NotUseful; 1815c6c1daeSBarry Smith window_attributes.backing_pixel = backgnd_pixel; 1825c6c1daeSBarry Smith window_attributes.save_under = 1; 1835c6c1daeSBarry Smith window_attributes.event_mask = 0; 1845c6c1daeSBarry Smith window_attributes.do_not_propagate_mask = 0; 1855c6c1daeSBarry Smith window_attributes.override_redirect = 0; 1865c6c1daeSBarry Smith window_attributes.colormap = XiWin->cmap; 1875c6c1daeSBarry Smith /* None for cursor does NOT mean none, it means cursor of Parent */ 1885c6c1daeSBarry Smith window_attributes.cursor = None; 189a297a907SKarl Rupp 1905c6c1daeSBarry Smith wmask = CWBackPixmap | CWBackPixel | CWBorderPixmap | CWBitGravity | 1915c6c1daeSBarry Smith CWWinGravity | CWBackingStore | CWBackingPixel | CWOverrideRedirect | 1925c6c1daeSBarry Smith CWSaveUnder | CWEventMask | CWDontPropagate | 1935c6c1daeSBarry Smith CWCursor | CWColormap; 1945c6c1daeSBarry Smith 19515d5bc79SLisandro 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); 1965c6c1daeSBarry Smith if (!XiWin->win) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open X window"); 1975c6c1daeSBarry Smith 1985c6c1daeSBarry Smith /* set window manager hints */ 1995c6c1daeSBarry Smith { 2005c6c1daeSBarry Smith XWMHints wm_hints; 2015c6c1daeSBarry Smith XClassHint class_hints; 2025c6c1daeSBarry Smith XTextProperty windowname,iconname; 2035c6c1daeSBarry Smith 204a297a907SKarl Rupp if (label) XStringListToTextProperty(&label,1,&windowname); 205a297a907SKarl Rupp else XStringListToTextProperty(&label,0,&windowname); 206a297a907SKarl Rupp if (label) XStringListToTextProperty(&label,1,&iconname); 207a297a907SKarl Rupp else XStringListToTextProperty(&label,0,&iconname); 2085c6c1daeSBarry Smith 2095c6c1daeSBarry Smith wm_hints.initial_state = NormalState; 2105c6c1daeSBarry Smith wm_hints.input = True; 2115c6c1daeSBarry Smith wm_hints.flags = StateHint|InputHint; 2125c6c1daeSBarry Smith 2135c6c1daeSBarry Smith /* These properties can be used by window managers to decide how to display a window */ 2145c6c1daeSBarry Smith class_hints.res_name = (char*)"petsc"; 2155c6c1daeSBarry Smith class_hints.res_class = (char*)"PETSc"; 2165c6c1daeSBarry Smith 2175c6c1daeSBarry Smith size_hints.x = x; 2185c6c1daeSBarry Smith size_hints.y = y; 2195c6c1daeSBarry Smith size_hints.min_width = 4*border_width; 2205c6c1daeSBarry Smith size_hints.min_height = 4*border_width; 2215c6c1daeSBarry Smith size_hints.width = w; 2225c6c1daeSBarry Smith size_hints.height = h; 2235c6c1daeSBarry Smith size_hints.flags = USPosition | USSize | PMinSize; 2245c6c1daeSBarry Smith 2255c6c1daeSBarry Smith XSetWMProperties(XiWin->disp,XiWin->win,&windowname,&iconname,0,0,&size_hints,&wm_hints,&class_hints); 2265c6c1daeSBarry Smith XFree((void*)windowname.value); 2275c6c1daeSBarry Smith XFree((void*)iconname.value); 2285c6c1daeSBarry Smith } 229481cee7bSLisandro Dalcin 2305c6c1daeSBarry Smith /* make the window visible */ 2315c6c1daeSBarry Smith XSelectInput(XiWin->disp,XiWin->win,ExposureMask|StructureNotifyMask); 2325c6c1daeSBarry Smith XMapWindow(XiWin->disp,XiWin->win); 2335c6c1daeSBarry Smith 2345c6c1daeSBarry Smith /* some window systems are cruel and interfere with the placement of 2355c6c1daeSBarry Smith windows. We wait here for the window to be created or to die */ 236*09440f25SLisandro Dalcin if (PetscDrawXiWaitMap(XiWin)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Wait for X window failed"); 2375c6c1daeSBarry Smith PetscFunctionReturn(0); 2385c6c1daeSBarry Smith } 2395c6c1daeSBarry Smith 2405c6c1daeSBarry Smith #undef __FUNCT__ 2415c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindow" 24215d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiQuickWindow(PetscDraw_X *XiWin,char *name,int x,int y,int nx,int ny) 2435c6c1daeSBarry Smith { 24415d5bc79SLisandro Dalcin Window root; 24515d5bc79SLisandro Dalcin unsigned int w,h,dummy; 2465c6c1daeSBarry Smith PetscErrorCode ierr; 2475c6c1daeSBarry Smith 2485c6c1daeSBarry Smith PetscFunctionBegin; 24915d5bc79SLisandro Dalcin ierr = PetscDrawSetColormap_X(XiWin,(Colormap)0);CHKERRQ(ierr); 25015d5bc79SLisandro Dalcin ierr = PetscDrawXiDisplayWindow(XiWin,name,x,y,nx,ny);CHKERRQ(ierr); 25115d5bc79SLisandro Dalcin XSetWindowBackground(XiWin->disp,XiWin->win,XiWin->background); 25215d5bc79SLisandro Dalcin XClearWindow(XiWin->disp,XiWin->win); 2535c6c1daeSBarry Smith 25415d5bc79SLisandro Dalcin XGetGeometry(XiWin->disp,XiWin->win,&root,&x,&y,&w,&h,&dummy,&dummy); 25515d5bc79SLisandro Dalcin XiWin->x = x; 25615d5bc79SLisandro Dalcin XiWin->y = y; 25715d5bc79SLisandro Dalcin XiWin->w = (int)w; 25815d5bc79SLisandro Dalcin XiWin->h = (int)h; 2595c6c1daeSBarry Smith PetscFunctionReturn(0); 2605c6c1daeSBarry Smith } 2615c6c1daeSBarry Smith 2625c6c1daeSBarry Smith /* 2635c6c1daeSBarry Smith A version from an already defined window 2645c6c1daeSBarry Smith */ 2655c6c1daeSBarry Smith #undef __FUNCT__ 2665c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindowFromWindow" 26715d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiQuickWindowFromWindow(PetscDraw_X *XiWin,Window win) 2685c6c1daeSBarry Smith { 2695c6c1daeSBarry Smith Window root; 27015d5bc79SLisandro Dalcin int x,y; 27115d5bc79SLisandro Dalcin unsigned int w,h,dummy; 2725c6c1daeSBarry Smith XWindowAttributes attributes; 27315d5bc79SLisandro Dalcin PetscErrorCode ierr; 2745c6c1daeSBarry Smith 2755c6c1daeSBarry Smith PetscFunctionBegin; 27615d5bc79SLisandro Dalcin XiWin->win = win; 27715d5bc79SLisandro Dalcin XGetWindowAttributes(XiWin->disp,XiWin->win,&attributes); 27815d5bc79SLisandro Dalcin ierr = PetscDrawSetColormap_X(XiWin,attributes.colormap);CHKERRQ(ierr); 279481cee7bSLisandro Dalcin 28015d5bc79SLisandro Dalcin XGetGeometry(XiWin->disp,XiWin->win,&root,&x,&y,&w,&h,&dummy,&dummy); 28115d5bc79SLisandro Dalcin XiWin->x = x; 28215d5bc79SLisandro Dalcin XiWin->y = y; 28315d5bc79SLisandro Dalcin XiWin->w = (int)w; 28415d5bc79SLisandro Dalcin XiWin->h = (int)h; 2855c6c1daeSBarry Smith PetscFunctionReturn(0); 2865c6c1daeSBarry Smith } 2875c6c1daeSBarry Smith 2885c6c1daeSBarry Smith 289*09440f25SLisandro Dalcin #undef __FUNCT__ 290*09440f25SLisandro Dalcin #define __FUNCT__ "PetscDrawXiQuickPixmap" 291*09440f25SLisandro Dalcin PetscErrorCode PetscDrawXiQuickPixmap(PetscDraw_X* XiWin) 292*09440f25SLisandro Dalcin { 2935c6c1daeSBarry Smith PetscFunctionBegin; 294*09440f25SLisandro Dalcin if (XiWin->drw) XFreePixmap(XiWin->disp,XiWin->drw); 295*09440f25SLisandro Dalcin XiWin->drw = XCreatePixmap(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),XiWin->w,XiWin->h,XiWin->depth); 296*09440f25SLisandro Dalcin PetscDrawXiSetPixVal(XiWin,XiWin->background); 297*09440f25SLisandro Dalcin XFillRectangle(XiWin->disp,XiWin->drw,XiWin->gc.set,0,0,XiWin->w,XiWin->h); 298*09440f25SLisandro Dalcin XSync(XiWin->disp,False); 2995c6c1daeSBarry Smith PetscFunctionReturn(0); 3005c6c1daeSBarry Smith } 3015c6c1daeSBarry Smith 302*09440f25SLisandro Dalcin PETSC_INTERN PetscErrorCode PetscDrawSetSave_X(PetscDraw,const char[]); 303*09440f25SLisandro Dalcin 3045c6c1daeSBarry Smith #undef __FUNCT__ 3055c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSetSave_X" 3065c6c1daeSBarry Smith PetscErrorCode PetscDrawSetSave_X(PetscDraw draw,const char *filename) 3075c6c1daeSBarry Smith { 3085c6c1daeSBarry Smith PetscErrorCode ierr; 3095c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN) 3105c6c1daeSBarry Smith PetscMPIInt rank; 3115c6c1daeSBarry Smith #endif 3125c6c1daeSBarry Smith 3135c6c1daeSBarry Smith PetscFunctionBegin; 3145c6c1daeSBarry Smith PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 3155c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN) 316ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 3175c6c1daeSBarry Smith if (!rank) { 318d45a07a7SBarry Smith char command[PETSC_MAX_PATH_LEN]; 319d45a07a7SBarry Smith FILE *fd; 320d45a07a7SBarry Smith int err; 321d45a07a7SBarry Smith 322d45a07a7SBarry Smith ierr = PetscMemzero(command,sizeof(command));CHKERRQ(ierr); 3239982bd17SBarry Smith ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"rm -fr %s %s.m4v",draw->savefilename,draw->savefilename);CHKERRQ(ierr); 324e97f6855SBarry Smith ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr); 3250076e027SBarry Smith ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr); 3269982bd17SBarry Smith ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"mkdir %s",draw->savefilename);CHKERRQ(ierr); 327e97f6855SBarry Smith ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr); 3280076e027SBarry Smith ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr); 3295c6c1daeSBarry Smith } 3305c6c1daeSBarry Smith #endif 3315c6c1daeSBarry Smith PetscFunctionReturn(0); 3325c6c1daeSBarry Smith } 3335c6c1daeSBarry Smith 3341cda70a7SBarry Smith 3355c6c1daeSBarry Smith #if defined(PETSC_HAVE_AFTERIMAGE) 3365c6c1daeSBarry Smith #include <afterimage.h> 337aee23540SBarry Smith 33876f01e85SBarry Smith /* String names of possible Afterimage formats */ 33976f01e85SBarry Smith const char *PetscAfterImageFormats[] = { 34076f01e85SBarry Smith ".Xpm", 34176f01e85SBarry Smith ".Xpm.Z", 34276f01e85SBarry Smith ".Xpm.gz", 34376f01e85SBarry Smith ".Png", 34476f01e85SBarry Smith ".Jpeg", 345f140b876SBarry Smith ".Xcf", /* Gimp format */ 34676f01e85SBarry Smith ".Ppm", 34776f01e85SBarry Smith ".Pnm", 348f140b876SBarry Smith "MS Windows Bitmap", 349f140b876SBarry Smith "MS Windows Icon", 350f140b876SBarry Smith "MS Windows Cursor", 35176f01e85SBarry Smith ".Gif", 35276f01e85SBarry Smith ".Tiff", 353f140b876SBarry Smith "Afterstep XMLScript", 354f140b876SBarry Smith "Scalable Vector Graphics (SVG)", 35576f01e85SBarry Smith ".Xbm", 35676f01e85SBarry Smith "Targa", 35776f01e85SBarry Smith ".Pcx", 35876f01e85SBarry Smith ".HTML", 35976f01e85SBarry Smith "XML", 36076f01e85SBarry Smith "Unknown" 361aee23540SBarry Smith }; 362aee23540SBarry Smith 363aee23540SBarry Smith #undef __FUNCT__ 36476f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageStringToFormat" 36576f01e85SBarry Smith static PetscErrorCode PetscAfterimageStringToFormat(const char *ext,ASImageFileTypes *format) 366aee23540SBarry Smith { 36776f01e85SBarry Smith PetscInt i; 368aee23540SBarry Smith PetscErrorCode ierr; 36976f01e85SBarry Smith PetscBool flg; 370aee23540SBarry Smith 371aee23540SBarry Smith PetscFunctionBegin; 372f140b876SBarry Smith ierr = PetscStrcasecmp(".Jpg",ext,&flg);CHKERRQ(ierr); 373f140b876SBarry Smith if (flg) ext = ".Jpeg"; 37476f01e85SBarry Smith for (i=0; i<sizeof(PetscAfterImageFormats)/sizeof(char**); i++) { 37576f01e85SBarry Smith ierr = PetscStrcasecmp(PetscAfterImageFormats[i],ext,&flg);CHKERRQ(ierr); 37676f01e85SBarry Smith if (flg) { 37776f01e85SBarry Smith *format = (ASImageFileTypes)i; 37876f01e85SBarry Smith PetscFunctionReturn(0); 37976f01e85SBarry Smith } 38076f01e85SBarry Smith } 38176f01e85SBarry Smith *format = ASIT_Unknown; 38276f01e85SBarry Smith PetscFunctionReturn(0); 38376f01e85SBarry Smith } 38476f01e85SBarry Smith 38576f01e85SBarry Smith #if defined(PETSC_HAVE_SAWS) 38676f01e85SBarry Smith #include <petscviewersaws.h> 38776f01e85SBarry Smith /* 38876f01e85SBarry Smith The PetscAfterimage object and functions are used to maintain a list of file images created by Afterimage that can 38976f01e85SBarry Smith be displayed by the SAWs webserver. 39076f01e85SBarry Smith */ 39176f01e85SBarry Smith typedef struct _P_PetscAfterimage *PetscAfterimage; 39276f01e85SBarry Smith struct _P_PetscAfterimage { 39376f01e85SBarry Smith PetscAfterimage next; 39476f01e85SBarry Smith char *filename; 39576f01e85SBarry Smith char *ext; 39676f01e85SBarry Smith PetscInt cnt; 39776f01e85SBarry Smith } ; 39876f01e85SBarry Smith 39976f01e85SBarry Smith static PetscAfterimage afterimages = 0; 40076f01e85SBarry Smith 40176f01e85SBarry Smith #undef __FUNCT__ 40276f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageDestroy" 40376f01e85SBarry Smith static PetscErrorCode PetscAfterimageDestroy(void) 40476f01e85SBarry Smith { 40576f01e85SBarry Smith PetscErrorCode ierr; 40676f01e85SBarry Smith PetscAfterimage afterimage,oafterimage = afterimages; 40776f01e85SBarry Smith 40876f01e85SBarry Smith PetscFunctionBegin; 40976f01e85SBarry Smith while (oafterimage) { 41076f01e85SBarry Smith afterimage = oafterimage->next; 41176f01e85SBarry Smith ierr = PetscFree(oafterimage->filename);CHKERRQ(ierr); 41276f01e85SBarry Smith ierr = PetscFree(oafterimage->ext);CHKERRQ(ierr); 41376f01e85SBarry Smith ierr = PetscFree(oafterimage);CHKERRQ(ierr); 41476f01e85SBarry Smith oafterimage = afterimage; 415aee23540SBarry Smith } 416aee23540SBarry Smith PetscFunctionReturn(0); 417aee23540SBarry Smith } 418aee23540SBarry Smith 419aee23540SBarry Smith #undef __FUNCT__ 42076f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageAdd" 42176f01e85SBarry Smith static PetscErrorCode PetscAfterimageAdd(const char *filename,const char *ext,PetscInt cnt) 422aee23540SBarry Smith { 423aee23540SBarry Smith PetscErrorCode ierr; 42476f01e85SBarry Smith PetscAfterimage afterimage,oafterimage = afterimages; 425aee23540SBarry Smith PetscBool flg; 426aee23540SBarry Smith 427aee23540SBarry Smith PetscFunctionBegin; 42876f01e85SBarry Smith if (oafterimage){ 42976f01e85SBarry Smith ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr); 43076f01e85SBarry Smith if (flg) { 43176f01e85SBarry Smith oafterimage->cnt = cnt; 43276f01e85SBarry Smith PetscFunctionReturn(0); 433aee23540SBarry Smith } 43476f01e85SBarry Smith while (oafterimage->next) { 43576f01e85SBarry Smith oafterimage = oafterimage->next; 43676f01e85SBarry Smith ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr); 43776f01e85SBarry Smith if (flg) { 43876f01e85SBarry Smith oafterimage->cnt = cnt; 43976f01e85SBarry Smith PetscFunctionReturn(0); 44076f01e85SBarry Smith } 44176f01e85SBarry Smith } 44276f01e85SBarry Smith ierr = PetscNew(&afterimage);CHKERRQ(ierr); 44376f01e85SBarry Smith oafterimage->next = afterimage; 444aee23540SBarry Smith } else { 44576f01e85SBarry Smith ierr = PetscNew(&afterimage);CHKERRQ(ierr); 44676f01e85SBarry Smith afterimages = afterimage; 447aee23540SBarry Smith } 44876f01e85SBarry Smith ierr = PetscStrallocpy(filename,&afterimage->filename);CHKERRQ(ierr); 44976f01e85SBarry Smith ierr = PetscStrallocpy(ext,&afterimage->ext);CHKERRQ(ierr); 45076f01e85SBarry Smith afterimage->cnt = cnt; 45176f01e85SBarry Smith ierr = PetscRegisterFinalize(PetscAfterimageDestroy);CHKERRQ(ierr); 452aee23540SBarry Smith PetscFunctionReturn(0); 453aee23540SBarry Smith } 454aee23540SBarry Smith 455aee23540SBarry Smith #endif 456aee23540SBarry Smith 457*09440f25SLisandro Dalcin PETSC_INTERN PetscErrorCode PetscDrawSave_X(PetscDraw); 458*09440f25SLisandro Dalcin 4595c6c1daeSBarry Smith #undef __FUNCT__ 4605c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSave_X" 4615c6c1daeSBarry Smith PetscErrorCode PetscDrawSave_X(PetscDraw draw) 4625c6c1daeSBarry Smith { 4635c6c1daeSBarry Smith PetscDraw_X *drawx = (PetscDraw_X*)draw->data; 4645c6c1daeSBarry Smith XImage *image; 4655c6c1daeSBarry Smith ASImage *asimage; 466681455b2SBarry Smith struct ASVisual *asv; 4675c6c1daeSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 4685c6c1daeSBarry Smith PetscErrorCode ierr; 4695c6c1daeSBarry Smith PetscMPIInt rank; 470681455b2SBarry Smith int depth; 47176f01e85SBarry Smith ASImageFileTypes format; 4725c6c1daeSBarry Smith 4735c6c1daeSBarry Smith PetscFunctionBegin; 4745c6c1daeSBarry Smith if (!draw->savefilename) PetscFunctionReturn(0); 4755b399a63SLisandro Dalcin ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 4765b399a63SLisandro Dalcin 4775b399a63SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 4785b399a63SLisandro Dalcin XSync(drawx->disp,True); 4795b399a63SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 4805b399a63SLisandro Dalcin ierr = MPI_Barrier(PetscObjectComm((PetscObject)draw));CHKERRQ(ierr); 4815b399a63SLisandro Dalcin 4825b399a63SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 4835b399a63SLisandro Dalcin if (rank) goto finally; /* only process 0 handles the saving business */ 484681455b2SBarry Smith depth = DefaultDepth(drawx->disp,drawx->screen); 485681455b2SBarry Smith asv = create_asvisual(drawx->disp,drawx->screen,depth,NULL);if (!asv) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASVisual"); 4865b399a63SLisandro Dalcin image = XGetImage(drawx->disp,PetscDrawXiDrawable(drawx),0,0,drawx->w,drawx->h,AllPlanes,ZPixmap); 48776f01e85SBarry Smith if (!image) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot XGetImage()"); 488ce94432eSBarry Smith asimage = picture_ximage2asimage(asv,image,0,0);if (!asimage) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASImage"); 4898b7fcac6SBarry Smith if (draw->savesinglefile) { 49076f01e85SBarry Smith ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s%s",draw->savefilename,draw->savefilename,draw->savefilenameext);CHKERRQ(ierr); 4918b7fcac6SBarry Smith } else { 49276f01e85SBarry Smith ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s_%d%s",draw->savefilename,draw->savefilename,draw->savefilecount++,draw->savefilenameext);CHKERRQ(ierr); 4938b7fcac6SBarry Smith } 49476f01e85SBarry Smith ierr = PetscAfterimageStringToFormat(draw->savefilenameext,&format);CHKERRQ(ierr); 49576f01e85SBarry Smith ASImage2file(asimage,0,filename,format,0); 4961cda70a7SBarry Smith #if defined(PETSC_HAVE_SAWS) 4971cda70a7SBarry Smith { 498aee23540SBarry Smith char body[4096]; 49976f01e85SBarry Smith PetscAfterimage afterimage; 500aee23540SBarry Smith size_t len = 0; 501aee23540SBarry Smith 50276f01e85SBarry Smith ierr = PetscAfterimageAdd(draw->savefilename,draw->savefilenameext,draw->savefilecount-1);CHKERRQ(ierr); 50376f01e85SBarry Smith afterimage = afterimages; 50476f01e85SBarry Smith while (afterimage) { 50576f01e85SBarry Smith if (draw->savesinglefile) { 50676f01e85SBarry Smith ierr = PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s%s\" alt=\"None\">",afterimage->filename,afterimage->filename,afterimage->ext);CHKERRQ(ierr); 50776f01e85SBarry Smith } else { 50876f01e85SBarry 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); 50976f01e85SBarry Smith } 510aee23540SBarry Smith ierr = PetscStrlen(body,&len);CHKERRQ(ierr); 51176f01e85SBarry Smith afterimage = afterimage->next; 512aee23540SBarry Smith } 513aee23540SBarry Smith ierr = PetscStrcat(body,"<br>\n");CHKERRQ(ierr); 51443da4ab2SBarry Smith if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1)); 51543da4ab2SBarry Smith PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body)); 5161cda70a7SBarry Smith } 5171cda70a7SBarry Smith #endif 518681455b2SBarry Smith destroy_asvisual(asv,0); 5195b399a63SLisandro Dalcin XDestroyImage(image); 5205b399a63SLisandro Dalcin finally: 5215b399a63SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 5225c6c1daeSBarry Smith PetscFunctionReturn(0); 5235c6c1daeSBarry Smith } 5245b399a63SLisandro Dalcin 5255c6c1daeSBarry Smith /* 5265c6c1daeSBarry Smith There are routines wanted by AfterImage for PNG files 5275c6c1daeSBarry Smith */ 5285c6c1daeSBarry Smith void crc32(void) {;} 5295c6c1daeSBarry Smith void inflateReset(void) {;} 5305c6c1daeSBarry Smith void deflateReset(void) {;} 5315c6c1daeSBarry Smith void deflateInit2(void) {;} 5325c6c1daeSBarry Smith void deflateInit2_(void) {;} 5335c6c1daeSBarry Smith void deflate(void) {;} 5345c6c1daeSBarry Smith void deflateEnd(void) {;} 5355c6c1daeSBarry Smith 5365c6c1daeSBarry Smith #endif 5375c6c1daeSBarry Smith 5385c6c1daeSBarry Smith 5395c6c1daeSBarry Smith 540