1 
2 #include <X11/Xmd.h>
3 
4 #include "wconfig.h"
5 
6 #include "WINGsP.h"
7 
8 #include "GNUstep.h"
9 
10 #include <X11/Xatom.h>
11 
12 typedef struct W_Window {
13 	W_Class widgetClass;
14 	W_View *view;
15 
16 	struct W_Window *nextPtr;	/* next in the window list */
17 
18 	struct W_Window *owner;
19 
20 	char *title;
21 
22 	WMPixmap *miniImage;	/* miniwindow */
23 	char *miniTitle;
24 
25 	char *wname;
26 
27 	WMSize resizeIncrement;
28 	WMSize baseSize;
29 	WMSize minSize;
30 	WMSize maxSize;
31 	WMPoint minAspect;
32 	WMPoint maxAspect;
33 
34 	WMPoint upos;
35 	WMPoint ppos;
36 
37 	WMAction *closeAction;
38 	void *closeData;
39 
40 	int level;
41 
42 	struct {
43 		unsigned style:4;
44 		unsigned configured:1;
45 		unsigned documentEdited:1;
46 
47 		unsigned setUPos:1;
48 		unsigned setPPos:1;
49 		unsigned setAspect:1;
50 	} flags;
51 } _Window;
52 
53 
54 static void willResizeWindow(W_ViewDelegate *, WMView *, unsigned *, unsigned *);
55 
56 struct W_ViewDelegate _WindowViewDelegate = {
57 	NULL,
58 	NULL,
59 	NULL,
60 	NULL,
61 	willResizeWindow
62 };
63 
64 #define DEFAULT_WIDTH	400
65 #define DEFAULT_HEIGHT	180
66 
67 static void destroyWindow(_Window * win);
68 
69 static void handleEvents(XEvent * event, void *clientData);
70 
71 static void realizeWindow(WMWindow * win);
72 
realizeObserver(void * self,WMNotification * not)73 static void realizeObserver(void *self, WMNotification * not)
74 {
75 	/* Parameter not used, but tell the compiler that it is ok */
76 	(void) not;
77 
78 	realizeWindow(self);
79 }
80 
WMCreatePanelWithStyleForWindow(WMWindow * owner,const char * name,int style)81 WMWindow *WMCreatePanelWithStyleForWindow(WMWindow * owner, const char *name, int style)
82 {
83 	WMWindow *win;
84 
85 	win = WMCreateWindowWithStyle(owner->view->screen, name, style);
86 	win->owner = owner;
87 
88 	return win;
89 }
90 
WMCreatePanelForWindow(WMWindow * owner,const char * name)91 WMWindow *WMCreatePanelForWindow(WMWindow * owner, const char *name)
92 {
93 	return WMCreatePanelWithStyleForWindow(owner, name,
94 					       WMTitledWindowMask | WMClosableWindowMask | WMResizableWindowMask);
95 }
96 
WMChangePanelOwner(WMWindow * win,WMWindow * newOwner)97 void WMChangePanelOwner(WMWindow * win, WMWindow * newOwner)
98 {
99 	win->owner = newOwner;
100 
101 	if (win->view->flags.realized && newOwner) {
102 		XSetTransientForHint(win->view->screen->display, win->view->window, newOwner->view->window);
103 	}
104 }
105 
WMCreateWindow(WMScreen * screen,const char * name)106 WMWindow *WMCreateWindow(WMScreen * screen, const char *name)
107 {
108 	return WMCreateWindowWithStyle(screen, name, WMTitledWindowMask
109 				       | WMClosableWindowMask
110 				       | WMMiniaturizableWindowMask | WMResizableWindowMask);
111 }
112 
WMCreateWindowWithStyle(WMScreen * screen,const char * name,int style)113 WMWindow *WMCreateWindowWithStyle(WMScreen * screen, const char *name, int style)
114 {
115 	_Window *win;
116 
117 	win = wmalloc(sizeof(_Window));
118 	win->widgetClass = WC_Window;
119 
120 	win->view = W_CreateTopView(screen);
121 	if (!win->view) {
122 		wfree(win);
123 		return NULL;
124 	}
125 	win->view->self = win;
126 
127 	win->view->delegate = &_WindowViewDelegate;
128 
129 	win->wname = wstrdup(name);
130 
131 	/* add to the window list of the screen (application) */
132 	win->nextPtr = screen->windowList;
133 	screen->windowList = win;
134 
135 	WMCreateEventHandler(win->view, ExposureMask | StructureNotifyMask
136 			     | ClientMessageMask | FocusChangeMask, handleEvents, win);
137 
138 	W_ResizeView(win->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
139 
140 	WMAddNotificationObserver(realizeObserver, win, WMViewRealizedNotification, win->view);
141 
142 	win->flags.style = style;
143 
144 	win->level = WMNormalWindowLevel;
145 
146 	/* kluge. Find a better solution */
147 	W_SetFocusOfTopLevel(win->view, win->view);
148 
149 	return win;
150 }
151 
setWindowTitle(WMWindow * win,const char * title)152 static void setWindowTitle(WMWindow * win, const char *title)
153 {
154 	WMScreen *scr = win->view->screen;
155 	XTextProperty property;
156 	int result;
157 
158 	result = XmbTextListToTextProperty(scr->display, (char **)&title, 1, XStdICCTextStyle, &property);
159 	if (result == XNoMemory || result == XLocaleNotSupported) {
160 		wwarning(_("window title conversion error... using STRING encoding"));
161 		XStoreName(scr->display, win->view->window, title);
162 	} else {
163 		XSetWMName(scr->display, win->view->window, &property);
164 		if (property.value)
165 			XFree(property.value);
166 	}
167 
168 	XChangeProperty(scr->display, win->view->window,
169 			scr->netwmName, scr->utf8String, 8,
170 			PropModeReplace, (unsigned char *)title, strlen(title));
171 }
172 
setMiniwindowTitle(WMWindow * win,const char * title)173 static void setMiniwindowTitle(WMWindow * win, const char *title)
174 {
175 	WMScreen *scr = win->view->screen;
176 	XTextProperty property;
177 	int result;
178 
179 	result = XmbTextListToTextProperty(scr->display, (char **)&title, 1, XStdICCTextStyle, &property);
180 	if (result == XNoMemory || result == XLocaleNotSupported) {
181 		wwarning(_("icon title conversion error... using STRING encoding"));
182 		XSetIconName(scr->display, win->view->window, title);
183 	} else {
184 		XSetWMIconName(scr->display, win->view->window, &property);
185 		if (property.value)
186 			XFree(property.value);
187 	}
188 
189 	XChangeProperty(scr->display, win->view->window,
190 			scr->netwmIconName, scr->utf8String, 8,
191 			PropModeReplace, (unsigned char *)title, strlen(title));
192 }
193 
setMiniwindow(WMWindow * win,RImage * image)194 static void setMiniwindow(WMWindow *win, RImage *image)
195 {
196 	WMScreen *scr = win->view->screen;
197 	unsigned long *data;
198 	int x, y;
199 	int o;
200 
201 	if (!image)
202 		return;
203 
204 	data = wmalloc((image->width * image->height + 2) * sizeof(long));
205 
206 	o = 0;
207 	data[o++] = image->width;
208 	data[o++] = image->height;
209 
210 	for (y = 0; y < image->height; y++) {
211 		for (x = 0; x < image->width; x++) {
212 			unsigned long pixel;
213 			int offs = (x + y * image->width);
214 
215 			if (image->format == RRGBFormat) {
216 				pixel  = ((unsigned long) image->data[offs * 3    ]) << 16;
217 				pixel |= ((unsigned long) image->data[offs * 3 + 1]) <<  8;
218 				pixel |= ((unsigned long) image->data[offs * 3 + 2]);
219 			} else {
220 				pixel  = ((unsigned long) image->data[offs * 4    ]) << 16;
221 				pixel |= ((unsigned long) image->data[offs * 4 + 1]) <<  8;
222 				pixel |= ((unsigned long) image->data[offs * 4 + 2]);
223 				pixel |= ((unsigned long) image->data[offs * 4 + 3]) << 24;
224 			}
225 
226 			data[o++] = pixel;
227 		}
228 	}
229 
230 	XChangeProperty(scr->display, win->view->window, scr->netwmIcon,
231 			XA_CARDINAL, 32, PropModeReplace,
232 			(unsigned char *)data, (image->width * image->height + 2));
233 
234 	wfree(data);
235 }
236 
WMSetWindowTitle(WMWindow * win,const char * title)237 void WMSetWindowTitle(WMWindow * win, const char *title)
238 {
239 	wassertr(title != NULL);
240 
241 	if (win->title != NULL)
242 		wfree(win->title);
243 
244 	win->title = wstrdup(title);
245 
246 	if (win->view->flags.realized) {
247 		setWindowTitle(win, title);
248 	}
249 }
250 
WMSetWindowCloseAction(WMWindow * win,WMAction * action,void * clientData)251 void WMSetWindowCloseAction(WMWindow * win, WMAction * action, void *clientData)
252 {
253 	Atom *atoms = NULL;
254 	Atom *newAtoms;
255 	int count;
256 	WMScreen *scr = win->view->screen;
257 
258 	if (win->view->flags.realized) {
259 		if (action && !win->closeAction) {
260 			if (!XGetWMProtocols(scr->display, win->view->window, &atoms, &count)) {
261 				count = 0;
262 			}
263 			newAtoms = wmalloc((count + 1) * sizeof(Atom));
264 			if (count > 0)
265 				memcpy(newAtoms, atoms, count * sizeof(Atom));
266 			newAtoms[count++] = scr->deleteWindowAtom;
267 			XSetWMProtocols(scr->display, win->view->window, newAtoms, count);
268 			if (atoms)
269 				XFree(atoms);
270 			wfree(newAtoms);
271 		} else if (!action && win->closeAction) {
272 			int i, ncount;
273 
274 			if (XGetWMProtocols(scr->display, win->view->window, &atoms, &count) && count > 0) {
275 				newAtoms = wmalloc((count - 1) * sizeof(Atom));
276 				ncount = 0;
277 				for (i = 0; i < count; i++) {
278 					if (atoms[i] != scr->deleteWindowAtom) {
279 						newAtoms[i] = atoms[i];
280 						ncount++;
281 					}
282 				}
283 				XSetWMProtocols(scr->display, win->view->window, newAtoms, ncount);
284 				if (atoms)
285 					XFree(atoms);
286 				wfree(newAtoms);
287 			}
288 		}
289 	}
290 	win->closeAction = action;
291 	win->closeData = clientData;
292 }
293 
willResizeWindow(W_ViewDelegate * self,WMView * view,unsigned * width,unsigned * height)294 static void willResizeWindow(W_ViewDelegate * self, WMView * view, unsigned *width, unsigned *height)
295 {
296 	WMWindow *win = (WMWindow *) view->self;
297 
298 	/* Parameter not used, but tell the compiler that it is ok */
299 	(void) self;
300 
301 	if (win->minSize.width > 0 && win->minSize.height > 0) {
302 		if (*width < win->minSize.width)
303 			*width = win->minSize.width;
304 		if (*height < win->minSize.height)
305 			*height = win->minSize.height;
306 	}
307 
308 	if (win->maxSize.width > 0 && win->maxSize.height > 0) {
309 		if (*width > win->maxSize.width)
310 			*width = win->maxSize.width;
311 		if (*height > win->maxSize.height)
312 			*height = win->maxSize.height;
313 	}
314 }
315 
setSizeHints(WMWindow * win)316 static void setSizeHints(WMWindow * win)
317 {
318 	XSizeHints *hints;
319 
320 	hints = XAllocSizeHints();
321 	if (!hints) {
322 		wwarning("could not allocate memory for window size hints");
323 		return;
324 	}
325 
326 	hints->flags = 0;
327 
328 	if (win->flags.setPPos) {
329 		hints->flags |= PPosition;
330 		hints->x = win->ppos.x;
331 		hints->y = win->ppos.y;
332 	}
333 	if (win->flags.setUPos) {
334 		hints->flags |= USPosition;
335 		hints->x = win->upos.x;
336 		hints->y = win->upos.y;
337 	}
338 	if (win->minSize.width > 0 && win->minSize.height > 0) {
339 		hints->flags |= PMinSize;
340 		hints->min_width = win->minSize.width;
341 		hints->min_height = win->minSize.height;
342 	}
343 	if (win->maxSize.width > 0 && win->maxSize.height > 0) {
344 		hints->flags |= PMaxSize;
345 		hints->max_width = win->maxSize.width;
346 		hints->max_height = win->maxSize.height;
347 	}
348 	if (win->baseSize.width > 0 && win->baseSize.height > 0) {
349 		hints->flags |= PBaseSize;
350 		hints->base_width = win->baseSize.width;
351 		hints->base_height = win->baseSize.height;
352 	}
353 	if (win->resizeIncrement.width > 0 && win->resizeIncrement.height > 0) {
354 		hints->flags |= PResizeInc;
355 		hints->width_inc = win->resizeIncrement.width;
356 		hints->height_inc = win->resizeIncrement.height;
357 	}
358 	if (win->flags.setAspect) {
359 		hints->flags |= PAspect;
360 		hints->min_aspect.x = win->minAspect.x;
361 		hints->min_aspect.y = win->minAspect.y;
362 		hints->max_aspect.x = win->maxAspect.x;
363 		hints->max_aspect.y = win->maxAspect.y;
364 	}
365 
366 	if (hints->flags) {
367 		XSetWMNormalHints(win->view->screen->display, win->view->window, hints);
368 	}
369 	XFree(hints);
370 }
371 
writeGNUstepWMAttr(WMScreen * scr,Window window,GNUstepWMAttributes * attr)372 static void writeGNUstepWMAttr(WMScreen * scr, Window window, GNUstepWMAttributes * attr)
373 {
374 	unsigned long data[9];
375 
376 	/* handle idiot compilers where array of CARD32 != struct of CARD32 */
377 	data[0] = attr->flags;
378 	data[1] = attr->window_style;
379 	data[2] = attr->window_level;
380 	data[3] = 0;		/* reserved */
381 	/* The X protocol says XIDs are 32bit */
382 	data[4] = attr->miniaturize_pixmap;
383 	data[5] = attr->close_pixmap;
384 	data[6] = attr->miniaturize_mask;
385 	data[7] = attr->close_mask;
386 	data[8] = attr->extra_flags;
387 	XChangeProperty(scr->display, window, scr->attribsAtom, scr->attribsAtom,
388 			32, PropModeReplace, (unsigned char *)data, 9);
389 }
390 
setWindowMakerHints(WMWindow * win)391 static void setWindowMakerHints(WMWindow * win)
392 {
393 	GNUstepWMAttributes attribs;
394 	WMScreen *scr = WMWidgetScreen(win);
395 
396 	memset(&attribs, 0, sizeof(GNUstepWMAttributes));
397 	attribs.flags = GSWindowStyleAttr | GSWindowLevelAttr | GSExtraFlagsAttr;
398 	attribs.window_style = win->flags.style;
399 	attribs.window_level = win->level;
400 	if (win->flags.documentEdited)
401 		attribs.extra_flags = GSDocumentEditedFlag;
402 	else
403 		attribs.extra_flags = 0;
404 
405 	writeGNUstepWMAttr(scr, win->view->window, &attribs);
406 }
407 
realizeWindow(WMWindow * win)408 static void realizeWindow(WMWindow * win)
409 {
410 	XWMHints *hints;
411 	XClassHint *classHint;
412 	WMScreen *scr = win->view->screen;
413 	Atom atoms[4];
414 	int count;
415 
416 	classHint = XAllocClassHint();
417 	classHint->res_name = win->wname;
418 	classHint->res_class = WMGetApplicationName();
419 	XSetClassHint(scr->display, win->view->window, classHint);
420 	XFree(classHint);
421 
422 	hints = XAllocWMHints();
423 	hints->flags = 0;
424 	if (!scr->aflags.simpleApplication) {
425 		hints->flags |= WindowGroupHint;
426 		hints->window_group = scr->groupLeader;
427 	}
428 	if (win->miniImage) {
429 		hints->flags |= IconPixmapHint;
430 		hints->icon_pixmap = WMGetPixmapXID(win->miniImage);
431 		hints->icon_mask = WMGetPixmapMaskXID(win->miniImage);
432 		if (hints->icon_mask != None) {
433 			hints->flags |= IconMaskHint;
434 		}
435 	}
436 	if (hints->flags != 0)
437 		XSetWMHints(scr->display, win->view->window, hints);
438 	XFree(hints);
439 
440 	count = 0;
441 	if (win->closeAction) {
442 		atoms[count++] = scr->deleteWindowAtom;
443 	}
444 
445 	if (count > 0)
446 		XSetWMProtocols(scr->display, win->view->window, atoms, count);
447 
448 	if (win->title || win->miniTitle)
449 		XmbSetWMProperties(scr->display, win->view->window, win->title,
450 				   win->miniTitle, NULL, 0, NULL, NULL, NULL);
451 
452 	setWindowMakerHints(win);
453 
454 	setSizeHints(win);
455 
456 	if (win->owner) {
457 		XSetTransientForHint(scr->display, win->view->window, win->owner->view->window);
458 	}
459 
460 	if (win->title)
461 		setWindowTitle(win, win->title);
462 }
463 
WMSetWindowAspectRatio(WMWindow * win,int minX,int minY,int maxX,int maxY)464 void WMSetWindowAspectRatio(WMWindow * win, int minX, int minY, int maxX, int maxY)
465 {
466 	win->flags.setAspect = 1;
467 	win->minAspect.x = minX;
468 	win->minAspect.y = minY;
469 	win->maxAspect.x = maxX;
470 	win->maxAspect.y = maxY;
471 	if (win->view->flags.realized)
472 		setSizeHints(win);
473 }
474 
WMSetWindowInitialPosition(WMWindow * win,int x,int y)475 void WMSetWindowInitialPosition(WMWindow * win, int x, int y)
476 {
477 	win->flags.setPPos = 1;
478 	win->ppos.x = x;
479 	win->ppos.y = y;
480 	if (win->view->flags.realized)
481 		setSizeHints(win);
482 	WMMoveWidget(win, x, y);
483 }
484 
WMSetWindowUserPosition(WMWindow * win,int x,int y)485 void WMSetWindowUserPosition(WMWindow * win, int x, int y)
486 {
487 	win->flags.setUPos = 1;
488 	win->upos.x = x;
489 	win->upos.y = y;
490 	if (win->view->flags.realized)
491 		setSizeHints(win);
492 	WMMoveWidget(win, x, y);
493 }
494 
WMSetWindowMinSize(WMWindow * win,unsigned width,unsigned height)495 void WMSetWindowMinSize(WMWindow * win, unsigned width, unsigned height)
496 {
497 	win->minSize.width = width;
498 	win->minSize.height = height;
499 	if (win->view->flags.realized)
500 		setSizeHints(win);
501 }
502 
WMSetWindowMaxSize(WMWindow * win,unsigned width,unsigned height)503 void WMSetWindowMaxSize(WMWindow * win, unsigned width, unsigned height)
504 {
505 	win->maxSize.width = width;
506 	win->maxSize.height = height;
507 	if (win->view->flags.realized)
508 		setSizeHints(win);
509 }
510 
WMSetWindowBaseSize(WMWindow * win,unsigned width,unsigned height)511 void WMSetWindowBaseSize(WMWindow * win, unsigned width, unsigned height)
512 {
513 	/* TODO: validate sizes */
514 	win->baseSize.width = width;
515 	win->baseSize.height = height;
516 	if (win->view->flags.realized)
517 		setSizeHints(win);
518 }
519 
WMSetWindowResizeIncrements(WMWindow * win,unsigned wIncr,unsigned hIncr)520 void WMSetWindowResizeIncrements(WMWindow * win, unsigned wIncr, unsigned hIncr)
521 {
522 	win->resizeIncrement.width = wIncr;
523 	win->resizeIncrement.height = hIncr;
524 	if (win->view->flags.realized)
525 		setSizeHints(win);
526 }
527 
WMSetWindowLevel(WMWindow * win,int level)528 void WMSetWindowLevel(WMWindow * win, int level)
529 {
530 	win->level = level;
531 	if (win->view->flags.realized)
532 		setWindowMakerHints(win);
533 }
534 
WMSetWindowDocumentEdited(WMWindow * win,Bool flag)535 void WMSetWindowDocumentEdited(WMWindow * win, Bool flag)
536 {
537 	flag = ((flag == 0) ? 0 : 1);
538 	if (win->flags.documentEdited != flag) {
539 		win->flags.documentEdited = flag;
540 		if (win->view->flags.realized)
541 			setWindowMakerHints(win);
542 	}
543 }
544 
WMSetWindowMiniwindowImage(WMWindow * win,RImage * image)545 void WMSetWindowMiniwindowImage(WMWindow * win, RImage * image)
546 {
547 	if (win->view->flags.realized)
548 		setMiniwindow(win, image);
549 }
550 
WMSetWindowMiniwindowPixmap(WMWindow * win,WMPixmap * pixmap)551 void WMSetWindowMiniwindowPixmap(WMWindow * win, WMPixmap * pixmap)
552 {
553 	if ((win->miniImage && !pixmap) || (!win->miniImage && pixmap)) {
554 		if (win->miniImage)
555 			WMReleasePixmap(win->miniImage);
556 
557 		if (pixmap)
558 			win->miniImage = WMRetainPixmap(pixmap);
559 		else
560 			win->miniImage = NULL;
561 
562 		if (win->view->flags.realized) {
563 			XWMHints *hints;
564 
565 			hints = XGetWMHints(win->view->screen->display, win->view->window);
566 			if (!hints) {
567 				hints = XAllocWMHints();
568 				if (!hints) {
569 					wwarning("could not allocate memory for WM hints");
570 					return;
571 				}
572 				hints->flags = 0;
573 			}
574 			if (pixmap) {
575 				hints->flags |= IconPixmapHint;
576 				hints->icon_pixmap = WMGetPixmapXID(pixmap);
577 				hints->icon_mask = WMGetPixmapMaskXID(pixmap);
578 				if (hints->icon_mask != None) {
579 					hints->flags |= IconMaskHint;
580 				}
581 			}
582 			XSetWMHints(win->view->screen->display, win->view->window, hints);
583 			XFree(hints);
584 		}
585 	}
586 }
587 
WMSetWindowMiniwindowTitle(WMWindow * win,const char * title)588 void WMSetWindowMiniwindowTitle(WMWindow * win, const char *title)
589 {
590 	if (win && ((win->miniTitle && !title) || (!win->miniTitle && title)
591 	    || (title && win->miniTitle && strcoll(title, win->miniTitle) != 0))) {
592 		if (win->miniTitle)
593 			wfree(win->miniTitle);
594 
595 		if (title)
596 			win->miniTitle = wstrdup(title);
597 		else
598 			win->miniTitle = NULL;
599 
600 		if (win->view->flags.realized) {
601 			setMiniwindowTitle(win, title);
602 		}
603 	}
604 }
605 
WMCloseWindow(WMWindow * win)606 void WMCloseWindow(WMWindow * win)
607 {
608 	WMUnmapWidget(win);
609 	/* withdraw the window */
610 	if (win->view->flags.realized)
611 		XWithdrawWindow(win->view->screen->display, win->view->window, win->view->screen->screen);
612 }
613 
handleEvents(XEvent * event,void * clientData)614 static void handleEvents(XEvent * event, void *clientData)
615 {
616 	_Window *win = (_Window *) clientData;
617 	W_View *view = win->view;
618 
619 	switch (event->type) {
620 	case ClientMessage:
621 		if (event->xclient.message_type == win->view->screen->protocolsAtom
622 		    && event->xclient.format == 32
623 		    && event->xclient.data.l[0] == win->view->screen->deleteWindowAtom) {
624 
625 			if (win->closeAction) {
626 				(*win->closeAction) (win, win->closeData);
627 			}
628 		}
629 		break;
630 		/*
631 		 * was causing windows to ignore commands like closeWindow
632 		 * after the windows is iconized/restored or a workspace change
633 		 * if this is really needed, put the MapNotify portion too and
634 		 * fix the restack bug in wmaker
635 		 case UnmapNotify:
636 		 WMUnmapWidget(win);
637 		 break;
638 		 *
639 		 case MapNotify:
640 		 WMMapWidget(win);
641 		 break;
642 
643 		 */
644 	case DestroyNotify:
645 		destroyWindow(win);
646 		break;
647 
648 	case ConfigureNotify:
649 		if (event->xconfigure.width != view->size.width || event->xconfigure.height != view->size.height) {
650 
651 			view->size.width = event->xconfigure.width;
652 			view->size.height = event->xconfigure.height;
653 
654 			if (view->flags.notifySizeChanged) {
655 				WMPostNotificationName(WMViewSizeDidChangeNotification, view, NULL);
656 			}
657 		}
658 		if (event->xconfigure.x != view->pos.x || event->xconfigure.y != view->pos.y) {
659 
660 			if (event->xconfigure.send_event) {
661 				view->pos.x = event->xconfigure.x;
662 				view->pos.y = event->xconfigure.y;
663 			} else {
664 				Window foo;
665 
666 				XTranslateCoordinates(view->screen->display,
667 						      view->window, view->screen->rootWin,
668 						      event->xconfigure.x, event->xconfigure.y,
669 						      &view->pos.x, &view->pos.y, &foo);
670 			}
671 		}
672 		break;
673 	}
674 }
675 
destroyWindow(_Window * win)676 static void destroyWindow(_Window * win)
677 {
678 	WMScreen *scr = win->view->screen;
679 
680 	WMRemoveNotificationObserver(win);
681 
682 	if (scr->windowList == win) {
683 		scr->windowList = scr->windowList->nextPtr;
684 	} else {
685 		WMWindow *ptr;
686 		ptr = scr->windowList;
687 
688 		if (ptr) {
689 			while (ptr->nextPtr) {
690 				if (ptr->nextPtr == win) {
691 					ptr->nextPtr = ptr->nextPtr->nextPtr;
692 					break;
693 				}
694 				ptr = ptr->nextPtr;
695 			}
696 		}
697 	}
698 
699 	if (win->title) {
700 		wfree(win->title);
701 	}
702 
703 	if (win->miniTitle) {
704 		wfree(win->miniTitle);
705 	}
706 
707 	if (win->miniImage) {
708 		WMReleasePixmap(win->miniImage);
709 	}
710 
711 	if (win->wname)
712 		wfree(win->wname);
713 
714 	wfree(win);
715 }
716