Actual source code: xinit.c

petsc-3.5.4 2015-05-23
Report Typos and Errors
  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: #if defined(PETSC_HAVE_SAWS)
305: #include <petscviewersaws.h>
306: typedef struct _P_PetscGif *PetscGif;
307: struct _P_PetscGif {
308:   PetscGif next;
309:   char     *filename;
310: } ;

312: static PetscGif gifs = 0;

316: static PetscErrorCode PetscGifDestroy(void)
317: {
319:   PetscGif       gif,ogif = gifs;

322:   while (ogif) {
323:     gif = ogif->next;
324:     PetscFree(ogif->filename);
325:     PetscFree(ogif);
326:     ogif = gif;
327:   }
328:   return(0);
329: }

333: static PetscErrorCode PetscGifAdd(const char *filename)
334: {
336:   PetscGif       gif,ogif = gifs;
337:   PetscBool      flg;

340:   if (ogif){
341:     PetscStrcmp(filename,ogif->filename,&flg);
342:     if (flg) return(0);
343:     while (ogif->next) {
344:       ogif = ogif->next;
345:       PetscStrcmp(filename,ogif->filename,&flg);
346:       if (flg) return(0);
347:     }
348:     PetscNew(&gif);
349:     ogif->next = gif;
350:   } else {
351:     PetscNew(&gif);
352:     gifs = gif;
353:   }
354:   PetscStrallocpy(filename,&gif->filename);
355:   PetscRegisterFinalize(PetscGifDestroy);
356:   return(0);
357: }

359: #endif

363: PetscErrorCode PetscDrawSave_X(PetscDraw draw)
364: {
365:   PetscDraw_X      *drawx = (PetscDraw_X*)draw->data;
366:   XImage           *image;
367:   ASImage          *asimage;
368:   struct  ASVisual *asv;
369:   char             filename[PETSC_MAX_PATH_LEN];
370:   PetscErrorCode   ierr;
371:   PetscMPIInt      rank;
372:   int              depth;

375:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
376:   if (rank) return(0);
377:   if (!draw->savefilename) return(0);
378:   if (draw->savefilecount == -1) {
379:     /* The first PetscDrawClear() should happen before any drawing has been done, hence do not save at the first PetscDrawClear() */
380:     draw->savefilecount++;
381:     return(0);
382:   }
383:   XSynchronize(drawx->disp, True);
384:   depth = DefaultDepth( drawx->disp, drawx->screen );
385:   asv   = create_asvisual(drawx->disp, drawx->screen, depth, NULL);if (!asv) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASVisual");

387:   image   = XGetImage(drawx->disp, drawx->drw ? drawx->drw : drawx->win, 0, 0, drawx->w, drawx->h, AllPlanes, ZPixmap);
388:   if (!image) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot XGetImage()");\
389:   asimage = picture_ximage2asimage (asv,image,0,0);if (!asimage) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASImage");
390:   if (draw->savesinglefile) {
391:     PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s.Gif",draw->savefilename,draw->savefilename);
392:   } else {
393:     PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s_%d.Gif",draw->savefilename,draw->savefilename,draw->savefilecount++);
394:   }
395:   ASImage2file(asimage, 0, filename,ASIT_Gif,0);
396: #if defined(PETSC_HAVE_SAWS)
397:   {
398:     char     body[4096];
399:     PetscGif gif;
400:     size_t   len = 0;

402:     PetscGifAdd(draw->savefilename);
403:     gif  = gifs;
404:     while (gif) {
405:       PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s.Gif\" alt=\"None\">",gif->filename,gif->filename);
406:       PetscStrlen(body,&len);
407:       gif  = gif->next;
408:     }
409:     PetscStrcat(body,"<br>\n");
410:     if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1));
411:     PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body));
412:   }
413: #endif

415:   XDestroyImage(image);
416:   destroy_asvisual(asv,0);
417:   return(0);
418: }
419: /*
420:    There are routines wanted by AfterImage for PNG files
421:  */
422: void crc32(void) {;}
423: void inflateReset(void) {;}
424: void deflateReset(void) {;}
425: void deflateInit2(void) {;}
426: void deflateInit2_(void) {;}
427: void deflate(void) {;}
428: void deflateEnd(void) {;}

430: #endif