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 (ust->vstack()->mode().kill())
154 v->handle_event(e, ust->mouse_pos());
159 static int user_state_post_pointer_event(lua_State *l)
161 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
163 if (ust->vstack()->mode().kill())
166 View *v = ust->kbd_focus();
167 if (!lua_isnil(l, 2))
168 v = lua_check_class<Lua_view_proxy>(l, 2)->view();
173 Point m = ust->mouse_pos();
175 e.time = lua_tonumber(l, 4);
176 e.payload.stream_id = (l4_umword_t)lua_touserdata(l, 3);
177 e.payload.type = L4RE_EV_ABS;
178 e.payload.code = L4RE_ABS_X;
179 e.payload.value = m.x();
180 v->handle_event(e, ust->mouse_pos());
181 e.payload.code = L4RE_ABS_Y;
182 e.payload.value = m.y();
183 v->handle_event(e, ust->mouse_pos());
188 static int user_state_set_pointer(lua_State *l)
190 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
193 x = lua_tointeger(l, 2);
194 y = lua_tointeger(l, 3);
195 ust->set_pointer(x, y);
199 static int user_state_move_pointer(lua_State *l)
201 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
204 x = lua_tointeger(l, 2);
205 y = lua_tointeger(l, 3);
206 ust->move_pointer(x, y);
211 static int user_state_toggle_mode(lua_State *l)
213 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
216 x = lua_tointeger(l, 2);
217 ust->vstack()->toggle_mode((Mag_server::Mode::Mode_flag)x);
221 static int user_state_find_pointed_view(lua_State *l)
223 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
224 Lua_view_proxy *vp = lua_check_class<Lua_view_proxy>(l, 2);
225 vp->view(ust->vstack()->find(ust->mouse_pos()));
229 static int user_state_create_view_proxy(lua_State *l)
231 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
232 if (lua_alloc_class<Lua_view_proxy>(l, ust))
239 static int lua_view_proxy_set(lua_State *l)
241 int top = lua_gettop(l);
242 Lua_view_proxy *d = lua_check_class<Lua_view_proxy>(l, 1);
244 if (top >= 2 || !lua_isnil(l, 2))
245 sv = lua_check_class<Lua_view_proxy>(l, 2)->view();
250 static int user_state_set_kbd_focus(lua_State *l)
252 int top = lua_gettop(l);
253 User_state *ust = lua_check_class<Lua_user_state>(l, 1)->u;
255 if (top >= 2 && !lua_isnil(l,2))
256 v = lua_check_class<Lua_view_proxy>(l, 2)->view();
258 lua_pushboolean(l, ust->set_focus(v));
263 char const *const Lua_user_state::_class = "Mag_server.User_state_class";
264 char const *const Lua_view_proxy::_class = "Mag_server.View_proxy_class";
267 luaL_Reg const Lua_user_state::_ops[] =
268 { { "set_pointer", &user_state_set_pointer },
269 { "move_pointer", &user_state_move_pointer },
270 { "set_kbd_focus", &user_state_set_kbd_focus },
271 { "post_event", &user_state_post_event },
272 { "post_pointer_event", &user_state_post_pointer_event },
273 { "toggle_mode", &user_state_toggle_mode },
274 { "create_view_proxy", &user_state_create_view_proxy },
275 { "find_pointed_view", &user_state_find_pointed_view },
279 luaL_Reg const Lua_view_proxy::_ops[] =
280 { { "set", &lua_view_proxy_set },
288 static void dump_stack(lua_State *l)
290 int i = lua_gettop(l);
293 int t = lua_type(l, i);
297 printf("#%02d: '%s'\n", i, lua_tostring(l, i));
300 printf("#%02d: %s\n", i, lua_toboolean(l, i) ? "true" : "false");
303 printf("#%02d: %g\n", i, lua_tonumber(l, i));
306 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");
327 lua_alloc_class<Lua_view_proxy>(l, u->u);
328 lua_setfield(l, -2, "focused_view");
333 User_state::User_state(lua_State *lua, View_stack *_vstack, View *cursor)
334 : _vstack(_vstack), _mouse_pos(0,0), _keyboard_focus(0),
335 _mouse_cursor(cursor), _l(lua)
337 lua_getglobal(_l, "Mag");
338 lua_alloc_class<Lua_user_state>(_l, this);
339 lua_setfield(_l, -2, "user_state");
341 lua_pushcfunction(_l, &Lua::ab_create);
342 lua_setfield(_l, -2, "Axis_buf");
347 vstack()->push_top(_mouse_cursor, true);
348 vstack()->update_all_views();
351 User_state::~User_state()
353 lua_getglobal(_l, "Mag");
355 lua_setfield(_l, -2, "user_state");
360 User_state::forget_view(View *v)
362 vstack()->forget_view(v);
363 for (View_proxy *p = _view_proxies; p; p = p->_n)
366 if (_keyboard_focus == v)
371 User_state::set_focus(View *v)
373 if (_keyboard_focus == v)
377 _keyboard_focus->set_focus(false);
386 User_state::handle_event(Event const &e)
388 lua_getfield(_l, LUA_GLOBALSINDEX, "handle_event");
389 lua_pushlightuserdata(_l, const_cast<Event *>(&e));
390 if (lua_pcall(_l, 1, 0, 0))
392 fprintf(stderr, "ERROR: lua event handling returned: %s.\n", lua_tostring(_l, -1));