/* * \brief Launchpad main program * \date 2006-08-30 * \author Norman Feske */ /* * Copyright (C) 2006-2012 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ #include "config.h" #include "elements.h" #include "platform.h" #include "canvas_rgb565.h" #include "tick.h" #include "redraw_manager.h" #include "user_state.h" #include "launchpad_window.h" #include "printf.h" #include #include #include /** * Runtime configuration */ namespace Config { int iconbar_detail = 1; int background_detail = 1; int mouse_cursor = 1; int browser_attr = 0; } extern int native_startup(int, char **); /** * Facility to keep the available quota display up-to-date */ class Avail_quota_update : public Tick { private: Launchpad *_launchpad; Genode::size_t _avail; public: /** * Constructor */ Avail_quota_update(Launchpad *launchpad): _launchpad(launchpad), _avail(0) { schedule(200); } /** * Tick interface */ int on_tick() { Genode::size_t new_avail = Genode::env()->ram_session()->avail(); /* update launchpad window if needed */ if (new_avail != _avail) _launchpad->quota(new_avail); _avail = new_avail; /* schedule next tick */ return 1; } }; /** * Process launchpad XML configuration */ static void process_config(Launchpad *launchpad) { using namespace Genode; Xml_node config_node = config()->xml_node(); /* * Iterate through all entries of the config file and create * launchpad entries as specified. */ int launcher_cnt = 0; for (unsigned i = 0; i < config_node.num_sub_nodes(); i++) { Xml_node node = config_node.sub_node(i); if (node.has_type("launcher")) /* catch XML syntax errors within launcher node */ try { /* read file name and default quote from launcher node */ Xml_node filename_node = node.sub_node("filename"); size_t filename_len = filename_node.content_size(); char *filename = (char *)env()->heap()->alloc(filename_len + 1); if (!filename) { ::printf("Error: Out of memory while processing configuration\n"); return; } filename_node.value(filename, filename_len + 1); Xml_node ram_quota_node = node.sub_node("ram_quota"); Number_of_bytes default_ram_quota = 0; ram_quota_node.value(&default_ram_quota); /* obtain configuration for the child */ Init::Child_config *config = new (env()->heap()) Init::Child_config(Genode::env()->ram_session_cap(), node); /* add launchpad entry */ launchpad->add_launcher(filename, default_ram_quota, config->dataspace()); launcher_cnt++; } catch (...) { ::printf("Warning: Launcher entry %d is malformed.\n", launcher_cnt + 1); } else { char buf[32]; node.type_name(buf, sizeof(buf)); ::printf("Warning: Ignoring unsupported tag <%s>.\n", buf); } } } static long read_int_attr_from_config(const char *attr, long default_value) { long result = default_value; try { Genode::config()->xml_node().attribute(attr).value(&result); } catch (...) { } return result; } /** * Main program */ int main(int argc, char **argv) { using namespace Genode; if (native_startup(argc, argv)) return -1; /* look for dynamic linker */ try { static Genode::Rom_connection rom("ld.lib.so"); Genode::Process::dynamic_linker(rom.dataspace()); } catch (...) { } long initial_x = read_int_attr_from_config("xpos", 550); long initial_y = read_int_attr_from_config("ypos", 150); long initial_w = read_int_attr_from_config("width", 400); long initial_h = read_int_attr_from_config("height", 400); /* init platform */ static Platform pf(initial_x, initial_y, initial_w, initial_h, 400); /* init canvas */ static Chunky_canvas canvas; canvas.init(static_cast(pf.buf_adr()), pf.scr_w()*pf.scr_h()); canvas.set_size(pf.scr_w(), pf.scr_h()); canvas.clip(0, 0, pf.scr_w(), pf.scr_h()); /* init redraw manager */ static Redraw_manager redraw(&canvas, &pf, pf.vw(), pf.vh()); /* create instance of launchpad window */ static Launchpad_window launchpad( &pf, &redraw, pf.scr_w(), pf.scr_h(), env()->ram_session()->avail() ); /* request config file from ROM service */ try { process_config(&launchpad); /* if there exists no configuration, use defaults */ } catch (...) { launchpad.add_launcher("testnit", 512*1024); launchpad.add_launcher("scout", 11*1024*1024); launchpad.add_launcher("launchpad", 6*1024*1024); launchpad.add_launcher("nitlog", 1*1024*1024); launchpad.add_launcher("liquid_fb", 7*1024*1024); launchpad.add_launcher("nitpicker", 1*1024*1024); } Avail_quota_update avail_quota_update(&launchpad); /* create user state manager */ static User_state user_state(&launchpad, &launchpad, pf.vx(), pf.vy()); /* assign launchpad window as root element to redraw manager */ redraw.root(&launchpad); pf.view_geometry(pf.vx(), pf.vy(), pf.vw(), pf.vh()); launchpad.parent(&user_state); launchpad.format(pf.vw(), pf.vh()); launchpad.ypos(0); Genode::printf("--- entering main loop ---\n"); /* enter main loop */ Event ev; unsigned long curr_time, old_time; curr_time = old_time = pf.timer_ticks(); do { pf.get_event(&ev); launchpad.gui_lock.lock(); if (ev.type != Event::WHEEL) { ev.mx -= user_state.vx(); ev.my -= user_state.vy(); } user_state.handle_event(ev); if (ev.type == Event::REFRESH) pf.scr_update(0, 0, pf.scr_w(), pf.scr_h()); if (ev.type == Event::TIMER) Tick::handle(pf.timer_ticks()); /* perform periodic redraw */ curr_time = pf.timer_ticks(); if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) { old_time = curr_time; redraw.process(); } launchpad.gui_lock.unlock(); } while (ev.type != Event::QUIT); return 0; }