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 <l4/mag-gfx/geometry>
11 #include <l4/mag-gfx/canvas>
14 #include <l4/util/util.h>
16 #include <l4/cxx/iostream>
17 #include <l4/cxx/exceptions>
18 #include <l4/re/util/cap_alloc>
19 #include <l4/re/error_helper>
22 #include <l4/re/video/goos>
23 #include <l4/re/util/video/goos_fb>
24 #include <l4/re/util/br_manager>
25 #include <l4/re/util/debug>
37 #include "background.h"
38 #include "big_mouse.h"
39 #include "input_driver"
40 #include "object_gc.h"
46 using namespace Mag_server;
48 extern char const _binary_mag_lua_start[];
49 extern char const _binary_mag_lua_end[];
50 extern char const _binary_default_tff_start[];
52 namespace Mag_server {
54 Core_api_impl *core_api;
59 static void start_plugins(Core_api *core)
61 for (Plugin *p = Plugin::_first; p; p = p->_next)
72 class My_reg : public Registry, private Object_gc
75 My_reg(My_reg const &);
76 void operator = (My_reg const &);
78 class Del_handler : public L4::Irqep_t<Del_handler>
84 explicit Del_handler(Object_gc *gc) : gc(gc) {}
90 L4::Cap<L4::Irq> _del_irq;
93 My_reg(L4::Ipc_svr::Server_iface *sif) : Registry(sif)
95 _del_irq = register_irq_obj(new Del_handler(this));
97 _server->register_del_irq(_del_irq);
100 void add_gc_obj(Object *o)
102 Object_gc::add_obj(o);
105 void gc_obj(Object *o)
113 poll_input(Core_api_impl *core)
115 for (Input_source *i = core->input_sources(); i; i = i->next())
119 class Loop_hooks : public L4::Ipc_svr::Ignore_errors,
120 public L4Re::Util::Br_manager
123 l4_kernel_clock_t to;
126 to = l4_kip_clock(l4re_kip()) + 40000;
129 l4_timeout_t timeout()
130 { return l4_timeout(L4_IPC_TIMEOUT_0, l4_timeout_abs(to, 8)); }
132 void setup_wait(l4_utcb_t *utcb, L4::Ipc_svr::Reply_mode reply_mode)
134 if (to <= l4_kip_clock(l4re_kip())
135 && reply_mode == L4::Ipc_svr::Reply_separate)
137 poll_input(core_api);
138 core_api->user_state()->vstack()->flush();
141 while (to - 10000 < l4_kip_clock(l4re_kip()))
145 Br_manager::setup_wait(utcb, reply_mode);
148 L4::Ipc_svr::Reply_mode before_reply(l4_msgtag_t, l4_utcb_t *)
150 if (to <= l4_kip_clock(l4re_kip()))
151 return L4::Ipc_svr::Reply_separate;
152 return L4::Ipc_svr::Reply_compound;
156 static L4::Server<Loop_hooks> server(l4_utcb());
157 static My_reg registry(&server);
159 using L4Re::Util::Auto_cap;
163 static void test_texture(Texture *t)
165 char *tb = (char *)t->pixels();
166 for (int y = 0; y < t->size().h(); ++y)
167 for (int x = 0; x < t->size().w(); ++x)
169 t->type()->set(tb, Pixel_info::Col(x*400, y*300, x*y, 0));
170 tb += t->type()->bytes;
175 int load_lua_plugin(Core_api *core_api, char const *name)
177 char const *n = name;
179 if (access(n, F_OK) != 0)
182 printf("loading '%s'\n", n);
184 lua_State *_l = core_api->lua_state();
185 int err = luaL_dofile(_l, n);
188 printf("ERROR: loading '%s': %s\n", n, lua_tostring(_l, -1));
189 lua_pop(_l, lua_gettop(_l));
193 lua_pop(_l, lua_gettop(_l));
197 int load_so_plugin(Core_api *core_api, char const *name)
199 static char const *const pfx = "libmag-";
200 static char const *const sfx = ".so";
201 char *n = new char [strlen(name) + strlen(pfx) + strlen(sfx) + 1];
203 strcpy(n + strlen(pfx), name);
204 strcpy(n + strlen(pfx) + strlen(name), sfx);
206 printf("loading '%s'\n", n);
208 void *pl = dlopen(n, RTLD_LAZY);
211 printf("ERROR: loading '%s': %s\n", n, dlerror());
217 void (*ini)(Core_api*) = (void (*)(Core_api*))dlsym(pl, "init_plugin");
224 static const luaL_Reg libs[] =
226 { "_G", luaopen_base },
227 {LUA_LOADLIBNAME, luaopen_package},
228 // { LUA_IOLIBNAME, luaopen_io },
229 { LUA_STRLIBNAME, luaopen_string },
230 {LUA_LOADLIBNAME, luaopen_package},
231 {LUA_DBLIBNAME, luaopen_debug},
232 {LUA_TABLIBNAME, luaopen_table},
236 struct Err : L4Re::Util::Err { Err() : L4Re::Util::Err(Fatal, "") {} };
238 int run(int argc, char const *argv[])
243 dbg.printf("Hello from MAG\n");
244 L4Re::Env const *env = L4Re::Env::env();
246 L4::Cap<L4Re::Video::Goos> fb
247 = chkcap(env->get_cap<L4Re::Video::Goos>("fb"), "requesting frame-buffer", 0);
249 L4Re::Util::Video::Goos_fb goos_fb(fb);
250 L4Re::Video::View::Info view_i;
251 chksys(goos_fb.view_info(&view_i), "requesting frame-buffer info");
253 L4Re::Rm::Auto_region<char *> fb_addr;
254 chksys(env->rm()->attach(&fb_addr, goos_fb.buffer()->size(),
255 L4Re::Rm::Search_addr,
256 L4::Ipc::make_cap_rw(goos_fb.buffer()),
257 0, L4_SUPERPAGESHIFT));
259 dbg.printf("mapped frame buffer at %p\n", fb_addr.get());
261 Screen_factory *f = dynamic_cast<Screen_factory*>(Screen_factory::set.find(view_i.pixel_info));
264 printf("ERROR: could not start screen driver for given video mode.\n"
265 " Maybe unsupported pixel format... exiting\n");
269 Canvas *screen = f->create_canvas(fb_addr.get() + view_i.buffer_offset,
270 Area(view_i.width, view_i.height), view_i.bytes_per_line);
273 dbg.printf(" memory %p - %p\n", (void*)fb_addr.get(),
274 (void*)(fb_addr.get() + goos_fb.buffer()->size()));
278 p_err.printf("ERROR: could not start screen driver for given video mode.\n"
279 " Maybe unsupported pixel format... exiting\n");
283 View *cursor = f->create_cursor(big_mouse);
284 Background bg(screen->size());
286 L4Re::Video::View *screen_view = 0;
289 L4Re::Video::Goos::Info i;
290 goos_fb.goos()->info(&i);
291 if (!i.auto_refresh())
292 screen_view = goos_fb.view();
295 lua_State *lua = luaL_newstate();
299 p_err.printf("ERROR: cannot allocate Lua state\n");
304 lua_setglobal(lua, "Mag");
306 for (int i = 0; libs[i].func; ++i)
308 luaL_requiref(lua, libs[i].name, libs[i].func, 1);
313 static Font label_font(&_binary_default_tff_start[0]);
314 static View_stack vstack(screen, screen_view, &bg, &label_font);
315 static User_state user_state(lua, &vstack, cursor);
316 static Core_api_impl core_api(®istry, lua, &user_state, fb, &label_font);
317 Mag_server::core_api = &core_api;
320 if ((err = luaL_loadbuffer(lua, _binary_mag_lua_start, _binary_mag_lua_end - _binary_mag_lua_start, "@mag.lua")))
322 p_err.printf("lua error: %s.\n", lua_tostring(lua, -1));
323 lua_pop(lua, lua_gettop(lua));
324 if (err == LUA_ERRSYNTAX)
325 throw L4::Runtime_error(L4_EINVAL, lua_tostring(lua, -1));
327 throw L4::Out_of_memory(lua_tostring(lua, -1));
330 if ((err = lua_pcall(lua, 0, 1, 0)))
332 p_err.printf("lua error: %s.\n", lua_tostring(lua, -1));
333 lua_pop(lua, lua_gettop(lua));
334 if (err == LUA_ERRSYNTAX)
335 throw L4::Runtime_error(L4_EINVAL, lua_tostring(lua, -1));
337 throw L4::Out_of_memory(lua_tostring(lua, -1));
340 lua_pop(lua, lua_gettop(lua));
342 Plugin_manager::start_plugins(&core_api);
344 for (int i = 1; i < argc; ++i)
346 if (load_lua_plugin(&core_api, argv[i]) == 1)
347 load_so_plugin(&core_api, argv[i]);
350 server.loop<L4::Runtime_error>(®istry);
356 int main(int argc, char const *argv[])
360 return run(argc, argv);
362 catch (L4::Runtime_error const &e)
364 L4::cerr << "Error: " << e << '\n';
366 catch (L4::Base_exception const &e)
368 L4::cerr << "Error: " << e << '\n';
370 catch (std::exception const &e)
372 L4::cerr << "Error: " << e.what() << '\n';