Date: 2015-10-02T21:58:53+00:00

Actual source code: xinit.c
petsc-3.6.2 2015-10-02
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: /* 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