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>
16 #include <l4/sys/capability>
17 #include <l4/sys/factory>
18 #include <l4/sys/typeinfo_svr>
19 #include <l4/cxx/ipc_server>
20 #include <l4/cxx/iostream>
21 #include <l4/cxx/l4iostream>
22 #include <l4/cxx/minmax>
24 #include <l4/re/protocols>
27 #include <l4/l4con/l4con.h>
28 #include <l4/input/libinput.h>
30 #include <l4/re/util/video/goos_svr>
31 #include <l4/re/util/video/goos_fb>
32 #include <l4/re/util/event_svr>
33 #include <l4/re/util/event_buffer>
34 #include <l4/re/util/cap_alloc>
36 #include "object_registry_gc"
43 // ---------------------------------------------------------------
45 static L4::Cap<void> rcv_cap()
47 static L4::Cap<void> _rcv_cap = L4Re::Util::cap_alloc.alloc<void>();
51 // XXX: why is this in the L4Re::Util namespace ???
52 static L4Re::Util::Object_registry_gc
53 con_registry(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::Server_object,
64 int dispatch(l4_umword_t obj, L4::Ipc_iostream &ios);
66 void setup_info(l4con_vc *vc);
67 void reg_fbds(l4_cap_idx_t c);
68 void send_event(l4input *ev);
72 long pslim_fill(L4::Ipc_iostream &ios);
73 long pslim_copy(L4::Ipc_iostream &ios);
74 long puts(L4::Ipc_iostream &ios);
75 long puts_scale(L4::Ipc_iostream &ios);
76 long get_font_size(L4::Ipc_iostream &ios);
78 virtual int refresh(int x, int y, int w, int h);
80 long vc_dispatch(L4::Ipc_iostream &ios);
82 static L4::Cap<void> rcv_cap() { return ::rcv_cap(); }
84 L4Re::Util::Event_buffer evbuf;
92 Vc::refresh(int x, int y, int w, int h)
99 return con_vc_direct_update_component(this, &r);
107 L4Re::Util::Auto_cap<L4Re::Dataspace>::Cap b
108 = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
112 if ((r = L4Re::Env::env()->mem_alloc()->alloc(L4_PAGESIZE, b.get())) < 0)
115 if ((r = evbuf.attach(b.get(), L4Re::Env::env()->rm())) < 0)
118 memset(evbuf.buf(), 0, b.get()->size());
128 return con_vc_close_component(this);
133 con_vc_close_component(this);
137 Vc::pslim_fill(L4::Ipc_iostream &ios)
139 l4con_pslim_rect_t r;
140 l4con_pslim_color_t c;
143 ios >> x >> y >> w >> h >> c;
150 return con_vc_pslim_fill_component(this, &r, c);
154 Vc::pslim_copy(L4::Ipc_iostream &ios)
156 l4con_pslim_rect_t r;
160 ios >> x >> y >> w >> h >> dx >> dy;
167 return con_vc_pslim_copy_component(this, &r, dx, dy);
171 Vc::puts(L4::Ipc_iostream &ios)
178 l4con_pslim_color_t fg_color;
179 l4con_pslim_color_t bg_color;
181 ios >> x >> y >> fg_color >> bg_color
182 >> L4::ipc_buf_in(s, len);
184 len = cxx::min<unsigned long>(len, sizeof(buf));
187 return con_vc_puts_component(this, buf, len, x, y, fg_color, bg_color);
191 Vc::puts_scale(L4::Ipc_iostream &ios)
196 short x, y, scale_x, scale_y;
197 l4con_pslim_color_t fg_color;
198 l4con_pslim_color_t bg_color;
200 ios >> x >> y >> fg_color >> bg_color >> scale_x >> scale_y
201 >> L4::ipc_buf_in(s, len);
203 len = cxx::min<unsigned long>(len, sizeof(buf));
206 return con_vc_puts_scale_component(this, buf, len, x, y, fg_color, bg_color,
211 Vc::get_font_size(L4::Ipc_iostream &ios)
213 int w = FONT_XRES, h = FONT_YRES;
219 Vc::vc_dispatch(L4::Ipc_iostream &ios)
224 if (tag.label() != L4con::Protocol)
225 return -L4_EBADPROTO;
232 case L4con::L4con_::Close:
234 case L4con::L4con_::Pslim_fill:
235 return pslim_fill(ios);
236 case L4con::L4con_::Puts:
238 case L4con::L4con_::Puts_scale:
239 return puts_scale(ios);
240 case L4con::L4con_::Get_font_size:
241 return get_font_size(ios);
248 Vc::dispatch(l4_umword_t obj, L4::Ipc_iostream &ios)
254 case L4::Meta::Protocol:
255 return L4::Util::handle_meta_request<L4con>(ios);
256 case L4Re::Protocol::Goos:
257 return L4Re::Util::Video::Goos_svr::dispatch(obj, ios);
258 case L4Re::Protocol::Event:
260 return L4Re::Util::Event_svr<Vc>::dispatch(obj, ios);
261 case L4con::Protocol:
262 return vc_dispatch(ios);
264 return -L4_EBADPROTO;
268 extern "C" l4con_vc *alloc_vc()
271 extern "C" void create_event(struct l4con_vc *vc)
272 { ((Vc *)vc)->create_event(); }
275 Vc::setup_info(l4con_vc *vc)
277 _screen_info.pixel_info = *(L4Re::Video::Pixel_info *)&fb_info.pixel_info;
278 _screen_info.width = vc->client_xres;
279 _screen_info.height = vc->client_yres;
280 _screen_info.flags = 0;
281 _screen_info.num_static_views = 1;
282 _screen_info.num_static_buffers = 1;
286 _view_info.buffer_offset = 0;
287 _view_info.bytes_per_line = vc->bytes_per_line;
291 Vc::send_event(l4input *ev)
293 evbuf.put(*reinterpret_cast<L4Re::Event_buffer::Event const*>(ev));
297 extern "C" void fill_out_info(l4con_vc *vc)
298 { ((Vc *)vc)->setup_info(vc); }
300 extern "C" void send_event_client(struct l4con_vc *vc, l4input *ev)
303 printf("WARNING: Emiting invalid event!\n");
305 if (vc_mode & CON_IN)
306 ((Vc *)vc)->send_event(ev);
309 extern "C" void register_fb_ds(struct l4con_vc *vc)
310 { ((Vc *)vc)->reg_fbds(vc->vfb_ds); }
314 Vc::reg_fbds(l4_cap_idx_t c)
316 L4::Cap<L4Re::Dataspace> t(c);
320 class Controller : public L4::Server_object
323 int dispatch(l4_umword_t obj, L4::Ipc_iostream &ios);
327 Controller::dispatch(l4_umword_t, L4::Ipc_iostream &ios)
334 case L4::Meta::Protocol:
335 return L4::Util::handle_meta_request<L4::Factory>(ios);
336 case L4::Factory::Protocol:
339 return -L4_EBADPROTO;
342 if (!L4::kobject_typeid<L4con>()->
343 has_proto(L4::Ipc::read<L4::Factory::Proto>(ios)))
346 int connum = con_if_open_component(CON_VFB);
350 con_registry.register_obj_with_gc((Vc *)vc[connum], 0);
352 //con_registry.ref_cnt_add((Vc *)vc[connum], -1);
353 ios << ((Vc *)vc[connum])->obj_cap();
357 // ---------------------------------------------------------------
359 class My_timeout_hooks
362 static l4_cpu_time_t next_timeout(l4_cpu_time_t old)
363 { return old + REQUEST_TIMEOUT_DELTA; }
365 static l4_cpu_time_t current_time()
366 { return l4re_kip()->clock; }
371 con_registry.gc_run(500);
374 void setup_wait(L4::Ipc_istream &istr, L4::Ipc_svr::Reply_mode)
377 istr << L4::Small_buf(rcv_cap().cap(), L4_RCV_ITEM_LOCAL_ID);
378 l4_utcb_br_u(istr.utcb())->bdr = 0;
381 static int timeout_br() { return 8; }
385 public L4::Ipc_svr::Ignore_errors,
386 public L4::Ipc_svr::Timed_work<My_timeout_hooks>
389 static L4::Server<My_hooks> con_server(l4_utcb());
391 int server_loop(void)
393 static Controller ctrl;
395 if (!con_registry.register_obj(&ctrl, "con"))
397 printf("Service registration failed.\n");
401 printf("Ready. Waiting for clients\n");
402 con_server.loop(con_registry);