1 /*
2  * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
3  *     economic rights: Technische Universität Dresden (Germany)
4  *
5  * This file is part of TUD:OS and distributed under the terms of the
6  * GNU General Public License 2.
7  * Please see the COPYING-GPL-2 file for details.
8  *
9  * As a special exception, you may use this file as part of a free software
10  * library without restriction.  Specifically, if other files instantiate
11  * templates or use macros or inline functions from this file, or you compile
12  * this file and link it with other files to produce an executable, this
13  * file does not by itself cause the resulting executable to be covered by
14  * the GNU General Public License.  This exception does not however
15  * invalidate any other reasons why the executable file might be covered by
16  * the GNU General Public License.
17  */
18 
19 #include <l4/re/error_helper>
20 #include <l4/re/util/video/goos_fb>
21 #include <l4/re/util/cap_alloc>
22 #include <l4/re/util/env_ns>
23 
24 #include <l4/re/rm>
25 #include <l4/re/env>
26 #include <l4/re/namespace>
27 
28 namespace L4Re { namespace Util { namespace Video {
29 
30 void
init()31 Goos_fb::init()
32 {
33   using namespace L4Re::Video;
34   using L4Re::chksys;
35   using L4Re::chkcap;
36 
37   Goos::Info gi;
38   chksys(_goos->info(&gi), "requesting goos info");
39 
40   if (gi.has_dynamic_views())
41     {
42       chksys(_goos->create_view(&_view), "createing dynamic goos view");
43       _flags |= F_dyn_view;
44     }
45   else // we just assume view 0 to be our's and ignore other possible views
46     _view = _goos->view(0);
47 
48   View::Info vi;
49   chksys(_view.info(&vi), "requesting goos view information");
50 
51   _buffer = chkcap(cap_alloc.alloc<L4Re::Dataspace>(),
52                    "allocating goos buffer cap");
53 
54   if (vi.has_static_buffer())
55     chksys(_goos->get_static_buffer(vi.buffer_index, _buffer),
56            "requesting static goos buffer");
57   else
58     {
59       unsigned long buffer_sz = gi.pixel_info.bytes_per_pixel() * gi.width * gi.height;
60       _buffer_index = chksys(_goos->create_buffer(buffer_sz, _buffer),
61                              "allocating goos buffer");
62       _flags |= F_dyn_buffer;
63 
64       // use the allocated buffer, at offset 0
65       vi.buffer_index = _buffer_index;
66       vi.buffer_offset = 0;
67       vi.pixel_info = gi.pixel_info;
68       vi.bytes_per_line = gi.width * gi.pixel_info.bytes_per_pixel();
69 
70       // we want a fullscreen view
71       vi.xpos = 0;
72       vi.ypos = 0;
73       vi.width = gi.width;
74       vi.height = gi.height;
75 
76       chksys(_view.set_info(vi), "setting up dynamic view");
77       chksys(_view.push_top(), "bringing view to top");
78     }
79 }
80 
81 void
setup(L4::Cap<L4Re::Video::Goos> goos)82 Goos_fb::setup(L4::Cap<L4Re::Video::Goos> goos)
83 {
84   _goos = goos;
85   init();
86 }
87 
88 void
setup(char const * name)89 Goos_fb::setup(char const *name)
90 {
91   Env_ns ns;
92   //_goos = chkcap(cap_alloc.alloc<L4Re::Video::Goos>(), "allocating goos cap");
93   _goos = chkcap(ns.query<L4Re::Video::Goos>(name), "requesting goos cap", 0);
94   _flags |= F_dyn_goos;
95 
96   //chksys(L4Re::Env::env()->names()->query(name, _goos), "requesting goos service");
97   init();
98 }
99 
Goos_fb(L4::Cap<L4Re::Video::Goos> goos)100 Goos_fb::Goos_fb(L4::Cap<L4Re::Video::Goos> goos)
101 : _goos(goos), _buffer(L4_INVALID_CAP), _flags(0)
102 { init(); }
103 
104 
Goos_fb(char const * name)105 Goos_fb::Goos_fb(char const *name)
106 : _goos(L4_INVALID_CAP), _buffer(L4_INVALID_CAP), _flags(0)
107 { setup(name); }
108 
109 void *
attach_buffer()110 Goos_fb::attach_buffer()
111 {
112   void *fb_addr = 0;
113   L4Re::chkcap(_goos);
114   L4Re::chksys(L4Re::Env::env()->rm()
115       ->attach(&fb_addr, _buffer->size(),
116                L4Re::Rm::F::Search_addr | L4Re::Rm::F::RW, _buffer,
117                0, L4_SUPERPAGESHIFT), "attaching frame-buffer memory");
118   return fb_addr;
119 }
120 
~Goos_fb()121 Goos_fb::~Goos_fb()
122 {
123   if (!_goos.is_valid())
124     return;
125 
126   if (_flags & F_dyn_view)
127     _goos->delete_view(_view);
128 
129   if (_flags & F_dyn_buffer)
130     _goos->delete_buffer(_buffer_index);
131 
132   if (_buffer.is_valid())
133     cap_alloc.free(_buffer);
134 
135   if (_flags & F_dyn_goos)
136     cap_alloc.free(_goos);
137 }
138 
139 
140 }}}
141