7 #include <xcb/composite.h>
8 #include <xcb/damage.h>
18 /* queried things, don't read them directly from the struct */
22 xcb_visualid_t visual;
27 GHashTable *plugin_data;
29 xcb_damage_damage_t damage;
31 xcb_get_window_attributes_cookie_t ck_get_attr;
32 xcb_get_geometry_cookie_t ck_get_geom;
33 xcb_void_cookie_t ck_get_pixmap;
36 static void window_get_attributes_reply(d_window_priv_t *w);
37 static void window_get_geometry_reply(d_window_priv_t *w);
40 window_new(xcb_window_t id, struct d_screen *sc)
44 w = malloc(sizeof(d_window_priv_t));
52 screen_stacking_add(sc, (d_window_t*)w);
54 w->ck_get_attr = xcb_get_window_attributes(sc->dpy->conn, id);
55 w->ck_get_geom = xcb_get_geometry(sc->dpy->conn, id);
57 w->ck_get_pixmap.sequence = 0;
59 w->plugin_data = g_hash_table_new_full((GHashFunc)g_str_hash,
60 (GEqualFunc)g_str_equal,
63 //printf("new window 0x%x\n", w->id);
65 return (d_window_t*)w;
69 window_ref(d_window_t *pubw)
71 d_window_priv_t *w = (d_window_priv_t*)pubw;
77 window_unref(d_window_t *pubw)
79 d_window_priv_t *w = (d_window_priv_t*)pubw;
81 if (w && --w->ref == 0) {
84 screen_stacking_remove(w->sc, (d_window_t*)w);
86 if ((p = window_get_pixmap(pubw))) {
87 xcb_free_pixmap(w->sc->dpy->conn, p);
91 g_hash_table_unref(w->plugin_data);
97 window_update_pixmap(d_window_priv_t *w)
101 /* XXX can we save it for until we get the new pixmap? */
102 if ((p = window_get_pixmap((d_window_t*)w))) {
103 xcb_free_pixmap(w->sc->dpy->conn, p);
104 w->pixmap = XCB_NONE;
107 //printf("updating pixmap for 0x%x\n", w->id);
109 w->pixmap = xcb_generate_id(w->sc->dpy->conn);
111 xcb_composite_name_window_pixmap_checked(w->sc->dpy->conn,
113 xcb_flush(w->sc->dpy->conn);
117 window_show(d_window_t *pubw)
119 d_window_priv_t *w = (d_window_priv_t*)pubw;
121 window_is_mapped(pubw); /* kill any ongoing request */
123 printf("show window 0x%x\n", w->id);
125 window_update_pixmap(w);
130 window_hide(d_window_t *pubw)
132 d_window_priv_t *w = (d_window_priv_t*)pubw;
134 window_is_mapped(pubw); /* kill any ongoing request */
136 printf("hide window 0x%x\n", w->id);
142 window_become_zombie(d_window_t *pubw)
144 d_window_priv_t *w = (d_window_priv_t*)pubw;
146 if (w->zombie) return;
152 window_is_zombie(d_window_t *pubw)
154 d_window_priv_t *w = (d_window_priv_t*)pubw;
159 window_is_input_only(d_window_t *pubw)
161 d_window_priv_t *w = (d_window_priv_t*)pubw;
162 if (w->ck_get_attr.sequence)
163 window_get_attributes_reply(w);
164 return w->input_only;
168 window_get_area(d_window_t *pubw, int *x, int *y, int *width, int *height,
171 d_window_priv_t *w = (d_window_priv_t*)pubw;
172 if (w->ck_get_geom.sequence)
173 window_get_geometry_reply(w);
178 *border_width = w->bw;
182 window_get_attributes_reply(d_window_priv_t *w)
184 xcb_get_window_attributes_reply_t *rep;
185 xcb_generic_error_t *err = NULL;
187 rep = xcb_get_window_attributes_reply(w->sc->dpy->conn,
192 w->input_only = rep->_class == XCB_WINDOW_CLASS_INPUT_ONLY;
193 w->mapped = rep->map_state != XCB_MAP_STATE_UNMAPPED;
194 w->visual = rep->visual;
198 w->input_only = TRUE;
200 w->visual = XCB_NONE;
203 printf("error getting attributes for window 0x%x\n", w->id);
206 w->ck_get_attr.sequence = 0;
210 window_get_geometry_reply(d_window_priv_t *w)
212 xcb_get_geometry_reply_t *rep;
213 xcb_generic_error_t *err = NULL;
215 rep = xcb_get_geometry_reply(w->sc->dpy->conn,
224 w->bw = rep->border_width;
233 printf("error getting geometry for window 0x%x\n", w->id);
236 w->ck_get_geom.sequence = 0;
240 window_is_mapped(d_window_t *pubw)
242 d_window_priv_t *w = (d_window_priv_t*)pubw;
243 if (w->ck_get_attr.sequence)
244 window_get_attributes_reply(w);
249 window_get_pixmap(d_window_t *pubw)
251 d_window_priv_t *w = (d_window_priv_t*)pubw;
253 if (w->ck_get_pixmap.sequence) {
254 xcb_generic_error_t *err;
255 //printf("** checking get pixmap 0x%x\n", w->id);
256 err = xcb_request_check(w->sc->dpy->conn, w->ck_get_pixmap);
258 w->pixmap = XCB_NONE;
259 printf("error getting named pixmap for window 0x%x\n", w->id);
262 w->ck_get_pixmap.sequence = 0;
264 //printf("returning pixmap 0x%x for window 0x%x\n", w->pixmap, w->id);
269 window_get_visual(d_window_t *pubw)
271 d_window_priv_t *w = (d_window_priv_t*)pubw;
272 if (w->ck_get_attr.sequence)
273 window_get_attributes_reply(w);
278 window_configure(d_window_t *pubw, int x, int y, int width, int height,
281 d_window_priv_t *w = (d_window_priv_t*)pubw;
283 /* this overrides any reply from our get_geometry call */
284 if (w->ck_get_geom.sequence)
285 w->ck_get_geom.sequence = 0;
290 w->bw = border_width;
294 window_reconfigure(d_window_t *w)
296 window_update_pixmap((d_window_priv_t*)w);
300 window_add_plugin_data(d_window_t *pubw, const char *key, void *data)
302 d_window_priv_t *w = (d_window_priv_t*)pubw;
303 char *skey = g_strdup(key);
304 g_hash_table_replace(w->plugin_data, skey, data);
308 window_find_plugin_data(d_window_t *pubw, const char *key)
310 d_window_priv_t *w = (d_window_priv_t*)pubw;
311 return g_hash_table_lookup(w->plugin_data, key);
315 window_remove_plugin_data(d_window_t *pubw, const char *key)
317 d_window_priv_t *w = (d_window_priv_t*)pubw;
318 g_hash_table_remove(w->plugin_data, key);
322 window_create_damage(d_window_t *pubw)
324 d_window_priv_t *w = (d_window_priv_t*)pubw;
326 if (!window_is_input_only(pubw)) {
327 assert(w->damage == XCB_NONE);
328 w->damage = xcb_generate_id(w->sc->dpy->conn);
329 xcb_damage_create(w->sc->dpy->conn, w->damage, w->id,
330 XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);
334 void window_destroy_damage(d_window_t *pubw)
336 d_window_priv_t *w = (d_window_priv_t*)pubw;
339 xcb_damage_destroy(w->sc->dpy->conn, w->damage);
340 w->damage = XCB_NONE;