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/minmax>
22 #include <l4/re/protocols>
25 #include <l4/l4con/l4con.h>
26 #include <l4/input/libinput.h>
28 #include <l4/re/util/video/goos_svr>
29 #include <l4/re/util/video/goos_fb>
30 #include <l4/re/util/event_svr>
31 #include <l4/re/util/event_buffer>
32 #include <l4/re/util/cap_alloc>
34 #include "object_registry_gc"
41 // ---------------------------------------------------------------
43 static L4::Cap<void> rcv_cap()
45 static L4::Cap<void> _rcv_cap = L4Re::Util::cap_alloc.alloc<void>();
49 // XXX: why is this in the L4Re::Util namespace ???
50 static L4Re::Util::Object_registry_gc
51 con_registry(L4Re::Env::env()->main_thread(),
52 L4Re::Env::env()->factory());
54 class Vc : public L4Re::Util::Video::Goos_svr,
55 public L4Re::Util::Event_svr<Vc>,
56 public L4::Server_object,
62 int dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios);
64 void setup_info(l4con_vc *vc);
65 void reg_fbds(l4_cap_idx_t c);
66 void send_event(l4input *ev);
70 long pslim_fill(L4::Ipc::Iostream &ios);
71 long pslim_copy(L4::Ipc::Iostream &ios);
72 long puts(L4::Ipc::Iostream &ios);
73 long puts_scale(L4::Ipc::Iostream &ios);
74 long get_font_size(L4::Ipc::Iostream &ios);
76 virtual int refresh(int x, int y, int w, int h);
78 long vc_dispatch(L4::Ipc::Iostream &ios);
80 static L4::Cap<void> rcv_cap() { return ::rcv_cap(); }
81 void reset_event_buffer() { evbuf.reset(); }
83 L4Re::Util::Event_buffer evbuf;
91 Vc::refresh(int x, int y, int w, int h)
98 return con_vc_direct_update_component(this, &r);
106 L4Re::Util::Auto_cap<L4Re::Dataspace>::Cap b
107 = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
111 if ((r = L4Re::Env::env()->mem_alloc()->alloc(L4_PAGESIZE, b.get())) < 0)
114 if ((r = evbuf.attach(b.get(), L4Re::Env::env()->rm())) < 0)
117 memset(evbuf.buf(), 0, b.get()->size());
127 return con_vc_close_component(this);
132 con_vc_close_component(this);
136 Vc::pslim_fill(L4::Ipc::Iostream &ios)
138 l4con_pslim_rect_t r;
139 l4con_pslim_color_t c;
142 ios >> x >> y >> w >> h >> c;
149 return con_vc_pslim_fill_component(this, &r, c);
153 Vc::pslim_copy(L4::Ipc::Iostream &ios)
155 l4con_pslim_rect_t r;
159 ios >> x >> y >> w >> h >> dx >> dy;
166 return con_vc_pslim_copy_component(this, &r, dx, dy);
170 Vc::puts(L4::Ipc::Iostream &ios)
177 l4con_pslim_color_t fg_color;
178 l4con_pslim_color_t bg_color;
180 ios >> x >> y >> fg_color >> bg_color
181 >> L4::Ipc::Buf_in<char>(s, len);
183 len = cxx::min<unsigned long>(len, sizeof(buf));
186 return con_vc_puts_component(this, buf, len, x, y, fg_color, bg_color);
190 Vc::puts_scale(L4::Ipc::Iostream &ios)
195 short x, y, scale_x, scale_y;
196 l4con_pslim_color_t fg_color;
197 l4con_pslim_color_t bg_color;
199 ios >> x >> y >> fg_color >> bg_color >> scale_x >> scale_y
200 >> L4::Ipc::Buf_in<char>(s, len);
202 len = cxx::min<unsigned long>(len, sizeof(buf));
205 return con_vc_puts_scale_component(this, buf, len, x, y, fg_color, bg_color,
210 Vc::get_font_size(L4::Ipc::Iostream &ios)
212 int w = FONT_XRES, h = FONT_YRES;
218 Vc::vc_dispatch(L4::Ipc::Iostream &ios)
223 if (tag.label() != L4con::Protocol)
224 return -L4_EBADPROTO;
231 case L4con::L4con_::Close:
233 case L4con::L4con_::Pslim_fill:
234 return pslim_fill(ios);
235 case L4con::L4con_::Puts:
237 case L4con::L4con_::Puts_scale:
238 return puts_scale(ios);
239 case L4con::L4con_::Get_font_size:
240 return get_font_size(ios);
247 Vc::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
253 case L4::Meta::Protocol:
254 return L4::Util::handle_meta_request<L4con>(ios);
255 case L4Re::Protocol::Goos:
256 return L4Re::Util::Video::Goos_svr::dispatch(obj, ios);
257 case L4Re::Protocol::Event:
259 return L4Re::Util::Event_svr<Vc>::dispatch(obj, ios);
260 case L4con::Protocol:
261 return vc_dispatch(ios);
263 return -L4_EBADPROTO;
267 extern "C" l4con_vc *alloc_vc()
270 extern "C" void create_event(struct l4con_vc *vc)
271 { ((Vc *)vc)->create_event(); }
274 Vc::setup_info(l4con_vc *vc)
276 _screen_info.pixel_info = *(L4Re::Video::Pixel_info *)&fb_info.pixel_info;
277 _screen_info.width = vc->client_xres;
278 _screen_info.height = vc->client_yres;
279 _screen_info.flags = 0;
280 _screen_info.num_static_views = 1;
281 _screen_info.num_static_buffers = 1;
285 _view_info.buffer_offset = 0;
286 _view_info.bytes_per_line = vc->bytes_per_line;
290 Vc::send_event(l4input *ev)
292 evbuf.put(*reinterpret_cast<L4Re::Event_buffer::Event const*>(ev));
293 static_assert(sizeof(L4Re::Event_buffer::Event) == sizeof(*ev),
298 extern "C" void fill_out_info(l4con_vc *vc)
299 { ((Vc *)vc)->setup_info(vc); }
301 extern "C" void send_event_client(struct l4con_vc *vc, l4input *ev)
304 printf("WARNING: Emiting invalid event!\n");
306 if (vc_mode & CON_IN)
307 ((Vc *)vc)->send_event(ev);
310 extern "C" void register_fb_ds(struct l4con_vc *vc)
311 { ((Vc *)vc)->reg_fbds(vc->vfb_ds); }
315 Vc::reg_fbds(l4_cap_idx_t c)
317 L4::Cap<L4Re::Dataspace> t(c);
321 class Controller : public L4::Server_object
324 int dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios);
328 Controller::dispatch(l4_umword_t, L4::Ipc::Iostream &ios)
335 case L4::Meta::Protocol:
336 return L4::Util::handle_meta_request<L4::Factory>(ios);
337 case L4::Factory::Protocol:
340 return -L4_EBADPROTO;
343 if (!L4::kobject_typeid<L4con>()->
344 has_proto(L4::Ipc::read<L4::Factory::Proto>(ios)))
347 int connum = con_if_open_component(CON_VFB);
351 con_registry.register_obj_with_gc((Vc *)vc[connum], 0);
353 //con_registry.ref_cnt_add((Vc *)vc[connum], -1);
354 ios << ((Vc *)vc[connum])->obj_cap();
358 // ---------------------------------------------------------------
360 class My_timeout_hooks
363 static l4_cpu_time_t next_timeout(l4_cpu_time_t old)
364 { return old + REQUEST_TIMEOUT_DELTA; }
366 static l4_cpu_time_t current_time()
367 { return l4re_kip()->clock; }
372 con_registry.gc_run(500);
375 void setup_wait(L4::Ipc::Istream &istr, L4::Ipc_svr::Reply_mode)
378 istr << L4::Ipc::Small_buf(rcv_cap().cap(), L4_RCV_ITEM_LOCAL_ID);
379 l4_utcb_br_u(istr.utcb())->bdr = 0;
382 static int timeout_br() { return 8; }
386 public L4::Ipc_svr::Ignore_errors,
387 public L4::Ipc_svr::Timed_work<My_timeout_hooks>
390 static L4::Server<My_hooks> con_server(l4_utcb());
392 int server_loop(void)
394 static Controller ctrl;
396 if (!con_registry.register_obj(&ctrl, "con"))
398 printf("Service registration failed.\n");
402 printf("Ready. Waiting for clients\n");
403 con_server.loop(con_registry);