void (*screen_root_pixmap_change)(d_screen_t *sc);
void (*window_show)(d_window_t *w);
void (*window_zombie_dead)(d_window_t *w);
+ void (*window_move)(d_window_t *w);
void (*window_resize)(d_window_t *w);
void (*window_reshape)(d_window_t *w);
static void glxrender_root_pixmap_change(d_screen_t *sc);
static void paint_root(d_screen_t *sc, data_t *d);
static void paint_window(d_window_t *window, data_t *d, window_data_t *wd,
- gboolean opaque, int x, int y);
-static void paint_shadow(d_window_t *w, data_t *d, window_data_t *wd,
- int x, int y);
+ GLfloat z);
+static void paint_shadow(data_t *d, window_data_t *wd, GLfloat z);
static void glxrender_update_window_pixmap(d_window_t *w, data_t *d,
window_data_t *wd);
+static void glxrender_update_window_region(d_window_t *w, window_data_t *wd);
static void glxrender_free_window_pixmap(d_window_t *w, data_t *d,
window_data_t *wd);
static void glxrender_free_root_pixmap(d_screen_t *sc, data_t *d);
static void glxrender_window_show(d_window_t *window);
static void glxrender_window_zombie_dead(d_window_t *window);
+static void glxrender_window_move(d_window_t *window);
static void glxrender_window_resize(d_window_t *window);
static void glxrender_window_reshape(d_window_t *window);
d->window_show = sc->window_show;
d->window_zombie_dead = sc->window_zombie_dead;
d->window_resize = sc->window_resize;
+ d->window_move = sc->window_move;
d->window_reshape = sc->window_reshape;
screen_add_plugin_data(sc, plugin_id, d);
sc->window_show = glxrender_window_show;
sc->window_zombie_dead = glxrender_window_zombie_dead;
sc->window_resize = glxrender_window_resize;
+ sc->window_move = glxrender_window_move;
sc->window_reshape = glxrender_window_reshape;
d->shadowalpha = 0.2f; /* 20% */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
+ glEnable(GL_DEPTH_TEST);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glXSwapBuffers(sc->dpy->xlib_dpy, sc->overlay);
d->bind_func = (BindEXTFunc)
glxrender_free(d_screen_t *sc)
{
data_t *d = screen_find_plugin_data(sc, plugin_id);
- glxrender_free_root_pixmap(sc, d);
- free(d);
+ if (d) {
+ glxrender_free_root_pixmap(sc, d);
+ free(d);
+ }
screen_remove_plugin_data(sc, plugin_id);
}
glXDestroyPixmap(w->sc->dpy->xlib_dpy, wd->glpixmap);
wd->glpixmap = XCB_NONE;
+ }
+ if (wd->nrects) {
free(wd->texcoords);
free(wd->vertices);
wd->nrects = 0;
glBindTexture(GL_TEXTURE_2D, 0);
- {
- int x, y, width, height, bwidth;
-
- window_get_area(w, &x, &y, &width, &height, &bwidth);
-
- wd->texcoords = (GLfloat*)malloc(sizeof(GLfloat) * 4);
- wd->texcoords[LEFT] = 0.0f;
- wd->texcoords[TOP] = 0.0f;
- wd->texcoords[RIGHT] = 1.0f;
- wd->texcoords[BOTTOM] = 1.0f;
+ glxrender_update_window_region(w, wd);
+}
- wd->vertices = (GLint*)malloc(sizeof(GLint) * 4);
- wd->vertices[LEFT] = 0;
- wd->vertices[TOP] = 0;
- wd->vertices[RIGHT] = width + bwidth;
- wd->vertices[BOTTOM] = height + bwidth;
+static void
+glxrender_update_window_region(d_window_t *w, window_data_t *wd)
+{
+ xcb_xfixes_region_t reg;
+ xcb_xfixes_fetch_region_cookie_t ck;
+ xcb_xfixes_fetch_region_reply_t *rep;
+ xcb_rectangle_t area, *rects;
+ int nrects, i, x, y, wid, hei, bwid;
+
+ reg = window_get_region(w);
+ ck = xcb_xfixes_fetch_region_unchecked(w->sc->dpy->conn, reg);
+
+ window_get_area(w, &x, &y, &wid, &hei, &bwid);
+ area.x = x;
+ area.y = y;
+ area.width = wid + bwid * 2;
+ area.height = hei + bwid * 2;
+
+ rep = xcb_xfixes_fetch_region_reply(w->sc->dpy->conn, ck, NULL);
+ if (!rep) {
+ rects = &area;
+ nrects = 1;
+ }
+ else {
+ rects = xcb_xfixes_fetch_region_rectangles(rep);
+ nrects = xcb_xfixes_fetch_region_rectangles_length(rep);
+ }
- wd->nrects = 1;
+ wd->texcoords = (GLfloat*)malloc(sizeof(GLfloat) * (nrects * 4));
+ wd->vertices = (GLint*)malloc(sizeof(GLint) * (nrects * 4));
+ wd->nrects = nrects;
+
+ for (i = 0; i < nrects * 4; i += 4) {
+ wd->texcoords[i+LEFT] =
+ (GLfloat)(rects[i].x - area.x) / (GLfloat)area.width;
+ wd->texcoords[i+TOP] =
+ (GLfloat)(rects[i].y - area.y) / (GLfloat)area.height;
+ wd->texcoords[i+RIGHT] =
+ (GLfloat)(rects[i].x - area.x + rects[i].width) /
+ (GLfloat)area.width;
+ wd->texcoords[i+BOTTOM] =
+ (GLfloat)(rects[i].y - area.y + rects[i].height) /
+ (GLfloat)area.height;
+
+ wd->vertices[i+LEFT] = rects[i].x;
+ wd->vertices[i+TOP] = rects[i].y;
+ wd->vertices[i+RIGHT] = rects[i].x + rects[i].width;
+ wd->vertices[i+BOTTOM] = rects[i].y + rects[i].height;
}
+
+ if (rep)
+ free(rep);
}
static void
}
static void
+glxrender_window_move(d_window_t *w)
+{
+ data_t *d;
+ window_data_t *wd;
+
+ d = screen_find_plugin_data(w->sc, plugin_id);
+ wd = window_find_plugin_data(w, plugin_id);
+
+ /* pass it on */
+ d->window_move(w);
+
+ assert(wd != NULL);
+ glxrender_update_window_region(w, wd);
+}
+
+static void
glxrender_window_reshape(d_window_t *w)
{
data_t *d;
{
data_t *d = screen_find_plugin_data(sc, plugin_id);
d_list_it_t *it;
+ GLfloat z;
//printf("painting\n");
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ /* add 0.1f to keep everything above the root */
+ z = list_length(sc->stacking) * 0.1f + 0.1f;
+ for (it = list_top(sc->stacking); it; it = it->next) {
+ d_window_t *w = it->data;
+
+ if (!window_is_input_only(w) &&
+ (window_is_mapped(w) || window_is_zombie(w)))
+ {
+ int x, y, width, height, bwidth;
+ gboolean opaque;
+ window_data_t *wd;
+
+ window_get_area(w, &x, &y, &width, &height, &bwidth);
+
+ if (!(x < sc->super->width_in_pixels &&
+ y < sc->super->height_in_pixels &&
+ (x + width > 0 || x + width + d->xshadowoff > 0) &&
+ (y + height > 0 || y + height + d->yshadowoff > 0)))
+ {
+ continue;
+ }
+
+ opaque = !window_is_argb(w) && window_get_opacity(w) == 0xffff;
+
+ if (opaque) {
+ wd = window_find_plugin_data(w, plugin_id);
+
+ //glPushMatrix();
+
+ paint_window(w, d, wd, z + 0.05f);
+
+ //glPopMatrix();
+ }
+
+ z -= 0.1f;
+ }
+ }
+
paint_root(sc, d);
+ glEnable(GL_BLEND);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
for (it = list_bottom(sc->stacking); it; it = it->prev) {
d_window_t *w = it->data;
int x, y, width, height, bwidth;
gboolean opaque;
window_data_t *wd;
+ uint16_t opac;
+ GLfloat alpha;
window_get_area(w, &x, &y, &width, &height, &bwidth);
continue;
}
- opaque = !window_is_argb(w) && window_get_opacity(w) == 0xffff;
+ opac = window_get_opacity(w);
+ opaque = !window_is_argb(w) && opac == 0xffff;
wd = window_find_plugin_data(w, plugin_id);
- glPushMatrix();
+ //glPushMatrix();
+
+ /* black shadow */
+ alpha = d->shadowalpha;
+ alpha *= opac;
+ alpha /= 0xffff;
+ if (alpha >= 0.01) {
+ glColor4f(0.0f, 0.0f, 0.0f, alpha);
+ paint_shadow(d, wd, z);
+ }
- glTranslatef(d->xshadowoff, d->yshadowoff, 0.0f);
- paint_shadow(w, d, wd, x, y);
+ if (!opaque) {
+ glColor4us(opac, opac, opac, opac);
+ paint_window(w, d, wd, z + 0.05f);
+ }
- glTranslatef(-d->xshadowoff, -d->yshadowoff, 0.0f);
- paint_window(w, d, wd, opaque, x, y);
+ //glPopMatrix();
- glPopMatrix();
+ z += 0.1f;
}
}
+ glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glDisable(GL_BLEND);
+
//xcb_glx_swap_buffers(sc->dpy->conn, d->context_tag, sc->overlay);
glXSwapBuffers(sc->dpy->xlib_dpy, sc->overlay);
if (!d->root_glpixmap)
glxrender_update_root_pixmap(sc, d);
- glClear(GL_COLOR_BUFFER_BIT);
-
glBindTexture(GL_TEXTURE_2D, d->root_texname);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
- glVertex2i(0, 0);
+ glVertex3i(0, 0, 0);
glTexCoord2f(1, 0);
- glVertex2i(sc->super->width_in_pixels, 0);
+ glVertex3i(sc->super->width_in_pixels, 0, 0);
glTexCoord2f(1, 1);
- glVertex2i(sc->super->width_in_pixels, sc->super->height_in_pixels);
+ glVertex3i(sc->super->width_in_pixels, sc->super->height_in_pixels, 0);
glTexCoord2f(0, 1);
- glVertex2i(0, sc->super->height_in_pixels);
+ glVertex3i(0, sc->super->height_in_pixels, 0);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
}
static void
-paint_window(d_window_t *w, data_t *d, window_data_t *wd, gboolean opaque,
- int x, int y)
+paint_window(d_window_t *w, data_t *d, window_data_t *wd, GLfloat z)
{
- uint16_t o = window_get_opacity(w);
int i;
if (!wd->glpixmap)
glBindTexture(GL_TEXTURE_2D, wd->texname);
- if (!opaque) {
- glEnable(GL_BLEND);
-
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glColor4us(o, o, o, o);
- }
-
glBegin(GL_QUADS);
for (i = 0; i < wd->nrects * 4; i += 4) {
- // XXX use glVertex3i
glTexCoord2f(wd->texcoords[i+LEFT], wd->texcoords[i+TOP]);
- glVertex2i(x + wd->vertices[i+LEFT], y + wd->vertices[i+TOP]);
+ glVertex3f(wd->vertices[i+LEFT], wd->vertices[i+TOP], z);
glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+TOP]);
- glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+TOP]);
+ glVertex3f(wd->vertices[i+RIGHT], wd->vertices[i+TOP], z);
glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+BOTTOM]);
- glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+BOTTOM]);
+ glVertex3f(wd->vertices[i+RIGHT], wd->vertices[i+BOTTOM], z);
glTexCoord2f(wd->texcoords[i+LEFT], wd->texcoords[i+BOTTOM]);
- glVertex2i(x + wd->vertices[i+LEFT], y + wd->vertices[i+BOTTOM]);
+ glVertex3f(wd->vertices[i+LEFT], wd->vertices[i+BOTTOM], z);
}
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
-
- if (!opaque) {
- glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glDisable(GL_BLEND);
- }
}
static void
-paint_shadow(d_window_t *w, data_t *d, window_data_t *wd, int x, int y)
+paint_shadow(data_t *d, window_data_t *wd, GLfloat z)
{
- float alpha = d->shadowalpha;
+ int xoff = d->xshadowoff;
+ int yoff = d->yshadowoff;
int i;
if (wd->nrects < 1) return;
- alpha *= window_get_opacity(w);
- alpha /= 0xffff;
-
- if (alpha < 0.01) return;
-
- glEnable(GL_BLEND);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- /* black shadow */
- glColor4f(0.0f, 0.0f, 0.0f, alpha);
-
/* shape the shadow to the window */
glBindTexture(GL_TEXTURE_2D, wd->texname);
glBegin(GL_QUADS);
for (i = 0; i < wd->nrects * 4; i += 4) {
glTexCoord2f(wd->texcoords[i+LEFT], wd->texcoords[i+TOP]);
- glVertex2i(x + wd->vertices[i+LEFT], y + wd->vertices[i+TOP]);
+ glVertex3f(xoff+wd->vertices[i+LEFT], yoff+wd->vertices[i+TOP], z);
glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+TOP]);
- glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+TOP]);
+ glVertex3f(xoff+wd->vertices[i+RIGHT], yoff+wd->vertices[i+TOP], z);
glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+BOTTOM]);
- glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+BOTTOM]);
+ glVertex3f(xoff+wd->vertices[i+RIGHT], yoff+wd->vertices[i+BOTTOM], z);
glTexCoord2f(wd->texcoords[i+LEFT], wd->texcoords[i+BOTTOM]);
- glVertex2i(x + wd->vertices[i+LEFT], y + wd->vertices[i+BOTTOM]);
+ glVertex3f(xoff+wd->vertices[i+LEFT], yoff+wd->vertices[i+BOTTOM], z);
}
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
-
- glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glDisable(GL_BLEND);
}