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 "client_fb.h"
12 #include <l4/mag-gfx/clip_guard>
13 #include <l4/mag-gfx/texture>
15 #include <l4/mag/server/view_stack>
18 #include <l4/re/event_enums.h>
19 #include <l4/re/error_helper>
20 #include <l4/sys/factory>
21 #include <l4/re/util/meta>
22 #include <l4/re/console>
24 #include <l4/mag/server/user_state>
28 namespace Mag_server {
33 enum { Bar_height = 16 };
35 Client_fb::Client_fb(Core_api const *core, Rect const &pos, Point const &offs,
36 Texture *fb, L4::Cap<L4Re::Dataspace> const &fb_ds)
37 : View(pos.offset(0, 0, 0, Bar_height), F_need_frame),
39 _core(core), _offs(offs), _fb(fb),
40 _bar_size(pos.w(), Bar_height)
42 using L4Re::Video::View;
43 using L4Re::Video::Color_component;
44 using L4Re::Video::Goos;
47 _view_info.flags = View::F_none;
49 _view_info.view_index = 0;
52 _view_info.width = fb->size().w();
53 _view_info.height = fb->size().h();
54 _view_info.buffer_offset = 0;
55 _view_info.buffer_index = 0;
56 _view_info.bytes_per_line = _view_info.width * fb->type()->bytes_per_pixel();
57 _view_info.pixel_info = *fb->type();
59 _screen_info.flags = Goos::F_pointer;
60 _screen_info.width = _view_info.width;
61 _screen_info.height = _view_info.height;
62 _screen_info.num_static_views = 1;
63 _screen_info.num_static_buffers = 1;
64 _screen_info.pixel_info = _view_info.pixel_info;
67 L4Re::Env const *e = L4Re::Env::env();
68 _ev_ds = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
70 chksys(e->mem_alloc()->alloc(L4_PAGESIZE, _ev_ds.get()));
71 chksys(e->rm()->attach(&_ev_ds_m, L4_PAGESIZE, L4Re::Rm::Search_addr, _ev_ds.get(), 0, L4_PAGESHIFT));
73 _events = L4Re::Event_buffer(_ev_ds_m.get(), L4_PAGESIZE);
77 Client_fb::draw(Canvas *canvas, View_stack const *, Mode mode) const
79 /* use dimming in x-ray mode */
80 Canvas::Mix_mode op = mode.flat() ? Canvas::Solid : Canvas::Mixed;
82 /* is this the currently focused view? */
83 Rgb32::Color frame_color = focused() ? Rgb32::White : View::frame_color();
85 /* do not dim the focused view in x-ray mode */
86 if (mode.xray() && !mode.kill() && focused())
90 * The view content and label should never overdraw the
91 * frame of the view in non-flat Nitpicker modes. The frame
92 * is located outside the view area. By shrinking the
93 * clipping area to the view area, we protect the frame.
95 Clip_guard clip_guard(canvas, *this);
98 * If the clipping area shrinked to zero,
99 * we do not process drawing operations.
101 if (!canvas->clip_valid()/* || !_session*/)
104 /* draw view content */
105 Rgb32::Color mix_color = mode.kill() ? kill_color() : Rgb32::Black;
107 canvas->draw_box(Rect(p1(), _bar_size), Rgb32::Color(56, 68,88));
109 canvas->draw_texture(_fb, mix_color, _offs + p1() + Point(0, _bar_size.h()), op);
116 draw_label(canvas, _label_rect.p1(), _session->label(), WHITE, _title, frame_color);
121 Client_fb::handle_event(L4Re::Event_buffer::Event const &e,
124 static Point left_drag;
126 if (e.payload.type == L4RE_EV_ABS && e.payload.code == 1 && left_drag != Point())
128 Rect npos = Rect(p1() + mouse - left_drag, size());
130 _core->user_state()->vstack()->viewport(this, npos, true);
134 if (e.payload.type == L4RE_EV_KEY)
136 View_stack *_stack = _core->user_state()->vstack();
137 if (e.payload.code == L4RE_BTN_LEFT && e.payload.value == 1 &&
138 !_stack->on_top(this))
139 _stack->push_top(this);
141 if (e.payload.code == L4RE_BTN_LEFT && Rect(p1(), _bar_size).contains(mouse))
143 if (e.payload.value == 1)
145 else if (e.payload.value == 0)
151 if (e.payload.type == L4RE_EV_ABS && e.payload.code <= L4RE_ABS_Y)
153 // wait for the following ABS_Y axis
154 if (e.payload.type == L4RE_ABS_X)
157 Rect r = (*this - Rect(p1(), _bar_size)).b;
158 if (!r.contains(mouse))
161 Point mp = p1() + Point(0, _bar_size.h());
162 mp = Point(_fb->size()).min(Point(0,0).max(mouse - mp));
163 L4Re::Event_buffer::Event ne;
165 ne.payload.type = L4RE_EV_ABS;
166 ne.payload.code = L4RE_ABS_X;
167 ne.payload.value = mp.x();
168 ne.payload.stream_id = e.payload.stream_id;
170 ne.payload.code = L4RE_ABS_Y;
171 ne.payload.value = mp.y();
184 Client_fb::refresh(int x, int y, int w, int h)
186 _core->user_state()->vstack()->refresh_view(this, 0, Rect(p1() + Point(x, y + _bar_size.h()), Area(w, h)));
191 Client_fb::dispatch(l4_umword_t obj, L4::Ipc_iostream &s)
198 case L4::Meta::Protocol:
199 return L4Re::Util::handle_meta_request<L4Re::Console>(s);
201 return Icu_svr::dispatch(obj, s);
202 case L4Re::Protocol::Goos:
203 return L4Re::Util::Video::Goos_svr::dispatch(obj, s);
204 case L4Re::Protocol::Event:
210 case L4Re::Event_::Get:
218 return -L4_EBADPROTO;
226 _core->user_state()->forget_view(this);