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 wmask = CWBackPixmap | CWBackPixel | CWBorderPixmap | CWBitGravity | 115 CWWinGravity | CWBackingStore |CWBackingPixel |CWOverrideRedirect | 116 CWSaveUnder | CWEventMask | CWDontPropagate | 117 CWCursor | CWColormap ; 118 depth = XiWin->depth; 119 120 XiWin->win = XCreateWindow(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),x,y,w,h,border_width,depth,InputOutput,XiWin->vis,wmask,&window_attributes); 121 if (!XiWin->win) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open X window"); 122 123 /* set window manager hints */ 124 { 125 XWMHints wm_hints; 126 XClassHint class_hints; 127 XTextProperty windowname,iconname; 128 129 if (label) { XStringListToTextProperty(&label,1,&windowname);} 130 else { XStringListToTextProperty(&label,0,&windowname);} 131 if (label) { XStringListToTextProperty(&label,1,&iconname);} 132 else { XStringListToTextProperty(&label,0,&iconname);} 133 134 wm_hints.initial_state = NormalState; 135 wm_hints.input = True; 136 wm_hints.flags = StateHint|InputHint; 137 138 /* These properties can be used by window managers to decide how to display a window */ 139 class_hints.res_name = (char*)"petsc"; 140 class_hints.res_class = (char*)"PETSc"; 141 142 size_hints.x = x; 143 size_hints.y = y; 144 size_hints.min_width = 4*border_width; 145 size_hints.min_height = 4*border_width; 146 size_hints.width = w; 147 size_hints.height = h; 148 size_hints.flags = USPosition | USSize | PMinSize; 149 150 XSetWMProperties(XiWin->disp,XiWin->win,&windowname,&iconname,0,0,&size_hints,&wm_hints,&class_hints); 151 XFree((void*)windowname.value); 152 XFree((void*)iconname.value); 153 } 154 /* make the window visible */ 155 XSelectInput(XiWin->disp,XiWin->win,ExposureMask | StructureNotifyMask); 156 XMapWindow(XiWin->disp,XiWin->win); 157 158 159 /* some window systems are cruel and interfere with the placement of 160 windows. We wait here for the window to be created or to die */ 161 if (PetscDrawXi_wait_map(XiWin)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Wait for X window failed"); 162 163 flg = PETSC_FALSE; 164 ierr = PetscOptionsGetBool(PETSC_NULL,"-draw_virtual",&flg,PETSC_NULL);CHKERRQ(ierr); 165 if (flg) { 166 XiWin->drw = XCreatePixmap(XiWin->disp,XiWin->win,XiWin->w,XiWin->h,XiWin->depth); 167 XDestroyWindow(XiWin->disp,XiWin->win); 168 XiWin->win = 0; 169 PetscFunctionReturn(0); 170 } 171 172 /* Initial values for the upper left corner */ 173 XiWin->x = 0; 174 XiWin->y = 0; 175 PetscFunctionReturn(0); 176 } 177 178 #undef __FUNCT__ 179 #define __FUNCT__ "PetscDrawXiQuickWindow" 180 PetscErrorCode PetscDrawXiQuickWindow(PetscDraw_X* w,char* host,char* name,int x,int y,int nx,int ny) 181 { 182 PetscErrorCode ierr; 183 184 PetscFunctionBegin; 185 ierr = PetscDrawXiOpenDisplay(w,host);CHKERRQ(ierr); 186 187 w->vis = DefaultVisual(w->disp,w->screen); 188 w->depth = DefaultDepth(w->disp,w->screen); 189 190 ierr = PetscDrawSetColormap_X(w,host,(Colormap)0);CHKERRQ(ierr); 191 192 ierr = PetscDrawXiDisplayWindow(w,name,x,y,nx,ny,(PetscDrawXiPixVal)0);CHKERRQ(ierr); 193 PetscDrawXiSetGC(w,w->cmapping[1]); 194 PetscDrawXiSetPixVal(w,w->background); 195 196 ierr = PetscDrawXiFontFixed(w,6,10,&w->font);CHKERRQ(ierr); 197 if (w->win) { 198 XSetWindowBackground(w->disp,w->win,w->cmapping[0]); 199 XFillRectangle(w->disp,w->win,w->gc.set,0,0,nx,ny); 200 } 201 PetscFunctionReturn(0); 202 } 203 204 /* 205 A version from an already defined window 206 */ 207 #undef __FUNCT__ 208 #define __FUNCT__ "PetscDrawXiQuickWindowFromWindow" 209 PetscErrorCode PetscDrawXiQuickWindowFromWindow(PetscDraw_X* w,char *host,Window win) 210 { 211 Window root; 212 PetscErrorCode ierr; 213 int d; 214 unsigned int ud; 215 XWindowAttributes attributes; 216 217 PetscFunctionBegin; 218 ierr = PetscDrawXiOpenDisplay(w,host);CHKERRQ(ierr); 219 w->win = win; 220 XGetWindowAttributes(w->disp,w->win,&attributes); 221 222 w->vis = DefaultVisual(w->disp,w->screen); 223 w->depth = DefaultDepth(w->disp,w->screen); 224 ierr = PetscDrawSetColormap_X(w,host,attributes.colormap);CHKERRQ(ierr); 225 226 XGetGeometry(w->disp,w->win,&root,&d,&d,(unsigned int *)&w->w,(unsigned int *)&w->h,&ud,&ud); 227 w->x = w->y = 0; 228 229 PetscDrawXiSetGC(w,w->cmapping[1]); 230 PetscDrawXiSetPixVal(w,w->background); 231 XSetWindowBackground(w->disp,w->win,w->cmapping[0]); 232 ierr = PetscDrawXiFontFixed(w,6,10,&w->font);CHKERRQ(ierr); 233 PetscFunctionReturn(0); 234 } 235 236 /* 237 PetscDrawXiSetWindowLabel - Sets new label in open window. 238 */ 239 #undef __FUNCT__ 240 #define __FUNCT__ "PetscDrawXiSetWindowLabel" 241 PetscErrorCode PetscDrawXiSetWindowLabel(PetscDraw_X* Xiwin,char *label) 242 { 243 XTextProperty prop; 244 size_t len; 245 PetscErrorCode ierr; 246 247 PetscFunctionBegin; 248 XGetWMName(Xiwin->disp,Xiwin->win,&prop); 249 prop.value = (unsigned char *)label; 250 ierr = PetscStrlen(label,&len);CHKERRQ(ierr); 251 prop.nitems = (long) len; 252 XSetWMName(Xiwin->disp,Xiwin->win,&prop); 253 PetscFunctionReturn(0); 254 } 255 256 #undef __FUNCT__ 257 #define __FUNCT__ "PetscDrawXiSetToBackground" 258 PetscErrorCode PetscDrawXiSetToBackground(PetscDraw_X* XiWin) 259 { 260 PetscFunctionBegin; 261 if (XiWin->gc.cur_pix != XiWin->background) { 262 XSetForeground(XiWin->disp,XiWin->gc.set,XiWin->background); 263 XiWin->gc.cur_pix = XiWin->background; 264 } 265 PetscFunctionReturn(0); 266 267 } 268 269 #undef __FUNCT__ 270 #define __FUNCT__ "PetscDrawSetSave_X" 271 PetscErrorCode PetscDrawSetSave_X(PetscDraw draw,const char *filename) 272 { 273 PetscErrorCode ierr; 274 #if defined(PETSC_HAVE_POPEN) 275 PetscMPIInt rank; 276 char command[PETSC_MAX_PATH_LEN]; 277 FILE *fd; 278 #endif 279 280 PetscFunctionBegin; 281 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 282 #if defined(PETSC_HAVE_POPEN) 283 ierr = MPI_Comm_rank(((PetscObject)draw)->comm,&rank);CHKERRQ(ierr); 284 if (!rank) { 285 ierr = PetscSNPrintf(command,PETSC_MAX_PATH_LEN,"rm -f %s_[0-9]*.Gif %s.m4v",draw->savefilename,draw->savefilename);CHKERRQ(ierr); 286 ierr = PetscPOpen(((PetscObject)draw)->comm,PETSC_NULL,command,"r",&fd);CHKERRQ(ierr); 287 ierr = PetscPClose(((PetscObject)draw)->comm,fd,PETSC_NULL);CHKERRQ(ierr); 288 } 289 #endif 290 PetscFunctionReturn(0); 291 } 292 293 #if defined(PETSC_HAVE_AFTERIMAGE) 294 #include <afterimage.h> 295 #undef __FUNCT__ 296 #define __FUNCT__ "PetscDrawSave_X" 297 PetscErrorCode PetscDrawSave_X(PetscDraw draw) 298 { 299 PetscDraw_X *drawx = (PetscDraw_X*)draw->data; 300 XImage *image; 301 ASImage *asimage; 302 static struct ASVisual *asv = 0; 303 char filename[PETSC_MAX_PATH_LEN]; 304 PetscErrorCode ierr; 305 PetscMPIInt rank; 306 307 PetscFunctionBegin; 308 ierr = MPI_Comm_rank(((PetscObject)draw)->comm,&rank);CHKERRQ(ierr); 309 if (rank) PetscFunctionReturn(0); 310 if (!draw->savefilename) PetscFunctionReturn(0); 311 if (draw->savefilecount == -1) { 312 /* The first PetscDrawClear() should happen before any drawing has been done, hence do not save at the first PetscDrawClear() */ 313 draw->savefilecount++; 314 PetscFunctionReturn(0); 315 } 316 317 if (!asv) { 318 asv = create_asvisual(drawx->disp, 0, 0, 0);if (!asv) SETERRQ(((PetscObject)draw)->comm,PETSC_ERR_PLIB,"Cannot create AfterImage ASVisual"); 319 } 320 if (drawx->drw) { 321 image = XGetImage(drawx->disp, drawx->drw, 0, 0, drawx->w, drawx->h, AllPlanes, ZPixmap);if (!image) SETERRQ(((PetscObject)draw)->comm,PETSC_ERR_PLIB,"Cannot XGetImage()");\ 322 } else { 323 image = XGetImage(drawx->disp, drawx->win, 0, 0, drawx->w, drawx->h, AllPlanes, ZPixmap);if (!image) SETERRQ(((PetscObject)draw)->comm,PETSC_ERR_PLIB,"Cannot XGetImage()"); 324 } 325 asimage = picture_ximage2asimage (asv,image,0,0);if (!asimage) SETERRQ(((PetscObject)draw)->comm,PETSC_ERR_PLIB,"Cannot create AfterImage ASImage"); 326 ierr = PetscSNPrintf(filename,PETSC_MAX_PATH_LEN,"%s_%d.Gif",draw->savefilename,draw->savefilecount++);CHKERRQ(ierr); 327 ASImage2file(asimage, 0, filename,ASIT_Gif,0); 328 329 XDestroyImage(image); 330 PetscFunctionReturn(0); 331 } 332 /* 333 There are routines wanted by AfterImage for PNG files 334 */ 335 void crc32(void) {;} 336 void inflateReset(void) {;} 337 void deflateReset(void) {;} 338 void deflateInit2(void) {;} 339 void deflateInit2_(void) {;} 340 void deflate(void) {;} 341 void deflateEnd(void) {;} 342 343 #endif 344 345 346 347