mirror of https://github.com/PCSX2/pcsx2.git
537 lines
17 KiB
C++
537 lines
17 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: wx/dfb/wrapdfb.h
|
|
// Purpose: wx wrappers for DirectFB interfaces
|
|
// Author: Vaclav Slavik
|
|
// Created: 2006-08-23
|
|
// Copyright: (c) 2006 REA Elektronik GmbH
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef _WX_DFB_WRAPDFB_H_
|
|
#define _WX_DFB_WRAPDFB_H_
|
|
|
|
#include "wx/dfb/dfbptr.h"
|
|
#include "wx/gdicmn.h"
|
|
#include "wx/vidmode.h"
|
|
|
|
#include <directfb.h>
|
|
#include <directfb_version.h>
|
|
|
|
// DFB < 1.0 didn't have u8 type, only __u8
|
|
#if DIRECTFB_MAJOR_VERSION == 0
|
|
typedef __u8 u8;
|
|
#endif
|
|
|
|
|
|
wxDFB_DECLARE_INTERFACE(IDirectFB);
|
|
wxDFB_DECLARE_INTERFACE(IDirectFBDisplayLayer);
|
|
wxDFB_DECLARE_INTERFACE(IDirectFBFont);
|
|
wxDFB_DECLARE_INTERFACE(IDirectFBWindow);
|
|
wxDFB_DECLARE_INTERFACE(IDirectFBSurface);
|
|
wxDFB_DECLARE_INTERFACE(IDirectFBPalette);
|
|
wxDFB_DECLARE_INTERFACE(IDirectFBEventBuffer);
|
|
|
|
|
|
/**
|
|
Checks the @a code of a DirectFB call and returns true if it was
|
|
successful and false if it failed, logging the errors as appropriate
|
|
(asserts for programming errors, wxLogError for runtime failures).
|
|
*/
|
|
bool wxDfbCheckReturn(DFBResult code);
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxDfbEvent
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/**
|
|
The struct defined by this macro is a thin wrapper around DFB*Event type.
|
|
It is needed because DFB*Event are typedefs and so we can't forward declare
|
|
them, but we need to pass them to methods declared in public headers where
|
|
<directfb.h> cannot be included. So this struct just holds the event value,
|
|
it's sole purpose is that it can be forward declared.
|
|
*/
|
|
#define WXDFB_DEFINE_EVENT_WRAPPER(T) \
|
|
struct wx##T \
|
|
{ \
|
|
wx##T() {} \
|
|
wx##T(const T& event) : m_event(event) {} \
|
|
\
|
|
operator T&() { return m_event; } \
|
|
operator const T&() const { return m_event; } \
|
|
T* operator&() { return &m_event; } \
|
|
\
|
|
DFBEventClass GetClass() const { return m_event.clazz; } \
|
|
\
|
|
private: \
|
|
T m_event; \
|
|
};
|
|
|
|
WXDFB_DEFINE_EVENT_WRAPPER(DFBEvent)
|
|
WXDFB_DEFINE_EVENT_WRAPPER(DFBWindowEvent)
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxDfbWrapper<T>
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/// Base class for wxDfbWrapper<T>
|
|
class wxDfbWrapperBase
|
|
{
|
|
public:
|
|
/// Increases reference count of the object
|
|
void AddRef()
|
|
{
|
|
m_refCnt++;
|
|
}
|
|
|
|
/// Decreases reference count and if it reaches zero, deletes the object
|
|
void Release()
|
|
{
|
|
if ( --m_refCnt == 0 )
|
|
delete this;
|
|
}
|
|
|
|
/// Returns result code of the last call
|
|
DFBResult GetLastResult() const { return m_lastResult; }
|
|
|
|
protected:
|
|
wxDfbWrapperBase() : m_refCnt(1), m_lastResult(DFB_OK) {}
|
|
|
|
/// Dtor may only be called from Release()
|
|
virtual ~wxDfbWrapperBase() {}
|
|
|
|
/**
|
|
Checks the @a result of a DirectFB call and returns true if it was
|
|
successful and false if it failed. Also stores result of the call
|
|
so that it can be obtained by calling GetLastResult().
|
|
*/
|
|
bool Check(DFBResult result)
|
|
{
|
|
m_lastResult = result;
|
|
return wxDfbCheckReturn(result);
|
|
}
|
|
|
|
protected:
|
|
/// Reference count
|
|
unsigned m_refCnt;
|
|
|
|
/// Result of the last DirectFB call
|
|
DFBResult m_lastResult;
|
|
};
|
|
|
|
/**
|
|
This template is base class for friendly C++ wrapper around DirectFB
|
|
interface T.
|
|
|
|
The wrapper provides same API as DirectFB, with a few exceptions:
|
|
- methods return true/false instead of error code
|
|
- methods that return or create another interface return pointer to the
|
|
interface (or NULL on failure) instead of storing it in the last
|
|
argument
|
|
- interface arguments use wxFooPtr type instead of raw DirectFB pointer
|
|
- methods taking flags use int type instead of an enum when the flags
|
|
can be or-combination of enum elements (this is workaround for
|
|
C++-unfriendly DirectFB API)
|
|
*/
|
|
template<typename T>
|
|
class wxDfbWrapper : public wxDfbWrapperBase
|
|
{
|
|
public:
|
|
/// "Raw" DirectFB interface type
|
|
typedef T DirectFBIface;
|
|
|
|
/// Returns raw DirectFB pointer
|
|
T *GetRaw() const { return m_ptr; }
|
|
|
|
protected:
|
|
/// To be called from ctor. Takes ownership of raw object.
|
|
void Init(T *ptr) { m_ptr = ptr; }
|
|
|
|
/// Dtor may only be used from Release
|
|
~wxDfbWrapper()
|
|
{
|
|
if ( m_ptr )
|
|
m_ptr->Release(m_ptr);
|
|
}
|
|
|
|
protected:
|
|
// pointer to DirectFB object
|
|
T *m_ptr;
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxIDirectFBFont
|
|
//-----------------------------------------------------------------------------
|
|
|
|
struct wxIDirectFBFont : public wxDfbWrapper<IDirectFBFont>
|
|
{
|
|
wxIDirectFBFont(IDirectFBFont *s) { Init(s); }
|
|
|
|
bool GetStringWidth(const char *text, int bytes, int *w)
|
|
{ return Check(m_ptr->GetStringWidth(m_ptr, text, bytes, w)); }
|
|
|
|
bool GetStringExtents(const char *text, int bytes,
|
|
DFBRectangle *logicalRect, DFBRectangle *inkRect)
|
|
{
|
|
return Check(m_ptr->GetStringExtents(m_ptr, text, bytes,
|
|
logicalRect, inkRect));
|
|
}
|
|
|
|
bool GetHeight(int *h)
|
|
{ return Check(m_ptr->GetHeight(m_ptr, h)); }
|
|
|
|
bool GetDescender(int *descender)
|
|
{ return Check(m_ptr->GetDescender(m_ptr, descender)); }
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxIDirectFBPalette
|
|
//-----------------------------------------------------------------------------
|
|
|
|
struct wxIDirectFBPalette : public wxDfbWrapper<IDirectFBPalette>
|
|
{
|
|
wxIDirectFBPalette(IDirectFBPalette *s) { Init(s); }
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxIDirectFBSurface
|
|
//-----------------------------------------------------------------------------
|
|
|
|
struct wxIDirectFBSurface : public wxDfbWrapper<IDirectFBSurface>
|
|
{
|
|
wxIDirectFBSurface(IDirectFBSurface *s) { Init(s); }
|
|
|
|
bool GetSize(int *w, int *h)
|
|
{ return Check(m_ptr->GetSize(m_ptr, w, h)); }
|
|
|
|
bool GetCapabilities(DFBSurfaceCapabilities *caps)
|
|
{ return Check(m_ptr->GetCapabilities(m_ptr, caps)); }
|
|
|
|
bool GetPixelFormat(DFBSurfacePixelFormat *caps)
|
|
{ return Check(m_ptr->GetPixelFormat(m_ptr, caps)); }
|
|
|
|
// convenience version of GetPixelFormat, returns DSPF_UNKNOWN if fails
|
|
DFBSurfacePixelFormat GetPixelFormat();
|
|
|
|
bool SetClip(const DFBRegion *clip)
|
|
{ return Check(m_ptr->SetClip(m_ptr, clip)); }
|
|
|
|
bool SetColor(u8 r, u8 g, u8 b, u8 a)
|
|
{ return Check(m_ptr->SetColor(m_ptr, r, g, b, a)); }
|
|
|
|
bool Clear(u8 r, u8 g, u8 b, u8 a)
|
|
{ return Check(m_ptr->Clear(m_ptr, r, g, b, a)); }
|
|
|
|
bool DrawLine(int x1, int y1, int x2, int y2)
|
|
{ return Check(m_ptr->DrawLine(m_ptr, x1, y1, x2, y2)); }
|
|
|
|
bool DrawRectangle(int x, int y, int w, int h)
|
|
{ return Check(m_ptr->DrawRectangle(m_ptr, x, y, w, h)); }
|
|
|
|
bool FillRectangle(int x, int y, int w, int h)
|
|
{ return Check(m_ptr->FillRectangle(m_ptr, x, y, w, h)); }
|
|
|
|
bool SetFont(const wxIDirectFBFontPtr& font)
|
|
{ return Check(m_ptr->SetFont(m_ptr, font->GetRaw())); }
|
|
|
|
bool DrawString(const char *text, int bytes, int x, int y, int flags)
|
|
{
|
|
return Check(m_ptr->DrawString(m_ptr, text, bytes, x, y,
|
|
(DFBSurfaceTextFlags)flags));
|
|
}
|
|
|
|
/**
|
|
Updates the front buffer from the back buffer. If @a region is not
|
|
NULL, only given rectangle is updated.
|
|
*/
|
|
bool FlipToFront(const DFBRegion *region = NULL);
|
|
|
|
wxIDirectFBSurfacePtr GetSubSurface(const DFBRectangle *rect)
|
|
{
|
|
IDirectFBSurface *s;
|
|
if ( Check(m_ptr->GetSubSurface(m_ptr, rect, &s)) )
|
|
return new wxIDirectFBSurface(s);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
wxIDirectFBPalettePtr GetPalette()
|
|
{
|
|
IDirectFBPalette *s;
|
|
if ( Check(m_ptr->GetPalette(m_ptr, &s)) )
|
|
return new wxIDirectFBPalette(s);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
bool SetPalette(const wxIDirectFBPalettePtr& pal)
|
|
{ return Check(m_ptr->SetPalette(m_ptr, pal->GetRaw())); }
|
|
|
|
bool SetBlittingFlags(int flags)
|
|
{
|
|
return Check(
|
|
m_ptr->SetBlittingFlags(m_ptr, (DFBSurfaceBlittingFlags)flags));
|
|
}
|
|
|
|
bool Blit(const wxIDirectFBSurfacePtr& source,
|
|
const DFBRectangle *source_rect,
|
|
int x, int y)
|
|
{ return Blit(source->GetRaw(), source_rect, x, y); }
|
|
|
|
bool Blit(IDirectFBSurface *source,
|
|
const DFBRectangle *source_rect,
|
|
int x, int y)
|
|
{ return Check(m_ptr->Blit(m_ptr, source, source_rect, x, y)); }
|
|
|
|
bool StretchBlit(const wxIDirectFBSurfacePtr& source,
|
|
const DFBRectangle *source_rect,
|
|
const DFBRectangle *dest_rect)
|
|
{
|
|
return Check(m_ptr->StretchBlit(m_ptr, source->GetRaw(),
|
|
source_rect, dest_rect));
|
|
}
|
|
|
|
/// Returns bit depth used by the surface or -1 on error
|
|
int GetDepth();
|
|
|
|
/**
|
|
Creates a new surface by cloning this one. New surface will have same
|
|
capabilities, pixel format and pixel data as the existing one.
|
|
|
|
@see CreateCompatible
|
|
*/
|
|
wxIDirectFBSurfacePtr Clone();
|
|
|
|
/// Flags for CreateCompatible()
|
|
enum CreateCompatibleFlags
|
|
{
|
|
/// Don't create double-buffered surface
|
|
CreateCompatible_NoBackBuffer = 1
|
|
};
|
|
|
|
/**
|
|
Creates a surface compatible with this one, i.e. surface with the same
|
|
capabilities and pixel format, but with different and size.
|
|
|
|
@param size Size of the surface to create. If wxDefaultSize, use the
|
|
size of this surface.
|
|
@param flags Or-combination of CreateCompatibleFlags values
|
|
*/
|
|
wxIDirectFBSurfacePtr CreateCompatible(const wxSize& size = wxDefaultSize,
|
|
int flags = 0);
|
|
|
|
bool Lock(DFBSurfaceLockFlags flags, void **ret_ptr, int *ret_pitch)
|
|
{ return Check(m_ptr->Lock(m_ptr, flags, ret_ptr, ret_pitch)); }
|
|
|
|
bool Unlock()
|
|
{ return Check(m_ptr->Unlock(m_ptr)); }
|
|
|
|
/// Helper struct for safe locking & unlocking of surfaces
|
|
struct Locked
|
|
{
|
|
Locked(const wxIDirectFBSurfacePtr& surface, DFBSurfaceLockFlags flags)
|
|
: m_surface(surface)
|
|
{
|
|
if ( !surface->Lock(flags, &ptr, &pitch) )
|
|
ptr = NULL;
|
|
}
|
|
|
|
~Locked()
|
|
{
|
|
if ( ptr )
|
|
m_surface->Unlock();
|
|
}
|
|
|
|
void *ptr;
|
|
int pitch;
|
|
|
|
private:
|
|
wxIDirectFBSurfacePtr m_surface;
|
|
};
|
|
|
|
|
|
private:
|
|
// this is private because we want user code to use FlipToFront()
|
|
bool Flip(const DFBRegion *region, int flags);
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxIDirectFBEventBuffer
|
|
//-----------------------------------------------------------------------------
|
|
|
|
struct wxIDirectFBEventBuffer : public wxDfbWrapper<IDirectFBEventBuffer>
|
|
{
|
|
wxIDirectFBEventBuffer(IDirectFBEventBuffer *s) { Init(s); }
|
|
|
|
bool CreateFileDescriptor(int *ret_fd)
|
|
{
|
|
return Check(m_ptr->CreateFileDescriptor(m_ptr, ret_fd));
|
|
}
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxIDirectFBWindow
|
|
//-----------------------------------------------------------------------------
|
|
|
|
struct wxIDirectFBWindow : public wxDfbWrapper<IDirectFBWindow>
|
|
{
|
|
wxIDirectFBWindow(IDirectFBWindow *s) { Init(s); }
|
|
|
|
bool GetID(DFBWindowID *id)
|
|
{ return Check(m_ptr->GetID(m_ptr, id)); }
|
|
|
|
bool GetPosition(int *x, int *y)
|
|
{ return Check(m_ptr->GetPosition(m_ptr, x, y)); }
|
|
|
|
bool GetSize(int *w, int *h)
|
|
{ return Check(m_ptr->GetSize(m_ptr, w, h)); }
|
|
|
|
bool MoveTo(int x, int y)
|
|
{ return Check(m_ptr->MoveTo(m_ptr, x, y)); }
|
|
|
|
bool Resize(int w, int h)
|
|
{ return Check(m_ptr->Resize(m_ptr, w, h)); }
|
|
|
|
bool SetOpacity(u8 opacity)
|
|
{ return Check(m_ptr->SetOpacity(m_ptr, opacity)); }
|
|
|
|
bool SetStackingClass(DFBWindowStackingClass klass)
|
|
{ return Check(m_ptr->SetStackingClass(m_ptr, klass)); }
|
|
|
|
bool RaiseToTop()
|
|
{ return Check(m_ptr->RaiseToTop(m_ptr)); }
|
|
|
|
bool LowerToBottom()
|
|
{ return Check(m_ptr->LowerToBottom(m_ptr)); }
|
|
|
|
wxIDirectFBSurfacePtr GetSurface()
|
|
{
|
|
IDirectFBSurface *s;
|
|
if ( Check(m_ptr->GetSurface(m_ptr, &s)) )
|
|
return new wxIDirectFBSurface(s);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
bool AttachEventBuffer(const wxIDirectFBEventBufferPtr& buffer)
|
|
{ return Check(m_ptr->AttachEventBuffer(m_ptr, buffer->GetRaw())); }
|
|
|
|
bool RequestFocus()
|
|
{ return Check(m_ptr->RequestFocus(m_ptr)); }
|
|
|
|
bool Destroy()
|
|
{ return Check(m_ptr->Destroy(m_ptr)); }
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxIDirectFBDisplayLayer
|
|
//-----------------------------------------------------------------------------
|
|
|
|
struct wxIDirectFBDisplayLayer : public wxDfbWrapper<IDirectFBDisplayLayer>
|
|
{
|
|
wxIDirectFBDisplayLayer(IDirectFBDisplayLayer *s) { Init(s); }
|
|
|
|
wxIDirectFBWindowPtr CreateWindow(const DFBWindowDescription *desc)
|
|
{
|
|
IDirectFBWindow *w;
|
|
if ( Check(m_ptr->CreateWindow(m_ptr, desc, &w)) )
|
|
return new wxIDirectFBWindow(w);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
bool GetConfiguration(DFBDisplayLayerConfig *config)
|
|
{ return Check(m_ptr->GetConfiguration(m_ptr, config)); }
|
|
|
|
wxVideoMode GetVideoMode();
|
|
|
|
bool GetCursorPosition(int *x, int *y)
|
|
{ return Check(m_ptr->GetCursorPosition(m_ptr, x, y)); }
|
|
|
|
bool WarpCursor(int x, int y)
|
|
{ return Check(m_ptr->WarpCursor(m_ptr, x, y)); }
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxIDirectFB
|
|
//-----------------------------------------------------------------------------
|
|
|
|
struct wxIDirectFB : public wxDfbWrapper<IDirectFB>
|
|
{
|
|
/**
|
|
Returns pointer to DirectFB singleton object, it never returns NULL
|
|
after wxApp was initialized. The object is cached, so calling this
|
|
method is cheap.
|
|
*/
|
|
static wxIDirectFBPtr Get()
|
|
{
|
|
if ( !ms_ptr ) CreateDirectFB();
|
|
return ms_ptr;
|
|
}
|
|
|
|
bool SetVideoMode(int w, int h, int bpp)
|
|
{ return Check(m_ptr->SetVideoMode(m_ptr, w, h, bpp)); }
|
|
|
|
wxIDirectFBSurfacePtr CreateSurface(const DFBSurfaceDescription *desc)
|
|
{
|
|
IDirectFBSurface *s;
|
|
if ( Check(m_ptr->CreateSurface(m_ptr, desc, &s)) )
|
|
return new wxIDirectFBSurface(s);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
wxIDirectFBEventBufferPtr CreateEventBuffer()
|
|
{
|
|
IDirectFBEventBuffer *b;
|
|
if ( Check(m_ptr->CreateEventBuffer(m_ptr, &b)) )
|
|
return new wxIDirectFBEventBuffer(b);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
wxIDirectFBFontPtr CreateFont(const char *filename,
|
|
const DFBFontDescription *desc)
|
|
{
|
|
IDirectFBFont *f;
|
|
if ( Check(m_ptr->CreateFont(m_ptr, filename, desc, &f)) )
|
|
return new wxIDirectFBFont(f);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
wxIDirectFBDisplayLayerPtr
|
|
GetDisplayLayer(DFBDisplayLayerID id = DLID_PRIMARY)
|
|
{
|
|
IDirectFBDisplayLayer *l;
|
|
if ( Check(m_ptr->GetDisplayLayer(m_ptr, id, &l)) )
|
|
return new wxIDirectFBDisplayLayer(l);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
/// Returns primary surface
|
|
wxIDirectFBSurfacePtr GetPrimarySurface();
|
|
|
|
private:
|
|
wxIDirectFB(IDirectFB *ptr) { Init(ptr); }
|
|
|
|
// creates ms_ptr instance
|
|
static void CreateDirectFB();
|
|
|
|
static void CleanUp();
|
|
friend class wxApp; // calls CleanUp
|
|
|
|
// pointer to the singleton IDirectFB object
|
|
static wxIDirectFBPtr ms_ptr;
|
|
};
|
|
|
|
#endif // _WX_DFB_WRAPDFB_H_
|