]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/mag/plugins/client_fb/client_fb.cc
0c3a3cab229a408eff8e17395693a1ef6becaea2
[l4.git] / l4 / pkg / mag / plugins / client_fb / client_fb.cc
1 /*
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)
5  *
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.
9  */
10 #include "client_fb.h"
11
12 #include <l4/mag-gfx/clip_guard>
13 #include <l4/mag-gfx/texture>
14
15 #include <l4/mag/server/view_stack>
16
17 #include <l4/re/env>
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>
23
24 #include <l4/mag/server/user_state>
25 #include <cstdio>
26
27
28 namespace Mag_server {
29
30 using L4Re::chksys;
31 using L4Re::chkcap;
32
33 Client_fb::Client_fb(Core_api const *core, Rect const &pos, Point const &offs,
34                      Texture *fb, L4::Cap<L4Re::Dataspace> const &fb_ds)
35 : View(pos, F_need_frame),
36   Icu_svr(1, &_ev_irq),
37   _core(core), _offs(offs), _fb(fb),
38   _bar_size(pos.w(), 16)
39 {
40   using L4Re::Video::View;
41   using L4Re::Video::Color_component;
42   using L4Re::Video::Goos;
43
44   _fb_ds = fb_ds;
45   _view_info.flags = View::F_none;
46
47   _view_info.view_index = 0;
48   _view_info.xpos = 0;
49   _view_info.ypos = 0;
50   _view_info.width = fb->size().w();
51   _view_info.height = fb->size().h();
52   _view_info.buffer_offset = 0;
53   _view_info.buffer_index = 0;
54   _view_info.bytes_per_line = _view_info.width * fb->type()->bytes_per_pixel();
55   _view_info.pixel_info = *fb->type();
56
57   _screen_info.flags = Goos::F_pointer;
58   _screen_info.width = _view_info.width;
59   _screen_info.height = _view_info.height;
60   _screen_info.num_static_views = 1;
61   _screen_info.num_static_buffers = 1;
62   _screen_info.pixel_info = _view_info.pixel_info;
63
64
65   L4Re::Env const *e = L4Re::Env::env();
66   _ev_ds = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
67
68   chksys(e->mem_alloc()->alloc(L4_PAGESIZE, _ev_ds.get()));
69   chksys(e->rm()->attach(&_ev_ds_m, L4_PAGESIZE, L4Re::Rm::Search_addr, _ev_ds.get(), 0, L4_PAGESHIFT));
70
71   _events = L4Re::Event_buffer(_ev_ds_m.get(), L4_PAGESIZE);
72 }
73
74 void
75 Client_fb::draw(Canvas *canvas, View_stack const *, Mode mode, bool focused) const
76 {
77   /* use dimming in x-ray mode */
78   Canvas::Mix_mode op = mode.flat() ? Canvas::Solid : Canvas::Mixed;
79
80   /* is this the currently focused view? */
81   Rgb32::Color frame_color = focused ? Rgb32::White : View::frame_color();
82
83   /* do not dim the focused view in x-ray mode */
84   if (mode.xray() && !mode.kill() && focused)
85     op = Canvas::Solid;
86
87   /*
88    * The view content and label should never overdraw the
89    * frame of the view in non-flat Nitpicker modes. The frame
90    * is located outside the view area. By shrinking the
91    * clipping area to the view area, we protect the frame.
92    */
93   Clip_guard clip_guard(canvas, *this);
94
95   /*
96    * If the clipping area shrinked to zero,
97    * we do not process drawing operations.
98    */
99   if (!canvas->clip_valid()/* || !_session*/)
100     return;
101
102   /* draw view content */
103   Rgb32::Color mix_color = mode.kill() ? kill_color() : Rgb32::Black;
104
105   canvas->draw_box(Rect(p1(), _bar_size), Rgb32::Color(56, 68,88));
106
107   canvas->draw_texture(_fb, mix_color, _offs + p1() + Point(0, _bar_size.h()), op);
108
109 #if 0
110   if (mode.flat())
111     return;
112
113   /* draw label */
114   draw_label(canvas, _label_rect.p1(), _session->label(), WHITE, _title, frame_color);
115 #endif
116 }
117
118 void
119 Client_fb::handle_event(L4Re::Event_buffer::Event const &e,
120                         Point const &mouse)
121 {
122   static Point left_drag;
123
124   if (e.payload.type == L4RE_EV_MAX && left_drag != Point())
125     {
126       Rect npos = Rect(p1() + mouse - left_drag, size());
127       left_drag = mouse;
128       _core->user_state()->vstack()->viewport(this, npos, true);
129       return;
130     }
131
132   if (e.payload.type == L4RE_EV_KEY)
133     {
134       View_stack *_stack = _core->user_state()->vstack();
135       if (e.payload.code == L4RE_BTN_LEFT && e.payload.value == 1 &&
136           !_stack->on_top(this))
137         _stack->push_top(this);
138
139       if (e.payload.code == L4RE_BTN_LEFT && Rect(p1(), _bar_size).contains(mouse))
140         {
141           if (e.payload.value == 1)
142             left_drag = mouse;
143           else if (e.payload.value == 0)
144             left_drag = Point();
145           return;
146         }
147     }
148
149   if (e.payload.type == L4RE_EV_MAX)
150     {
151       Rect r = (*this - Rect(p1(), _bar_size)).b;
152       if (!r.contains(mouse))
153         return;
154
155       L4Re::Event_buffer::Event ne;
156       ne.time = e.time;
157       ne.payload.type = L4RE_EV_ABS;
158       ne.payload.code = L4RE_ABS_X;
159       ne.payload.value = mouse.x() - p1().x();
160       ne.payload.stream_id = 0;
161       _events.put(ne);
162       ne.payload.code = L4RE_ABS_Y;
163       ne.payload.value = mouse.y() - p1().y() - _bar_size.h();
164       _events.put(ne);
165       _ev_irq.trigger();
166       return;
167     }
168
169   if (_events.put(e))
170     _ev_irq.trigger();
171
172 }
173
174
175 int
176 Client_fb::refresh(int x, int y, int w, int h)
177 {
178   _core->user_state()->vstack()->refresh_view(this, 0, Rect(p1() + Point(x, y + _bar_size.h()), Area(w, h)));
179   return 0;
180 }
181
182 int
183 Client_fb::dispatch(l4_umword_t obj, L4::Ipc_iostream &s)
184 {
185   l4_msgtag_t tag;
186   s >> tag;
187
188   switch (tag.label())
189     {
190     case L4::Meta::Protocol:
191       return L4Re::Util::handle_meta_request<L4Re::Console>(s);
192     case L4_PROTO_IRQ:
193       return Icu_svr::dispatch(obj, s);
194     case L4Re::Protocol::Goos:
195       return L4Re::Util::Video::Goos_svr::dispatch(obj, s);
196     case L4Re::Protocol::Event:
197         {
198           L4::Opcode op;
199           s >> op;
200           switch (op)
201             {
202             case L4Re::Event_::Get:
203               s << _ev_ds.get();
204               return L4_EOK;
205             default:
206               return -L4_ENOSYS;
207             }
208         }
209     default:
210       return -L4_EBADPROTO;
211     }
212 }
213
214
215 void
216 Client_fb::destroy()
217 {
218   _core->user_state()->forget_view(this);
219   delete _fb;
220   _fb = 0;
221 }
222
223 }