5 #include <X11/Xresource.h>
9 /* the notifications about views */
11 char *WMViewSizeDidChangeNotification
= "WMViewSizeDidChangeNotification";
12 char *WMViewFocusDidChangeNotification
= "WMViewFocusDidChangeNotification";
13 char *WMViewRealizedNotification
= "WMViewRealizedNotification";
17 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \
18 EnterWindowMask|LeaveWindowMask|PointerMotionMask|ExposureMask| \
19 VisibilityChangeMask|FocusChangeMask|PropertyChangeMask|\
20 SubstructureNotifyMask|SubstructureRedirectMask
23 static XSetWindowAttributes defAtts
= {
24 None
, /* background_pixmap */
25 0, /* background_pixel */
26 CopyFromParent
, /* border_pixmap */
28 ForgetGravity
, /* bit_gravity */
29 ForgetGravity
, /* win_gravity */
30 NotUseful
, /* backing_store */
31 (unsigned) ~0, /* backing_planes */
32 0, /* backing_pixel */
33 False
, /* save_under */
34 EVENT_MASK
, /* event_mask */
35 0, /* do_not_propagate_mask */
36 False
, /* override_redirect */
43 static XContext ViewContext
=0; /* context for views */
49 W_GetViewForXWindow(Display
*display
, Window window
)
53 if (XFindContext(display
, window
, ViewContext
, (XPointer
*)&view
)==0) {
62 unparentView(W_View
*view
)
64 /* remove from parent's children list */
65 if (view
->parent
!=NULL
) {
68 ptr
= view
->parent
->childrenList
;
70 view
->parent
->childrenList
= view
->nextSister
;
73 if (ptr
->nextSister
== view
) {
74 ptr
->nextSister
= view
->nextSister
;
77 ptr
= ptr
->nextSister
;
86 adoptChildView(W_View
*view
, W_View
*child
)
88 child
->nextSister
= NULL
;
90 /* add to end of children list of parent */
91 if (view
->childrenList
== NULL
) {
92 view
->childrenList
= child
;
96 ptr
= view
->childrenList
;
97 while (ptr
->nextSister
!=NULL
)
98 ptr
= ptr
->nextSister
;
99 ptr
->nextSister
= child
;
101 child
->parent
= view
;
106 createView(W_Screen
*screen
, W_View
*parent
)
111 ViewContext
= XUniqueContext();
113 view
= wmalloc(sizeof(W_View
));
114 memset(view
, 0, sizeof(W_View
));
118 view
->screen
= screen
;
121 /* attributes are not valid for root window */
122 view
->attribFlags
= CWEventMask
|CWBitGravity
;
123 view
->attribs
= defAtts
;
125 view
->attribFlags
|= CWBackPixel
|CWColormap
|CWBorderPixel
;
126 view
->attribs
.background_pixel
= W_PIXEL(screen
->gray
);
127 view
->attribs
.border_pixel
= W_PIXEL(screen
->black
);
128 view
->attribs
.colormap
= screen
->colormap
;
130 view
->backColor
= WMRetainColor(screen
->gray
);
132 adoptChildView(parent
, view
);
141 W_CreateView(W_View
*parent
)
143 return createView(parent
->screen
, parent
);
148 W_CreateRootView(W_Screen
*screen
)
152 view
= createView(screen
, NULL
);
154 view
->window
= screen
->rootWin
;
156 view
->flags
.realized
= 1;
157 view
->flags
.mapped
= 1;
158 view
->flags
.root
= 1;
161 WidthOfScreen(ScreenOfDisplay(screen
->display
, screen
->screen
));
163 HeightOfScreen(ScreenOfDisplay(screen
->display
, screen
->screen
));
170 W_CreateTopView(W_Screen
*screen
)
174 view
= createView(screen
, screen
->rootView
);
178 view
->flags
.topLevel
= 1;
179 view
->attribs
.event_mask
|= StructureNotifyMask
;
187 W_RealizeView(W_View
*view
)
190 Display
*dpy
= view
->screen
->display
;
193 assert(view
->size
.width
> 0);
194 assert(view
->size
.height
> 0);
197 if (view
->parent
&& !view
->parent
->flags
.realized
) {
198 wwarning("trying to realize widget of unrealized parent");
202 if (!view
->flags
.realized
) {
203 parentWID
= view
->parent
->window
;
204 view
->window
= XCreateWindow(dpy
, parentWID
, view
->pos
.x
, view
->pos
.y
,
205 view
->size
.width
, view
->size
.height
, 0,
206 view
->screen
->depth
, InputOutput
,
207 view
->screen
->visual
, view
->attribFlags
,
210 XSaveContext(dpy
, view
->window
, ViewContext
, (XPointer
)view
);
212 view
->flags
.realized
= 1;
214 if (view
->flags
.mapWhenRealized
) {
216 view
->flags
.mapWhenRealized
= 0;
219 WMPostNotificationName(WMViewRealizedNotification
, view
, NULL
);
222 /* realize children */
223 ptr
= view
->childrenList
;
227 ptr
= ptr
->nextSister
;
233 W_ReparentView(W_View
*view
, W_View
*newParent
, int x
, int y
)
235 Display
*dpy
= view
->screen
->display
;
237 assert(!view
->flags
.topLevel
);
240 adoptChildView(newParent
, view
);
242 if (view
->flags
.realized
) {
243 if (newParent
->flags
.realized
) {
244 XReparentWindow(dpy
, view
->window
, newParent
->window
, x
, y
);
246 wwarning("trying to reparent realized view to unrealized parent");
258 W_MapView(W_View
*view
)
260 if (!view
->flags
.mapped
) {
261 if (view
->flags
.realized
) {
262 XMapRaised(view
->screen
->display
, view
->window
);
263 XFlush(view
->screen
->display
);
264 view
->flags
.mapped
= 1;
266 view
->flags
.mapWhenRealized
= 1;
274 * maps all children of the current view that where already realized.
277 W_MapSubviews(W_View
*view
)
279 XMapSubwindows(view
->screen
->display
, view
->window
);
280 XFlush(view
->screen
->display
);
282 view
= view
->childrenList
;
284 view
->flags
.mapped
= 1;
285 view
->flags
.mapWhenRealized
= 0;
286 view
= view
->nextSister
;
293 W_UnmapSubviews(W_View
*view
)
295 XUnmapSubwindows(view
->screen
->display
, view
->window
);
296 XFlush(view
->screen
->display
);
298 view
= view
->childrenList
;
300 view
->flags
.mapped
= 0;
301 view
->flags
.mapWhenRealized
= 0;
302 view
= view
->nextSister
;
309 W_UnmapView(W_View
*view
)
311 view
->flags
.mapWhenRealized
= 0;
312 if (!view
->flags
.mapped
)
315 XUnmapWindow(view
->screen
->display
, view
->window
);
316 XFlush(view
->screen
->display
);
318 view
->flags
.mapped
= 0;
323 W_TopLevelOfView(W_View
*view
)
327 for (toplevel
=view
; !toplevel
->flags
.topLevel
; toplevel
=toplevel
->parent
);
334 destroyView(W_View
*view
)
338 if (view
->flags
.alreadyDead
)
340 view
->flags
.alreadyDead
= 1;
342 /* delete the balloon text for the view, if there's any */
343 WMSetBalloonTextForView(NULL
, view
);
345 if (view
->nextFocusChain
)
346 view
->nextFocusChain
->prevFocusChain
= view
->prevFocusChain
;
347 if (view
->prevFocusChain
)
348 view
->prevFocusChain
->nextFocusChain
= view
->nextFocusChain
;
350 /* Do not leave focus in a inexisting control */
351 if (W_FocusedViewOfToplevel(W_TopLevelOfView(view
))==view
)
352 W_SetFocusOfTopLevel(W_TopLevelOfView(view
), NULL
);
354 if (view
->flags
.topLevel
) {
355 W_FocusInfo
*info
= view
->screen
->focusInfo
;
356 /* remove focus information associated to this toplevel */
359 if (info
->toplevel
==view
) {
360 view
->screen
->focusInfo
= info
->next
;
364 if (info
->next
->toplevel
== view
)
369 W_FocusInfo
*next
= info
->next
->next
;
373 /* else the toplevel did not have any focused subview */
378 /* destroy children recursively */
379 while (view
->childrenList
!=NULL
) {
380 ptr
= view
->childrenList
;
381 ptr
->flags
.parentDying
= 1;
385 if (ptr
== view
->childrenList
) {
386 view
->childrenList
= ptr
->nextSister
;
391 W_CallDestroyHandlers(view
);
393 if (view
->flags
.realized
) {
394 XDeleteContext(view
->screen
->display
, view
->window
, ViewContext
);
396 /* if parent is being destroyed, it will die naturaly */
397 if (!view
->flags
.parentDying
|| view
->flags
.topLevel
)
398 XDestroyWindow(view
->screen
->display
, view
->window
);
401 /* remove self from parent's children list */
404 W_CleanUpEvents(view
);
406 WMUnregisterViewDraggedTypes(view
);
409 if (view
->dragSourceProcs
)
410 wfree(view
->dragSourceProcs
);
412 if (view
->dragDestinationProcs
)
413 wfree(view
->dragDestinationProcs
);
421 W_DestroyView(W_View
*view
)
429 W_MoveView(W_View
*view
, int x
, int y
)
431 assert(view
->flags
.root
==0);
433 if (view
->delegate
&& view
->delegate
->willMove
) {
434 (*view
->delegate
->willMove
)(view
->delegate
, view
, &x
, &y
);
437 if (view
->pos
.x
== x
&& view
->pos
.y
== y
)
440 if (view
->flags
.realized
) {
441 XMoveWindow(view
->screen
->display
, view
->window
, x
, y
);
446 if (view
->delegate
&& view
->delegate
->didMove
) {
447 (*view
->delegate
->didMove
)(view
->delegate
, view
);
453 W_ResizeView(W_View
*view
, unsigned int width
, unsigned int height
)
457 if (view
->delegate
&& view
->delegate
->willResize
) {
458 (*view
->delegate
->willResize
)(view
->delegate
, view
, &width
, &height
);
464 if (view
->size
.width
== width
&& view
->size
.height
== height
)
467 shrinked
= width
< view
->size
.width
|| height
< view
->size
.height
;
469 if (view
->flags
.realized
) {
470 XResizeWindow(view
->screen
->display
, view
->window
, width
, height
);
472 view
->size
.width
= width
;
473 view
->size
.height
= height
;
475 if (view
->delegate
&& view
->delegate
->didResize
) {
476 (*view
->delegate
->didResize
)(view
->delegate
, view
);
479 if (view
->flags
.notifySizeChanged
)
480 WMPostNotificationName(WMViewSizeDidChangeNotification
, view
, NULL
);
485 W_RedisplayView(W_View
*view
)
489 if (!view
->flags
.mapped
)
492 ev
.xexpose
.type
= Expose
;
493 ev
.xexpose
.display
= view
->screen
->display
;
494 ev
.xexpose
.window
= view
->window
;
495 ev
.xexpose
.count
= 0;
502 W_SetViewBackgroundColor(W_View
*view
, WMColor
*color
)
505 WMReleaseColor(view
->backColor
);
506 view
->backColor
= WMRetainColor(color
);
508 view
->attribFlags
|= CWBackPixel
;
509 view
->attribs
.background_pixel
= color
->color
.pixel
;
510 if (view
->flags
.realized
) {
511 XSetWindowBackground(view
->screen
->display
, view
->window
,
513 XClearWindow(view
->screen
->display
, view
->window
);
520 W_FocusedViewOfToplevel(W_View
*view
)
522 WMScreen
*scr
= view
->screen
;
525 for (info
= scr
->focusInfo
; info
!=NULL
; info
= info
->next
)
526 if (view
== info
->toplevel
)
532 return info
->focused
;
537 W_SetFocusOfTopLevel(W_View
*toplevel
, W_View
*view
)
539 WMScreen
*scr
= toplevel
->screen
;
543 for (info
= scr
->focusInfo
; info
!=NULL
; info
= info
->next
)
544 if (toplevel
== info
->toplevel
)
548 info
= wmalloc(sizeof(W_FocusInfo
));
549 info
->toplevel
= toplevel
;
550 info
->focused
= view
;
551 info
->next
= scr
->focusInfo
;
552 scr
->focusInfo
= info
;
554 event
.xfocus
.mode
= NotifyNormal
;
555 event
.xfocus
.detail
= NotifyDetailNone
;
557 /* simulate FocusOut event */
558 event
.xfocus
.type
= FocusOut
;
559 W_DispatchMessage(info
->focused
, &event
);
561 info
->focused
= view
;
564 /* simulate FocusIn event */
565 event
.xfocus
.type
= FocusIn
;
566 W_DispatchMessage(view
, &event
);
572 W_BroadcastMessage(W_View
*targetParent
, XEvent
*event
)
576 target
= targetParent
->childrenList
;
577 while (target
!=NULL
) {
578 W_DispatchMessage(target
, event
);
580 target
= target
->nextSister
;
586 W_DispatchMessage(W_View
*target
, XEvent
*event
)
588 if (target
->window
==None
)
590 event
->xclient
.window
= target
->window
;
591 event
->xclient
.display
= target
->screen
->display
;
593 WMHandleEvent(event
);
595 XSendEvent(target->screen->display, target->window, False,
596 SubstructureNotifyMask, event);
603 W_RetainView(WMView
*view
)
612 W_ReleaseView(WMView
*view
)
615 if (view
->refCount
< 1) {
622 WMWidgetOfView(WMView
*view
)
629 WMGetViewSize(WMView
*view
)
635 WMGetViewPosition(WMView
*view
)
642 WMSetViewNotifySizeChanges(WMView
*view
, Bool flag
)
644 view
->flags
.notifySizeChanged
= flag
;
648 WMViewXID(WMView
*view
)
655 WMGetViewScreenPosition(WMView
*view
)
657 WMScreen
*scr
= W_VIEW_SCREEN(view
);
661 XTranslateCoordinates(scr
->display
, W_VIEW_DRAWABLE(view
),
662 scr
->rootWin
, 0, 0, &x
, &y
, &foo
);
664 return wmkpoint(x
, y
);