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.
10 #include "input_source"
17 #include <l4/cxx/exceptions>
18 #include <l4/re/event_enums.h>
22 #include "lua_glue.swg.h"
24 //#define CONFIG_SCREENSHOT
25 #if defined (CONFIG_SCREENSHOT)
31 using namespace Mag_server;
33 static void base64_encodeblock(char const *_in, char *out)
35 unsigned char const *in = (unsigned char const *)_in;
37 out[0] = (in[0] >> 2) + ' ';
38 out[1] = (((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)) + ' ';
39 out[2] = (((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)) + ' ';
40 out[3] = (in[2] & 0x3f) + ' ';
43 static void uuencode(char const *in, unsigned long bytes)
62 base64_encodeblock(in, out);
71 printf("%c%s\n", cnt + ' ', uubuf);
75 static void maybe_screenshot(User_state *ust, User_state::Event const &e)
77 if (e.payload.type != L4RE_EV_KEY || e.payload.value != 1
78 || e.payload.code != L4RE_KEY_F12)
83 printf("Start screen shot ==========================\n");
84 printf("begin 600 screenshot.Z\n");
90 s.next_in = (Bytef*)ust->vstack()->canvas()->buffer();
91 s.avail_in = ust->vstack()->canvas()->size().h() * ust->vstack()->canvas()->bytes_per_line();
92 s.total_in = s.avail_in;
95 deflateInit2(&s, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY);
99 flush = s.avail_in ? Z_NO_FLUSH : Z_FINISH;
102 s.next_out = (Bytef*)obuf;
103 s.avail_out = sizeof(obuf);
105 if (deflate(&s, flush) == Z_STREAM_ERROR)
107 printf("\nERROR: compressing screenshot\n");
111 unsigned b = sizeof(obuf) - s.avail_out;
115 while (s.avail_out == 0);
117 while (flush != Z_FINISH); //s.avail_out == 0);
121 printf("\nEND screen shot ==========================\n");
126 inline void maybe_screenshot(Mag_server::User_state *, Mag_server::User_state::Event const &) {}
129 int luaopen_Mag(lua_State*);
131 namespace Mag_server {
133 User_state *user_state;
135 Hid_report::Hid_report(l4_umword_t dev_id, unsigned rels, unsigned abss, unsigned mscs,
136 unsigned sws, unsigned mts)
137 : _device_id(dev_id), _kevs(0), _abs_info(0)
139 _vals[0].create(rels, 0);
140 _vals[1].create(abss, 0);
141 _vals[2].create(mscs, 0);
142 _vals[3].create(sws, 0);
148 _mt = new Valuator<int>[_mts];
151 for (unsigned i = 0; i < _mts; ++i)
152 _mt[i].create(Num_mt_vals, Mt_val_offset); // 13 mt axes, currently
155 Hid_report::~Hid_report()
164 for (unsigned i = 0; i < Num_types; ++i)
167 for (unsigned i = 0; i < _mts; ++i)
173 Valuator<int> const *
174 Hid_report::get_vals(unsigned char type) const
176 // check for out of range...
177 if (type < Type_offset || (type = type - Type_offset) >= Num_types)
184 Hid_report::get_vals(unsigned char type)
186 // check for out of range...
187 if (type < Type_offset || (type = type - Type_offset) >= Num_types)
193 Valuator<int> const *
194 Hid_report::get_mt_vals(unsigned id) const
196 if (_mts && id < _mts - 1)
203 Hid_report::get(unsigned char type, unsigned code, int &val) const
205 // check for out of range...
206 if (type < Type_offset || (type = type - Type_offset) >= Num_types)
209 if (!_vals[type].valid(code))
212 val = _vals[type][code].val();
217 Hid_report::set(unsigned char type, unsigned code, int val)
219 // check for out of range...
220 if (type < Type_offset || (type = type - Type_offset) >= Num_types)
223 _vals[type].set(code, val);
227 Hid_report::mt_get(unsigned id, unsigned code, int &val) const
232 if (!_mt[id].valid(code))
235 val = _mt[id][code].val();
240 Hid_report::mt_set(unsigned code, int val)
245 _mt[_mts-1].set(code, val);
249 Hid_report::submit_mt()
254 Valuator<int> &s = _mt[_mts-1];
255 Value<int> id = s[0x39];
262 if (id.val() >= (long)_mts - 1)
268 _mt[id.val()].swap(s);
273 Hid_report::add_key(int code, int value)
275 if (_kevs >= Num_key_events)
278 _kev[_kevs].code = code;
279 _kev[_kevs].value = value;
284 Hid_report::Key_event const *
285 Hid_report::get_key_event(unsigned idx) const
293 Hid_report::Key_event const *
294 Hid_report::find_key_event(int code) const
296 for (unsigned i = 0; i < _kevs; ++i)
297 if (_kev[i].code == code)
304 Hid_report::remove_key_event(int code)
307 for (i = 0; i < _kevs && _kev[i].code != code; ++i)
313 memmove(_kev + i, _kev + i + 1, (_kevs - i - 1) * sizeof(Key_event));
319 User_state::set_pointer(int x, int y, bool hide)
322 Rect scr(Point(0, 0), vstack()->canvas()->size());
327 if (hide && _mouse_cursor->x1() < scr.x2())
328 vstack()->viewport(_mouse_cursor, Rect(scr.p2(), _mouse_cursor->size()), true);
330 if (!hide && _mouse_cursor->p1() != _mouse_pos)
331 vstack()->viewport(_mouse_cursor, Rect(_mouse_pos, _mouse_cursor->size()), true);
335 static void dump_stack(lua_State *l)
337 int i = lua_gettop(l);
340 int t = lua_type(l, i);
344 printf("#%02d: '%s'\n", i, lua_tostring(l, i));
347 printf("#%02d: %s\n", i, lua_toboolean(l, i) ? "true" : "false");
350 printf("#%02d: %g\n", i, lua_tonumber(l, i));
353 printf("#%02d: [%s] %p\n", i, lua_typename(l, t), lua_topointer(l, i));
362 User_state::User_state(lua_State *lua, View_stack *_vstack, View *cursor)
363 : _vstack(_vstack), _mouse_pos(0,0), _keyboard_focus(0),
364 _mouse_cursor(cursor), _l(lua)
369 vstack()->push_top(_mouse_cursor, true);
370 Point pos(vstack()->canvas()->size());
371 vstack()->viewport(_mouse_cursor, Rect(pos, _mouse_cursor->size()), true);
373 vstack()->update_all_views();
377 User_state::~User_state()
383 User_state::forget_view(View *v)
385 vstack()->forget_view(v);
386 for (View_proxy *p = _view_proxies; p; p = p->_n)
389 if (_keyboard_focus == v)
392 if (_vstack->focused() == v)
394 _vstack->set_focused(0);
395 _vstack->update_all_views();
400 User_state::set_focus(View *v)
402 if (_keyboard_focus == v)
406 _keyboard_focus->set_focus(false);
408 _vstack->set_focused(v);
417 User_state::get_input_stream_info_for_id(l4_umword_t id, Input_info *info) const
420 int top = lua_gettop(l);
421 lua_getglobal(l, "input_source_info");
422 lua_pushinteger(l, id);
423 if (lua_pcall(l, 1, 2, 0))
425 fprintf(stderr, "ERROR: lua event handling returned: %s.\n", lua_tostring(l, -1));
430 int r = lua_tointeger(l, -2);
438 L4Re::Event_stream_info *i = 0;
439 swig_type_info *type = SWIG_TypeQuery(l, "L4Re::Event_stream_info *");
442 fprintf(stderr, "Ooops: did not find type 'L4Re::Event_stream_info'\n");
446 if (!SWIG_IsOK(SWIG_ConvertPtr(l, -1, (void**)&i, type, 0)))
448 fprintf(stderr, "Ooops: expected 'L4Re::Event_stream_info' as arg 2\n");
465 User_state::get_input_axis_info(l4_umword_t id, unsigned naxes, unsigned const *axis,
466 Input_absinfo *info, unsigned char *ax_mode) const
469 int top = lua_gettop(l);
470 lua_getglobal(l, "input_source_abs_info");
471 lua_pushinteger(l, id);
472 for (unsigned i = 0; i < naxes; ++i)
473 lua_pushinteger(l, axis[i]);
475 if (lua_pcall(l, 1 + naxes, 1 + naxes, 0))
477 fprintf(stderr, "ERROR: lua event handling returned: %s.\n", lua_tostring(l, -1));
482 int r = lua_tointeger(l, top + 1);
489 for (unsigned i = 0; i < naxes; ++i)
491 int ndx = top + i + 2;
492 if (!lua_istable(l, ndx) && !lua_isuserdata(l, ndx))
494 fprintf(stderr, "ERROR: lua event handling returned: %s.\n", lua_tostring(l, top + 1));
499 lua_getfield(l, ndx, "value");
500 info[i].value = lua_tointeger(l, -1);
503 lua_getfield(l, ndx, "min");
504 info[i].min = lua_tointeger(l, -1);
507 lua_getfield(l, ndx, "max");
508 info[i].max = lua_tointeger(l, -1);
511 lua_getfield(l, ndx, "fuzz");
512 info[i].fuzz = lua_tointeger(l, -1);
515 lua_getfield(l, ndx, "flat");
516 info[i].flat = lua_tointeger(l, -1);
519 lua_getfield(l, ndx, "resolution");
520 info[i].resolution = lua_tointeger(l, -1);
525 lua_getfield(l, ndx, "mode");
526 ax_mode[i] = lua_tointeger(l, -1);