0 /*
1 * widget.c - general window manager widget
2 */
3
4 /*
5 * Copyright 2006-2007 Johan Veenhuizen
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26 #include <X11/cursorfont.h>
27 #include <X11/Xlib.h>
28 #include <X11/Xresource.h>
29 #include <X11/Xutil.h>
30
31 #include "global.h"
32 #include "widget.h"
33
34 static XContext wmcontext;
35
36 static LIST_DEFINE(repaintlist);
37
38 void widget_init(void)
39 {
40 wmcontext = XUniqueContext();
41 }
42
43 void widget_fini(void)
44 {
45 }
46
47 void create_widget(struct widget *widget, enum widget_type type,
48 Window xparent, unsigned class, int x, int y, int width, int height)
49 {
50 XSetWindowAttributes attr;
51
52 widget->type = type;
53 widget->dim.x = x;
54 widget->dim.y = y;
55 widget->dim.width = width;
56 widget->dim.height = height;
57 widget->event = NULL;
58 widget->mapped = False;
59 attr.override_redirect = True;
60 widget->xwindow = XCreateWindow(display, xparent,
61 x, y, width, height, 0,
62 CopyFromParent,
63 class,
64 CopyFromParent,
65 CWOverrideRedirect, &attr);
66 XSaveContext(display, widget->xwindow, wmcontext, (XPointer)widget);
67 widget->prepare_repaint = NULL;
68 widget->repaint = NULL;
69 LIST_INIT(&widget->repaintlink);
70 }
71
72 void save_widget_context(struct widget *widget, Window xwindow)
73 {
74 clerr();
75 XSaveContext(display, xwindow, wmcontext, (XPointer)widget);
76 sterr();
77 }
78
79 struct widget *find_widget(Window xwindow, enum widget_type type)
80 {
81 struct widget *widget;
82
83 if (XFindContext(display, xwindow, wmcontext,
84 (XPointer *)&widget) == 0)
85 return (type == WIDGET_ANY || widget->type == type) ?
86 widget : NULL;
87 else
88 return NULL;
89 }
90
91 void resize_widget(struct widget *widget, int width, int height)
92 {
93 widget->dim.width = width;
94 widget->dim.height = height;
95 XResizeWindow(display, widget->xwindow, width, height);
96 }
97
98 void move_widget(struct widget *widget, int x, int y)
99 {
100 widget->dim.x = x;
101 widget->dim.y = y;
102 XMoveWindow(display, widget->xwindow, x, y);
103 }
104
105 void moveresize_widget(struct widget *widget, int x, int y,
106 int width, int height)
107 {
108 widget->dim.x = x;
109 widget->dim.y = y;
110 widget->dim.width = width;
111 widget->dim.height = height;
112 XMoveResizeWindow(display, widget->xwindow, x, y, width, height);
113 }
114
115 void map_widget(struct widget *widget)
116 {
117 if (!widget) return;
118 widget->mapped = 1;
119 XMapWindow(display, widget->xwindow);
120 }
121
122 void unmap_widget(struct widget *widget)
123 {
124 widget->mapped = 0;
125 XUnmapWindow(display, widget->xwindow);
126 }
127
128 void destroy_widget(struct widget *widget)
129 {
130 LIST_REMOVE(&widget->repaintlink);
131 XDeleteContext(display, widget->xwindow, wmcontext);
132 XDestroyWindow(display, widget->xwindow);
133 }
134
135 void delete_widget_context(Window xwindow)
136 {
137 XDeleteContext(display, xwindow, wmcontext);
138 }
139
140 void schedule_widget_repaint(struct widget *wp)
141 {
142 if (!wp) return;
143 if (wp->prepare_repaint != NULL)
144 wp->prepare_repaint(wp);
145 if (!LIST_MEMBER(&wp->repaintlink))
146 LIST_INSERT_TAIL(&repaintlist, &wp->repaintlink);
147 }
148
149 void repaint_widgets(void)
150 {
151 struct widget *wp;
152 LIST *lp;
153
154 while (!LIST_EMPTY(&repaintlist)) {
155 lp = LIST_HEAD(&repaintlist);
156 LIST_REMOVE(lp);
157 wp = LIST_ITEM(lp, struct widget, repaintlink);
158 if (wp->repaint != NULL)
159 wp->repaint(wp);
160 }
161 }
162