Actual source code: xinit.c
petsc-3.6.1 2015-08-06
2: /*
3: This file contains routines to open an X window display and window
4: This consists of a number of routines that set the various
5: fields in the Window structure, which is passed to
6: all of these routines.
8: Note that if you use the default visual and colormap, then you
9: can use these routines with any X toolkit that will give you the
10: Window id of the window that it is managing. Use that instead of the
11: call to PetscDrawXiCreateWindow . Similarly for the Display.
12: */
14: #include <../src/sys/classes/draw/impls/x/ximpl.h>
16: extern PetscErrorCode PetscDrawXiUniformHues(PetscDraw_X*,int);
17: extern PetscErrorCode PetscDrawXi_wait_map(PetscDraw_X*);
18: extern PetscErrorCode PetscDrawXiFontFixed(PetscDraw_X*,int,int,PetscDrawXiFont**);
19: extern PetscErrorCode PetscDrawXiInitCmap(PetscDraw_X*);
20: extern PetscErrorCode PetscDrawSetColormap_X(PetscDraw_X*,char*,Colormap);
22: /*
23: PetscDrawXiOpenDisplay - Open a display
24: */
27: PetscErrorCode PetscDrawXiOpenDisplay(PetscDraw_X *XiWin,char *display_name)
28: {
30: XiWin->disp = XOpenDisplay(display_name);
31: if (!XiWin->disp) {
32: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open display on %s\n. Make sure your COMPUTE NODES are authorized to connect \n\
33: to this X server and either your DISPLAY variable\n\
34: is set or you use the -display name option\n",display_name);
35: }
36: XiWin->screen = DefaultScreen(XiWin->disp);
37: return(0);
38: }
41: /*
42: PetscDrawXiSetGC - set the GC structure in the base window
43: */
46: PetscErrorCode PetscDrawXiSetGC(PetscDraw_X *XiWin,PetscDrawXiPixVal fg)
47: {
48: XGCValues gcvalues; /* window graphics context values */
51: /* Set the graphics contexts */
52: /* create a gc for the ROP_SET operation (writing the fg value to a pixel) */
53: /* (do this with function GXcopy; GXset will automatically write 1) */
54: gcvalues.function = GXcopy;
55: gcvalues.foreground = fg;
56: XiWin->gc.cur_pix = fg;
57: XiWin->gc.set = XCreateGC(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),GCFunction | GCForeground,&gcvalues);
58: return(0);
59: }
61: /*
62: Actually display a window at [x,y] with sizes (w,h)
63: If w and/or h are 0, use the sizes in the fields of XiWin
64: (which may have been set by, for example, PetscDrawXiSetWindowSize)
65: */
68: PetscErrorCode PetscDrawXiDisplayWindow(PetscDraw_X *XiWin,char *label,int x,int y,int w,int h,PetscDrawXiPixVal backgnd_pixel)
69: {
70: unsigned int wavail,havail;
71: XSizeHints size_hints;
72: XWindowAttributes in_window_attributes;
73: XSetWindowAttributes window_attributes;
74: int depth,border_width;
75: unsigned long wmask;
76: PetscBool flg;
77: PetscErrorCode ierr;
80: /* get the available widths */
81: wavail = DisplayWidth(XiWin->disp,XiWin->screen);
82: havail = DisplayHeight(XiWin->disp,XiWin->screen);
83: if (w <= 0 || h <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"X Window display has invalid height or width");
84: if ((unsigned int) w > wavail) w = wavail;
85: if ((unsigned int) h > havail) h = havail;
87: border_width = 0;
88: if (x < 0) x = 0;
89: if (y < 0) y = 0;
90: x = ((unsigned int) x + w > wavail) ? wavail - w : (unsigned int)x;
91: y = ((unsigned int) y + h > havail) ? havail - h : (unsigned int)y;
93: /* We need XCreateWindow since we may need an visual other than the default one */
94: XGetWindowAttributes(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),&in_window_attributes);
95: window_attributes.background_pixmap = None;
96: window_attributes.background_pixel = backgnd_pixel;
97: /* No border for now */
98: window_attributes.border_pixmap = None;
99: /*
100: window_attributes.border_pixel = border_pixel;
101: */
102: window_attributes.bit_gravity = in_window_attributes.bit_gravity;
103: window_attributes.win_gravity = in_window_attributes.win_gravity;
104: /* Backing store is too slow in color systems */
105: window_attributes.backing_store = 0;
106: window_attributes.backing_pixel = backgnd_pixel;
107: window_attributes.save_under = 1;
108: window_attributes.event_mask = 0;
109: window_attributes.do_not_propagate_mask = 0;
110: window_attributes.override_redirect = 0;
111: window_attributes.colormap = XiWin->cmap;
112: /* None for cursor does NOT mean none, it means cursor of Parent */
113: window_attributes.cursor = None;
115: wmask = CWBackPixmap | CWBackPixel | CWBorderPixmap | CWBitGravity |
116: CWWinGravity | CWBackingStore |CWBackingPixel |CWOverrideRedirect |
117: CWSaveUnder | CWEventMask | CWDontPropagate |
118: CWCursor | CWColormap;
119: depth = XiWin->depth;
121: XiWin->win = XCreateWindow(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),x,y,w,h,border_width,depth,InputOutput,XiWin->vis,wmask,&window_attributes);
122: if (!XiWin->win) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open X window");
124: /* set window manager hints */
125: {
126: XWMHints wm_hints;
127: XClassHint class_hints;
128: XTextProperty windowname,iconname;
130: if (label) XStringListToTextProperty(&label,1,&windowname);
131: else XStringListToTextProperty(&label,0,&windowname);
132: if (label) XStringListToTextProperty(&label,1,&iconname);
133: else XStringListToTextProperty(&label,0,&iconname);
135: wm_hints.initial_state = NormalState;
136: wm_hints.input = True;
137: wm_hints.flags = StateHint|InputHint;
139: /* These properties can be used by window managers to decide how to display a window */
140: class_hints.res_name = (char*)"petsc";
141: class_hints.res_class = (char*)"PETSc";
143: size_hints.x = x;
144: size_hints.y = y;
145: size_hints.min_width = 4*border_width;
146: size_hints.min_height = 4*border_width;
147: size_hints.width = w;
148: size_hints.height = h;
149: size_hints.flags = USPosition | USSize | PMinSize;
151: XSetWMProperties(XiWin->disp,XiWin->win,&windowname,&iconname,0,0,&size_hints,&wm_hints,&class_hints);
152: XFree((void*)windowname.value);
153: XFree((void*)iconname.value);
154: }
155: /* make the window visible */
156: XSelectInput(XiWin->disp,XiWin->win,ExposureMask | StructureNotifyMask);
157: XMapWindow(XiWin->disp,XiWin->win);
160: /* some window systems are cruel and interfere with the placement of
161: windows. We wait here for the window to be created or to die */
162: if (PetscDrawXi_wait_map(XiWin)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Wait for X window failed");
164: flg = PETSC_FALSE;
165: PetscOptionsGetBool(NULL,"-draw_virtual",&flg,NULL);
166: if (flg) {
167: XiWin->drw = XCreatePixmap(XiWin->disp,XiWin->win,XiWin->w,XiWin->h,XiWin->depth);
168: XDestroyWindow(XiWin->disp,XiWin->win);
169: XiWin->win = 0;
170: return(0);
171: }
173: /* Initial values for the upper left corner */
174: XiWin->x = 0;
175: XiWin->y = 0;
176: return(0);
177: }
181: PetscErrorCode PetscDrawXiQuickWindow(PetscDraw_X *w,char *host,char *name,int x,int y,int nx,int ny)
182: {
186: PetscDrawXiOpenDisplay(w,host);
188: w->vis = DefaultVisual(w->disp,w->screen);
189: w->depth = DefaultDepth(w->disp,w->screen);
191: PetscDrawSetColormap_X(w,host,(Colormap)0);
193: PetscDrawXiDisplayWindow(w,name,x,y,nx,ny,(PetscDrawXiPixVal)0);
194: PetscDrawXiSetGC(w,w->cmapping[1]);
195: PetscDrawXiSetPixVal(w,w->background);
197: PetscDrawXiFontFixed(w,6,10,&w->font);
198: if (w->win) {
199: XSetWindowBackground(w->disp,w->win,w->cmapping[0]);
200: XFillRectangle(w->disp,w->win,w->gc.set,0,0,nx,ny);
201: }
202: return(0);
203: }
205: /*
206: A version from an already defined window
207: */
210: PetscErrorCode PetscDrawXiQuickWindowFromWindow(PetscDraw_X *w,char *host,Window win)
211: {
212: Window root;
213: PetscErrorCode ierr;
214: int d;
215: unsigned int ud;
216: XWindowAttributes attributes;
219: PetscDrawXiOpenDisplay(w,host);
220: w->win = win;
221: XGetWindowAttributes(w->disp,w->win,&attributes);
223: w->vis = DefaultVisual(w->disp,w->screen);
224: w->depth = DefaultDepth(w->disp,w->screen);
225: PetscDrawSetColormap_X(w,host,attributes.colormap);
227: XGetGeometry(w->disp,w->win,&root,&d,&d,(unsigned int*)&w->w,(unsigned int*)&w->h,&ud,&ud);
228: w->x = w->y = 0;
230: PetscDrawXiSetGC(w,w->cmapping[1]);
231: PetscDrawXiSetPixVal(w,w->background);
232: XSetWindowBackground(w->disp,w->win,w->cmapping[0]);
233: PetscDrawXiFontFixed(w,6,10,&w->font);
234: return(0);
235: }
237: /*
238: PetscDrawXiSetWindowLabel - Sets new label in open window.
239: */
242: PetscErrorCode PetscDrawXiSetWindowLabel(PetscDraw_X *Xiwin,char *label)
243: {
244: XTextProperty prop;
245: size_t len;
249: XGetWMName(Xiwin->disp,Xiwin->win,&prop);
250: prop.value = (unsigned char*)label;
251: PetscStrlen(label,&len);
252: prop.nitems = (long) len;
253: XSetWMName(Xiwin->disp,Xiwin->win,&prop);
254: return(0);
255: }
259: PetscErrorCode PetscDrawXiSetToBackground(PetscDraw_X *XiWin)
260: {
262: if (XiWin->gc.cur_pix != XiWin->background) {
263: XSetForeground(XiWin->disp,XiWin->gc.set,XiWin->background);
264: XiWin->gc.cur_pix = XiWin->background;
265: }
266: return(0);
268: }
272: PetscErrorCode PetscDrawSetSave_X(PetscDraw draw,const char *filename)
273: {
275: #if defined(PETSC_HAVE_POPEN)
276: PetscMPIInt rank;
277: #endif
281: #if defined(PETSC_HAVE_POPEN)
282: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
283: if (!rank) {
284: char command[PETSC_MAX_PATH_LEN];
285: FILE *fd;
286: int err;
288: PetscMemzero(command,sizeof(command));
289: PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"rm -fr %s %s.m4v",draw->savefilename,draw->savefilename);
290: PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);
291: PetscPClose(PETSC_COMM_SELF,fd,&err);
292: PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"mkdir %s",draw->savefilename);
293: PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);
294: PetscPClose(PETSC_COMM_SELF,fd,&err);
295: }
296: #endif
297: return(0);
298: }
301: #if defined(PETSC_HAVE_AFTERIMAGE)
302: #include <afterimage.h>
304: /* String names of possible Afterimage formats */
305: const char *PetscAfterImageFormats[] = {
306: ".Xpm",
307: ".Xpm.Z",
308: ".Xpm.gz",
309: ".Png",
310: ".Jpeg",
311: ".Xcf", /* Gimp format */
312: ".Ppm",
313: ".Pnm",
314: "MS Windows Bitmap",
315: "MS Windows Icon",
316: "MS Windows Cursor",
317: ".Gif",
318: ".Tiff",
319: "Afterstep XMLScript",
320: "Scalable Vector Graphics (SVG)",
321: ".Xbm",
322: "Targa",
323: ".Pcx",
324: ".HTML",
325: "XML",
326: "Unknown"
327: };
331: static PetscErrorCode PetscAfterimageStringToFormat(const char *ext,ASImageFileTypes *format)
332: {
333: PetscInt i;
335: PetscBool flg;
338: PetscStrcasecmp(".Jpg",ext,&flg);
339: if (flg) ext = ".Jpeg";
340: for (i=0; i<sizeof(PetscAfterImageFormats)/sizeof(char**); i++) {
341: PetscStrcasecmp(PetscAfterImageFormats[i],ext,&flg);
342: if (flg) {
343: *format = (ASImageFileTypes)i;
344: return(0);
345: }
346: }
347: *format = ASIT_Unknown;
348: return(0);
349: }
351: #if defined(PETSC_HAVE_SAWS)
352: #include <petscviewersaws.h>
353: /*
354: The PetscAfterimage object and functions are used to maintain a list of file images created by Afterimage that can
355: be displayed by the SAWs webserver.
356: */
357: typedef struct _P_PetscAfterimage *PetscAfterimage;
358: struct _P_PetscAfterimage {
359: PetscAfterimage next;
360: char *filename;
361: char *ext;
362: PetscInt cnt;
363: } ;
365: static PetscAfterimage afterimages = 0;
369: static PetscErrorCode PetscAfterimageDestroy(void)
370: {
372: PetscAfterimage afterimage,oafterimage = afterimages;
375: while (oafterimage) {
376: afterimage = oafterimage->next;
377: PetscFree(oafterimage->filename);
378: PetscFree(oafterimage->ext);
379: PetscFree(oafterimage);
380: oafterimage = afterimage;
381: }
382: return(0);
383: }
387: static PetscErrorCode PetscAfterimageAdd(const char *filename,const char *ext,PetscInt cnt)
388: {
389: PetscErrorCode ierr;
390: PetscAfterimage afterimage,oafterimage = afterimages;
391: PetscBool flg;
394: if (oafterimage){
395: PetscStrcmp(filename,oafterimage->filename,&flg);
396: if (flg) {
397: oafterimage->cnt = cnt;
398: return(0);
399: }
400: while (oafterimage->next) {
401: oafterimage = oafterimage->next;
402: PetscStrcmp(filename,oafterimage->filename,&flg);
403: if (flg) {
404: oafterimage->cnt = cnt;
405: return(0);
406: }
407: }
408: PetscNew(&afterimage);
409: oafterimage->next = afterimage;
410: } else {
411: PetscNew(&afterimage);
412: afterimages = afterimage;
413: }
414: PetscStrallocpy(filename,&afterimage->filename);
415: PetscStrallocpy(ext,&afterimage->ext);
416: afterimage->cnt = cnt;
417: PetscRegisterFinalize(PetscAfterimageDestroy);
418: return(0);
419: }
421: #endif
425: PetscErrorCode PetscDrawSave_X(PetscDraw draw)
426: {
427: PetscDraw_X *drawx = (PetscDraw_X*)draw->data;
428: XImage *image;
429: ASImage *asimage;
430: struct ASVisual *asv;
431: char filename[PETSC_MAX_PATH_LEN];
432: PetscErrorCode ierr;
433: PetscMPIInt rank;
434: int depth;
435: ASImageFileTypes format;
438: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
439: if (rank) return(0);
440: if (!draw->savefilename) return(0);
441: if (draw->savefilecount == -1) {
442: /* The first PetscDrawClear() should happen before any drawing has been done, hence do not save at the first PetscDrawClear() */
443: draw->savefilecount++;
444: return(0);
445: }
446: XSynchronize(drawx->disp, True);
447: depth = DefaultDepth( drawx->disp, drawx->screen );
448: asv = create_asvisual(drawx->disp, drawx->screen, depth, NULL);if (!asv) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASVisual");
450: image = XGetImage(drawx->disp, drawx->drw ? drawx->drw : drawx->win, 0, 0, drawx->w, drawx->h, AllPlanes, ZPixmap);
451: if (!image) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot XGetImage()");
452: asimage = picture_ximage2asimage (asv,image,0,0);if (!asimage) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASImage");
453: if (draw->savesinglefile) {
454: PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s%s",draw->savefilename,draw->savefilename,draw->savefilenameext);
455: } else {
456: PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s_%d%s",draw->savefilename,draw->savefilename,draw->savefilecount++,draw->savefilenameext);
457: }
458: PetscAfterimageStringToFormat(draw->savefilenameext,&format);
459: ASImage2file(asimage, 0, filename,format,0);
460: #if defined(PETSC_HAVE_SAWS)
461: {
462: char body[4096];
463: PetscAfterimage afterimage;
464: size_t len = 0;
466: PetscAfterimageAdd(draw->savefilename,draw->savefilenameext,draw->savefilecount-1);
467: afterimage = afterimages;
468: while (afterimage) {
469: if (draw->savesinglefile) {
470: PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s%s\" alt=\"None\">",afterimage->filename,afterimage->filename,afterimage->ext);
471: } else {
472: PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s_%d%s\" alt=\"None\">",afterimage->filename,afterimage->filename,afterimage->cnt,afterimage->ext);
473: }
474: PetscStrlen(body,&len);
475: afterimage = afterimage->next;
476: }
477: PetscStrcat(body,"<br>\n");
478: if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1));
479: PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body));
480: }
481: #endif
483: XDestroyImage(image);
484: destroy_asvisual(asv,0);
485: return(0);
486: }
487: /*
488: There are routines wanted by AfterImage for PNG files
489: */
490: void crc32(void) {;}
491: void inflateReset(void) {;}
492: void deflateReset(void) {;}
493: void deflateInit2(void) {;}
494: void deflateInit2_(void) {;}
495: void deflate(void) {;}
496: void deflateEnd(void) {;}
498: #endif