Make callbacks to rules.execute optional
[awesome.git] / objects / drawable.c
blobe0484b56b6361e4a58ce5409d89051ea1de9e273
1 /*
2 * drawable.c - drawable functions
4 * Copyright © 2008-2009 Julien Danjou <julien@danjou.info>
5 * Copyright © 2010-2012 Uli Schlachter <psychon@znc.in>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "drawable.h"
24 #include "common/luaobject.h"
25 #include "globalconf.h"
27 #include <cairo-xcb.h>
29 static lua_class_t drawable_class;
31 LUA_OBJECT_FUNCS(drawable_class, drawable_t, drawable)
33 drawable_t *
34 drawable_allocator(lua_State *L, drawable_refresh_callback *callback, void *data)
36 drawable_t *d = drawable_new(L);
37 d->refresh_callback = callback;
38 d->refresh_data = data;
39 d->refreshed = false;
40 d->surface = NULL;
41 d->pixmap = XCB_NONE;
42 return d;
45 static void
46 drawable_unset_surface(drawable_t *d)
48 cairo_surface_finish(d->surface);
49 cairo_surface_destroy(d->surface);
50 if (d->pixmap)
51 xcb_free_pixmap(globalconf.connection, d->pixmap);
52 d->refreshed = false;
53 d->surface = NULL;
54 d->pixmap = XCB_NONE;
57 static void
58 drawable_wipe(drawable_t *d)
60 drawable_unset_surface(d);
63 void
64 drawable_set_geometry(drawable_t *d, int didx, area_t geom)
66 area_t old = d->geometry;
67 d->geometry = geom;
69 bool size_changed = (old.width != geom.width) || (old.height != geom.height);
70 if (size_changed)
71 drawable_unset_surface(d);
72 if (size_changed && geom.width > 0 && geom.height > 0)
74 d->pixmap = xcb_generate_id(globalconf.connection);
75 xcb_create_pixmap(globalconf.connection, globalconf.default_depth, d->pixmap,
76 globalconf.screen->root, geom.width, geom.height);
77 d->surface = cairo_xcb_surface_create(globalconf.connection,
78 d->pixmap, globalconf.visual,
79 geom.width, geom.height);
80 luaA_object_emit_signal(globalconf.L, didx, "property::surface", 0);
83 if (old.x != geom.x)
84 luaA_object_emit_signal(globalconf.L, didx, "property::x", 0);
85 if (old.y != geom.y)
86 luaA_object_emit_signal(globalconf.L, didx, "property::y", 0);
87 if (old.width != geom.width)
88 luaA_object_emit_signal(globalconf.L, didx, "property::width", 0);
89 if (old.height != geom.height)
90 luaA_object_emit_signal(globalconf.L, didx, "property::height", 0);
93 /** Get a drawable's surface
94 * \param L The Lua VM state.
95 * \param drawable The drawable object.
96 * \return The number of elements pushed on stack.
98 static int
99 luaA_drawable_get_surface(lua_State *L, drawable_t *drawable)
101 /* Lua gets its own reference which it will have to destroy */
102 lua_pushlightuserdata(L, cairo_surface_reference(drawable->surface));
103 return 1;
106 /** Refresh a drawable's content. This has to be called whenever some drawing to
107 * the drawable's surface has been done and should become visible.
108 * \param L The Lua VM state.
109 * \return The number of elements pushed on stack.
111 static int
112 luaA_drawable_refresh(lua_State *L)
114 drawable_t *drawable = luaA_checkudata(L, 1, &drawable_class);
115 drawable->refreshed = true;
116 (*drawable->refresh_callback)(drawable->refresh_data);
118 return 0;
121 /** Return drawable geometry.
122 * \param L The Lua VM state.
123 * \return The number of elements pushed on stack.
124 * \luastack
125 * \lreturn A table with drawable coordinates.
127 static int
128 luaA_drawable_geometry(lua_State *L)
130 drawable_t *d = luaA_checkudata(L, 1, &drawable_class);
131 return luaA_pusharea(L, d->geometry);
134 void
135 drawable_class_setup(lua_State *L)
137 static const struct luaL_Reg drawable_methods[] =
139 LUA_CLASS_METHODS(drawable)
140 { NULL, NULL }
143 static const struct luaL_Reg drawable_meta[] =
145 LUA_OBJECT_META(drawable)
146 LUA_CLASS_META
147 { "refresh", luaA_drawable_refresh },
148 { "geometry", luaA_drawable_geometry },
149 { NULL, NULL },
152 luaA_class_setup(L, &drawable_class, "drawable", NULL,
153 (lua_class_allocator_t) drawable_new,
154 (lua_class_collector_t) drawable_wipe, NULL,
155 luaA_class_index_miss_property, luaA_class_newindex_miss_property,
156 drawable_methods, drawable_meta);
157 luaA_class_add_property(&drawable_class, "surface",
158 NULL,
159 (lua_class_propfunc_t) luaA_drawable_get_surface,
160 NULL);
162 signal_add(&drawable_class.signals, "button::press");
163 signal_add(&drawable_class.signals, "button::release");
164 signal_add(&drawable_class.signals, "mouse::enter");
165 signal_add(&drawable_class.signals, "mouse::leave");
166 signal_add(&drawable_class.signals, "mouse::move");
167 signal_add(&drawable_class.signals, "property::height");
168 signal_add(&drawable_class.signals, "property::width");
169 signal_add(&drawable_class.signals, "property::x");
170 signal_add(&drawable_class.signals, "property::y");
171 signal_add(&drawable_class.signals, "property::surface");
174 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80