#include <stdlib.h>
#include <string.h>
#include <xcb/xcb.h>
+#include <xcb/damage.h>
typedef struct {
int foo;
xcb_configure_notify_event_t *cev;
d_screen_t *sc;
d_window_t *w, *above;
+ int x, y, width, height, bwidth;
cev = (xcb_configure_notify_event_t*)ev;
sc = display_screen_from_root(dpy, cev->event);
if (!sc) break;
w = screen_find_window(sc, cev->window);
- sc->window_configure(w, cev->x, cev->y,
- cev->width, cev->height, cev->border_width);
+ window_get_area(w, &x, &y, &width, &height, &bwidth);
+ if (x != cev->x || y != cev->y || width != cev->width ||
+ height != cev->height || bwidth != cev->border_width)
+ {
+ window_configure(w, cev->x, cev->y,
+ cev->width, cev->height,
+ cev->border_width);
+ if (window_is_mapped(w))
+ sc->window_reconfigure(w);
+ }
above = screen_find_window(sc, cev->above_sibling);
screen_stacking_move_above(sc, w, above);
screen_refresh(w->sc);
break;
}
default:
+ if (ev->response_type - dpy->damage.event == XCB_DAMAGE_NOTIFY) {
+ xcb_damage_notify_event_t *dev;
+ d_list_it_t *it;
+
+ dev = (xcb_damage_notify_event_t*)ev;
+ for (it = list_top(dpy->screens); it; it = it->next) {
+ d_screen_t *sc = it->data;
+ d_window_t *w;
+
+ w = screen_find_window(sc, dev->drawable);
+ if (w) {
+ screen_refresh(w->sc);
+ break;
+ }
+ }
+ xcb_damage_subtract(dpy->conn, dev->damage,
+ XCB_NONE, XCB_NONE);
+ }
break;
}
free(ev);
+ xcb_flush(dpy->conn);
}
}
{
gboolean quit;
- paint(dpy);
-
quit = FALSE;
while (!quit) {
struct timeval next, now, *wait;
d_list_it_t *it;
fd_set fds;
+ event(dpy);
+
npaint = 0;
for (it = list_top(dpy->screens); it; it = it->next) {
d_screen_t *sc = it->data;
FD_ZERO(&fds);
FD_SET(dpy->fd, &fds);
+ //printf("select %d\n", npaint);
+
r = select(dpy->fd+1, &fds, NULL, NULL, wait);
if (r < 0)
printf("select error\n");
else if (r == 0) {
//printf("select timeout\n");
paint(dpy);
- }
- else {
- //printf("select data\n");
- /*if (FD_ISSET(dpy->fd, &fds))*/ {
- event(dpy);
- }
+ xcb_flush(dpy->conn);
}
if (xcb_connection_has_error(dpy->conn))
quit = TRUE;
- else
- xcb_flush(dpy->conn);
}
}
rep = xcb_get_extension_data(dpy->conn, &xcb_##name##_id); \
\
ext = find_extension_##name(dpy) \
- ext->present = rep && rep->present; \
- ext->error = rep && rep->first_error; \
- ext->event = rep && rep->first_event; \
- ext->opcode = rep && rep->major_opcode; \
+ ext->present = rep && rep->present; \
+ ext->error = rep ? rep->first_error : 0; \
+ ext->event = rep ? rep->first_event : 0; \
+ ext->opcode = rep ? rep->major_opcode : 0; \
\
if (ext->present) \
ck_##name = xcb_##name##_query_version(dpy->conn, \
case 72: req = "PutImage"; break;
default: break;
}
+ else if (major_opcode == dpy->damage.opcode)
+ switch (minor_opcode)
+ {
+ case 0: req = "DamageQueryVersion"; break;
+ case 1: req = "DamageCreate"; break;
+ case 2: req = "DamageDestroy"; break;
+ case 3: req = "DamageSubtract"; break;
+ default: break;
+ }
+ else if (major_opcode == dpy->render.opcode)
+ switch (minor_opcode)
+ {
+ case 0: req = "RenderQueryVersion"; break;
+ case 1: req = "RenderQueryPictFormats"; break;
+ case 2: req = "RenderQueryPictIndexValues"; break;
+ case 4: req = "RenderCreatePicture"; break;
+ case 5: req = "RenderChangePicture"; break;
+ case 6: req = "RenderSetPictureClipRectangles"; break;
+ case 7: req = "RenderFreePicture"; break;
+ case 8: req = "RenderComposite"; break;
+ case 10: req = "RenderCompositeTrapezoids"; break;
+ case 11: req = "RenderCompositeTriangles"; break;
+ case 12: req = "RenderCompositeTriStrip"; break;
+ case 13: req = "RenderCompositeTriFan"; break;
+ case 17: req = "RenderCreateGlyphSet"; break;
+ case 18: req = "RenderReferenceGlyphSet"; break;
+ case 19: req = "RenderFreeGlyphSet"; break;
+ case 20: req = "RenderAddGlyphs"; break;
+ case 22: req = "RenderFreeGlyphs"; break;
+ case 23: req = "RenderCompositeGlyphs8"; break;
+ case 24: req = "RenderCompositeGlyphs16"; break;
+ case 25: req = "RenderCompositeGlyphs32"; break;
+ case 26: req = "RenderFillRectangles"; break;
+ case 27: req = "RenderCreateCursor"; break;
+ case 28: req = "RenderSetPictureTransform"; break;
+ case 29: req = "RenderQueryFilters"; break;
+ case 30: req = "RenderSetPictureFilter"; break;
+ case 31: req = "RenderCreateAnimCursor"; break;
+ case 32: req = "RenderAddTraps"; break;
+ case 33: req = "RenderCreateSolidFill"; break;
+ case 34: req = "RenderLinearGradient"; break;
+ case 35: req = "RenderRadialGradient"; break;
+ case 36: req = "RenderConicalGradient"; break;
+ default: break;
+ }
+ else if (major_opcode == dpy->composite.opcode)
+ switch (minor_opcode)
+ {
+ case 0: req = "CompositeQueryVersion"; break;
+ case 1: req = "CompositeRedirectWindow"; break;
+ case 2: req = "CompositeRedirectSubwindows"; break;
+ case 3: req = "CompositeUnredirectWindow"; break;
+ case 4: req = "CompositeUnredirectSubwindows"; break;
+ case 5: req = "CompositeCreateRegionFromBorderClip"; break;
+ case 6: req = "CompositeNameWindowPixmap"; break;
+ case 7: req = "CompositeGetOverlayWindow"; break;
+ case 8: req = "CompositeReleaseOverlayWindow"; break;
+ default: break;
+ }
if (name && req)
printf("XError: %s %s!\n",
printf("XError: code %d major opcode %d minor opcode %d!\n",
ev->error_code, major_opcode, minor_opcode);
- abort();
+ //abort();
}
int
#include "render.h"
#include "screen.h"
#include "window.h"
+#include "display.h"
#include "list.h"
#include <stdio.h>
#include <stdlib.h>
typedef struct {
void (*screen_paint)(d_screen_t *sc);
+ void (*window_show)(d_window_t *w);
+ void (*window_hide)(d_window_t *w);
+ void (*window_reconfigure)(d_window_t *w);
+
+ xcb_render_query_pict_formats_reply_t *pict_formats;
+ xcb_render_picture_t overlay_picture;
+ xcb_render_picture_t overlay_buffer;
+ xcb_render_picture_t solid_bg;
} data_t;
-static void render_paint_screen(d_screen_t *sc);
-static void paint_root(d_screen_t *sc);
+typedef struct {
+ xcb_render_picture_t picture;
+ xcb_void_cookie_t ck_picture;
+} window_data_t;
+
+static void render_screen_paint(d_screen_t *sc);
+static void paint_root(d_screen_t *sc, data_t *d);
static void paint_window(d_window_t *window);
+static void render_update_picture(d_window_t *w, data_t *d, window_data_t *wd,
+ gboolean children);
+static void render_free_picture(d_window_t *w, window_data_t *wd);
+static xcb_render_pictformat_t find_visual_format(data_t *d,
+ xcb_visualid_t visual);
+static xcb_render_picture_t solid_picture(d_screen_t *sc,
+ double a, double r,
+ double g, double b);
+
+static void render_window_show(d_window_t *window);
+static void render_window_hide(d_window_t *window);
+static void render_window_reconfigure(d_window_t *window);
void
render_init(d_screen_t *sc)
{
+ xcb_render_query_pict_formats_cookie_t ck;
+ xcb_render_pictformat_t format;
+ xcb_pixmap_t px;
+
data_t *d = malloc(sizeof(data_t));
d->screen_paint = sc->screen_paint;
+ d->window_show = sc->window_show;
+ d->window_hide = sc->window_hide;
+ d->window_reconfigure = sc->window_reconfigure;
screen_add_plugin_data(sc, PLUGIN_NAME, d);
- sc->screen_paint = render_paint_screen;
+ sc->screen_paint = render_screen_paint;
+ sc->window_show = render_window_show;
+ sc->window_hide = render_window_hide;
+ sc->window_reconfigure = render_window_reconfigure;
+
+ ck = xcb_render_query_pict_formats_unchecked(sc->dpy->conn);
+ d->pict_formats = xcb_render_query_pict_formats_reply(sc->dpy->conn, ck,
+ NULL);
+
+ format = find_visual_format(d, sc->super.root_visual);
+
+ d->overlay_picture = xcb_generate_id(sc->dpy->conn);
+ xcb_render_create_picture(sc->dpy->conn,
+ d->overlay_picture, sc->overlay, format,
+ 0, NULL);
+
+ /* make the double buffer */
+ px = xcb_generate_id(sc->dpy->conn);
+ xcb_create_pixmap(sc->dpy->conn, sc->super.root_depth, px,
+ sc->super.root, sc->super.width_in_pixels,
+ sc->super.height_in_pixels);
+ d->overlay_buffer = xcb_generate_id(sc->dpy->conn);
+ xcb_render_create_picture(sc->dpy->conn, d->overlay_buffer, px,
+ format, 0, 0);
+ xcb_free_pixmap(sc->dpy->conn, px);
+
+ d->solid_bg = solid_picture(sc, 1.0, 0.0, 0.0, 0.0);
}
void
render_free(d_screen_t *sc)
{
data_t *d = screen_find_plugin_data(sc, PLUGIN_NAME);
+ free(d->pict_formats);
+ xcb_render_free_picture(sc->dpy->conn, d->solid_bg);
+ xcb_render_free_picture(sc->dpy->conn, d->overlay_picture);
+ xcb_render_free_picture(sc->dpy->conn, d->overlay_buffer);
free(d);
}
+void
+render_window_free(d_window_t *w, window_data_t *wd)
+{
+ render_free_picture(w, wd);
+ free(wd);
+}
+
+static void
+render_window_show(d_window_t *w)
+{
+ data_t *d;
+ window_data_t *wd;
+
+ d = screen_find_plugin_data(w->sc, PLUGIN_NAME);
+
+ /* pass it on */
+ d->window_show(w);
+
+ wd = window_find_plugin_data(w, PLUGIN_NAME);
+ if (wd)
+ render_window_free(w, wd);
+
+ wd = malloc(sizeof(window_data_t));
+ wd->picture = XCB_NONE;
+ wd->ck_picture.sequence = 0;
+ window_add_plugin_data(w, PLUGIN_NAME, wd);
+
+ window_ref(w);
+}
+
static void
-render_paint_screen(d_screen_t *sc)
+render_window_hide(d_window_t *w)
+{
+ data_t *d;
+ window_data_t *wd;
+
+ d = screen_find_plugin_data(w->sc, PLUGIN_NAME);
+ wd = window_find_plugin_data(w, PLUGIN_NAME);
+ if (wd) {
+ render_window_free(w, wd);
+ window_remove_plugin_data(w, PLUGIN_NAME);
+ }
+
+ window_unref(w);
+
+ /* pass it on */
+ d->window_hide(w);
+}
+
+static
+xcb_render_picture_t solid_picture(d_screen_t *sc,
+ double a, double r,
+ double g, double b)
+{
+ xcb_render_picture_t picture;
+ xcb_render_color_t c;
+
+ picture = xcb_generate_id (sc->dpy->conn);
+
+ c.alpha = a * 0xffff;
+ c.red = a * r * 0xffff;
+ c.green = a * g * 0xffff;
+ c.blue = a * b * 0xffff;
+
+ xcb_render_create_solid_fill (sc->dpy->conn, picture, c);
+ return picture;
+}
+
+static xcb_render_pictformat_t
+find_visual_format(data_t *d, xcb_visualid_t visual)
+{
+ xcb_render_pictscreen_iterator_t si;
+ xcb_render_pictdepth_iterator_t di;
+ xcb_render_pictvisual_iterator_t vi;
+
+ if (!visual) return XCB_NONE;
+
+ /* go through all the screens */
+ si = xcb_render_query_pict_formats_screens_iterator(d->pict_formats);
+ for (; si.rem; xcb_render_pictscreen_next(&si)) {
+ di = xcb_render_pictscreen_depths_iterator(si.data);
+ for (; di.rem; xcb_render_pictdepth_next(&di)) {
+ vi = xcb_render_pictdepth_visuals_iterator(di.data);
+ for (; vi.rem; xcb_render_pictvisual_next(&vi)) {
+ if (vi.data->visual == visual)
+ return vi.data->format;
+ }
+ }
+ }
+ return XCB_NONE;
+}
+
+static xcb_render_picture_t
+render_get_picture(d_window_t *w, window_data_t *wd)
+{
+ if (wd->ck_picture.sequence) {
+ xcb_generic_error_t *err;
+ //printf("** checking create picture 0x%x\n", w->id);
+ err = xcb_request_check(w->sc->dpy->conn, wd->ck_picture);
+ if (err) {
+ wd->picture = XCB_NONE;
+ printf("error creating picture for window 0x%x\n", w->id);
+ free(err);
+ }
+ wd->ck_picture.sequence = 0;
+ }
+ //printf("returning picture 0x%x for window 0x%x\n", wd->picture, w->id);
+ return wd->picture;
+}
+
+static void
+render_free_picture(d_window_t *w, window_data_t *wd)
+{
+ xcb_render_picture_t pict;
+
+ pict = render_get_picture(w, wd);
+ if (pict) xcb_render_free_picture(w->sc->dpy->conn, pict);
+ wd->picture = XCB_NONE;
+}
+
+static void
+render_update_picture(d_window_t *w, data_t *d, window_data_t *wd,
+ gboolean children)
+{
+ xcb_pixmap_t px;
+
+ px = window_get_pixmap(w);
+ //printf("got pixmap 0x%x\n", px);
+ if (px) {
+ xcb_render_pictformat_t format;
+ const uint32_t vals = (children ?
+ XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS :
+ XCB_SUBWINDOW_MODE_CLIP_BY_CHILDREN);
+
+ render_free_picture(w, wd);
+
+ wd->picture = xcb_generate_id(w->sc->dpy->conn);
+ format = find_visual_format(d, window_get_visual(w));
+ wd->ck_picture =
+ xcb_render_create_picture_checked(w->sc->dpy->conn,
+ wd->picture, px, format,
+ XCB_RENDER_CP_SUBWINDOW_MODE,
+ &vals);
+ }
+}
+
+static void
+render_window_reconfigure(d_window_t *w)
+{
+ data_t *d;
+ window_data_t *wd;
+
+ d = screen_find_plugin_data(w->sc, PLUGIN_NAME);
+ wd = window_find_plugin_data(w, PLUGIN_NAME);
+ render_free_picture(w, wd);
+
+ /* pass it on */
+ d->window_hide(w);
+}
+
+static void
+render_screen_paint(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);
+ //printf("-- painting --\n");
+ paint_root(sc, d);
+#if 1
+ for (it = list_bottom(sc->stacking); it; it = it->prev) {
+ d_window_t *w = it->data;
+ if (!window_is_input_only(w) && window_is_mapped(w))
+ paint_window(w);
+ }
+#endif
+
+ /* copy the double buffer to the overlay window */
+ xcb_render_composite(sc->dpy->conn,
+ XCB_RENDER_PICT_OP_SRC,
+ d->overlay_buffer,
+ XCB_NONE,
+ d->overlay_picture,
+ 0, 0, 0, 0,
+ 0, 0,
+ sc->super.width_in_pixels,
+ sc->super.height_in_pixels);
/* call the function we replaced in the chain */
d->screen_paint(sc);
}
static void
-paint_root(d_screen_t *sc)
+paint_root(d_screen_t *sc, data_t *d)
{
- int w, h;
-
- w = sc->super.width_in_pixels;
- h = sc->super.height_in_pixels;
-
- //printf("-- paint root 0x%x --\n", sc->super.root);
+ xcb_render_composite(sc->dpy->conn,
+ XCB_RENDER_PICT_OP_CLEAR,
+ d->solid_bg,
+ XCB_NONE,
+ d->overlay_buffer,
+ 0, 0, 0, 0,
+ 0, 0,
+ sc->super.width_in_pixels,
+ sc->super.height_in_pixels);
}
static void
paint_window(d_window_t *w)
{
- //printf("-- paint window 0x%x --\n", w->id);
+ data_t *d;
+ window_data_t *wd;
+ xcb_render_picture_t pict;
+ int x, y, width, height, bwidth;
+
+ d = screen_find_plugin_data(w->sc, PLUGIN_NAME);
+ wd = window_find_plugin_data(w, PLUGIN_NAME);
+
+ if (!wd->picture)
+ render_update_picture(w, d, wd, TRUE);
+ pict = render_get_picture(w, wd);
+
+ //printf("-- paint window 0x%x picture 0x%x --\n", w->id, wd->picture);
+ window_get_area(w, &x, &y, &width, &height, &bwidth);
+ xcb_render_composite(w->sc->dpy->conn,
+ XCB_RENDER_PICT_OP_SRC,
+ /*XCB_RENDER_PICT_OP_OVER, - for argb */
+ wd->picture,
+ XCB_NONE,
+ d->overlay_buffer,
+ 0, 0, 0, 0,
+ x, y, width + bwidth*2, height + bwidth *2);
}
#include <stdlib.h>
#include <stdio.h>
#include <xcb/composite.h>
+#include <xcb/xfixes.h>
#define ROOT_MASK (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | \
XCB_EVENT_MASK_STRUCTURE_NOTIFY)
sc->ref = 1;
sc->dpy = dpy;
sc->num = num;
- sc->root = NULL;
gettimeofday(&sc->next_repaint, NULL);
sc->need_repaint = TRUE;
screen_unref(d_screen_t *sc)
{
if (sc && --sc->ref == 0) {
- if (sc->root)
- screen_remove_window(sc, sc->root);
-
g_hash_table_unref(sc->winhash);
list_unref(sc->stacking);
g_hash_table_unref(sc->plugin_data);
screen_init(d_screen_t *sc)
{
uint32_t mask;
-#if DO_COMP
xcb_generic_error_t *err;
xcb_void_cookie_t redir_ck;
xcb_composite_get_overlay_window_cookie_t overlay_ck;
redir_ck =
xcb_composite_redirect_subwindows(sc->dpy->conn, sc->super.root,
+ XCB_COMPOSITE_REDIRECT_AUTOMATIC);
+
+#if 1
+ redir_ck =
+ xcb_composite_redirect_subwindows(sc->dpy->conn, sc->super.root,
XCB_COMPOSITE_REDIRECT_MANUAL);
overlay_ck = xcb_composite_get_overlay_window(sc->dpy->conn,
}
sc->overlay = overlay_rep->overlay_win;
free(overlay_rep);
+
+ /* make the overlay window click-through */
+ if (sc->overlay) {
+ xcb_xfixes_region_t region;
+
+ region = xcb_generate_id(sc->dpy->conn);
+ xcb_xfixes_create_region(sc->dpy->conn, region, 0, NULL);
+ xcb_xfixes_set_window_shape_region(sc->dpy->conn,
+ sc->overlay,
+ XCB_SHAPE_SK_BOUNDING,
+ 0, 0, XCB_NONE);
+ xcb_xfixes_set_window_shape_region(sc->dpy->conn,
+ sc->overlay,
+ XCB_SHAPE_SK_INPUT,
+ 0, 0, region);
+ xcb_xfixes_destroy_region(sc->dpy->conn, region);
+ }
#endif
mask = SELECTION_MASK;
w = window_new(wid, sc);
g_hash_table_insert(sc->winhash, &w->id, w);
- printf("screen added window 0x%x\n", w->id);
+ window_create_damage(w);
+
+ //printf("screen added window 0x%x\n", w->id);
return w;
}
xcb_query_tree_cookie_t ck;
xcb_query_tree_reply_t *rep;
- sc->root = screen_add_window(sc, sc->super.root);
-
ck = xcb_query_tree(sc->dpy->conn, sc->super.root);
rep = xcb_query_tree_reply(sc->dpy->conn, ck, NULL);
if (rep) {
void
screen_remove_window(d_screen_t *sc, struct d_window *w)
{
- printf("screen removed window 0x%x\n", w->id);
+ //printf("screen removed window 0x%x\n", w->id);
+ window_destroy_damage(w);
g_hash_table_remove(sc->winhash, &w->id);
sc->window_become_zombie(w);
window_unref(w);
sc->window_show = window_show;
sc->window_hide = window_hide;
sc->window_become_zombie = window_become_zombie;
- sc->window_configure = window_configure;
+ sc->window_reconfigure = window_reconfigure;
}
void
screen_add_plugin_data(d_screen_t *sc, const char *key, void *data)
{
char *skey = g_strdup(key);
- g_hash_table_insert(sc->plugin_data, skey, data);
+ g_hash_table_replace(sc->plugin_data, skey, data);
}
void*
void screen_refresh(d_screen_t *sc)
{
sc->need_repaint = TRUE;
+ //printf("*** need repaint! ***\n");
}
xcb_atom_t selatom; /* ditto.. */
xcb_window_t overlay;
- struct d_window *root;
struct timeval next_repaint;
gboolean need_repaint;
void (*window_show)(struct d_window *w);
void (*window_hide)(struct d_window *w);
void (*window_become_zombie)(struct d_window *w);
- void (*window_configure)(struct d_window *w, int x, int y,
- int width, int height, int border_width);
+ void (*window_reconfigure)(struct d_window *w);
} d_screen_t;
d_screen_t* screen_new(struct d_display *dpy, int num, xcb_screen_t *xcb);
#include "screen.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;
gboolean zombie;
- int opacity;
+ GHashTable *plugin_data;
- xcb_pixmap_t pixmap;
+ xcb_damage_damage_t damage;
xcb_get_window_attributes_cookie_t ck_get_attr;
xcb_get_geometry_cookie_t ck_get_geom;
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_pixmap.sequence = 0;
+ w->plugin_data = g_hash_table_new_full((GHashFunc)g_str_hash,
+ (GEqualFunc)g_str_equal,
+ g_free, NULL);
+
//printf("new window 0x%x\n", w->id);
return (d_window_t*)w;
w->pixmap = XCB_NONE;
}
+ g_hash_table_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);
-
/* 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,
}
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 */
+
+ 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 */
printf("hide window 0x%x\n", w->id);
}
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)
*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;
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);
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);
//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->ck_get_pixmap.sequence = 0;
}
//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->ck_get_attr.sequence)
+ 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)
w->ck_get_geom.sequence = 0;
w->x = x;
w->y = y;
- w->w = width + border_width * 2;
- w->h = height + border_width * 2;
+ w->w = width;
+ w->h = height;
+ w->bw = border_width;
+}
+
+void
+window_reconfigure(d_window_t *w)
+{
+ window_update_pixmap((d_window_priv_t*)w);
+}
+
+void
+window_add_plugin_data(d_window_t *pubw, const char *key, void *data)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
+ char *skey = g_strdup(key);
+ g_hash_table_replace(w->plugin_data, skey, data);
+}
+
+void*
+window_find_plugin_data(d_window_t *pubw, const char *key)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
+ return g_hash_table_lookup(w->plugin_data, key);
+}
+
+void
+window_remove_plugin_data(d_window_t *pubw, const char *key)
+{
+ d_window_priv_t *w = (d_window_priv_t*)pubw;
+ g_hash_table_remove(w->plugin_data, key);
+}
+
+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);
+ 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) {
+ xcb_damage_destroy(w->sc->dpy->conn, w->damage);
+ w->damage = XCB_NONE;
+ }
}
struct d_screen;
-#define WINDOW_OPACITY_MAX 100
-#define WINDOW_OPACITY_MIN 0
-
typedef struct d_window {
xcb_window_t id;
struct d_screen *sc;
void window_configure(d_window_t *w, int x, int y, int width, int height,
int border_width);
+void window_reconfigure(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);
+void window_get_area(d_window_t *pubw, int *x, int *y, int *width, int *height,
+ int *border_width);
xcb_pixmap_t window_get_pixmap(d_window_t *w);
+xcb_visualid_t window_get_visual(d_window_t *w);
+
+void window_add_plugin_data(d_window_t *w, const char *key, void *data);
+void* window_find_plugin_data(d_window_t *w, const char *key);
+void window_remove_plugin_data(d_window_t *w, const char *key);
+
+void window_create_damage(d_window_t *w);
+void window_destroy_damage(d_window_t *w);
#endif