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