xref: /petsc/src/sys/classes/draw/impls/x/xinit.c (revision f23aa3dd738493dcb3a70a8c0c7f5454aa9150c2)
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