1 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. 7 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 */ 13 14 #include <../src/sys/classes/draw/impls/x/ximpl.h> 15 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); 21 22 /* 23 PetscDrawXiOpenDisplay - Open a display 24 */ 25 #undef __FUNCT__ 26 #define __FUNCT__ "PetscDrawXiOpenDisplay" 27 PetscErrorCode PetscDrawXiOpenDisplay(PetscDraw_X *XiWin,char *display_name) 28 { 29 PetscFunctionBegin; 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 PetscFunctionReturn(0); 38 } 39 40 41 /* 42 PetscDrawXiSetGC - set the GC structure in the base window 43 */ 44 #undef __FUNCT__ 45 #define __FUNCT__ "PetscDrawXiSetGC" 46 PetscErrorCode PetscDrawXiSetGC(PetscDraw_X *XiWin,PetscDrawXiPixVal fg) 47 { 48 XGCValues gcvalues; /* window graphics context values */ 49 50 PetscFunctionBegin; 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 PetscFunctionReturn(0); 59 } 60 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 */ 66 #undef __FUNCT__ 67 #define __FUNCT__ "PetscDrawXiDisplayWindow" 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; 78 79 PetscFunctionBegin; 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; 86 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 : x; 91 y = ((unsigned int) y + h > havail) ? havail - h : y; 92 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; 114 115 wmask = CWBackPixmap | CWBackPixel | CWBorderPixmap | CWBitGravity | 116 CWWinGravity | CWBackingStore |CWBackingPixel |CWOverrideRedirect | 117 CWSaveUnder | CWEventMask | CWDontPropagate | 118 CWCursor | CWColormap; 119 depth = XiWin->depth; 120 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"); 123 124 /* set window manager hints */ 125 { 126 XWMHints wm_hints; 127 XClassHint class_hints; 128 XTextProperty windowname,iconname; 129 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); 134 135 wm_hints.initial_state = NormalState; 136 wm_hints.input = True; 137 wm_hints.flags = StateHint|InputHint; 138 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"; 142 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; 150 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); 158 159 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"); 163 164 flg = PETSC_FALSE; 165 ierr = PetscOptionsGetBool(NULL,"-draw_virtual",&flg,NULL);CHKERRQ(ierr); 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 PetscFunctionReturn(0); 171 } 172 173 /* Initial values for the upper left corner */ 174 XiWin->x = 0; 175 XiWin->y = 0; 176 PetscFunctionReturn(0); 177 } 178 179 #undef __FUNCT__ 180 #define __FUNCT__ "PetscDrawXiQuickWindow" 181 PetscErrorCode PetscDrawXiQuickWindow(PetscDraw_X *w,char *host,char *name,int x,int y,int nx,int ny) 182 { 183 PetscErrorCode ierr; 184 185 PetscFunctionBegin; 186 ierr = PetscDrawXiOpenDisplay(w,host);CHKERRQ(ierr); 187 188 w->vis = DefaultVisual(w->disp,w->screen); 189 w->depth = DefaultDepth(w->disp,w->screen); 190 191 ierr = PetscDrawSetColormap_X(w,host,(Colormap)0);CHKERRQ(ierr); 192 193 ierr = PetscDrawXiDisplayWindow(w,name,x,y,nx,ny,(PetscDrawXiPixVal)0);CHKERRQ(ierr); 194 PetscDrawXiSetGC(w,w->cmapping[1]); 195 PetscDrawXiSetPixVal(w,w->background); 196 197 ierr = PetscDrawXiFontFixed(w,6,10,&w->font);CHKERRQ(ierr); 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 PetscFunctionReturn(0); 203 } 204 205 /* 206 A version from an already defined window 207 */ 208 #undef __FUNCT__ 209 #define __FUNCT__ "PetscDrawXiQuickWindowFromWindow" 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; 217 218 PetscFunctionBegin; 219 ierr = PetscDrawXiOpenDisplay(w,host);CHKERRQ(ierr); 220 w->win = win; 221 XGetWindowAttributes(w->disp,w->win,&attributes); 222 223 w->vis = DefaultVisual(w->disp,w->screen); 224 w->depth = DefaultDepth(w->disp,w->screen); 225 ierr = PetscDrawSetColormap_X(w,host,attributes.colormap);CHKERRQ(ierr); 226 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; 229 230 PetscDrawXiSetGC(w,w->cmapping[1]); 231 PetscDrawXiSetPixVal(w,w->background); 232 XSetWindowBackground(w->disp,w->win,w->cmapping[0]); 233 ierr = PetscDrawXiFontFixed(w,6,10,&w->font);CHKERRQ(ierr); 234 PetscFunctionReturn(0); 235 } 236 237 /* 238 PetscDrawXiSetWindowLabel - Sets new label in open window. 239 */ 240 #undef __FUNCT__ 241 #define __FUNCT__ "PetscDrawXiSetWindowLabel" 242 PetscErrorCode PetscDrawXiSetWindowLabel(PetscDraw_X *Xiwin,char *label) 243 { 244 XTextProperty prop; 245 size_t len; 246 PetscErrorCode ierr; 247 248 PetscFunctionBegin; 249 XGetWMName(Xiwin->disp,Xiwin->win,&prop); 250 prop.value = (unsigned char*)label; 251 ierr = PetscStrlen(label,&len);CHKERRQ(ierr); 252 prop.nitems = (long) len; 253 XSetWMName(Xiwin->disp,Xiwin->win,&prop); 254 PetscFunctionReturn(0); 255 } 256 257 #undef __FUNCT__ 258 #define __FUNCT__ "PetscDrawXiSetToBackground" 259 PetscErrorCode PetscDrawXiSetToBackground(PetscDraw_X *XiWin) 260 { 261 PetscFunctionBegin; 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 PetscFunctionReturn(0); 267 268 } 269 270 #undef __FUNCT__ 271 #define __FUNCT__ "PetscDrawSetSave_X" 272 PetscErrorCode PetscDrawSetSave_X(PetscDraw draw,const char *filename) 273 { 274 PetscErrorCode ierr; 275 #if defined(PETSC_HAVE_POPEN) 276 PetscMPIInt rank; 277 char command[PETSC_MAX_PATH_LEN]; 278 FILE *fd; 279 #endif 280 281 PetscFunctionBegin; 282 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 283 #if defined(PETSC_HAVE_POPEN) 284 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 285 if (!rank) { 286 ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"rm -fr %s %s.m4v",draw->savefilename,draw->savefilename);CHKERRQ(ierr); 287 ierr = PetscPOpen(PetscObjectComm((PetscObject)draw),NULL,command,"r",&fd);CHKERRQ(ierr); 288 ierr = PetscPClose(PetscObjectComm((PetscObject)draw),fd,NULL);CHKERRQ(ierr); 289 ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"mkdir %s",draw->savefilename);CHKERRQ(ierr); 290 ierr = PetscPOpen(PetscObjectComm((PetscObject)draw),NULL,command,"r",&fd);CHKERRQ(ierr); 291 ierr = PetscPClose(PetscObjectComm((PetscObject)draw),fd,NULL);CHKERRQ(ierr); 292 } 293 #endif 294 PetscFunctionReturn(0); 295 } 296 297 #if defined(PETSC_HAVE_AFTERIMAGE) 298 #include <afterimage.h> 299 #undef __FUNCT__ 300 #define __FUNCT__ "PetscDrawSave_X" 301 PetscErrorCode PetscDrawSave_X(PetscDraw draw) 302 { 303 PetscDraw_X *drawx = (PetscDraw_X*)draw->data; 304 XImage *image; 305 ASImage *asimage; 306 static struct ASVisual *asv = 0; 307 char filename[PETSC_MAX_PATH_LEN]; 308 PetscErrorCode ierr; 309 PetscMPIInt rank; 310 311 PetscFunctionBegin; 312 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 313 if (rank) PetscFunctionReturn(0); 314 if (!draw->savefilename) PetscFunctionReturn(0); 315 if (draw->savefilecount == -1) { 316 /* The first PetscDrawClear() should happen before any drawing has been done, hence do not save at the first PetscDrawClear() */ 317 draw->savefilecount++; 318 PetscFunctionReturn(0); 319 } 320 321 if (!asv) { 322 asv = create_asvisual(drawx->disp, 0, 0, 0);if (!asv) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASVisual"); 323 } 324 image = XGetImage(drawx->disp, drawx->drw ? drawx->drw : drawx->win, 0, 0, drawx->w, drawx->h, AllPlanes, ZPixmap); 325 if (!image) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot XGetImage()");\ 326 asimage = picture_ximage2asimage (asv,image,0,0);if (!asimage) SETERRQ(PetscObjectComm((PetscObject)draw),PETSC_ERR_PLIB,"Cannot create AfterImage ASImage"); 327 ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s/%s_%d.Gif",draw->savefilename,draw->savefilename,draw->savefilecount++);CHKERRQ(ierr); 328 ASImage2file(asimage, 0, filename,ASIT_Gif,0); 329 330 XDestroyImage(image); 331 PetscFunctionReturn(0); 332 } 333 /* 334 There are routines wanted by AfterImage for PNG files 335 */ 336 void crc32(void) {;} 337 void inflateReset(void) {;} 338 void deflateReset(void) {;} 339 void deflateInit2(void) {;} 340 void deflateInit2_(void) {;} 341 void deflate(void) {;} 342 void deflateEnd(void) {;} 343 344 #endif 345 346 347 348