Actual source code: xinit.c
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: PETSC_INTERN PetscErrorCode PetscDrawSetColormap_X(PetscDraw_X*,Colormap);
18: /*
19: PetscDrawXiOpenDisplay - Open and setup a display
20: */
21: static PetscErrorCode PetscDrawXiOpenDisplay(PetscDraw_X *XiWin,const char display[])
22: {
23: XiWin->disp = XOpenDisplay(display);
24: if (!XiWin->disp) {
25: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open display on %s\n\
26: Make sure your COMPUTE NODES are authorized to connect \n\
27: to this X server and either your DISPLAY variable\n\
28: is set or you use the -display name option\n",display);
29: }
30: XiWin->screen = DefaultScreen(XiWin->disp);
31: XiWin->vis = DefaultVisual(XiWin->disp,XiWin->screen);
32: XiWin->depth = DefaultDepth(XiWin->disp,XiWin->screen);
33: XiWin->cmap = DefaultColormap(XiWin->disp,XiWin->screen);
34: XiWin->background = WhitePixel(XiWin->disp,XiWin->screen);
35: XiWin->foreground = BlackPixel(XiWin->disp,XiWin->screen);
36: return 0;
37: }
39: PetscErrorCode PetscDrawXiClose(PetscDraw_X *XiWin)
40: {
41: if (!XiWin) return 0;
42: PetscFree(XiWin->font);
43: if (XiWin->disp) {
44: #if defined(PETSC_HAVE_SETJMP_H)
45: jmp_buf jmpbuf;
46: PetscXIOErrorHandler xioerrhdl;
47: PetscMemcpy(&jmpbuf,&PetscXIOErrorHandlerJumpBuf,sizeof(jmpbuf));
48: xioerrhdl = PetscSetXIOErrorHandler(PetscXIOErrorHandlerJump);
49: if (!setjmp(PetscXIOErrorHandlerJumpBuf))
50: #endif
51: {
52: XFreeGC(XiWin->disp,XiWin->gc.set);
53: XCloseDisplay(XiWin->disp);
54: }
55: XiWin->disp = NULL;
56: #if defined(PETSC_HAVE_SETJMP_H)
57: (void)PetscSetXIOErrorHandler(xioerrhdl);
58: PetscMemcpy(&PetscXIOErrorHandlerJumpBuf,&jmpbuf,sizeof(jmpbuf));
59: #endif
60: }
61: return 0;
62: }
64: /*
65: PetscDrawXiCreateGC - setup the GC structure
66: */
67: static PetscErrorCode PetscDrawXiCreateGC(PetscDraw_X *XiWin,PetscDrawXiPixVal fg)
68: {
69: XGCValues gcvalues; /* window graphics context values */
71: /* Set the graphics contexts */
72: /* create a gc for the ROP_SET operation (writing the fg value to a pixel) */
73: /* (do this with function GXcopy; GXset will automatically write 1) */
74: gcvalues.function = GXcopy;
75: gcvalues.foreground = fg;
76: XiWin->gc.cur_pix = fg;
77: XiWin->gc.set = XCreateGC(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),GCFunction|GCForeground,&gcvalues);
79: return 0;
80: }
82: /*
83: PetscDrawXiInit - basic setup the draw (display, graphics context, font)
84: */
85: PetscErrorCode PetscDrawXiInit(PetscDraw_X *XiWin,const char display[])
86: {
87: PetscDrawXiOpenDisplay(XiWin,display);
88: PetscDrawXiCreateGC(XiWin,XiWin->foreground);
89: PetscDrawXiFontFixed(XiWin,6,10,&XiWin->font);
90: return 0;
91: }
93: /*
94: This routine waits until the window is actually created or destroyed
95: Returns 0 if window is mapped; 1 if window is destroyed.
96: */
97: static PetscErrorCode PetscDrawXiWaitMap(PetscDraw_X *XiWin)
98: {
99: XEvent event;
101: while (1) {
102: XMaskEvent(XiWin->disp,ExposureMask|StructureNotifyMask,&event);
103: if (event.xany.window != XiWin->win) break;
104: else {
105: switch (event.type) {
106: case ConfigureNotify:
107: /* window has been moved or resized */
108: XiWin->w = event.xconfigure.width - 2 * event.xconfigure.border_width;
109: XiWin->h = event.xconfigure.height - 2 * event.xconfigure.border_width;
110: break;
111: case DestroyNotify:
112: return 1;
113: case Expose:
114: return 0;
115: /* else ignore event */
116: }
117: }
118: }
119: return 0;
120: }
122: /*
123: Actually display a window at [x,y] with sizes (w,h)
124: */
125: static PetscErrorCode PetscDrawXiDisplayWindow(PetscDraw_X *XiWin,char *label,int x,int y,int w,int h)
126: {
127: unsigned int wavail,havail;
128: XSizeHints size_hints;
129: XWindowAttributes in_window_attributes;
130: XSetWindowAttributes window_attributes;
131: unsigned int border_width = 0;
132: unsigned long backgnd_pixel = WhitePixel(XiWin->disp,XiWin->screen);
133: unsigned long wmask;
135: /* get the available widths */
136: wavail = DisplayWidth(XiWin->disp,XiWin->screen);
137: havail = DisplayHeight(XiWin->disp,XiWin->screen);
139: if ((unsigned int)w > wavail) w = wavail;
140: if ((unsigned int)h > havail) h = havail;
142: if (x < 0) x = (int)(wavail - (unsigned int)w + (unsigned int)x);
143: if (y < 0) y = (int)(havail - (unsigned int)h + (unsigned int)y);
144: x = ((unsigned int)x + w > wavail) ? (int)(wavail - (unsigned int)w) : x;
145: y = ((unsigned int)y + h > havail) ? (int)(havail - (unsigned int)h) : y;
147: /* We need XCreateWindow since we may need an visual other than the default one */
148: XGetWindowAttributes(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),&in_window_attributes);
149: window_attributes.background_pixmap = None;
150: window_attributes.background_pixel = backgnd_pixel;
151: /* No border for now */
152: window_attributes.border_pixmap = None;
153: /*
154: window_attributes.border_pixel = border_pixel;
155: */
156: window_attributes.bit_gravity = in_window_attributes.bit_gravity;
157: window_attributes.win_gravity = in_window_attributes.win_gravity;
158: /* Backing store is too slow in color systems */
159: window_attributes.backing_store = NotUseful;
160: window_attributes.backing_pixel = backgnd_pixel;
161: window_attributes.save_under = 1;
162: window_attributes.event_mask = 0;
163: window_attributes.do_not_propagate_mask = 0;
164: window_attributes.override_redirect = 0;
165: window_attributes.colormap = XiWin->cmap;
166: /* None for cursor does NOT mean none, it means cursor of Parent */
167: window_attributes.cursor = None;
169: wmask = CWBackPixmap | CWBackPixel | CWBorderPixmap | CWBitGravity |
170: CWWinGravity | CWBackingStore | CWBackingPixel | CWOverrideRedirect |
171: CWSaveUnder | CWEventMask | CWDontPropagate |
172: CWCursor | CWColormap;
174: XiWin->win = XCreateWindow(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),x,y,w,h,border_width,XiWin->depth,InputOutput,XiWin->vis,wmask,&window_attributes);
177: /* set window manager hints */
178: {
179: XWMHints wm_hints;
180: XClassHint class_hints;
181: XTextProperty windowname,iconname;
183: if (label) XStringListToTextProperty(&label,1,&windowname);
184: else XStringListToTextProperty(&label,0,&windowname);
185: if (label) XStringListToTextProperty(&label,1,&iconname);
186: else XStringListToTextProperty(&label,0,&iconname);
188: wm_hints.initial_state = NormalState;
189: wm_hints.input = True;
190: wm_hints.flags = StateHint|InputHint;
192: /* These properties can be used by window managers to decide how to display a window */
193: class_hints.res_name = (char*)"petsc";
194: class_hints.res_class = (char*)"PETSc";
196: size_hints.x = x;
197: size_hints.y = y;
198: size_hints.min_width = 4*border_width;
199: size_hints.min_height = 4*border_width;
200: size_hints.width = w;
201: size_hints.height = h;
202: size_hints.flags = USPosition | USSize | PMinSize;
204: XSetWMProperties(XiWin->disp,XiWin->win,&windowname,&iconname,NULL,0,&size_hints,&wm_hints,&class_hints);
205: XFree((void*)windowname.value);
206: XFree((void*)iconname.value);
207: }
209: /* make the window visible */
210: XSelectInput(XiWin->disp,XiWin->win,ExposureMask|StructureNotifyMask);
211: XMapWindow(XiWin->disp,XiWin->win);
212: /* some window systems are cruel and interfere with the placement of
213: windows. We wait here for the window to be created or to die */
215: XSelectInput(XiWin->disp,XiWin->win,NoEventMask);
216: return 0;
217: }
219: PetscErrorCode PetscDrawXiQuickWindow(PetscDraw_X *XiWin,char *name,int x,int y,int nx,int ny)
220: {
221: PetscDrawSetColormap_X(XiWin,(Colormap)0);
222: PetscDrawXiDisplayWindow(XiWin,name,x,y,nx,ny);
223: XSetWindowBackground(XiWin->disp,XiWin->win,XiWin->background);
224: XClearWindow(XiWin->disp,XiWin->win);
225: return 0;
226: }
228: /*
229: A version from an already defined window
230: */
231: PetscErrorCode PetscDrawXiQuickWindowFromWindow(PetscDraw_X *XiWin,Window win)
232: {
233: XWindowAttributes attributes;
235: XiWin->win = win;
236: XGetWindowAttributes(XiWin->disp,XiWin->win,&attributes);
237: PetscDrawSetColormap_X(XiWin,attributes.colormap);
238: return 0;
239: }
241: PetscErrorCode PetscDrawXiQuickPixmap(PetscDraw_X* XiWin)
242: {
243: if (XiWin->drw) XFreePixmap(XiWin->disp,XiWin->drw);
244: XiWin->drw = XCreatePixmap(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),XiWin->w,XiWin->h,XiWin->depth);
245: PetscDrawXiSetPixVal(XiWin,XiWin->background);
246: XFillRectangle(XiWin->disp,XiWin->drw,XiWin->gc.set,0,0,XiWin->w,XiWin->h);
247: XSync(XiWin->disp,False);
248: return 0;
249: }
251: PetscErrorCode PetscDrawXiResizeWindow(PetscDraw_X* XiWin,int w,int h)
252: {
253: XEvent event;
254: XSelectInput(XiWin->disp,XiWin->win,StructureNotifyMask);
255: XResizeWindow(XiWin->disp,XiWin->win,(unsigned int)w,(unsigned int)h);
256: XWindowEvent(XiWin->disp,XiWin->win,StructureNotifyMask,&event);
257: XSelectInput(XiWin->disp,XiWin->win,NoEventMask);
258: return 0;
259: }
261: PetscErrorCode PetscDrawXiGetGeometry(PetscDraw_X *XiWin,int *x,int *y,int *w,int *h)
262: {
263: XWindowAttributes attributes;
264: Window root,parent,child;
265: int xx=0,yy=0;
266: unsigned int ww=0,hh=0,dummy;
267: if (XiWin->win) {
268: XGetGeometry(XiWin->disp,XiWin->win,&parent,&xx,&yy,&ww,&hh,&dummy,&dummy);
269: root = RootWindow(XiWin->disp,XiWin->screen);
270: if (!XTranslateCoordinates(XiWin->disp,XiWin->win,root,0,0,&xx,&yy,&child)) {
271: XGetWindowAttributes(XiWin->disp,XiWin->win,&attributes);
272: root = attributes.screen->root;
273: (void)XTranslateCoordinates(XiWin->disp,XiWin->win,root,0,0,&xx,&yy,&child);
274: }
275: } else if (XiWin->drw) {
276: XGetGeometry(XiWin->disp,XiWin->drw,&root,&xx,&yy,&ww,&hh,&dummy,&dummy);
277: }
278: if (x) *x = xx;
279: if (y) *y = yy;
280: if (w) *w = (int)ww;
281: if (h) *h = (int)hh;
282: return 0;
283: }