11 #include <xcb/composite.h>
12 #include <xcb/damage.h>
22 /* queried things, don't read them directly from the struct */
26 xcb_visualid_t visual;
34 d_list_t *plugin_data;
36 xcb_damage_damage_t damage;
38 gboolean waiting_attr;
39 xcb_get_window_attributes_cookie_t ck_get_attr;
40 gboolean waiting_geom;
41 xcb_get_geometry_cookie_t ck_get_geom;
44 static void window_get_attributes_reply(d_window_priv_t *w);
45 static void window_get_geometry_reply(d_window_priv_t *w);
48 window_new(xcb_window_t id, struct d_screen *sc)
52 w = malloc(sizeof(d_window_priv_t));
61 screen_stacking_add(sc, (d_window_t*)w);
63 w->ck_get_attr = xcb_get_window_attributes(sc->dpy->conn, id);
64 w->waiting_attr = TRUE;
66 w->ck_get_geom = xcb_get_geometry(sc->dpy->conn, id);
67 w->waiting_geom = TRUE;
69 w->plugin_data = list_new();
71 //printf("new window 0x%x\n", w->id);
73 return (d_window_t*)w;
77 window_ref(d_window_t *pubw)
79 d_window_priv_t *w = (d_window_priv_t*)pubw;
85 window_unref(d_window_t *pubw)
87 d_window_priv_t *w = (d_window_priv_t*)pubw;
89 if (w && --w->ref == 0) {
90 screen_stacking_remove(w->sc, (d_window_t*)w);
93 /* this may cause an error if the pixmap was never valid, but
95 xcb_free_pixmap(w->sc->dpy->conn, w->pixmap);
99 list_unref(w->plugin_data);
105 window_get_pixmap(d_window_t *pubw)
107 d_window_priv_t *w = (d_window_priv_t*)pubw;
114 window_update_pixmap(d_window_priv_t *w)
116 if (window_is_zombie((d_window_t*)w)) return;
118 /* the pixmap may not be valid even though it is non-zero, but
119 we can free it anyways and let it fail. we don't need to wait
120 for a response from the server */
122 xcb_free_pixmap(w->sc->dpy->conn, w->pixmap);
123 w->pixmap = XCB_NONE;
126 //printf("updating pixmap for 0x%x\n", w->id);
128 /* we don't check the result of this call, because it seems that sometimes
129 the X server just doesn't reply. if we check it, we end up hanging
130 sometimes waiting for the reply */
131 w->pixmap = xcb_generate_id(w->sc->dpy->conn);
132 xcb_composite_name_window_pixmap(w->sc->dpy->conn, w->id, w->pixmap);
133 //printf("requested pixmap sequence %u\n", w->ck_get_pixmap.sequence);
135 xcb_flush(w->sc->dpy->conn);
139 window_show(d_window_t *pubw)
141 d_window_priv_t *w = (d_window_priv_t*)pubw;
145 //printf("show window 0x%x\n", w->id);
147 window_update_pixmap(w);
152 window_hide(d_window_t *pubw)
154 d_window_priv_t *w = (d_window_priv_t*)pubw;
158 //printf("hide window 0x%x\n", w->id);
164 window_fake_unmapped(d_window_t *pubw)
166 d_window_priv_t *w = (d_window_priv_t*)pubw;
172 window_become_zombie(d_window_t *pubw)
174 d_window_priv_t *w = (d_window_priv_t*)pubw;
176 if (w->zombie) return;
182 window_is_zombie(d_window_t *pubw)
184 d_window_priv_t *w = (d_window_priv_t*)pubw;
189 window_is_input_only(d_window_t *pubw)
191 d_window_priv_t *w = (d_window_priv_t*)pubw;
193 window_get_attributes_reply(w);
194 return w->input_only;
198 window_get_area(d_window_t *pubw, int *x, int *y, int *width, int *height,
201 d_window_priv_t *w = (d_window_priv_t*)pubw;
203 window_get_geometry_reply(w);
208 *border_width = w->bw;
212 window_get_attributes_reply(d_window_priv_t *w)
214 xcb_get_window_attributes_reply_t *rep;
215 xcb_generic_error_t *err = NULL;
217 rep = xcb_get_window_attributes_reply(w->sc->dpy->conn,
222 w->input_only = rep->_class == XCB_WINDOW_CLASS_INPUT_ONLY;
223 w->attr_mapped = rep->map_state != XCB_MAP_STATE_UNMAPPED;
224 w->visual = rep->visual;
225 //printf("0x%x attributes mapped %d\n", w->id, w->mapped);
229 w->input_only = TRUE;
230 w->attr_mapped = FALSE;
231 w->visual = XCB_NONE;
234 printf("error getting attributes for window 0x%x\n", w->id);
237 w->waiting_attr = FALSE;
241 window_get_geometry_reply(d_window_priv_t *w)
243 xcb_get_geometry_reply_t *rep;
244 xcb_generic_error_t *err = NULL;
246 rep = xcb_get_geometry_reply(w->sc->dpy->conn,
255 w->bw = rep->border_width;
264 printf("error getting geometry for window 0x%x\n", w->id);
267 w->waiting_geom = FALSE;
271 window_is_mapped(d_window_t *pubw)
273 d_window_priv_t *w = (d_window_priv_t*)pubw;
278 window_is_attr_mapped(d_window_t *pubw)
280 d_window_priv_t *w = (d_window_priv_t*)pubw;
282 window_get_attributes_reply(w);
283 return w->attr_mapped;
287 window_get_visual(d_window_t *pubw)
289 d_window_priv_t *w = (d_window_priv_t*)pubw;
291 window_get_attributes_reply(w);
296 window_configure(d_window_t *pubw, int x, int y, int width, int height,
299 d_window_priv_t *w = (d_window_priv_t*)pubw;
301 /* this overrides any reply from our get_geometry call */
303 w->waiting_geom = FALSE;
308 w->bw = border_width;
312 window_move(d_window_t *w)
318 window_resize(d_window_t *w)
320 window_update_pixmap((d_window_priv_t*)w);
324 window_add_plugin_data(d_window_t *pubw, int id, void *data)
326 d_window_priv_t *w = (d_window_priv_t*)pubw;
327 plugin_data_add(w->plugin_data, id, data);
331 window_find_plugin_data(d_window_t *pubw, int id)
333 d_window_priv_t *w = (d_window_priv_t*)pubw;
334 return plugin_data_find(w->plugin_data, id);
338 window_remove_plugin_data(d_window_t *pubw, int id)
340 d_window_priv_t *w = (d_window_priv_t*)pubw;
341 plugin_data_remove(w->plugin_data, id);
345 window_create_damage(d_window_t *pubw)
347 d_window_priv_t *w = (d_window_priv_t*)pubw;
349 if (!window_is_input_only(pubw)) {
350 assert(w->damage == XCB_NONE);
351 w->damage = xcb_generate_id(w->sc->dpy->conn);
352 //printf("creating damage 0x%x\n", w->damage);
353 xcb_damage_create(w->sc->dpy->conn, w->damage, w->id,
354 XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);
358 void window_destroy_damage(d_window_t *pubw)
360 d_window_priv_t *w = (d_window_priv_t*)pubw;
363 //printf("destroying damage 0x%x\n", w->damage);
364 xcb_damage_destroy(w->sc->dpy->conn, w->damage);
365 w->damage = XCB_NONE;