Drawin: Re-add shape support

Commit 03e0ee53d2 removed window shapes, because at the time I was too
lazy to port them from the old image system to oocairo.

This commit re-adds them, but for now only as a way to set the shape.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2012-11-05 17:56:56 +01:00
parent 4711354b5d
commit 37d074f881
6 changed files with 89 additions and 0 deletions

View File

@ -31,6 +31,7 @@
#include <xcb/xcb_event.h>
#include <xcb/xinerama.h>
#include <xcb/xtest.h>
#include <xcb/shape.h>
#include <X11/Xlib-xcb.h>
@ -405,6 +406,7 @@ main(int argc, char **argv)
xcb_prefetch_extension_data(globalconf.connection, &xcb_test_id);
xcb_prefetch_extension_data(globalconf.connection, &xcb_randr_id);
xcb_prefetch_extension_data(globalconf.connection, &xcb_xinerama_id);
xcb_prefetch_extension_data(globalconf.connection, &xcb_shape_id);
/* initialize dbus */
a_dbus_init();

View File

@ -138,6 +138,7 @@ pkg_check_modules(AWESOME_REQUIRED REQUIRED
xcb-randr
xcb-xtest
xcb-xinerama
xcb-shape
xcb-util>=0.3.8
xcb-keysyms>=0.3.4
xcb-icccm>=0.3.8

View File

@ -16,6 +16,8 @@ module("drawin")
-- @field width The width of the drawin.
-- @field height The height of the drawin.
-- @field drawable The drawin's drawable.
-- @field shape_bounding The drawin's bounding shape as a (native) cairo surface.
-- @field shape_clip The drawin's clip shape as a (native) cairo surface.
-- @class table
-- @name drawin

View File

@ -32,6 +32,7 @@
#include "common/xutil.h"
#include <cairo-xcb.h>
#include <xcb/shape.h>
LUA_OBJECT_FUNCS(drawin_class, drawin_t, drawin)
@ -536,6 +537,38 @@ luaA_drawin_get_drawable(lua_State *L, drawin_t *drawin)
return 1;
}
/** Set the drawin's bounding shape.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_set_shape_bounding(lua_State *L, drawin_t *drawin)
{
cairo_surface_t *surf = NULL;
if(!lua_isnil(L, -1))
surf = (cairo_surface_t *)lua_touserdata(L, -1);
xwindow_set_shape(drawin->window, drawin->geometry.width, drawin->geometry.width,
XCB_SHAPE_SK_BOUNDING, surf, -drawin->border_width);
return 0;
}
/** Set the drawin's clip shape.
* \param L The Lua VM state.
* \param drawin The drawin object.
* \return The number of elements pushed on stack.
*/
static int
luaA_drawin_set_shape_clip(lua_State *L, drawin_t *drawin)
{
cairo_surface_t *surf = NULL;
if(!lua_isnil(L, -1))
surf = (cairo_surface_t *)lua_touserdata(L, -1);
xwindow_set_shape(drawin->window, drawin->geometry.width, drawin->geometry.width,
XCB_SHAPE_SK_CLIP, surf, 0);
return 0;
}
void
drawin_class_setup(lua_State *L)
{
@ -596,6 +629,14 @@ drawin_class_setup(lua_State *L)
(lua_class_propfunc_t) luaA_window_set_type,
(lua_class_propfunc_t) luaA_window_get_type,
(lua_class_propfunc_t) luaA_window_set_type);
luaA_class_add_property(&drawin_class, "shape_bounding",
(lua_class_propfunc_t) luaA_drawin_set_shape_bounding,
NULL,
(lua_class_propfunc_t) luaA_drawin_set_shape_bounding);
luaA_class_add_property(&drawin_class, "shape_clip",
(lua_class_propfunc_t) luaA_drawin_set_shape_clip,
NULL,
(lua_class_propfunc_t) luaA_drawin_set_shape_clip);
signal_add(&drawin_class.signals, "property::border_width");
signal_add(&drawin_class.signals, "property::cursor");

View File

@ -21,6 +21,8 @@
#include <xcb/xcb.h>
#include <xcb/xcb_atom.h>
#include <xcb/shape.h>
#include <cairo-xcb.h>
#include "xwindow.h"
#include "objects/button.h"
@ -256,4 +258,42 @@ xwindow_set_border_color(xcb_window_t w, color_t *color)
xcb_change_window_attributes(globalconf.connection, w, XCB_CW_BORDER_PIXEL, &color->pixel);
}
/** Turn a cairo surface into a pixmap with depth 1 */
static xcb_pixmap_t
xwindow_shape_pixmap(int width, int height, cairo_surface_t *surf)
{
xcb_pixmap_t pixmap = xcb_generate_id(globalconf.connection);
cairo_surface_t *dest;
cairo_t *cr;
xcb_create_pixmap(globalconf.connection, 1, pixmap, globalconf.screen->root, width, height);
dest = cairo_xcb_surface_create_for_bitmap(globalconf.connection, globalconf.screen, pixmap, width, height);
cr = cairo_create(dest);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface(cr, surf, 0, 0);
cairo_paint(cr);
cairo_destroy(cr);
cairo_surface_flush(dest);
cairo_surface_finish(dest);
cairo_surface_destroy(dest);
return pixmap;
}
/** Set one of a window's shapes */
void
xwindow_set_shape(xcb_window_t win, int width, int height, enum xcb_shape_sk_t kind, cairo_surface_t *surf, int offset)
{
xcb_pixmap_t pixmap = XCB_NONE;
if (surf)
pixmap = xwindow_shape_pixmap(width, height, surf);
xcb_shape_mask(globalconf.connection, XCB_SHAPE_SO_SET, kind, win, offset, offset, pixmap);
if (pixmap != XCB_NONE)
xcb_free_pixmap(globalconf.connection, pixmap);
}
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -25,6 +25,8 @@
#include "globalconf.h"
#include "draw.h"
enum xcb_shape_sk_t;
void xwindow_set_state(xcb_window_t, uint32_t);
xcb_get_property_cookie_t xwindow_get_state_unchecked(xcb_window_t);
uint32_t xwindow_get_state_reply(xcb_get_property_cookie_t);
@ -38,6 +40,7 @@ void xwindow_grabkeys(xcb_window_t, key_array_t *);
void xwindow_takefocus(xcb_window_t);
void xwindow_set_cursor(xcb_window_t, xcb_cursor_t);
void xwindow_set_border_color(xcb_window_t, color_t *);
void xwindow_set_shape(xcb_window_t, int, int, enum xcb_shape_sk_t, cairo_surface_t *, int);
#endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80