+#include "efence.h"
+
#include "window.h"
#include "screen.h"
+#include "plugin.h"
+#include "list.h"
#include "display.h"
#include <stdlib.h>
+#include <assert.h>
#include <stdio.h>
#include <xcb/composite.h>
+#include <xcb/damage.h>
typedef struct {
/* public stuff */
int ref;
/* queried things, don't read them directly from the struct */
- int x, y, w, h;
+ int x, y, w, h, bw;
gboolean mapped;
gboolean input_only;
+ xcb_visualid_t visual;
+ xcb_pixmap_t pixmap;
+
+ double opacity;
gboolean zombie;
- int opacity;
+ d_list_t *plugin_data;
- xcb_pixmap_t pixmap;
+ xcb_damage_damage_t damage;
+ gboolean waiting_attr;
xcb_get_window_attributes_cookie_t ck_get_attr;
+ gboolean waiting_geom;
xcb_get_geometry_cookie_t ck_get_geom;
+ gboolean waiting_pixmap;
xcb_void_cookie_t ck_get_pixmap;
} d_window_priv_t;
w->ref = 1;
w->sc = sc;
w->zombie = FALSE;
- w->opacity = WINDOW_OPACITY_MAX;
w->pixmap = XCB_NONE;
+ w->damage = XCB_NONE;
screen_stacking_add(sc, (d_window_t*)w);
w->ck_get_attr = xcb_get_window_attributes(sc->dpy->conn, id);
+ w->waiting_attr = TRUE;
+
w->ck_get_geom = xcb_get_geometry(sc->dpy->conn, id);
+ w->waiting_geom = TRUE;
- w->ck_get_pixmap.sequence = 0;
+ w->waiting_pixmap = FALSE;
+
+ w->plugin_data = list_new();
//printf("new window 0x%x\n", w->id);
w->pixmap = XCB_NONE;
}
+ list_unref(w->plugin_data);
free(w);
}
}
-void
-window_show(d_window_t *pubw)
+static void
+window_update_pixmap(d_window_priv_t *w)
{
- d_window_priv_t *w = (d_window_priv_t*)pubw;
xcb_pixmap_t p;
- if (window_is_mapped(pubw)) return;
-
- printf("show window 0x%x\n", w->id);
+ if (window_is_zombie((d_window_t*)w)) return;
/* XXX can we save it for until we get the new pixmap? */
- if ((p = window_get_pixmap(pubw))) {
+ if ((p = window_get_pixmap((d_window_t*)w))) {
xcb_free_pixmap(w->sc->dpy->conn, p);
w->pixmap = XCB_NONE;
}
- w->mapped = TRUE;
+ //printf("updating pixmap for 0x%x\n", w->id);
+
w->pixmap = xcb_generate_id(w->sc->dpy->conn);
w->ck_get_pixmap =
xcb_composite_name_window_pixmap_checked(w->sc->dpy->conn,
w->id, w->pixmap);
+ w->waiting_pixmap = TRUE;
xcb_flush(w->sc->dpy->conn);
}
void
+window_show(d_window_t *pubw)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
+
+ window_is_mapped(pubw); /* kill any ongoing request */
+ assert(!w->mapped);
+
+ //printf("show window 0x%x\n", w->id);
+
+ window_update_pixmap(w);
+ w->mapped = TRUE;
+}
+
+void
window_hide(d_window_t *pubw)
{
d_window_priv_t *w = (d_window_priv_t*)pubw;
- if (!window_is_mapped(pubw)) return;
+ window_is_mapped(pubw); /* kill any ongoing request */
+ assert(w->mapped);
+
+ //printf("hide window 0x%x\n", w->id);
+
+ w->mapped = FALSE;
+}
- printf("hide window 0x%x\n", w->id);
+void
+window_fake_unmapped(d_window_t *pubw)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
w->mapped = FALSE;
}
window_is_input_only(d_window_t *pubw)
{
d_window_priv_t *w = (d_window_priv_t*)pubw;
- if (w->ck_get_attr.sequence)
+ if (w->waiting_attr)
window_get_attributes_reply(w);
return w->input_only;
}
void
-window_get_area(d_window_t *pubw, int *x, int *y, int *width, int *height)
+window_get_area(d_window_t *pubw, int *x, int *y, int *width, int *height,
+ int *border_width)
{
d_window_priv_t *w = (d_window_priv_t*)pubw;
- if (w->ck_get_geom.sequence)
+ if (w->waiting_geom)
window_get_geometry_reply(w);
*x = w->x;
*y = w->y;
*width = w->w;
*height = w->h;
+ *border_width = w->bw;
}
static void
if (rep) {
w->input_only = rep->_class == XCB_WINDOW_CLASS_INPUT_ONLY;
w->mapped = rep->map_state != XCB_MAP_STATE_UNMAPPED;
+ w->visual = rep->visual;
+ //printf("0x%x attributes mapped %d\n", w->id, w->mapped);
free(rep);
}
else {
w->input_only = TRUE;
w->mapped = FALSE;
+ w->visual = XCB_NONE;
}
if (err) {
printf("error getting attributes for window 0x%x\n", w->id);
free(err);
}
- w->ck_get_attr.sequence = 0;
+ w->waiting_attr = FALSE;
}
static void
if (rep) {
w->x = rep->x;
w->y = rep->y;
- w->w = rep->width + rep->border_width * 2;
- w->h = rep->height + rep->border_width * 2;
+ w->w = rep->width;
+ w->h = rep->height;
+ w->bw = rep->border_width;
free(rep);
}
else {
w->x = w->y = -1;
w->w = w->h = 1;
+ w->bw = 0;
}
if (err) {
printf("error getting geometry for window 0x%x\n", w->id);
free(err);
}
- w->ck_get_geom.sequence = 0;
+ w->waiting_geom = FALSE;
}
gboolean
window_is_mapped(d_window_t *pubw)
{
d_window_priv_t *w = (d_window_priv_t*)pubw;
- if (w->ck_get_attr.sequence)
+ if (w->waiting_attr)
window_get_attributes_reply(w);
return w->mapped;
}
window_get_pixmap(d_window_t *pubw)
{
d_window_priv_t *w = (d_window_priv_t*)pubw;
- if (w->ck_get_pixmap.sequence) {
+
+ if (w->waiting_pixmap) {
xcb_generic_error_t *err;
//printf("** checking get pixmap 0x%x\n", w->id);
err = xcb_request_check(w->sc->dpy->conn, w->ck_get_pixmap);
if (err) {
+ w->pixmap = XCB_NONE;
printf("error getting named pixmap for window 0x%x\n", w->id);
free(err);
}
- w->pixmap = XCB_NONE;
+ w->waiting_pixmap = FALSE;
}
//printf("returning pixmap 0x%x for window 0x%x\n", w->pixmap, w->id);
return w->pixmap;
}
+
+xcb_visualid_t
+window_get_visual(d_window_t *pubw)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
+ if (w->waiting_attr)
+ window_get_attributes_reply(w);
+ return w->visual;
+}
+
+void
+window_configure(d_window_t *pubw, int x, int y, int width, int height,
+ int border_width)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
+
+ /* this overrides any reply from our get_geometry call */
+ if (w->waiting_geom)
+ w->waiting_geom = FALSE;
+ w->x = x;
+ w->y = y;
+ w->w = width;
+ w->h = height;
+ w->bw = border_width;
+}
+
+void
+window_move(d_window_t *w)
+{
+ (void)w;
+}
+
+void
+window_resize(d_window_t *w)
+{
+ window_update_pixmap((d_window_priv_t*)w);
+}
+
+void
+window_add_plugin_data(d_window_t *pubw, int id, void *data)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
+ plugin_data_add(w->plugin_data, id, data);
+}
+
+void*
+window_find_plugin_data(d_window_t *pubw, int id)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
+ return plugin_data_find(w->plugin_data, id);
+}
+
+void
+window_remove_plugin_data(d_window_t *pubw, int id)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
+ plugin_data_remove(w->plugin_data, id);
+}
+
+void
+window_create_damage(d_window_t *pubw)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
+
+ if (!window_is_input_only(pubw)) {
+ assert(w->damage == XCB_NONE);
+ w->damage = xcb_generate_id(w->sc->dpy->conn);
+ //printf("creating damage 0x%x\n", w->damage);
+ xcb_damage_create(w->sc->dpy->conn, w->damage, w->id,
+ XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);
+ }
+}
+
+void window_destroy_damage(d_window_t *pubw)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
+
+ if (w->damage) {
+ //printf("destroying damage 0x%x\n", w->damage);
+ xcb_damage_destroy(w->sc->dpy->conn, w->damage);
+ w->damage = XCB_NONE;
+ }
+}