get attributes/geometry/pixmap for windows
authorDana Jansens <danakj@orodu.net>
Wed, 5 Mar 2008 02:14:10 +0000 (21:14 -0500)
committerDana Jansens <danakj@orodu.net>
Wed, 5 Mar 2008 02:15:59 +0000 (21:15 -0500)
dcompmgr.c
display.c
render.c
screen.c
window.c
window.h

index c20025a..26363c4 100644 (file)
@@ -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);
index ef2ba70..99d154c 100644 (file)
--- 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;
index 1843cc4..5aafc6e 100644 (file)
--- a/render.c
+++ b/render.c
@@ -1,5 +1,7 @@
 #include "render.h"
 #include "screen.h"
+#include "window.h"
+#include "list.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <xcb/render.h>
@@ -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);
+}
index f86f719..9ea9cca 100644 (file)
--- 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;
 }
 
index 9ba6bfd..658d10f 100644 (file)
--- a/window.c
+++ b/window.c
 #include "window.h"
 #include "screen.h"
+#include "display.h"
 #include <stdlib.h>
 #include <stdio.h>
+#include <xcb/composite.h>
+
+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;
+}
index 07e80dc..c0484cb 100644 (file)
--- 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