From e85c3335254928debb87426febef8204d225173f Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 4 Mar 2008 21:14:10 -0500 Subject: [PATCH] get attributes/geometry/pixmap for windows --- dcompmgr.c | 19 ++++- display.c | 1 + render.c | 25 +++++++ screen.c | 1 + window.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++++---- window.h | 14 ++-- 6 files changed, 238 insertions(+), 23 deletions(-) diff --git a/dcompmgr.c b/dcompmgr.c index c20025a..26363c4 100644 --- a/dcompmgr.c +++ b/dcompmgr.c @@ -29,7 +29,7 @@ event(d_display_t *dpy) xcb_generic_event_t *ev; while ((ev = xcb_poll_for_event(dpy->conn))) { - printf("event %d\n", ev->response_type); + //printf("event %d\n", ev->response_type); if (!ev->response_type) { display_error(dpy, (xcb_generic_error_t*)ev); @@ -181,11 +181,11 @@ run(d_display_t *dpy) if (r < 0) printf("select error\n"); else if (r == 0) { - printf("select timeout\n"); + //printf("select timeout\n"); paint(dpy); } else { - printf("select data\n"); + //printf("select data\n"); /*if (FD_ISSET(dpy->fd, &fds))*/ { event(dpy); } @@ -274,6 +274,19 @@ main(int argc, char **argv) setup_functions(dpy); + { + /* some of the windows may already be visible */ + d_list_it_t *sc_it; + + for (sc_it = list_top(dpy->screens); sc_it; sc_it = sc_it->next) { + d_screen_t *sc = sc_it->data; + d_list_it_t *it; + for (it = list_top(sc->stacking); it; it = it->next) + if (window_is_mapped(it->data)) + sc->window_show(it->data); + } + } + run(dpy); cleanup_functions(dpy); diff --git a/display.c b/display.c index ef2ba70..99d154c 100644 --- a/display.c +++ b/display.c @@ -246,6 +246,7 @@ display_error(d_display_t *dpy, xcb_generic_error_t *ev) default: break; } + req = NULL; if (major_opcode <= 127) switch (major_opcode) { case 1: req = "CreateWindow"; break; diff --git a/render.c b/render.c index 1843cc4..5aafc6e 100644 --- a/render.c +++ b/render.c @@ -1,5 +1,7 @@ #include "render.h" #include "screen.h" +#include "window.h" +#include "list.h" #include #include #include @@ -11,6 +13,8 @@ typedef struct { } data_t; static void render_paint_screen(d_screen_t *sc); +static void paint_root(d_screen_t *sc); +static void paint_window(d_window_t *window); void render_init(d_screen_t *sc) @@ -33,9 +37,30 @@ static void render_paint_screen(d_screen_t *sc) { data_t *d = screen_find_plugin_data(sc, PLUGIN_NAME); + d_list_it_t *it; printf("-- painting --\n"); + paint_root(sc); + for (it = list_bottom(sc->stacking); it; it = it->prev) + paint_window(it->data); /* call the function we replaced in the chain */ d->screen_paint(sc); } + +static void +paint_root(d_screen_t *sc) +{ + int w, h; + + w = sc->super.width_in_pixels; + h = sc->super.height_in_pixels; + + //printf("-- paint root 0x%x --\n", sc->super.root); +} + +static void +paint_window(d_window_t *w) +{ + //printf("-- paint window 0x%x --\n", w->id); +} diff --git a/screen.c b/screen.c index f86f719..9ea9cca 100644 --- a/screen.c +++ b/screen.c @@ -126,6 +126,7 @@ screen_register(d_screen_t *sc) xcb_ungrab_server(sc->dpy->conn); xcb_flush(sc->dpy->conn); + return ret; } diff --git a/window.c b/window.c index 9ba6bfd..658d10f 100644 --- a/window.c +++ b/window.c @@ -1,57 +1,119 @@ #include "window.h" #include "screen.h" +#include "display.h" #include #include +#include + +typedef struct { + /* public stuff */ + xcb_window_t id; + struct d_screen *sc; + + /* private stuff */ + int ref; + + /* queried things, don't read them directly from the struct */ + int x, y, w, h; + gboolean mapped; + gboolean input_only; + + gboolean zombie; + + int opacity; + + xcb_pixmap_t pixmap; + + xcb_get_window_attributes_cookie_t ck_get_attr; + xcb_get_geometry_cookie_t ck_get_geom; + xcb_void_cookie_t ck_get_pixmap; +} d_window_priv_t; + +static void window_get_attributes_reply(d_window_priv_t *w); +static void window_get_geometry_reply(d_window_priv_t *w); d_window_t* window_new(xcb_window_t id, struct d_screen *sc) { - d_window_t *w; + d_window_priv_t *w; - w = malloc(sizeof(d_window_t)); + w = malloc(sizeof(d_window_priv_t)); w->id = id; w->ref = 1; w->sc = sc; - w->mapped = FALSE; w->zombie = FALSE; w->opacity = WINDOW_OPACITY_MAX; + w->pixmap = XCB_NONE; + + screen_stacking_add(sc, (d_window_t*)w); + + w->ck_get_attr = xcb_get_window_attributes(sc->dpy->conn, id); + w->ck_get_geom = xcb_get_geometry(sc->dpy->conn, id); - screen_stacking_add(sc, w); + w->ck_get_pixmap.sequence = 0; - printf("new window 0x%x\n", w->id); + //printf("new window 0x%x\n", w->id); - return w; + return (d_window_t*)w; } void -window_ref(d_window_t *w) +window_ref(d_window_t *pubw) { + d_window_priv_t *w = (d_window_priv_t*)pubw; + ++w->ref; } void -window_unref(d_window_t *w) +window_unref(d_window_t *pubw) { + d_window_priv_t *w = (d_window_priv_t*)pubw; + if (w && --w->ref == 0) { - screen_stacking_remove(w->sc, w); + xcb_pixmap_t p; + + screen_stacking_remove(w->sc, (d_window_t*)w); + + if ((p = window_get_pixmap(pubw))) { + xcb_free_pixmap(w->sc->dpy->conn, p); + w->pixmap = XCB_NONE; + } + free(w); } } void -window_show(d_window_t *w) +window_show(d_window_t *pubw) { - if (w->mapped) return; + 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); + /* XXX can we save it for until we get the new pixmap? */ + if ((p = window_get_pixmap(pubw))) { + xcb_free_pixmap(w->sc->dpy->conn, p); + w->pixmap = XCB_NONE; + } + w->mapped = TRUE; + 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); + xcb_flush(w->sc->dpy->conn); } void -window_hide(d_window_t *w) +window_hide(d_window_t *pubw) { - if (!w->mapped) return; + d_window_priv_t *w = (d_window_priv_t*)pubw; + + if (!window_is_mapped(pubw)) return; printf("hide window 0x%x\n", w->id); @@ -59,9 +121,120 @@ window_hide(d_window_t *w) } void -window_become_zombie(d_window_t *w) +window_become_zombie(d_window_t *pubw) { + d_window_priv_t *w = (d_window_priv_t*)pubw; + if (w->zombie) return; w->zombie = TRUE; } + +gboolean +window_is_zombie(d_window_t *pubw) +{ + d_window_priv_t *w = (d_window_priv_t*)pubw; + return w->zombie; +} + +gboolean +window_is_input_only(d_window_t *pubw) +{ + d_window_priv_t *w = (d_window_priv_t*)pubw; + if (w->ck_get_attr.sequence) + 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) +{ + d_window_priv_t *w = (d_window_priv_t*)pubw; + if (w->ck_get_geom.sequence) + window_get_geometry_reply(w); + *x = w->x; + *y = w->y; + *width = w->w; + *height = w->h; +} + +static void +window_get_attributes_reply(d_window_priv_t *w) +{ + xcb_get_window_attributes_reply_t *rep; + xcb_generic_error_t *err = NULL; + + rep = xcb_get_window_attributes_reply(w->sc->dpy->conn, + w->ck_get_attr, + &err); + + if (rep) { + w->input_only = rep->_class == XCB_WINDOW_CLASS_INPUT_ONLY; + w->mapped = rep->map_state != XCB_MAP_STATE_UNMAPPED; + free(rep); + } + else { + w->input_only = TRUE; + w->mapped = FALSE; + } + if (err) { + printf("error getting attributes for window 0x%x\n", w->id); + free(err); + } + w->ck_get_attr.sequence = 0; +} + +static void +window_get_geometry_reply(d_window_priv_t *w) +{ + xcb_get_geometry_reply_t *rep; + xcb_generic_error_t *err = NULL; + + rep = xcb_get_geometry_reply(w->sc->dpy->conn, + w->ck_get_geom, + &err); + + 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; + free(rep); + } + else { + w->x = w->y = -1; + w->w = w->h = 1; + } + if (err) { + printf("error getting geometry for window 0x%x\n", w->id); + free(err); + } + w->ck_get_geom.sequence = 0; +} + +gboolean +window_is_mapped(d_window_t *pubw) +{ + d_window_priv_t *w = (d_window_priv_t*)pubw; + if (w->ck_get_attr.sequence) + window_get_attributes_reply(w); + return w->mapped; +} + +xcb_pixmap_t +window_get_pixmap(d_window_t *pubw) +{ + d_window_priv_t *w = (d_window_priv_t*)pubw; + if (w->ck_get_pixmap.sequence) { + 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) { + printf("error getting named pixmap for window 0x%x\n", w->id); + free(err); + } + w->pixmap = XCB_NONE; + } + //printf("returning pixmap 0x%x for window 0x%x\n", w->pixmap, w->id); + return w->pixmap; +} diff --git a/window.h b/window.h index 07e80dc..c0484cb 100644 --- a/window.h +++ b/window.h @@ -11,13 +11,7 @@ struct d_screen; typedef struct d_window { xcb_window_t id; - int ref; struct d_screen *sc; - - gboolean mapped; - gboolean zombie; - - int opacity; } d_window_t; d_window_t* window_new(xcb_window_t id, struct d_screen *sc); @@ -30,4 +24,12 @@ void window_hide(d_window_t *w); void window_become_zombie(d_window_t *w); +gboolean window_is_zombie(d_window_t *w); +gboolean window_is_input_only(d_window_t *w); +gboolean window_is_mapped(d_window_t *w); + +void window_get_area(d_window_t *w, int *x, int *y, int *width, int *height); + +xcb_pixmap_t window_get_pixmap(d_window_t *w); + #endif -- 2.34.1