1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/dfb/wrapdfb.h
3 // Purpose:     wx wrappers for DirectFB interfaces
4 // Author:      Vaclav Slavik
5 // Created:     2006-08-23
6 // Copyright:   (c) 2006 REA Elektronik GmbH
7 // Licence:     wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9 
10 #ifndef _WX_DFB_WRAPDFB_H_
11 #define _WX_DFB_WRAPDFB_H_
12 
13 #include "wx/dfb/dfbptr.h"
14 #include "wx/gdicmn.h"
15 #include "wx/vidmode.h"
16 
17 #include <directfb.h>
18 #include <directfb_version.h>
19 
20 // DFB < 1.0 didn't have u8 type, only __u8
21 #if DIRECTFB_MAJOR_VERSION == 0
22 typedef __u8 u8;
23 #endif
24 
25 
26 wxDFB_DECLARE_INTERFACE(IDirectFB);
27 wxDFB_DECLARE_INTERFACE(IDirectFBDisplayLayer);
28 wxDFB_DECLARE_INTERFACE(IDirectFBFont);
29 wxDFB_DECLARE_INTERFACE(IDirectFBWindow);
30 wxDFB_DECLARE_INTERFACE(IDirectFBSurface);
31 wxDFB_DECLARE_INTERFACE(IDirectFBPalette);
32 wxDFB_DECLARE_INTERFACE(IDirectFBEventBuffer);
33 
34 
35 /**
36     Checks the @a code of a DirectFB call and returns true if it was
37     successful and false if it failed, logging the errors as appropriate
38     (asserts for programming errors, wxLogError for runtime failures).
39  */
40 bool wxDfbCheckReturn(DFBResult code);
41 
42 //-----------------------------------------------------------------------------
43 // wxDfbEvent
44 //-----------------------------------------------------------------------------
45 
46 /**
47     The struct defined by this macro is a thin wrapper around DFB*Event type.
48     It is needed because DFB*Event are typedefs and so we can't forward declare
49     them, but we need to pass them to methods declared in public headers where
50     <directfb.h> cannot be included. So this struct just holds the event value,
51     it's sole purpose is that it can be forward declared.
52  */
53 #define WXDFB_DEFINE_EVENT_WRAPPER(T)                                       \
54     struct wx##T                                                            \
55     {                                                                       \
56         wx##T() {}                                                          \
57         wx##T(const T& event) : m_event(event) {}                           \
58                                                                             \
59         operator T&() { return m_event; }                                   \
60         operator const T&() const { return m_event; }                       \
61         T* operator&() { return &m_event; }                                 \
62                                                                             \
63         DFBEventClass GetClass() const { return m_event.clazz; }            \
64                                                                             \
65     private:                                                                \
66         T m_event;                                                          \
67     };
68 
69 WXDFB_DEFINE_EVENT_WRAPPER(DFBEvent)
WXDFB_DEFINE_EVENT_WRAPPER(DFBWindowEvent)70 WXDFB_DEFINE_EVENT_WRAPPER(DFBWindowEvent)
71 
72 
73 //-----------------------------------------------------------------------------
74 // wxDfbWrapper<T>
75 //-----------------------------------------------------------------------------
76 
77 /// Base class for wxDfbWrapper<T>
78 class wxDfbWrapperBase
79 {
80 public:
81     /// Increases reference count of the object
82     void AddRef()
83     {
84         m_refCnt++;
85     }
86 
87     /// Decreases reference count and if it reaches zero, deletes the object
88     void Release()
89     {
90         if ( --m_refCnt == 0 )
91             delete this;
92     }
93 
94     /// Returns result code of the last call
95     DFBResult GetLastResult() const { return m_lastResult; }
96 
97 protected:
98     wxDfbWrapperBase() : m_refCnt(1), m_lastResult(DFB_OK) {}
99 
100     /// Dtor may only be called from Release()
101     virtual ~wxDfbWrapperBase() {}
102 
103     /**
104         Checks the @a result of a DirectFB call and returns true if it was
105         successful and false if it failed. Also stores result of the call
106         so that it can be obtained by calling GetLastResult().
107      */
108     bool Check(DFBResult result)
109     {
110         m_lastResult = result;
111         return wxDfbCheckReturn(result);
112     }
113 
114 protected:
115     /// Reference count
116     unsigned m_refCnt;
117 
118     /// Result of the last DirectFB call
119     DFBResult m_lastResult;
120 };
121 
122 /**
123     This template is base class for friendly C++ wrapper around DirectFB
124     interface T.
125 
126     The wrapper provides same API as DirectFB, with a few exceptions:
127      - methods return true/false instead of error code
128      - methods that return or create another interface return pointer to the
129        interface (or NULL on failure) instead of storing it in the last
130        argument
131      - interface arguments use wxFooPtr type instead of raw DirectFB pointer
132      - methods taking flags use int type instead of an enum when the flags
133        can be or-combination of enum elements (this is workaround for
134        C++-unfriendly DirectFB API)
135  */
136 template<typename T>
137 class wxDfbWrapper : public wxDfbWrapperBase
138 {
139 public:
140     /// "Raw" DirectFB interface type
141     typedef T DirectFBIface;
142 
143     /// Returns raw DirectFB pointer
GetRaw()144     T *GetRaw() const { return m_ptr; }
145 
146 protected:
147     /// To be called from ctor. Takes ownership of raw object.
Init(T * ptr)148     void Init(T *ptr) { m_ptr = ptr; }
149 
150     /// Dtor may only be used from Release
~wxDfbWrapper()151     ~wxDfbWrapper()
152     {
153         if ( m_ptr )
154             m_ptr->Release(m_ptr);
155     }
156 
157 protected:
158     // pointer to DirectFB object
159     T *m_ptr;
160 };
161 
162 
163 //-----------------------------------------------------------------------------
164 // wxIDirectFBFont
165 //-----------------------------------------------------------------------------
166 
167 struct wxIDirectFBFont : public wxDfbWrapper<IDirectFBFont>
168 {
wxIDirectFBFontwxIDirectFBFont169     wxIDirectFBFont(IDirectFBFont *s) { Init(s); }
170 
GetStringWidthwxIDirectFBFont171     bool GetStringWidth(const char *text, int bytes, int *w)
172         { return Check(m_ptr->GetStringWidth(m_ptr, text, bytes, w)); }
173 
GetStringExtentswxIDirectFBFont174     bool GetStringExtents(const char *text, int bytes,
175                           DFBRectangle *logicalRect, DFBRectangle *inkRect)
176     {
177         return Check(m_ptr->GetStringExtents(m_ptr, text, bytes,
178                                                logicalRect, inkRect));
179     }
180 
GetHeightwxIDirectFBFont181     bool GetHeight(int *h)
182         { return Check(m_ptr->GetHeight(m_ptr, h)); }
183 
GetDescenderwxIDirectFBFont184     bool GetDescender(int *descender)
185         { return Check(m_ptr->GetDescender(m_ptr, descender)); }
186 };
187 
188 
189 //-----------------------------------------------------------------------------
190 // wxIDirectFBPalette
191 //-----------------------------------------------------------------------------
192 
193 struct wxIDirectFBPalette : public wxDfbWrapper<IDirectFBPalette>
194 {
wxIDirectFBPalettewxIDirectFBPalette195     wxIDirectFBPalette(IDirectFBPalette *s) { Init(s); }
196 };
197 
198 
199 //-----------------------------------------------------------------------------
200 // wxIDirectFBSurface
201 //-----------------------------------------------------------------------------
202 
203 struct wxIDirectFBSurface : public wxDfbWrapper<IDirectFBSurface>
204 {
wxIDirectFBSurfacewxIDirectFBSurface205     wxIDirectFBSurface(IDirectFBSurface *s) { Init(s); }
206 
GetSizewxIDirectFBSurface207     bool GetSize(int *w, int *h)
208         { return Check(m_ptr->GetSize(m_ptr, w, h)); }
209 
GetCapabilitieswxIDirectFBSurface210     bool GetCapabilities(DFBSurfaceCapabilities *caps)
211         { return Check(m_ptr->GetCapabilities(m_ptr, caps)); }
212 
GetPixelFormatwxIDirectFBSurface213     bool GetPixelFormat(DFBSurfacePixelFormat *caps)
214         { return Check(m_ptr->GetPixelFormat(m_ptr, caps)); }
215 
216     // convenience version of GetPixelFormat, returns DSPF_UNKNOWN if fails
217     DFBSurfacePixelFormat GetPixelFormat();
218 
SetClipwxIDirectFBSurface219     bool SetClip(const DFBRegion *clip)
220         { return Check(m_ptr->SetClip(m_ptr, clip)); }
221 
SetColorwxIDirectFBSurface222     bool SetColor(u8 r, u8 g, u8 b, u8 a)
223         { return Check(m_ptr->SetColor(m_ptr, r, g, b, a)); }
224 
ClearwxIDirectFBSurface225     bool Clear(u8 r, u8 g, u8 b, u8 a)
226         { return Check(m_ptr->Clear(m_ptr, r, g, b, a)); }
227 
DrawLinewxIDirectFBSurface228     bool DrawLine(int x1, int y1, int x2, int y2)
229         { return Check(m_ptr->DrawLine(m_ptr, x1, y1, x2, y2)); }
230 
DrawRectanglewxIDirectFBSurface231     bool DrawRectangle(int x, int y, int w, int h)
232         { return Check(m_ptr->DrawRectangle(m_ptr, x, y, w, h)); }
233 
FillRectanglewxIDirectFBSurface234     bool FillRectangle(int x, int y, int w, int h)
235         { return Check(m_ptr->FillRectangle(m_ptr, x, y, w, h)); }
236 
SetFontwxIDirectFBSurface237     bool SetFont(const wxIDirectFBFontPtr& font)
238         { return Check(m_ptr->SetFont(m_ptr, font->GetRaw())); }
239 
DrawStringwxIDirectFBSurface240     bool DrawString(const char *text, int bytes, int x, int y, int flags)
241     {
242         return Check(m_ptr->DrawString(m_ptr, text, bytes, x, y,
243                                          (DFBSurfaceTextFlags)flags));
244     }
245 
246     /**
247         Updates the front buffer from the back buffer. If @a region is not
248         NULL, only given rectangle is updated.
249      */
250     bool FlipToFront(const DFBRegion *region = NULL);
251 
GetSubSurfacewxIDirectFBSurface252     wxIDirectFBSurfacePtr GetSubSurface(const DFBRectangle *rect)
253     {
254         IDirectFBSurface *s;
255         if ( Check(m_ptr->GetSubSurface(m_ptr, rect, &s)) )
256             return new wxIDirectFBSurface(s);
257         else
258             return NULL;
259     }
260 
GetPalettewxIDirectFBSurface261     wxIDirectFBPalettePtr GetPalette()
262     {
263         IDirectFBPalette *s;
264         if ( Check(m_ptr->GetPalette(m_ptr, &s)) )
265             return new wxIDirectFBPalette(s);
266         else
267             return NULL;
268     }
269 
SetPalettewxIDirectFBSurface270     bool SetPalette(const wxIDirectFBPalettePtr& pal)
271         { return Check(m_ptr->SetPalette(m_ptr, pal->GetRaw())); }
272 
SetBlittingFlagswxIDirectFBSurface273     bool SetBlittingFlags(int flags)
274     {
275         return Check(
276             m_ptr->SetBlittingFlags(m_ptr, (DFBSurfaceBlittingFlags)flags));
277     }
278 
BlitwxIDirectFBSurface279     bool Blit(const wxIDirectFBSurfacePtr& source,
280               const DFBRectangle *source_rect,
281               int x, int y)
282         { return Blit(source->GetRaw(), source_rect, x, y); }
283 
BlitwxIDirectFBSurface284     bool Blit(IDirectFBSurface *source,
285               const DFBRectangle *source_rect,
286               int x, int y)
287         { return Check(m_ptr->Blit(m_ptr, source, source_rect, x, y)); }
288 
StretchBlitwxIDirectFBSurface289     bool StretchBlit(const wxIDirectFBSurfacePtr& source,
290               const DFBRectangle *source_rect,
291               const DFBRectangle *dest_rect)
292     {
293         return Check(m_ptr->StretchBlit(m_ptr, source->GetRaw(),
294                                         source_rect, dest_rect));
295     }
296 
297     /// Returns bit depth used by the surface or -1 on error
298     int GetDepth();
299 
300     /**
301         Creates a new surface by cloning this one. New surface will have same
302         capabilities, pixel format and pixel data as the existing one.
303 
304         @see CreateCompatible
305      */
306     wxIDirectFBSurfacePtr Clone();
307 
308     /// Flags for CreateCompatible()
309     enum CreateCompatibleFlags
310     {
311         /// Don't create double-buffered surface
312         CreateCompatible_NoBackBuffer = 1
313     };
314 
315     /**
316         Creates a surface compatible with this one, i.e. surface with the same
317         capabilities and pixel format, but with different and size.
318 
319         @param size  Size of the surface to create. If wxDefaultSize, use the
320                      size of this surface.
321         @param flags Or-combination of CreateCompatibleFlags values
322      */
323     wxIDirectFBSurfacePtr CreateCompatible(const wxSize& size = wxDefaultSize,
324                                            int flags = 0);
325 
LockwxIDirectFBSurface326     bool Lock(DFBSurfaceLockFlags flags, void **ret_ptr, int *ret_pitch)
327         { return Check(m_ptr->Lock(m_ptr, flags, ret_ptr, ret_pitch)); }
328 
UnlockwxIDirectFBSurface329     bool Unlock()
330         { return Check(m_ptr->Unlock(m_ptr)); }
331 
332     /// Helper struct for safe locking & unlocking of surfaces
333     struct Locked
334     {
LockedwxIDirectFBSurface::Locked335         Locked(const wxIDirectFBSurfacePtr& surface, DFBSurfaceLockFlags flags)
336             : m_surface(surface)
337         {
338             if ( !surface->Lock(flags, &ptr, &pitch) )
339                 ptr = NULL;
340         }
341 
~LockedwxIDirectFBSurface::Locked342         ~Locked()
343         {
344             if ( ptr )
345                 m_surface->Unlock();
346         }
347 
348         void *ptr;
349         int pitch;
350 
351     private:
352         wxIDirectFBSurfacePtr m_surface;
353     };
354 
355 
356 private:
357     // this is private because we want user code to use FlipToFront()
358     bool Flip(const DFBRegion *region, int flags);
359 };
360 
361 
362 //-----------------------------------------------------------------------------
363 // wxIDirectFBEventBuffer
364 //-----------------------------------------------------------------------------
365 
366 struct wxIDirectFBEventBuffer : public wxDfbWrapper<IDirectFBEventBuffer>
367 {
wxIDirectFBEventBufferwxIDirectFBEventBuffer368     wxIDirectFBEventBuffer(IDirectFBEventBuffer *s) { Init(s); }
369 
CreateFileDescriptorwxIDirectFBEventBuffer370     bool CreateFileDescriptor(int *ret_fd)
371     {
372         return Check(m_ptr->CreateFileDescriptor(m_ptr, ret_fd));
373     }
374 };
375 
376 
377 //-----------------------------------------------------------------------------
378 // wxIDirectFBWindow
379 //-----------------------------------------------------------------------------
380 
381 struct wxIDirectFBWindow : public wxDfbWrapper<IDirectFBWindow>
382 {
wxIDirectFBWindowwxIDirectFBWindow383     wxIDirectFBWindow(IDirectFBWindow *s) { Init(s); }
384 
GetIDwxIDirectFBWindow385     bool GetID(DFBWindowID *id)
386         { return Check(m_ptr->GetID(m_ptr, id)); }
387 
GetPositionwxIDirectFBWindow388     bool GetPosition(int *x, int *y)
389         { return Check(m_ptr->GetPosition(m_ptr, x, y)); }
390 
GetSizewxIDirectFBWindow391     bool GetSize(int *w, int *h)
392         { return Check(m_ptr->GetSize(m_ptr, w, h)); }
393 
MoveTowxIDirectFBWindow394     bool MoveTo(int x, int y)
395         { return Check(m_ptr->MoveTo(m_ptr, x, y)); }
396 
ResizewxIDirectFBWindow397     bool Resize(int w, int h)
398         { return Check(m_ptr->Resize(m_ptr, w, h)); }
399 
SetOpacitywxIDirectFBWindow400     bool SetOpacity(u8 opacity)
401         { return Check(m_ptr->SetOpacity(m_ptr, opacity)); }
402 
SetStackingClasswxIDirectFBWindow403     bool SetStackingClass(DFBWindowStackingClass klass)
404         { return Check(m_ptr->SetStackingClass(m_ptr, klass)); }
405 
RaiseToTopwxIDirectFBWindow406     bool RaiseToTop()
407         { return Check(m_ptr->RaiseToTop(m_ptr)); }
408 
LowerToBottomwxIDirectFBWindow409     bool LowerToBottom()
410         { return Check(m_ptr->LowerToBottom(m_ptr)); }
411 
GetSurfacewxIDirectFBWindow412     wxIDirectFBSurfacePtr GetSurface()
413     {
414         IDirectFBSurface *s;
415         if ( Check(m_ptr->GetSurface(m_ptr, &s)) )
416             return new wxIDirectFBSurface(s);
417         else
418             return NULL;
419     }
420 
AttachEventBufferwxIDirectFBWindow421     bool AttachEventBuffer(const wxIDirectFBEventBufferPtr& buffer)
422         { return Check(m_ptr->AttachEventBuffer(m_ptr, buffer->GetRaw())); }
423 
RequestFocuswxIDirectFBWindow424     bool RequestFocus()
425         { return Check(m_ptr->RequestFocus(m_ptr)); }
426 
DestroywxIDirectFBWindow427     bool Destroy()
428         { return Check(m_ptr->Destroy(m_ptr)); }
429 };
430 
431 
432 //-----------------------------------------------------------------------------
433 // wxIDirectFBDisplayLayer
434 //-----------------------------------------------------------------------------
435 
436 struct wxIDirectFBDisplayLayer : public wxDfbWrapper<IDirectFBDisplayLayer>
437 {
wxIDirectFBDisplayLayerwxIDirectFBDisplayLayer438     wxIDirectFBDisplayLayer(IDirectFBDisplayLayer *s) { Init(s); }
439 
CreateWindowwxIDirectFBDisplayLayer440     wxIDirectFBWindowPtr CreateWindow(const DFBWindowDescription *desc)
441     {
442         IDirectFBWindow *w;
443         if ( Check(m_ptr->CreateWindow(m_ptr, desc, &w)) )
444             return new wxIDirectFBWindow(w);
445         else
446             return NULL;
447     }
448 
GetConfigurationwxIDirectFBDisplayLayer449     bool GetConfiguration(DFBDisplayLayerConfig *config)
450         { return Check(m_ptr->GetConfiguration(m_ptr, config)); }
451 
452     wxVideoMode GetVideoMode();
453 
GetCursorPositionwxIDirectFBDisplayLayer454     bool GetCursorPosition(int *x, int *y)
455         { return Check(m_ptr->GetCursorPosition(m_ptr, x, y)); }
456 
WarpCursorwxIDirectFBDisplayLayer457     bool WarpCursor(int x, int y)
458         { return Check(m_ptr->WarpCursor(m_ptr, x, y)); }
459 };
460 
461 
462 //-----------------------------------------------------------------------------
463 // wxIDirectFB
464 //-----------------------------------------------------------------------------
465 
466 struct wxIDirectFB : public wxDfbWrapper<IDirectFB>
467 {
468     /**
469         Returns pointer to DirectFB singleton object, it never returns NULL
470         after wxApp was initialized. The object is cached, so calling this
471         method is cheap.
472      */
GetwxIDirectFB473     static wxIDirectFBPtr Get()
474     {
475         if ( !ms_ptr ) CreateDirectFB();
476         return ms_ptr;
477     }
478 
SetVideoModewxIDirectFB479     bool SetVideoMode(int w, int h, int bpp)
480         { return Check(m_ptr->SetVideoMode(m_ptr, w, h, bpp)); }
481 
CreateSurfacewxIDirectFB482     wxIDirectFBSurfacePtr CreateSurface(const DFBSurfaceDescription *desc)
483     {
484         IDirectFBSurface *s;
485         if ( Check(m_ptr->CreateSurface(m_ptr, desc, &s)) )
486             return new wxIDirectFBSurface(s);
487         else
488             return NULL;
489     }
490 
CreateEventBufferwxIDirectFB491     wxIDirectFBEventBufferPtr CreateEventBuffer()
492     {
493         IDirectFBEventBuffer *b;
494         if ( Check(m_ptr->CreateEventBuffer(m_ptr, &b)) )
495             return new wxIDirectFBEventBuffer(b);
496         else
497             return NULL;
498     }
499 
CreateFontwxIDirectFB500     wxIDirectFBFontPtr CreateFont(const char *filename,
501                                   const DFBFontDescription *desc)
502     {
503         IDirectFBFont *f;
504         if ( Check(m_ptr->CreateFont(m_ptr, filename, desc, &f)) )
505             return new wxIDirectFBFont(f);
506         else
507             return NULL;
508     }
509 
510     wxIDirectFBDisplayLayerPtr
511     GetDisplayLayer(DFBDisplayLayerID id = DLID_PRIMARY)
512     {
513         IDirectFBDisplayLayer *l;
514         if ( Check(m_ptr->GetDisplayLayer(m_ptr, id, &l)) )
515             return new wxIDirectFBDisplayLayer(l);
516         else
517             return NULL;
518     }
519 
520     /// Returns primary surface
521     wxIDirectFBSurfacePtr GetPrimarySurface();
522 
523 private:
wxIDirectFBwxIDirectFB524     wxIDirectFB(IDirectFB *ptr) { Init(ptr); }
525 
526     // creates ms_ptr instance
527     static void CreateDirectFB();
528 
529     static void CleanUp();
530     friend class wxApp; // calls CleanUp
531 
532     // pointer to the singleton IDirectFB object
533     static wxIDirectFBPtr ms_ptr;
534 };
535 
536 #endif // _WX_DFB_WRAPDFB_H_
537