2 * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
17 #include <l4/cxx/exceptions>
18 #include <l4/re/event_enums.h>
22 namespace Mag_server {
25 User_state::set_pointer(int x, int y)
28 Rect scr(Point(0, 0), vstack()->canvas()->size());
35 vstack()->viewport(_mouse_cursor, Rect(_mouse_pos, _mouse_cursor->size()), true);
50 Axis_buf(unsigned char _s) : s(_s-1) { assert ((_s & s) == 0); }
51 l4_int32_t get(unsigned char idx) const { return v[idx & s]; }
52 void set(unsigned char idx, l4_int32_t val) { v[idx & s] = val; }
54 static char const *const _class;
55 static luaL_Reg const _ops[];
58 static int ab_get(lua_State *l)
60 Axis_buf *s = lua_check_class<Axis_buf>(l, 1);
61 int idx = lua_tointeger(l, 2);
62 lua_pushinteger(l, s->get(idx));
66 static int ab_set(lua_State *l)
68 Axis_buf *s = lua_check_class<Axis_buf>(l, 1);
69 int idx = lua_tointeger(l, 2);
70 s->set(idx, lua_tointeger(l, 3));
74 static int ab_copy(lua_State *l)
76 Axis_buf *s = lua_check_class<Axis_buf>(l, 1);
77 int idx1 = lua_tointeger(l, 2);
78 int idx2 = lua_tointeger(l, 3);
79 s->set(idx1, s->get(idx2));
83 static int ab_create(lua_State *l)
85 unsigned long sz = lua_tointeger(l, 1);
87 for (z = 0; z < 8 && (1UL << z) < sz; ++z)
90 unsigned long msz = sizeof(Axis_buf) + sizeof(l4_int32_t) * sz;
91 new (lua_newuserdata(l, msz)) Axis_buf(sz);
93 if (luaL_newmetatable(l, Axis_buf::_class))
95 lua_pushcfunction(l, &ab_set);
96 lua_setfield(l, -2, "__newindex");
98 Lua_register_ops<Axis_buf>::init(l);
99 lua_setfield(l, -2, "__index");
101 lua_setmetatable(l, -2);
105 char const *const Axis_buf::_class = "Mag_server.Lua.Axis_buf";
106 luaL_Reg const Axis_buf::_ops[] = {
109 { "copy", &ab_copy },
117 struct Lua_user_state
120 static char const *const _class;
121 static luaL_Reg const _ops[];
122 explicit Lua_user_state(User_state *u) : u(u) {}
125 struct Lua_view_proxy : public User_state::View_proxy
127 explicit Lua_view_proxy(User_state *u) : View_proxy(u) {}
128 static char const *const _class;
129 static luaL_Reg const _ops[];
132 static int user_state_post_event(lua_State *l)
134 int top = lua_gettop(l);
135 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
136 View *v = ust->kbd_focus();
137 if (top >= 2 && !lua_isnil(l, 2))
138 v = lua_check_class<Lua_view_proxy>(l, 2)->view();
141 e.time = lua_tonumber(l, 4);
142 e.payload.stream_id = (l4_umword_t)lua_touserdata(l, 3);
143 e.payload.type = lua_tointeger(l, 5);
144 e.payload.code = lua_tointeger(l, 6);
145 e.payload.value = lua_tointeger(l, 7);
147 if (top >= 8 && lua_toboolean(l, 8))
148 ust->vstack()->update_all_views();
150 if (v && (!ust->vstack()->mode().kill() || v->super_view()))
151 v->handle_event(e, ust->mouse_pos());
156 static int user_state_post_pointer_event(lua_State *l)
158 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
161 View *v = ust->kbd_focus();
162 if (!lua_isnil(l, 2))
163 v = lua_check_class<Lua_view_proxy>(l, 2)->view();
168 if (ust->vstack()->mode().kill() && !v->super_view())
171 Point m = ust->mouse_pos();
173 e.time = lua_tonumber(l, 4);
174 e.payload.stream_id = (l4_umword_t)lua_touserdata(l, 3);
175 e.payload.type = L4RE_EV_ABS;
176 e.payload.code = L4RE_ABS_X;
177 e.payload.value = m.x();
178 v->handle_event(e, ust->mouse_pos());
179 e.payload.code = L4RE_ABS_Y;
180 e.payload.value = m.y();
181 v->handle_event(e, ust->mouse_pos());
186 static int user_state_set_pointer(lua_State *l)
188 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
191 x = lua_tointeger(l, 2);
192 y = lua_tointeger(l, 3);
193 ust->set_pointer(x, y);
197 static int user_state_move_pointer(lua_State *l)
199 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
202 x = lua_tointeger(l, 2);
203 y = lua_tointeger(l, 3);
204 ust->move_pointer(x, y);
209 static int user_state_toggle_mode(lua_State *l)
211 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
214 x = lua_tointeger(l, 2);
215 ust->vstack()->toggle_mode((Mag_server::Mode::Mode_flag)x);
219 static int user_state_find_pointed_view(lua_State *l)
221 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
222 Lua_view_proxy *vp = lua_check_class<Lua_view_proxy>(l, 2);
223 vp->view(ust->vstack()->find(ust->mouse_pos()));
227 static int user_state_create_view_proxy(lua_State *l)
229 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
230 if (lua_alloc_class<Lua_view_proxy>(l, ust))
237 static int lua_view_proxy_set(lua_State *l)
239 int top = lua_gettop(l);
240 Lua_view_proxy *d = lua_check_class<Lua_view_proxy>(l, 1);
242 if (top >= 2 || !lua_isnil(l, 2))
243 sv = lua_check_class<Lua_view_proxy>(l, 2)->view();
248 static int user_state_set_kbd_focus(lua_State *l)
250 int top = lua_gettop(l);
251 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
253 if (top >= 2 && !lua_isnil(l,2))
254 v = lua_check_class<Lua_view_proxy>(l, 2)->view();
256 lua_pushboolean(l, ust->set_focus(v));
261 char const *const Lua_user_state::_class = "Mag_server.User_state_class";
262 char const *const Lua_view_proxy::_class = "Mag_server.View_proxy_class";
265 luaL_Reg const Lua_user_state::_ops[] =
266 { { "set_pointer", &user_state_set_pointer },
267 { "move_pointer", &user_state_move_pointer },
268 { "set_kbd_focus", &user_state_set_kbd_focus },
269 { "post_event", &user_state_post_event },
270 { "post_pointer_event", &user_state_post_pointer_event },
271 { "toggle_mode", &user_state_toggle_mode },
272 { "create_view_proxy", &user_state_create_view_proxy },
273 { "find_pointed_view", &user_state_find_pointed_view },
277 luaL_Reg const Lua_view_proxy::_ops[] =
278 { { "set", &lua_view_proxy_set },
287 static void dump_stack(lua_State *l)
289 int i = lua_gettop(l);
292 int t = lua_type(l, i);
296 printf("#%02d: '%s'\n", i, lua_tostring(l, i));
299 printf("#%02d: %s\n", i, lua_toboolean(l, i) ? "true" : "false");
302 printf("#%02d: %g\n", i, lua_tonumber(l, i));
305 printf("#%02d: [%s] %p\n", i, lua_typename(l, t), lua_topointer(l, i));
315 struct Lua_register_ops<Lua_user_state>
317 static void init(lua_State *l)
319 luaL_register(l, NULL, Lua_user_state::_ops);
320 Lua_user_state *u = (Lua_user_state*)lua_touserdata(l, -3);
321 Area sz = u->u->vstack()->canvas()->size();
322 lua_pushinteger(l, sz.w());
323 lua_setfield(l, -2, "width");
324 lua_pushinteger(l, sz.h());
325 lua_setfield(l, -2, "height");
330 User_state::User_state(lua_State *lua, View_stack *_vstack, View *cursor)
331 : _vstack(_vstack), _mouse_pos(0,0), _keyboard_focus(0),
332 _mouse_cursor(cursor), _l(lua)
334 lua_getglobal(_l, "Mag");
335 lua_alloc_class<Lua_user_state>(_l, this);
336 lua_setfield(_l, -2, "user_state");
338 lua_pushcfunction(_l, &Lua::ab_create);
339 lua_setfield(_l, -2, "Axis_buf");
344 vstack()->push_top(_mouse_cursor, true);
345 vstack()->update_all_views();
348 User_state::~User_state()
350 lua_getglobal(_l, "Mag");
352 lua_setfield(_l, -2, "user_state");
357 User_state::forget_view(View *v)
359 vstack()->forget_view(v);
360 for (View_proxy *p = _view_proxies; p; p = p->_n)
363 if (_keyboard_focus == v)
366 if (_vstack->focused() == v)
367 _vstack->set_focused(0);
371 User_state::set_focus(View *v)
373 if (_keyboard_focus == v)
377 _keyboard_focus->set_focus(false);
379 _vstack->set_focused(v);
388 User_state::handle_event(Event const &e)
390 lua_getfield(_l, LUA_GLOBALSINDEX, "handle_event");
391 lua_pushlightuserdata(_l, const_cast<Event *>(&e));
392 if (lua_pcall(_l, 1, 0, 0))
394 fprintf(stderr, "ERROR: lua event handling returned: %s.\n", lua_tostring(_l, -1));