2 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>,
4 * Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
5 * economic rights: Technische Universität Dresden (Germany)
7 * This file is part of TUD:OS and distributed under the terms of the
8 * GNU General Public License 2.
9 * Please see the COPYING-GPL-2 file for details.
13 #include <l4/re/namespace>
14 #include <l4/re/util/cap_alloc>
15 #include <l4/re/util/br_manager>
17 #include <l4/sys/capability>
18 #include <l4/sys/factory>
19 #include <l4/cxx/ipc_timeout_queue>
20 #include <l4/sys/cxx/ipc_epiface>
21 #include <l4/cxx/minmax>
24 #include <l4/l4con/l4con.h>
25 #include <l4/input/libinput.h>
27 #include <l4/re/util/video/goos_svr>
28 #include <l4/re/util/video/goos_fb>
29 #include <l4/re/util/event_svr>
30 #include <l4/re/util/event_buffer>
31 #include <l4/re/util/cap_alloc>
32 #include <l4/re/console>
34 #include "object_registry_gc"
41 // XXX: why is this in the L4Re::Util namespace ???
43 L4::Ipc_svr::Ignore_errors,
44 L4::Ipc_svr::Timeout_queue_hooks<My_hooks, L4Re::Util::Br_manager>
46 static l4_cpu_time_t now()
47 { return l4_kip_clock(l4re_kip()); }
50 static L4::Server<My_hooks> con_server(l4_utcb());
51 static L4Re::Util::Object_registry_gc
52 con_registry(&con_server,
53 L4Re::Env::env()->main_thread(),
54 L4Re::Env::env()->factory());
56 class Vc : public L4Re::Util::Video::Goos_svr,
57 public L4Re::Util::Event_svr<Vc>,
58 public L4::Epiface_t<Vc, L4con>,
62 using L4Re::Util::Video::Goos_svr::op_info;
63 using L4Re::Util::Event_svr<Vc>::op_info;
68 void setup_info(l4con_vc *vc);
69 void reg_fbds(l4_cap_idx_t c);
70 void send_event(l4input *ev);
75 long op_close(L4con::Rights)
78 long op_pslim_fill(L4con::Rights, int x, int y, int w, int h,
79 l4con_pslim_color_t color)
81 l4con_pslim_rect_t r(x, y, w, h);
82 return con_vc_pslim_fill_component(this, &r, color);
85 long op_pslim_copy(L4con::Rights, int x, int y, int w, int h,
86 l4_int16_t dx, l4_int16_t dy)
88 l4con_pslim_rect_t r(x, y, w, h);
89 return con_vc_pslim_copy_component(this, &r, dx, dy);
92 long op_puts(L4con::Rights, short x, short y, l4con_pslim_color_t fg_color,
93 l4con_pslim_color_t bg_color,
94 L4::Ipc::Array_in_buf<char, unsigned long> const &text)
96 return con_vc_puts_component(this, text.data, text.length, x, y,
100 long op_puts_scale(L4con::Rights, short x, short y, l4con_pslim_color_t fg_color,
101 l4con_pslim_color_t bg_color, short scale_x, short scale_y,
102 L4::Ipc::Array_in_buf<char, unsigned long> const &text)
104 return con_vc_puts_scale_component(this, text.data, text.length, x, y,
105 fg_color, bg_color, scale_x, scale_y);
108 long op_get_font_size(L4con::Rights, short &w, short &h)
116 virtual int refresh(int x, int y, int w, int h);
118 void reset_event_buffer() { evbuf.reset(); }
120 L4Re::Util::Event_buffer evbuf;
128 Vc::refresh(int x, int y, int w, int h)
130 l4con_pslim_rect_t r;
135 return con_vc_direct_update_component(this, &r);
143 L4Re::Util::Auto_cap<L4Re::Dataspace>::Cap b
144 = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
148 if ((r = L4Re::Env::env()->mem_alloc()->alloc(L4_PAGESIZE, b.get())) < 0)
151 if ((r = evbuf.attach(b.get(), L4Re::Env::env()->rm())) < 0)
154 memset(evbuf.buf(), 0, b.get()->size());
164 return con_vc_close_component(this);
169 con_vc_close_component(this);
173 extern "C" l4con_vc *alloc_vc()
176 extern "C" void create_event(struct l4con_vc *vc)
177 { ((Vc *)vc)->create_event(); }
180 Vc::setup_info(l4con_vc *vc)
182 _screen_info.pixel_info = *(L4Re::Video::Pixel_info *)&fb_info.pixel_info;
183 _screen_info.width = vc->client_xres;
184 _screen_info.height = vc->client_yres;
185 _screen_info.flags = 0;
186 _screen_info.num_static_views = 1;
187 _screen_info.num_static_buffers = 1;
191 _view_info.buffer_offset = 0;
192 _view_info.bytes_per_line = vc->bytes_per_line;
196 Vc::send_event(l4input *ev)
198 evbuf.put(*reinterpret_cast<L4Re::Event_buffer::Event const*>(ev));
199 static_assert(sizeof(L4Re::Event_buffer::Event) == sizeof(*ev),
204 extern "C" void fill_out_info(l4con_vc *vc)
205 { ((Vc *)vc)->setup_info(vc); }
207 extern "C" void send_event_client(struct l4con_vc *vc, l4input *ev)
210 printf("WARNING: Emiting invalid event!\n");
212 if (vc_mode & CON_IN)
213 ((Vc *)vc)->send_event(ev);
216 extern "C" void register_fb_ds(struct l4con_vc *vc)
217 { ((Vc *)vc)->reg_fbds(vc->vfb_ds); }
221 Vc::reg_fbds(l4_cap_idx_t c)
223 L4::Cap<L4Re::Dataspace> t(c);
227 class Controller : public L4::Epiface_t<Controller, L4::Factory>
230 long op_create(L4::Factory::Rights, L4::Ipc::Cap<void> &obj,
231 long type, L4::Ipc::Varg_list<> &&)
233 if (!L4::kobject_typeid<L4con>()->has_proto(type))
236 int connum = con_if_open_component(CON_VFB);
240 con_registry.register_obj_with_gc((Vc *)vc[connum], 0);
242 obj = L4::Ipc::make_cap(((Vc *)vc[connum])->obj_cap(), L4_CAP_FPAGE_RWSD);
247 // ---------------------------------------------------------------
248 struct Periodic : L4::Ipc_svr::Timeout_queue::Timeout
253 con_registry.gc_run(500);
254 con_server.queue.add(this, timeout() + REQUEST_TIMEOUT_DELTA);
258 static Periodic periodic;
260 int server_loop(void)
262 static Controller ctrl;
263 con_server.queue.add(&periodic,
264 l4_kip_clock(l4re_kip()) + REQUEST_TIMEOUT_DELTA);
266 if (!con_registry.register_obj(&ctrl, "con"))
268 printf("Service registration failed.\n");
272 printf("Ready. Waiting for clients\n");
273 con_server.loop<L4::Runtime_error, L4Re::Util::Object_registry_gc &>(con_registry);