]> Dogcows Code - chaz/openbox/blob - openbox/popup.c
dont need client.h in this header
[chaz/openbox] / openbox / popup.c
1 #include "openbox.h"
2 #include "frame.h"
3 #include "client.h"
4 #include "window.h"
5 #include "stacking.h"
6 #include "render/render.h"
7 #include "render/theme.h"
8
9 typedef struct Popup {
10 ObWindow obwin;
11 Window bg;
12
13 Window icon;
14 Window text;
15
16 gboolean hasicon;
17 RrAppearance *a_bg;
18 RrAppearance *a_icon;
19 RrAppearance *a_text;
20 int gravity;
21 int x;
22 int y;
23 int w;
24 int h;
25 gboolean mapped;
26 } Popup;
27
28 Popup *popup_new(gboolean hasicon)
29 {
30 XSetWindowAttributes attrib;
31 Popup *self = g_new(Popup, 1);
32
33 self->obwin.type = Window_Internal;
34 self->hasicon = hasicon;
35 self->a_text = NULL;
36 self->gravity = NorthWestGravity;
37 self->x = self->y = self->w = self->h = 0;
38 self->mapped = FALSE;
39 self->a_bg = self->a_icon = self->a_text = NULL;
40
41 attrib.override_redirect = True;
42 self->bg = XCreateWindow(ob_display, ob_root,
43 0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
44 InputOutput, RrVisual(ob_rr_inst),
45 CWOverrideRedirect, &attrib);
46
47 self->text = XCreateWindow(ob_display, self->bg,
48 0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
49 InputOutput, RrVisual(ob_rr_inst), 0, NULL);
50
51 if (self->hasicon)
52 self->icon = XCreateWindow(ob_display, self->bg,
53 0, 0, 1, 1, 0,
54 RrDepth(ob_rr_inst), InputOutput,
55 RrVisual(ob_rr_inst), 0, NULL);
56
57 XMapWindow(ob_display, self->text);
58 XMapWindow(ob_display, self->icon);
59
60 stacking_add(INTERNAL_AS_WINDOW(self));
61 return self;
62 }
63
64 void popup_free(Popup *self)
65 {
66 if (self) {
67 XDestroyWindow(ob_display, self->bg);
68 XDestroyWindow(ob_display, self->text);
69 XDestroyWindow(ob_display, self->icon);
70 RrAppearanceFree(self->a_bg);
71 RrAppearanceFree(self->a_icon);
72 RrAppearanceFree(self->a_text);
73 stacking_remove(self);
74 g_free(self);
75 }
76 }
77
78 void popup_position(Popup *self, int gravity, int x, int y)
79 {
80 self->gravity = gravity;
81 self->x = x;
82 self->y = y;
83 }
84
85 void popup_size(Popup *self, int w, int h)
86 {
87 self->w = w;
88 self->h = h;
89 }
90
91 void popup_size_to_string(Popup *self, char *text)
92 {
93 int textw, texth;
94 int iconw;
95
96 if (!self->a_text)
97 self->a_text = RrAppearanceCopy(ob_rr_theme->app_hilite_label);
98
99 self->a_text->texture[0].data.text.string = text;
100 RrMinsize(self->a_text, &textw, &texth);
101 textw += ob_rr_theme->bevel * 2;
102 texth += ob_rr_theme->bevel * 2;
103
104 self->h = texth + ob_rr_theme->bevel * 2;
105 iconw = (self->hasicon ? texth : 0);
106 self->w = textw + iconw + ob_rr_theme->bevel * (self->hasicon ? 3 : 2);
107 }
108
109 void popup_show(Popup *self, char *text, ObClientIcon *icon)
110 {
111 int x, y, w, h;
112 int textw, texth;
113 int iconw;
114
115 /* create the shit if needed */
116 if (!self->a_bg)
117 self->a_bg = RrAppearanceCopy(ob_rr_theme->app_hilite_bg);
118 if (self->hasicon && !self->a_icon)
119 self->a_icon = RrAppearanceCopy(ob_rr_theme->app_icon);
120 if (!self->a_text)
121 self->a_text = RrAppearanceCopy(ob_rr_theme->app_hilite_label);
122
123 XSetWindowBorderWidth(ob_display, self->bg, ob_rr_theme->bwidth);
124 XSetWindowBorder(ob_display, self->bg, ob_rr_theme->b_color->pixel);
125
126 /* set up the textures */
127 self->a_text->texture[0].data.text.string = text;
128 if (self->hasicon) {
129 if (icon) {
130 self->a_icon->texture[0].type = RR_TEXTURE_RGBA;
131 self->a_icon->texture[0].data.rgba.width = icon->width;
132 self->a_icon->texture[0].data.rgba.height = icon->height;
133 self->a_icon->texture[0].data.rgba.data = icon->data;
134 } else
135 self->a_icon->texture[0].type = RR_TEXTURE_NONE;
136 }
137
138 /* measure the shit out */
139 RrMinsize(self->a_text, &textw, &texth);
140 textw += ob_rr_theme->bevel * 2;
141 texth += ob_rr_theme->bevel * 2;
142
143 /* set the sizes up and reget the text sizes from the calculated
144 outer sizes */
145 if (self->h) {
146 h = self->h;
147 texth = h - (ob_rr_theme->bevel * 2);
148 } else
149 h = texth + ob_rr_theme->bevel * 2;
150 iconw = (self->hasicon ? texth : 0);
151 if (self->w) {
152 w = self->w;
153 textw = w - (iconw + ob_rr_theme->bevel * (self->hasicon ? 3 : 2));
154 } else
155 w = textw + iconw + ob_rr_theme->bevel * (self->hasicon ? 3 : 2);
156 /* sanity checks to avoid crashes! */
157 if (w < 1) w = 1;
158 if (h < 1) h = 1;
159 if (textw < 1) textw = 1;
160 if (texth < 1) texth = 1;
161
162 /* set up the x coord */
163 x = self->x;
164 switch (self->gravity) {
165 case NorthGravity:
166 case CenterGravity:
167 case SouthGravity:
168 x -= w / 2;
169 break;
170 case NorthEastGravity:
171 case EastGravity:
172 case SouthEastGravity:
173 x -= w;
174 break;
175 }
176
177 /* set up the y coord */
178 y = self->y;
179 switch (self->gravity) {
180 case WestGravity:
181 case CenterGravity:
182 case EastGravity:
183 y -= h / 2;
184 break;
185 case SouthWestGravity:
186 case SouthGravity:
187 case SouthEastGravity:
188 y -= h;
189 break;
190 }
191
192 /* set the windows/appearances up */
193 XMoveResizeWindow(ob_display, self->bg, x, y, w, h);
194
195 self->a_text->surface.parent = self->a_bg;
196 self->a_text->surface.parentx = iconw +
197 ob_rr_theme->bevel * (self->hasicon ? 2 : 1);
198 self->a_text->surface.parenty = ob_rr_theme->bevel;
199 XMoveResizeWindow(ob_display, self->text,
200 iconw + ob_rr_theme->bevel * (self->hasicon ? 2 : 1),
201 ob_rr_theme->bevel, textw, texth);
202
203 if (self->hasicon) {
204 if (iconw < 1) iconw = 1; /* sanity check for crashes */
205 self->a_icon->surface.parent = self->a_bg;
206 self->a_icon->surface.parentx = ob_rr_theme->bevel;
207 self->a_icon->surface.parenty = ob_rr_theme->bevel;
208 XMoveResizeWindow(ob_display, self->icon,
209 ob_rr_theme->bevel, ob_rr_theme->bevel,
210 iconw, texth);
211 }
212
213 RrPaint(self->a_bg, self->bg, w, h);
214 RrPaint(self->a_text, self->text, textw, texth);
215 if (self->hasicon)
216 RrPaint(self->a_icon, self->icon, iconw, texth);
217
218 if (!self->mapped) {
219 XMapWindow(ob_display, self->bg);
220 stacking_raise(INTERNAL_AS_WINDOW(self));
221 self->mapped = TRUE;
222 }
223 }
224
225 void popup_hide(Popup *self)
226 {
227 if (self->mapped) {
228 XUnmapWindow(ob_display, self->bg);
229 self->mapped = FALSE;
230 }
231 }
This page took 0.041603 seconds and 4 git commands to generate.