The Pedigree Project  0.1
winman.h
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #ifndef _WINMAN_H
21 #define _WINMAN_H
22 
23 #include <stdint.h>
24 #include <syslog.h>
25 #include <unistd.h>
26 
27 #include <string>
28 #include <vector>
29 
30 #include "pedigree/native/graphics/Graphics.h"
31 #include "pedigree/native/input/Input.h"
32 #include "pedigree/native/ipc/Ipc.h"
33 
34 #include <cairo/cairo.h>
35 
40 class SharedBuffer;
41 
42 #define WINDOW_BORDER_X 2
43 #define WINDOW_BORDER_Y 2
44 #define WINDOW_TITLE_H 20
45 
46 // Start location of the client rendering area.
47 #define WINDOW_CLIENT_START_X (WINDOW_BORDER_X)
48 #define WINDOW_CLIENT_START_Y (WINDOW_BORDER_Y + WINDOW_TITLE_H)
49 
50 // Insets from the end of the client area.
51 #define WINDOW_CLIENT_END_X (WINDOW_BORDER_X)
52 #define WINDOW_CLIENT_END_Y (WINDOW_BORDER_Y)
53 
54 // Total space from the W/H that the window manager has used and taken from the
55 // client area for rendering decorations etc...
56 #define WINDOW_CLIENT_LOST_W (WINDOW_CLIENT_START_X + WINDOW_CLIENT_END_X + 1)
57 #define WINDOW_CLIENT_LOST_H (WINDOW_CLIENT_START_Y + WINDOW_CLIENT_END_Y + 1)
58 
59 #define WINMAN_PANGO_FONT "DejaVu Sans Mono 12"
60 
67 {
68  public:
70  ~DirtyRectangle();
71 
72  void point(size_t x, size_t y);
73 
74  size_t getX() const
75  {
76  return m_X;
77  }
78  size_t getY() const
79  {
80  return m_Y;
81  }
82  size_t getX2() const
83  {
84  return m_X2;
85  }
86  size_t getY2() const
87  {
88  return m_Y2;
89  }
90  size_t getWidth() const
91  {
92  return m_X2 - m_X + 1;
93  }
94  size_t getHeight() const
95  {
96  return m_Y2 - m_Y + 1;
97  }
98 
99  void reset()
100  {
101  m_X = 0;
102  m_Y = 0;
103  m_X2 = 0;
104  m_X2 = 0;
105  }
106 
107  private:
108  size_t m_X, m_Y, m_X2, m_Y2;
109 };
110 
111 class WObject;
112 class Container;
113 class RootContainer;
114 class Window;
115 
119 class WObject
120 {
121  public:
122  enum Type
123  {
124  Container,
125  Window,
126  Root,
127  };
128 
129  WObject() : m_Dimensions(0, 0, 0, 0)
130  {
131  }
132 
133  virtual ~WObject()
134  {
135  }
136 
137  virtual Type getType() const = 0;
138 
139  virtual void resize(
140  ssize_t horizDistance, ssize_t vertDistance, WObject *pChild = 0) = 0;
141 
142  void reposition(
143  size_t x = ~0UL, size_t y = ~0UL, size_t w = ~0UL, size_t h = ~0UL);
144 
145  void bump(ssize_t bumpX = 0, ssize_t bumpY = 0);
146 
147  virtual void resized()
148  {
149  }
150 
151  PedigreeGraphics::Rect getCopyDimensions() const
152  {
153  return m_Dimensions;
154  }
155 
157  virtual void norefresh()
158  {
159  }
160 
162  virtual void yesrefresh()
163  {
164  }
165 
167  virtual void render(cairo_t *cr)
168  {
169  }
170 
171  protected:
172  void setDimensions(PedigreeGraphics::Rect &rt)
173  {
174  m_Dimensions = rt;
175  }
176 
177  PedigreeGraphics::Rect &getDimensions()
178  {
179  return m_Dimensions;
180  }
181 
183  virtual void refreshContext()
184  {
185  }
186 
187  private:
188  PedigreeGraphics::Rect m_Dimensions;
189 };
190 
195 class Window : public WObject
196 {
197  public:
198  Window(
199  uint64_t handle, int sock, struct sockaddr *sa, size_t sa_len,
200  ::Container *pParent);
201  Window();
202 
203  virtual ~Window();
204 
205  virtual Type getType() const
206  {
207  return WObject::Window;
208  }
209 
210  virtual void setTitle(const std::string &s)
211  {
212  m_sWindowTitle = s;
213  m_bPendingDecoration = true;
214  }
215 
216  virtual void render(cairo_t *cr);
217 
218  virtual void
219  resize(ssize_t horizDistance, ssize_t vertDistance, WObject *pChild = 0);
220 
221  virtual void focus();
222  virtual void nofocus();
223 
225  virtual void norefresh()
226  {
227  m_bRefresh = false;
228  }
229 
231  virtual void yesrefresh()
232  {
233  m_bRefresh = true;
234  refreshContext();
235  }
236 
237  virtual void refreshContext();
238 
239  void *getFramebuffer() const;
240 
241  virtual void sendMessage(const char *msg, size_t len);
242 
243  uint64_t getHandle() const
244  {
245  return m_Handle;
246  }
247 
248  ::Container *getParent() const
249  {
250  return m_pParent;
251  }
252 
253  void setParent(::Container *p)
254  {
255  m_pParent = p;
256  }
257 
258  void setDirty(PedigreeGraphics::Rect &dirty);
259 
260  PedigreeGraphics::Rect getDirty() const
261  {
262  // Different behaviour if we are waiting on a window redecoration
263  if (m_bPendingDecoration)
264  {
265  // Redraw ALL the things.
266  PedigreeGraphics::Rect rt = getCopyDimensions();
267  rt.update(0, 0, rt.getW(), rt.getH());
268  return rt;
269  }
270  return m_Dirty;
271  }
272 
273  bool isDirty() const
274  {
275  return m_bPendingDecoration || isClientDirty();
276  }
277 
278  private:
279  bool isClientDirty() const
280  {
281  return !(
282  m_Dirty.getX() == 0 && m_Dirty.getY() == 0 && m_Dirty.getW() == 0 &&
283  m_Dirty.getH() == 0);
284  }
285 
286  uint64_t m_Handle;
287 
288  ::Container *m_pParent;
289 
290  SharedBuffer *m_Framebuffer;
291 
292  std::string m_sWindowTitle;
293 
294  PedigreeGraphics::Rect m_Dirty;
295 
296  bool m_bPendingDecoration;
297 
298  bool m_bFocus;
299 
300  bool m_bRefresh;
301 
302  size_t m_nRegionWidth;
303  size_t m_nRegionHeight;
304 
305  int m_Socket;
306  struct sockaddr *m_Sa;
307  size_t m_SaLen;
308 };
309 
314 class Container : public WObject
315 {
316  protected:
317  typedef std::vector<WObject *> WObjectList_t;
318 
319  public:
320  enum Layout
321  {
322  SideBySide, // Subwindows are tiled side-by-side
323  Stacked, // Subwindows are tiled each above the other
324  };
325 
326  Container(WObject *pParent)
327  : m_Children(), m_pParent(pParent), m_Layout(SideBySide),
328  m_pFocusWindow(NULL)
329  {
330  }
331 
332  virtual ~Container()
333  {
334  }
335 
336  virtual Type getType() const
337  {
338  return WObject::Container;
339  }
340 
341  Layout getLayout() const
342  {
343  return m_Layout;
344  }
345 
346  void setLayout(Layout newLayout)
347  {
348  m_Layout = newLayout;
349  retile();
350  }
351 
352  ::Window *getFocusWindow() const
353  {
354  return m_pFocusWindow;
355  }
356 
357  void setFocusWindow(::Window *w)
358  {
359  m_pFocusWindow = w;
360  }
361 
365  void addChild(WObject *pChild, bool bNoRetile = false)
366  {
367  // insertion breaks retile() somehow.
368  // insertChild(m_pFocusWindow, pChild);
369  m_Children.push_back(pChild);
370  if ((pChild->getType() == WObject::Window) && (m_pFocusWindow == NULL))
371  {
372  m_pFocusWindow = static_cast<::Window *>(pChild);
373  }
374 
375  if (!bNoRetile)
376  {
377  retile();
378  }
379  }
380 
384  void replaceChild(WObject *pChild, WObject *pNewChild)
385  {
386  WObjectList_t::iterator it = m_Children.begin();
387  for (; it != m_Children.end(); ++it)
388  {
389  if ((*it) == pChild)
390  {
391  it = m_Children.erase(it);
392  m_Children.insert(it, pNewChild);
393  break;
394  }
395  }
396  }
397 
402  void insertChild(WObject *pCurrent, WObject *pNewChild)
403  {
404  WObjectList_t::iterator it = m_Children.begin();
405  for (; it != m_Children.end(); ++it)
406  {
407  if ((*it) == pCurrent)
408  {
409  ++it;
410  it = m_Children.insert(it, pNewChild);
411  break;
412  }
413  }
414 
415  if (it == m_Children.end())
416  {
417  m_Children.push_back(pNewChild);
418  }
419 
420  retile();
421  }
422 
426  void removeChild(WObject *pChild)
427  {
428  WObjectList_t::iterator it = m_Children.begin();
429  for (; it != m_Children.end(); ++it)
430  {
431  if ((*it) == pChild)
432  {
433  m_Children.erase(it);
434  break;
435  }
436  }
437 
438  // Did we actually erase something?
439  if (it != m_Children.end())
440  {
441  retile();
442  }
443  }
444 
448  size_t getChildCount() const
449  {
450  return m_Children.size();
451  }
452 
456  WObject *getChild(size_t n) const
457  {
458  if (n > m_Children.size())
459  {
460  return 0;
461  }
462 
463  return m_Children[n];
464  }
465 
471  WObject *getLeftSibling(const WObject *pChild) const;
472 
478  WObject *getRightSibling(const WObject *pChild) const;
479 
484  WObject *getLeftObject() const;
485 
490  WObject *getRightObject() const;
491 
497  WObject *getLeft(const WObject *obj) const;
498 
504  WObject *getRight(const WObject *obj) const;
505 
511  WObject *getUp(const WObject *obj) const;
512 
518  WObject *getDown(const WObject *obj) const;
519 
525  void retile();
526 
531  {
532  return m_pParent;
533  }
534 
540  virtual void
541  resize(ssize_t horizDistance, ssize_t vertDistance, WObject *pChild = 0);
542 
546  void render(cairo_t *cr);
547 
549  virtual void norefresh();
550 
552  virtual void yesrefresh();
553 
554  protected:
555  std::vector<WObject *> m_Children;
556 
557  Container() : Container(0)
558  {
559  }
560 
561  private:
562  WObject *m_pParent;
563 
564  Layout m_Layout;
565 
566  ::Window *m_pFocusWindow;
567 };
568 
572 class RootContainer : public Container
573 {
574  public:
575  RootContainer(size_t w, size_t h) : Container()
576  {
577  reposition(0, 0, w, h);
578  }
579 
580  virtual Type getType() const
581  {
582  return WObject::Root;
583  }
584 
585  virtual void
586  resize(ssize_t horizDistance, ssize_t vertDistance, WObject *pChild = 0);
587 };
588 
591 #endif
virtual void norefresh()
Don&#39;t refresh the context on every reposition.
Definition: winman.h:225
WObject * getParent() const
Definition: winman.h:530
virtual void yesrefresh()
Refresh context on every reposition.
Definition: winman.h:231
void replaceChild(WObject *pChild, WObject *pNewChild)
Definition: winman.h:384
size_t getChildCount() const
Definition: winman.h:448
Definition: winman.h:195
void addChild(WObject *pChild, bool bNoRetile=false)
Definition: winman.h:365
Abstracts a buffer shared between multiple processes.
Definition: util.h:33
void insertChild(WObject *pCurrent, WObject *pNewChild)
Definition: winman.h:402
void removeChild(WObject *pChild)
Definition: winman.h:426
WObject * getChild(size_t n) const
Definition: winman.h:456
virtual void yesrefresh()
Refresh context on every reposition.
Definition: winman.h:162
virtual void norefresh()
Don&#39;t refresh the context on every reposition.
Definition: winman.h:157
virtual void refreshContext()
Refresh our graphical context, called after reposition.
Definition: winman.h:183