L4Re - L4 Runtime Environment
goos
1 // vi:set ft=cpp: -*- Mode: C++ -*-
2 /*
3  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
4  * Alexander Warg <warg@os.inf.tu-dresden.de>
5  * economic rights: Technische Universit├Ąt Dresden (Germany)
6  *
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.
10  *
11  * As a special exception, you may use this file as part of a free software
12  * library without restriction. Specifically, if other files instantiate
13  * templates or use macros or inline functions from this file, or you compile
14  * this file and link it with other files to produce an executable, this
15  * file does not by itself cause the resulting executable to be covered by
16  * the GNU General Public License. This exception does not however
17  * invalidate any other reasons why the executable file might be covered by
18  * the GNU General Public License.
19  */
20 #pragma once
21 
22 #include <l4/sys/capability>
23 #include <l4/re/dataspace>
24 #include <l4/re/video/colors>
25 #include <l4/sys/cxx/ipc_iface>
26 
27 namespace L4Re { namespace Video {
28 
29 class L4_EXPORT Goos;
30 
31 /**
32  * \brief View.
33  */
34 class L4_EXPORT View
35 {
36 private:
37  friend class Goos;
38 
39  L4::Cap<Goos> _goos;
40  unsigned _view_idx;
41 
42  View(l4_cap_idx_t goos, unsigned idx)
43  : _goos(goos), _view_idx(_goos.is_valid() ? idx : ~0U) {}
44 
45  unsigned view_index() const throw()
46  { return _goos.is_valid() ? _view_idx : ~0U; }
47 
48 public:
49  View() : _goos(L4::Cap<Goos>::Invalid), _view_idx(~0U) {}
50 
51  /**
52  * \brief Flags on a view.
53  */
54  enum Flags
55  {
56  F_none = 0x00, ///< everything for this view is static (the VESA-FB case)
57  F_set_buffer = 0x01, ///< buffer object for this view can be changed
58  F_set_buffer_offset = 0x02, ///< buffer offset can be set
59  F_set_bytes_per_line = 0x04, ///< bytes per line can be set
60  F_set_pixel = 0x08, ///< pixel type can be set
61  F_set_position = 0x10, ///< position on screen can be set
62  F_dyn_allocated = 0x20, ///< View is dynamically allocated
63  F_set_background = 0x40, ///< Set view as background for session
64  F_set_flags = 0x80, ///< Set view flags (\see V_flags)
65 
66  /** Flags for a fully dynamic view */
67  F_fully_dynamic = F_set_buffer | F_set_buffer_offset | F_set_bytes_per_line
68  | F_set_pixel | F_set_position | F_dyn_allocated,
69  };
70 
71  /**
72  * \brief Property flags of a view.
73  *
74  * Such flags can be set or deleted with the #F_set_flags operation using
75  * the `set_info()` method.
76  */
77  enum V_flags
78  {
79  F_above = 0x1000, ///< Flag the view as stay on top
80  F_flags_mask = 0xff000, ///< Mask containing all possible property flags
81  };
82 
83  /**
84  * \brief Information structure of a view.
85  */
86  struct Info
87  {
88  unsigned flags; ///< Flags, see #Flags and #V_flags
89  unsigned view_index; ///< Index of the view
90 
91  unsigned long xpos; ///< X position in pixels of the view in the goos
92  unsigned long ypos; ///< Y position in pixels of the view in the goos
93  unsigned long width; ///< Width of the view in pixels
94  unsigned long height; ///< Height of the view in pixels
95  unsigned long buffer_offset; ///< Offset in the memory buffer in bytes
96  unsigned long bytes_per_line; ///< Bytes per line
97  Pixel_info pixel_info; ///< Pixel information
98  unsigned buffer_index; ///< Number of the buffer used for this view
99 
100  /** Return whether the view has a static buffer */
101  bool has_static_buffer() const { return !(flags & F_set_buffer); }
102  /** Return whether the static buffer offset is available */
103  bool has_static_buffer_offset() const { return !(flags & F_set_buffer_offset); }
104 
105  /** Return whether a buffer is set */
106  bool has_set_buffer() const { return flags & F_set_buffer; }
107  /** Return whether the given buffer offset is valid */
108  bool has_set_buffer_offset() const { return flags & F_set_buffer_offset; }
109  /** Return whether the given bytes-per-line value is valid */
110  bool has_set_bytes_per_line() const { return flags & F_set_bytes_per_line; }
111  /** Return whether the given pixel information is valid */
112  bool has_set_pixel() const { return flags & F_set_pixel; }
113  /** Return whether the position information given is valid */
114  bool has_set_position() const { return flags & F_set_position; }
115 
116  /** Dump information on the view information to a stream */
117  template< typename OUT >
118  void dump(OUT &s) const
119  {
120  s.printf("View::Info:\n"
121  " flags: %x\n"
122  " size: %ldx%ld\n"
123  " pos: %ldx%ld\n"
124  " bytes_per_line: %ld\n"
125  " buffer_offset: %lx\n"
126  " ",
127  flags, width, height, xpos, ypos,
128  bytes_per_line, buffer_offset);
129  pixel_info.dump(s);
130  s.printf("\n");
131  }
132  };
133 
134  /**
135  * \brief Return the view information of the view.
136  * \param[out] info Information structure pointer.
137  *
138  * \retval 0 Success
139  * \retval <0 Error
140  */
141  int info(Info *info) const throw();
142 
143  /**
144  * \brief Set the information structure for this view.
145  * \param info Information structure.
146  *
147  * \retval 0 Success
148  * \retval <0 Error
149  *
150  * The function will also set the view port according to the values given
151  * in the information structure.
152  */
153  int set_info(Info const &info) const throw();
154 
155  /**
156  * \brief Set the position of the view in the goos.
157  * \param scr_x X position
158  * \param scr_y Y position
159  * \param w Width
160  * \param h Height
161  * \param buf_offset Offset in the buffer in bytes
162  *
163  * \retval 0 Success
164  * \retval <0 Error
165  */
166  int set_viewport(int scr_x, int scr_y, int w, int h, unsigned long buf_offset) const throw();
167 
168  /**
169  * \brief Move this view in the view stack.
170  * \param pivot View to move relative to
171  * \param behind When true move the view behind the pivot view, if false
172  * move the view before the pivot view.
173  *
174  * \retval 0 Success
175  * \retval <0 Error
176  */
177  int stack(View const &pivot, bool behind = true) const throw();
178 
179  /** Make this view the top-most view */
180  int push_top() const throw()
181  { return stack(View(), true); }
182 
183  /** Push this view the back */
184  int push_bottom() const throw()
185  { return stack(View(), false); }
186 
187  /**
188  * \brief Refresh/Redraw the view.
189  * \param x X position.
190  * \param y Y position.
191  * \param w Width.
192  * \param h Height.
193  *
194  * \retval 0 Success
195  * \retval <0 Error
196  */
197  int refresh(int x, int y, int w, int h) const throw();
198 
199  /** \brief Return whether this view is valid */
200  bool valid() const { return _goos.is_valid(); }
201 };
202 
203 
204 /**
205  * \brief A goos.
206  */
207 class L4_EXPORT Goos :
208  public L4::Kobject_t<Goos, L4::Kobject, L4RE_PROTO_GOOS>
209 {
210 public:
211  /** Flags for a goos */
212  enum Flags
213  {
214  F_auto_refresh = 0x01, ///< The graphics display is automatically refreshed
215  F_pointer = 0x02, ///< We have a mouse pointer
216  F_dynamic_views = 0x04, ///< Supports dynamically allocated views
217  F_dynamic_buffers = 0x08, ///< Supports dynamically allocated buffers
218  };
219 
220  /** Information structure of a goos */
221  struct Info
222  {
223  unsigned long width; ///< Width
224  unsigned long height; ///< Height
225  unsigned flags; ///< Flags, see #Flags
226  unsigned num_static_views; ///< Number of static view
227  unsigned num_static_buffers; ///< Number of static buffers
228  Pixel_info pixel_info; ///< Pixel information
229 
230  /** Return whether this goos does auto refreshing or the view refresh
231  * functions must be used to make changes visible. */
232  bool auto_refresh() const { return flags & F_auto_refresh; }
233  /** Return whether a pointer is used by the provider of the goos */
234  bool has_pointer() const { return flags & F_pointer; }
235  /** Return whether dynamic view are supported */
236  bool has_dynamic_views() const { return flags & F_dynamic_views; }
237  /** Return whether dynamic buffers are supported */
238  bool has_dynamic_buffers() const { return flags & F_dynamic_buffers; }
239 
240  Info()
241  : width(0), height(0), flags(0), num_static_views(0),
242  num_static_buffers(0) {}
243  };
244 
245  /**
246  * \brief Return the goos information of the goos.
247  * \param[out] info Goos information structure pointer.
248  *
249  * \retval 0 Success
250  * \retval <0 Error
251  */
252  L4_INLINE_RPC(long, info, (Info *info));
253 
254  /**
255  * \brief Return a static buffer of a goos.
256  * \param idx Index of the static buffer.
257  * \param rbuf Capability slot to point the buffer dataspace to.
258  *
259  * \retval 0 Success
260  * \retval <0 Error
261  */
262  L4_RPC(long, get_static_buffer, (unsigned idx,
263  L4::Ipc::Out<L4::Cap<L4Re::Dataspace> > rbuf));
264 
265  /**
266  * \brief Create a buffer.
267  * \param size Size of buffer in bytes.
268  * \param rbuf Capability slot to point the buffer dataspace to.
269  *
270  * \retval >=0 Success, the value returned is the buffer index.
271  * \retval <0 Error
272  */
273  L4_RPC(long, create_buffer, (unsigned long size,
274  L4::Ipc::Out<L4::Cap<L4Re::Dataspace> > rbuf));
275 
276  /**
277  * \brief Delete a buffer.
278  * \param idx Buffer to delete.
279  *
280  * \retval 0 Success
281  * \retval <0 Error
282  */
283  L4_INLINE_RPC(long, delete_buffer, (unsigned idx));
284 
285  // Use a wrapper for this RPC as we enacapsulate the View
286  L4_INLINE_RPC_NF(long, create_view, ());
287 
288  /**
289  * \brief Create a view.
290  * \param[out] view A view object.
291  * \param utcb UTCB of the caller. This is a default parameter.
292  *
293  * \retval >=0 Success, the value returned is the view index.
294  * \retval <0 Error
295  */
296  int create_view(View *view, l4_utcb_t *utcb = l4_utcb()) const throw()
297  {
298  long r = create_view_t::call(c(), utcb);
299  if (r < 0)
300  return r;
301  *view = View(cap(), r);
302  return r;
303  }
304 
305  // Use a wrapper as Views are encapsulated
306  L4_INLINE_RPC_NF(long, delete_view, (unsigned index));
307 
308  /**
309  * \brief Delete a view.
310  * \param v The view object to delete.
311  * \param utcb UTCB of the caller. This is a default parameter.
312  *
313  * \retval 0 Success
314  * \retval <0 Error
315  */
316  int delete_view(View const &v, l4_utcb_t *utcb = l4_utcb()) const throw()
317  {
318  return delete_view_t::call(c(), v._view_idx, utcb);
319  }
320 
321  /**
322  * \brief Return a view.
323  * \param index Index of the view to return.
324  * \return The view.
325  */
326  View view(unsigned index) const throw();
327 
328  /**
329  * \brief Trigger refreshing of the given area on the virtual screen.
330  */
331  L4_INLINE_RPC(long, refresh, (int x, int y, int w, int h));
332 
333  // those are used by the View
334  L4_INLINE_RPC(long, view_info, (unsigned index, View::Info *info));
335  L4_INLINE_RPC(long, set_view_info, (unsigned index, View::Info const &info));
336  L4_INLINE_RPC(long, view_stack, (unsigned index, unsigned pivit, bool behind));
337  L4_INLINE_RPC(long, view_refresh, (unsigned index, int x, int y, int w, int h));
338 
339  typedef L4::Typeid::Rpcs<
340  info_t, get_static_buffer_t, create_buffer_t, create_view_t, delete_buffer_t,
341  delete_view_t, view_info_t, set_view_info_t, view_stack_t, view_refresh_t,
342  refresh_t
343  > Rpcs;
344 };
345 
346 inline View
347 Goos::view(unsigned index) const throw()
348 { return View(cap(), index); }
349 
350 inline int
351 View::info(Info *info) const throw()
352 { return _goos->view_info(_view_idx, info); }
353 
354 inline int
355 View::set_info(Info const &info) const throw()
356 { return _goos->set_view_info(_view_idx, info); }
357 
358 inline int
359 View::stack(View const &pivot, bool behind) const throw()
360 { return _goos->view_stack(_view_idx, pivot._view_idx, behind); }
361 
362 inline int
363 View::refresh(int x, int y, int w, int h) const throw()
364 { return _goos->view_refresh(_view_idx, x, y, w, h); }
365 
366 inline int
367 View::set_viewport(int scr_x, int scr_y, int w, int h,
368  unsigned long buf_offset) const throw()
369 {
370  Info i;
371  i.flags = F_set_buffer_offset | F_set_position;
372  i.buffer_offset = buf_offset;
373  i.xpos = scr_x;
374  i.ypos = scr_y;
375  i.width = w;
376  i.height = h;
377  return set_info(i);
378 }
379 
380 }}