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 PetscDrawXiUniformHues(PetscDraw_X*,int); 175c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXi_wait_map(PetscDraw_X*); 185c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXiFontFixed(PetscDraw_X*,int,int,PetscDrawXiFont**); 195c6c1daeSBarry Smith extern PetscErrorCode PetscDrawXiInitCmap(PetscDraw_X*); 205c6c1daeSBarry Smith extern PetscErrorCode PetscDrawSetColormap_X(PetscDraw_X*,char*,Colormap); 215c6c1daeSBarry Smith 225c6c1daeSBarry Smith /* 235c6c1daeSBarry Smith PetscDrawXiOpenDisplay - Open a display 245c6c1daeSBarry Smith */ 255c6c1daeSBarry Smith #undef __FUNCT__ 265c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiOpenDisplay" 275c6c1daeSBarry Smith PetscErrorCode PetscDrawXiOpenDisplay(PetscDraw_X *XiWin,char *display_name) 285c6c1daeSBarry Smith { 295c6c1daeSBarry Smith PetscFunctionBegin; 305c6c1daeSBarry Smith XiWin->disp = XOpenDisplay(display_name); 315c6c1daeSBarry Smith if (!XiWin->disp) { 325c6c1daeSBarry 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\ 335c6c1daeSBarry Smith to this X server and either your DISPLAY variable\n\ 345c6c1daeSBarry Smith is set or you use the -display name option\n",display_name); 355c6c1daeSBarry Smith } 365c6c1daeSBarry Smith XiWin->screen = DefaultScreen(XiWin->disp); 37*481cee7bSLisandro Dalcin XiWin->vis = DefaultVisual(XiWin->disp,XiWin->screen); 38*481cee7bSLisandro Dalcin XiWin->depth = DefaultDepth(XiWin->disp,XiWin->screen); 395c6c1daeSBarry Smith PetscFunctionReturn(0); 405c6c1daeSBarry Smith } 415c6c1daeSBarry Smith 425c6c1daeSBarry Smith 435c6c1daeSBarry Smith /* 445c6c1daeSBarry Smith PetscDrawXiSetGC - set the GC structure in the base window 455c6c1daeSBarry Smith */ 465c6c1daeSBarry Smith #undef __FUNCT__ 475c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetGC" 485c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetGC(PetscDraw_X *XiWin,PetscDrawXiPixVal fg) 495c6c1daeSBarry Smith { 505c6c1daeSBarry Smith XGCValues gcvalues; /* window graphics context values */ 515c6c1daeSBarry Smith 525c6c1daeSBarry Smith PetscFunctionBegin; 535c6c1daeSBarry Smith /* Set the graphics contexts */ 545c6c1daeSBarry Smith /* create a gc for the ROP_SET operation (writing the fg value to a pixel) */ 555c6c1daeSBarry Smith /* (do this with function GXcopy; GXset will automatically write 1) */ 565c6c1daeSBarry Smith gcvalues.function = GXcopy; 575c6c1daeSBarry Smith gcvalues.foreground = fg; 585c6c1daeSBarry Smith XiWin->gc.cur_pix = fg; 595c6c1daeSBarry Smith XiWin->gc.set = XCreateGC(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),GCFunction | GCForeground,&gcvalues); 605c6c1daeSBarry Smith PetscFunctionReturn(0); 615c6c1daeSBarry Smith } 625c6c1daeSBarry Smith 635c6c1daeSBarry Smith /* 645c6c1daeSBarry Smith Actually display a window at [x,y] with sizes (w,h) 655c6c1daeSBarry Smith If w and/or h are 0, use the sizes in the fields of XiWin 665c6c1daeSBarry Smith (which may have been set by, for example, PetscDrawXiSetWindowSize) 675c6c1daeSBarry Smith */ 685c6c1daeSBarry Smith #undef __FUNCT__ 695c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiDisplayWindow" 705c6c1daeSBarry Smith PetscErrorCode PetscDrawXiDisplayWindow(PetscDraw_X *XiWin,char *label,int x,int y,int w,int h,PetscDrawXiPixVal backgnd_pixel) 715c6c1daeSBarry Smith { 725c6c1daeSBarry Smith unsigned int wavail,havail; 735c6c1daeSBarry Smith XSizeHints size_hints; 745c6c1daeSBarry Smith XWindowAttributes in_window_attributes; 755c6c1daeSBarry Smith XSetWindowAttributes window_attributes; 765c6c1daeSBarry Smith int depth,border_width; 775c6c1daeSBarry Smith unsigned long wmask; 785c6c1daeSBarry Smith PetscBool flg; 795c6c1daeSBarry Smith PetscErrorCode ierr; 805c6c1daeSBarry Smith 815c6c1daeSBarry Smith PetscFunctionBegin; 825c6c1daeSBarry Smith /* get the available widths */ 835c6c1daeSBarry Smith wavail = DisplayWidth(XiWin->disp,XiWin->screen); 845c6c1daeSBarry Smith havail = DisplayHeight(XiWin->disp,XiWin->screen); 855c6c1daeSBarry Smith if (w <= 0 || h <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"X Window display has invalid height or width"); 865c6c1daeSBarry Smith if ((unsigned int) w > wavail) w = wavail; 875c6c1daeSBarry Smith if ((unsigned int) h > havail) h = havail; 885c6c1daeSBarry Smith 895c6c1daeSBarry Smith border_width = 0; 905c6c1daeSBarry Smith if (x < 0) x = 0; 915c6c1daeSBarry Smith if (y < 0) y = 0; 923964eb88SJed Brown x = ((unsigned int) x + w > wavail) ? wavail - w : (unsigned int)x; 933964eb88SJed Brown y = ((unsigned int) y + h > havail) ? havail - h : (unsigned int)y; 945c6c1daeSBarry Smith 955c6c1daeSBarry Smith /* We need XCreateWindow since we may need an visual other than the default one */ 965c6c1daeSBarry Smith XGetWindowAttributes(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),&in_window_attributes); 975c6c1daeSBarry Smith window_attributes.background_pixmap = None; 985c6c1daeSBarry Smith window_attributes.background_pixel = backgnd_pixel; 995c6c1daeSBarry Smith /* No border for now */ 1005c6c1daeSBarry Smith window_attributes.border_pixmap = None; 1015c6c1daeSBarry Smith /* 1025c6c1daeSBarry Smith window_attributes.border_pixel = border_pixel; 1035c6c1daeSBarry Smith */ 1045c6c1daeSBarry Smith window_attributes.bit_gravity = in_window_attributes.bit_gravity; 1055c6c1daeSBarry Smith window_attributes.win_gravity = in_window_attributes.win_gravity; 1065c6c1daeSBarry Smith /* Backing store is too slow in color systems */ 1075c6c1daeSBarry Smith window_attributes.backing_store = 0; 1085c6c1daeSBarry Smith window_attributes.backing_pixel = backgnd_pixel; 1095c6c1daeSBarry Smith window_attributes.save_under = 1; 1105c6c1daeSBarry Smith window_attributes.event_mask = 0; 1115c6c1daeSBarry Smith window_attributes.do_not_propagate_mask = 0; 1125c6c1daeSBarry Smith window_attributes.override_redirect = 0; 1135c6c1daeSBarry Smith window_attributes.colormap = XiWin->cmap; 1145c6c1daeSBarry Smith /* None for cursor does NOT mean none, it means cursor of Parent */ 1155c6c1daeSBarry Smith window_attributes.cursor = None; 116a297a907SKarl Rupp 1175c6c1daeSBarry Smith wmask = CWBackPixmap | CWBackPixel | CWBorderPixmap | CWBitGravity | 1185c6c1daeSBarry Smith CWWinGravity | CWBackingStore |CWBackingPixel |CWOverrideRedirect | 1195c6c1daeSBarry Smith CWSaveUnder | CWEventMask | CWDontPropagate | 1205c6c1daeSBarry Smith CWCursor | CWColormap; 1215c6c1daeSBarry Smith depth = XiWin->depth; 1225c6c1daeSBarry Smith 1235c6c1daeSBarry Smith XiWin->win = XCreateWindow(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),x,y,w,h,border_width,depth,InputOutput,XiWin->vis,wmask,&window_attributes); 1245c6c1daeSBarry Smith if (!XiWin->win) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open X window"); 1255c6c1daeSBarry Smith 1265c6c1daeSBarry Smith /* set window manager hints */ 1275c6c1daeSBarry Smith { 1285c6c1daeSBarry Smith XWMHints wm_hints; 1295c6c1daeSBarry Smith XClassHint class_hints; 1305c6c1daeSBarry Smith XTextProperty windowname,iconname; 1315c6c1daeSBarry Smith 132a297a907SKarl Rupp if (label) XStringListToTextProperty(&label,1,&windowname); 133a297a907SKarl Rupp else XStringListToTextProperty(&label,0,&windowname); 134a297a907SKarl Rupp if (label) XStringListToTextProperty(&label,1,&iconname); 135a297a907SKarl Rupp else XStringListToTextProperty(&label,0,&iconname); 1365c6c1daeSBarry Smith 1375c6c1daeSBarry Smith wm_hints.initial_state = NormalState; 1385c6c1daeSBarry Smith wm_hints.input = True; 1395c6c1daeSBarry Smith wm_hints.flags = StateHint|InputHint; 1405c6c1daeSBarry Smith 1415c6c1daeSBarry Smith /* These properties can be used by window managers to decide how to display a window */ 1425c6c1daeSBarry Smith class_hints.res_name = (char*)"petsc"; 1435c6c1daeSBarry Smith class_hints.res_class = (char*)"PETSc"; 1445c6c1daeSBarry Smith 1455c6c1daeSBarry Smith size_hints.x = x; 1465c6c1daeSBarry Smith size_hints.y = y; 1475c6c1daeSBarry Smith size_hints.min_width = 4*border_width; 1485c6c1daeSBarry Smith size_hints.min_height = 4*border_width; 1495c6c1daeSBarry Smith size_hints.width = w; 1505c6c1daeSBarry Smith size_hints.height = h; 1515c6c1daeSBarry Smith size_hints.flags = USPosition | USSize | PMinSize; 1525c6c1daeSBarry Smith 1535c6c1daeSBarry Smith XSetWMProperties(XiWin->disp,XiWin->win,&windowname,&iconname,0,0,&size_hints,&wm_hints,&class_hints); 1545c6c1daeSBarry Smith XFree((void*)windowname.value); 1555c6c1daeSBarry Smith XFree((void*)iconname.value); 1565c6c1daeSBarry Smith } 157*481cee7bSLisandro Dalcin 1585c6c1daeSBarry Smith /* make the window visible */ 1595c6c1daeSBarry Smith XSelectInput(XiWin->disp,XiWin->win,ExposureMask|StructureNotifyMask); 1605c6c1daeSBarry Smith XMapWindow(XiWin->disp,XiWin->win); 1615c6c1daeSBarry Smith 1625c6c1daeSBarry Smith /* some window systems are cruel and interfere with the placement of 1635c6c1daeSBarry Smith windows. We wait here for the window to be created or to die */ 1645c6c1daeSBarry Smith if (PetscDrawXi_wait_map(XiWin)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Wait for X window failed"); 1655c6c1daeSBarry Smith 1665c6c1daeSBarry Smith flg = PETSC_FALSE; 167c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-draw_virtual",&flg,NULL);CHKERRQ(ierr); 1685c6c1daeSBarry Smith if (flg) { 1695c6c1daeSBarry Smith XiWin->drw = XCreatePixmap(XiWin->disp,XiWin->win,XiWin->w,XiWin->h,XiWin->depth); 1705c6c1daeSBarry Smith XDestroyWindow(XiWin->disp,XiWin->win); 1715c6c1daeSBarry Smith XiWin->win = 0; 1725c6c1daeSBarry Smith PetscFunctionReturn(0); 1735c6c1daeSBarry Smith } 1745c6c1daeSBarry Smith 1755c6c1daeSBarry Smith /* Initial values for the upper left corner */ 1765c6c1daeSBarry Smith XiWin->x = 0; 1775c6c1daeSBarry Smith XiWin->y = 0; 1785c6c1daeSBarry Smith PetscFunctionReturn(0); 1795c6c1daeSBarry Smith } 1805c6c1daeSBarry Smith 1815c6c1daeSBarry Smith #undef __FUNCT__ 1825c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindow" 1835c6c1daeSBarry Smith PetscErrorCode PetscDrawXiQuickWindow(PetscDraw_X *w,char *host,char *name,int x,int y,int nx,int ny) 1845c6c1daeSBarry Smith { 1855c6c1daeSBarry Smith PetscErrorCode ierr; 1865c6c1daeSBarry Smith 1875c6c1daeSBarry Smith PetscFunctionBegin; 1885c6c1daeSBarry Smith ierr = PetscDrawXiOpenDisplay(w,host);CHKERRQ(ierr); 1895c6c1daeSBarry Smith 1905c6c1daeSBarry Smith ierr = PetscDrawSetColormap_X(w,host,(Colormap)0);CHKERRQ(ierr); 1915c6c1daeSBarry Smith 1925c6c1daeSBarry Smith ierr = PetscDrawXiDisplayWindow(w,name,x,y,nx,ny,(PetscDrawXiPixVal)0);CHKERRQ(ierr); 19300d931feSLisandro Dalcin PetscDrawXiSetGC(w,w->cmapping[PETSC_DRAW_BLACK]); 1945c6c1daeSBarry Smith PetscDrawXiSetPixVal(w,w->background); 1955c6c1daeSBarry Smith 1965c6c1daeSBarry Smith ierr = PetscDrawXiFontFixed(w,6,10,&w->font);CHKERRQ(ierr); 1975c6c1daeSBarry Smith if (w->win) { 19800d931feSLisandro Dalcin XSetWindowBackground(w->disp,w->win,w->cmapping[PETSC_DRAW_WHITE]); 1995c6c1daeSBarry Smith XFillRectangle(w->disp,w->win,w->gc.set,0,0,nx,ny); 2005c6c1daeSBarry Smith } 2015c6c1daeSBarry Smith PetscFunctionReturn(0); 2025c6c1daeSBarry Smith } 2035c6c1daeSBarry Smith 2045c6c1daeSBarry Smith /* 2055c6c1daeSBarry Smith A version from an already defined window 2065c6c1daeSBarry Smith */ 2075c6c1daeSBarry Smith #undef __FUNCT__ 2085c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindowFromWindow" 2095c6c1daeSBarry Smith PetscErrorCode PetscDrawXiQuickWindowFromWindow(PetscDraw_X *w,char *host,Window win) 2105c6c1daeSBarry Smith { 2115c6c1daeSBarry Smith Window root; 2125c6c1daeSBarry Smith PetscErrorCode ierr; 2135c6c1daeSBarry Smith int d; 2145c6c1daeSBarry Smith unsigned int ud; 2155c6c1daeSBarry Smith XWindowAttributes attributes; 2165c6c1daeSBarry Smith 2175c6c1daeSBarry Smith PetscFunctionBegin; 2185c6c1daeSBarry Smith ierr = PetscDrawXiOpenDisplay(w,host);CHKERRQ(ierr); 219*481cee7bSLisandro Dalcin 2205c6c1daeSBarry Smith w->win = win; 2215c6c1daeSBarry Smith XGetWindowAttributes(w->disp,w->win,&attributes); 2225c6c1daeSBarry Smith XGetGeometry(w->disp,w->win,&root,&d,&d,(unsigned int*)&w->w,(unsigned int*)&w->h,&ud,&ud); 2235c6c1daeSBarry Smith w->x = w->y = 0; 2245c6c1daeSBarry Smith 225*481cee7bSLisandro Dalcin ierr = PetscDrawSetColormap_X(w,host,attributes.colormap);CHKERRQ(ierr); 226*481cee7bSLisandro Dalcin 22700d931feSLisandro Dalcin PetscDrawXiSetGC(w,w->cmapping[PETSC_DRAW_BLACK]); 2285c6c1daeSBarry Smith PetscDrawXiSetPixVal(w,w->background); 22900d931feSLisandro Dalcin XSetWindowBackground(w->disp,w->win,w->cmapping[PETSC_DRAW_WHITE]); 2305c6c1daeSBarry Smith ierr = PetscDrawXiFontFixed(w,6,10,&w->font);CHKERRQ(ierr); 2315c6c1daeSBarry Smith PetscFunctionReturn(0); 2325c6c1daeSBarry Smith } 2335c6c1daeSBarry Smith 2345c6c1daeSBarry Smith /* 2355c6c1daeSBarry Smith PetscDrawXiSetWindowLabel - Sets new label in open window. 2365c6c1daeSBarry Smith */ 2375c6c1daeSBarry Smith #undef __FUNCT__ 2385c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetWindowLabel" 2395c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetWindowLabel(PetscDraw_X *Xiwin,char *label) 2405c6c1daeSBarry Smith { 2415c6c1daeSBarry Smith XTextProperty prop; 2425c6c1daeSBarry Smith size_t len; 2435c6c1daeSBarry Smith PetscErrorCode ierr; 2445c6c1daeSBarry Smith 2455c6c1daeSBarry Smith PetscFunctionBegin; 2465c6c1daeSBarry Smith XGetWMName(Xiwin->disp,Xiwin->win,&prop); 2475c6c1daeSBarry Smith prop.value = (unsigned char*)label; 2485c6c1daeSBarry Smith ierr = PetscStrlen(label,&len);CHKERRQ(ierr); 2495c6c1daeSBarry Smith prop.nitems = (long) len; 2505c6c1daeSBarry Smith XSetWMName(Xiwin->disp,Xiwin->win,&prop); 2515c6c1daeSBarry Smith PetscFunctionReturn(0); 2525c6c1daeSBarry Smith } 2535c6c1daeSBarry Smith 2545c6c1daeSBarry Smith #undef __FUNCT__ 2555c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiSetToBackground" 2565c6c1daeSBarry Smith PetscErrorCode PetscDrawXiSetToBackground(PetscDraw_X *XiWin) 2575c6c1daeSBarry Smith { 2585c6c1daeSBarry Smith PetscFunctionBegin; 2595c6c1daeSBarry Smith if (XiWin->gc.cur_pix != XiWin->background) { 2605c6c1daeSBarry Smith XSetForeground(XiWin->disp,XiWin->gc.set,XiWin->background); 2615c6c1daeSBarry Smith XiWin->gc.cur_pix = XiWin->background; 2625c6c1daeSBarry Smith } 2635c6c1daeSBarry Smith PetscFunctionReturn(0); 2645c6c1daeSBarry Smith 2655c6c1daeSBarry Smith } 2665c6c1daeSBarry Smith 2675c6c1daeSBarry Smith #undef __FUNCT__ 2685c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSetSave_X" 2695c6c1daeSBarry Smith PetscErrorCode PetscDrawSetSave_X(PetscDraw draw,const char *filename) 2705c6c1daeSBarry Smith { 2715c6c1daeSBarry Smith PetscErrorCode ierr; 2725c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN) 2735c6c1daeSBarry Smith PetscMPIInt rank; 2745c6c1daeSBarry Smith #endif 2755c6c1daeSBarry Smith 2765c6c1daeSBarry Smith PetscFunctionBegin; 2775c6c1daeSBarry Smith PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 2785c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN) 279ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 2805c6c1daeSBarry Smith if (!rank) { 281d45a07a7SBarry Smith char command[PETSC_MAX_PATH_LEN]; 282d45a07a7SBarry Smith FILE *fd; 283d45a07a7SBarry Smith int err; 284d45a07a7SBarry Smith 285d45a07a7SBarry Smith ierr = PetscMemzero(command,sizeof(command));CHKERRQ(ierr); 2869982bd17SBarry Smith ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"rm -fr %s %s.m4v",draw->savefilename,draw->savefilename);CHKERRQ(ierr); 287e97f6855SBarry Smith ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr); 2880076e027SBarry Smith ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr); 2899982bd17SBarry Smith ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"mkdir %s",draw->savefilename);CHKERRQ(ierr); 290e97f6855SBarry Smith ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr); 2910076e027SBarry Smith ierr = PetscPClose(PETSC_COMM_SELF,fd,&err);CHKERRQ(ierr); 2925c6c1daeSBarry Smith } 2935c6c1daeSBarry Smith #endif 2945c6c1daeSBarry Smith PetscFunctionReturn(0); 2955c6c1daeSBarry Smith } 2965c6c1daeSBarry Smith 2971cda70a7SBarry Smith 2985c6c1daeSBarry Smith #if defined(PETSC_HAVE_AFTERIMAGE) 2995c6c1daeSBarry Smith #include <afterimage.h> 300aee23540SBarry Smith 30176f01e85SBarry Smith /* String names of possible Afterimage formats */ 30276f01e85SBarry Smith const char *PetscAfterImageFormats[] = { 30376f01e85SBarry Smith ".Xpm", 30476f01e85SBarry Smith ".Xpm.Z", 30576f01e85SBarry Smith ".Xpm.gz", 30676f01e85SBarry Smith ".Png", 30776f01e85SBarry Smith ".Jpeg", 308f140b876SBarry Smith ".Xcf", /* Gimp format */ 30976f01e85SBarry Smith ".Ppm", 31076f01e85SBarry Smith ".Pnm", 311f140b876SBarry Smith "MS Windows Bitmap", 312f140b876SBarry Smith "MS Windows Icon", 313f140b876SBarry Smith "MS Windows Cursor", 31476f01e85SBarry Smith ".Gif", 31576f01e85SBarry Smith ".Tiff", 316f140b876SBarry Smith "Afterstep XMLScript", 317f140b876SBarry Smith "Scalable Vector Graphics (SVG)", 31876f01e85SBarry Smith ".Xbm", 31976f01e85SBarry Smith "Targa", 32076f01e85SBarry Smith ".Pcx", 32176f01e85SBarry Smith ".HTML", 32276f01e85SBarry Smith "XML", 32376f01e85SBarry Smith "Unknown" 324aee23540SBarry Smith }; 325aee23540SBarry Smith 326aee23540SBarry Smith #undef __FUNCT__ 32776f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageStringToFormat" 32876f01e85SBarry Smith static PetscErrorCode PetscAfterimageStringToFormat(const char *ext,ASImageFileTypes *format) 329aee23540SBarry Smith { 33076f01e85SBarry Smith PetscInt i; 331aee23540SBarry Smith PetscErrorCode ierr; 33276f01e85SBarry Smith PetscBool flg; 333aee23540SBarry Smith 334aee23540SBarry Smith PetscFunctionBegin; 335f140b876SBarry Smith ierr = PetscStrcasecmp(".Jpg",ext,&flg);CHKERRQ(ierr); 336f140b876SBarry Smith if (flg) ext = ".Jpeg"; 33776f01e85SBarry Smith for (i=0; i<sizeof(PetscAfterImageFormats)/sizeof(char**); i++) { 33876f01e85SBarry Smith ierr = PetscStrcasecmp(PetscAfterImageFormats[i],ext,&flg);CHKERRQ(ierr); 33976f01e85SBarry Smith if (flg) { 34076f01e85SBarry Smith *format = (ASImageFileTypes)i; 34176f01e85SBarry Smith PetscFunctionReturn(0); 34276f01e85SBarry Smith } 34376f01e85SBarry Smith } 34476f01e85SBarry Smith *format = ASIT_Unknown; 34576f01e85SBarry Smith PetscFunctionReturn(0); 34676f01e85SBarry Smith } 34776f01e85SBarry Smith 34876f01e85SBarry Smith #if defined(PETSC_HAVE_SAWS) 34976f01e85SBarry Smith #include <petscviewersaws.h> 35076f01e85SBarry Smith /* 35176f01e85SBarry Smith The PetscAfterimage object and functions are used to maintain a list of file images created by Afterimage that can 35276f01e85SBarry Smith be displayed by the SAWs webserver. 35376f01e85SBarry Smith */ 35476f01e85SBarry Smith typedef struct _P_PetscAfterimage *PetscAfterimage; 35576f01e85SBarry Smith struct _P_PetscAfterimage { 35676f01e85SBarry Smith PetscAfterimage next; 35776f01e85SBarry Smith char *filename; 35876f01e85SBarry Smith char *ext; 35976f01e85SBarry Smith PetscInt cnt; 36076f01e85SBarry Smith } ; 36176f01e85SBarry Smith 36276f01e85SBarry Smith static PetscAfterimage afterimages = 0; 36376f01e85SBarry Smith 36476f01e85SBarry Smith #undef __FUNCT__ 36576f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageDestroy" 36676f01e85SBarry Smith static PetscErrorCode PetscAfterimageDestroy(void) 36776f01e85SBarry Smith { 36876f01e85SBarry Smith PetscErrorCode ierr; 36976f01e85SBarry Smith PetscAfterimage afterimage,oafterimage = afterimages; 37076f01e85SBarry Smith 37176f01e85SBarry Smith PetscFunctionBegin; 37276f01e85SBarry Smith while (oafterimage) { 37376f01e85SBarry Smith afterimage = oafterimage->next; 37476f01e85SBarry Smith ierr = PetscFree(oafterimage->filename);CHKERRQ(ierr); 37576f01e85SBarry Smith ierr = PetscFree(oafterimage->ext);CHKERRQ(ierr); 37676f01e85SBarry Smith ierr = PetscFree(oafterimage);CHKERRQ(ierr); 37776f01e85SBarry Smith oafterimage = afterimage; 378aee23540SBarry Smith } 379aee23540SBarry Smith PetscFunctionReturn(0); 380aee23540SBarry Smith } 381aee23540SBarry Smith 382aee23540SBarry Smith #undef __FUNCT__ 38376f01e85SBarry Smith #define __FUNCT__ "PetscAfterimageAdd" 38476f01e85SBarry Smith static PetscErrorCode PetscAfterimageAdd(const char *filename,const char *ext,PetscInt cnt) 385aee23540SBarry Smith { 386aee23540SBarry Smith PetscErrorCode ierr; 38776f01e85SBarry Smith PetscAfterimage afterimage,oafterimage = afterimages; 388aee23540SBarry Smith PetscBool flg; 389aee23540SBarry Smith 390aee23540SBarry Smith PetscFunctionBegin; 39176f01e85SBarry Smith if (oafterimage){ 39276f01e85SBarry Smith ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr); 39376f01e85SBarry Smith if (flg) { 39476f01e85SBarry Smith oafterimage->cnt = cnt; 39576f01e85SBarry Smith PetscFunctionReturn(0); 396aee23540SBarry Smith } 39776f01e85SBarry Smith while (oafterimage->next) { 39876f01e85SBarry Smith oafterimage = oafterimage->next; 39976f01e85SBarry Smith ierr = PetscStrcmp(filename,oafterimage->filename,&flg);CHKERRQ(ierr); 40076f01e85SBarry Smith if (flg) { 40176f01e85SBarry Smith oafterimage->cnt = cnt; 40276f01e85SBarry Smith PetscFunctionReturn(0); 40376f01e85SBarry Smith } 40476f01e85SBarry Smith } 40576f01e85SBarry Smith ierr = PetscNew(&afterimage);CHKERRQ(ierr); 40676f01e85SBarry Smith oafterimage->next = afterimage; 407aee23540SBarry Smith } else { 40876f01e85SBarry Smith ierr = PetscNew(&afterimage);CHKERRQ(ierr); 40976f01e85SBarry Smith afterimages = afterimage; 410aee23540SBarry Smith } 41176f01e85SBarry Smith ierr = PetscStrallocpy(filename,&afterimage->filename);CHKERRQ(ierr); 41276f01e85SBarry Smith ierr = PetscStrallocpy(ext,&afterimage->ext);CHKERRQ(ierr); 41376f01e85SBarry Smith afterimage->cnt = cnt; 41476f01e85SBarry Smith ierr = PetscRegisterFinalize(PetscAfterimageDestroy);CHKERRQ(ierr); 415aee23540SBarry Smith PetscFunctionReturn(0); 416aee23540SBarry Smith } 417aee23540SBarry Smith 418aee23540SBarry Smith #endif 419aee23540SBarry Smith 4205c6c1daeSBarry Smith #undef __FUNCT__ 4215c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSave_X" 4225c6c1daeSBarry Smith PetscErrorCode PetscDrawSave_X(PetscDraw draw) 4235c6c1daeSBarry Smith { 4245c6c1daeSBarry Smith PetscDraw_X *drawx = (PetscDraw_X*)draw->data; 4255c6c1daeSBarry Smith XImage *image; 4265c6c1daeSBarry Smith ASImage *asimage; 427681455b2SBarry Smith struct ASVisual *asv; 4285c6c1daeSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 4295c6c1daeSBarry Smith PetscErrorCode ierr; 4305c6c1daeSBarry Smith PetscMPIInt rank; 431681455b2SBarry Smith int depth; 43276f01e85SBarry Smith ASImageFileTypes format; 4335c6c1daeSBarry Smith 4345c6c1daeSBarry Smith PetscFunctionBegin; 435ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 4365c6c1daeSBarry Smith if (rank) PetscFunctionReturn(0); 4375c6c1daeSBarry Smith if (!draw->savefilename) PetscFunctionReturn(0); 4385c6c1daeSBarry Smith if (draw->savefilecount == -1) { 4395c6c1daeSBarry Smith /* The first PetscDrawClear() should happen before any drawing has been done, hence do not save at the first PetscDrawClear() */ 4405c6c1daeSBarry Smith draw->savefilecount++; 4415c6c1daeSBarry Smith PetscFunctionReturn(0); 4425c6c1daeSBarry Smith } 443681455b2SBarry Smith XSynchronize(drawx->disp, True); 444681455b2SBarry Smith depth = DefaultDepth( drawx->disp, drawx->screen ); 445681455b2SBarry Smith asv = create_asvisual(drawx->disp, drawx->screen, depth, NULL);if (!asv) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASVisual"); 4465c6c1daeSBarry Smith 4479982bd17SBarry Smith image = XGetImage(drawx->disp, drawx->drw ? drawx->drw : drawx->win, 0, 0, drawx->w, drawx->h, AllPlanes, ZPixmap); 44876f01e85SBarry Smith if (!image) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot XGetImage()"); 449ce94432eSBarry Smith asimage = picture_ximage2asimage (asv,image,0,0);if (!asimage) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASImage"); 4508b7fcac6SBarry Smith if (draw->savesinglefile) { 45176f01e85SBarry Smith ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s%s",draw->savefilename,draw->savefilename,draw->savefilenameext);CHKERRQ(ierr); 4528b7fcac6SBarry Smith } else { 45376f01e85SBarry Smith ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s_%d%s",draw->savefilename,draw->savefilename,draw->savefilecount++,draw->savefilenameext);CHKERRQ(ierr); 4548b7fcac6SBarry Smith } 45576f01e85SBarry Smith ierr = PetscAfterimageStringToFormat(draw->savefilenameext,&format);CHKERRQ(ierr); 45676f01e85SBarry Smith ASImage2file(asimage, 0, filename,format,0); 4571cda70a7SBarry Smith #if defined(PETSC_HAVE_SAWS) 4581cda70a7SBarry Smith { 459aee23540SBarry Smith char body[4096]; 46076f01e85SBarry Smith PetscAfterimage afterimage; 461aee23540SBarry Smith size_t len = 0; 462aee23540SBarry Smith 46376f01e85SBarry Smith ierr = PetscAfterimageAdd(draw->savefilename,draw->savefilenameext,draw->savefilecount-1);CHKERRQ(ierr); 46476f01e85SBarry Smith afterimage = afterimages; 46576f01e85SBarry Smith while (afterimage) { 46676f01e85SBarry Smith if (draw->savesinglefile) { 46776f01e85SBarry Smith ierr = PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s%s\" alt=\"None\">",afterimage->filename,afterimage->filename,afterimage->ext);CHKERRQ(ierr); 46876f01e85SBarry Smith } else { 46976f01e85SBarry 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); 47076f01e85SBarry Smith } 471aee23540SBarry Smith ierr = PetscStrlen(body,&len);CHKERRQ(ierr); 47276f01e85SBarry Smith afterimage = afterimage->next; 473aee23540SBarry Smith } 474aee23540SBarry Smith ierr = PetscStrcat(body,"<br>\n");CHKERRQ(ierr); 47543da4ab2SBarry Smith if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1)); 47643da4ab2SBarry Smith PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body)); 4771cda70a7SBarry Smith } 4781cda70a7SBarry Smith #endif 4795c6c1daeSBarry Smith 4805c6c1daeSBarry Smith XDestroyImage(image); 481681455b2SBarry Smith destroy_asvisual(asv,0); 4825c6c1daeSBarry Smith PetscFunctionReturn(0); 4835c6c1daeSBarry Smith } 4845c6c1daeSBarry Smith /* 4855c6c1daeSBarry Smith There are routines wanted by AfterImage for PNG files 4865c6c1daeSBarry Smith */ 4875c6c1daeSBarry Smith void crc32(void) {;} 4885c6c1daeSBarry Smith void inflateReset(void) {;} 4895c6c1daeSBarry Smith void deflateReset(void) {;} 4905c6c1daeSBarry Smith void deflateInit2(void) {;} 4915c6c1daeSBarry Smith void deflateInit2_(void) {;} 4925c6c1daeSBarry Smith void deflate(void) {;} 4935c6c1daeSBarry Smith void deflateEnd(void) {;} 4945c6c1daeSBarry Smith 4955c6c1daeSBarry Smith #endif 4965c6c1daeSBarry Smith 4975c6c1daeSBarry Smith 4985c6c1daeSBarry Smith 499