From 3444c904594f2a6679ae2c863352efa0bb3b975e Mon Sep 17 00:00:00 2001
From: Krzysztof Konopko <kris@konagma.com>
Date: Thu, 12 Sep 2013 12:38:25 +0200
Subject: [PATCH] ++DFB: Fix dynamic casts

Using runtime type information in inline functions for non-exported
classes causes failures since the RTTI is generatedin the library and
in the client code and they both do not match.

GCC introduced explicit visibility attributes [1] which help to control
class/function visibility in a similar manner to WIN `__declspec`.

By default all ++DFB API classes are exported with all their methods.
If there's a need to hide some of the methods in the future, explicit
PPDFB_LOCAL macro can be added and used to hide them.

[1] http://gcc.gnu.org/wiki/Visibility
---
 include/++dfb/++dfb.h                  |   34 ++++----
 include/++dfb/idirectfb.h              |   64 +++++++-------
 include/++dfb/idirectfbdatabuffer.h    |   34 ++++----
 include/++dfb/idirectfbdisplaylayer.h  |   84 +++++++++---------
 include/++dfb/idirectfbeventbuffer.h   |   30 +++----
 include/++dfb/idirectfbfont.h          |   32 +++----
 include/++dfb/idirectfbimageprovider.h |   16 ++--
 include/++dfb/idirectfbinputdevice.h   |   34 ++++----
 include/++dfb/idirectfbpalette.h       |   20 ++---
 include/++dfb/idirectfbscreen.h        |   44 +++++-----
 include/++dfb/idirectfbsurface.h       |  148 ++++++++++++++++----------------
 include/++dfb/idirectfbvideoprovider.h |   42 ++++-----
 include/++dfb/idirectfbwindow.h        |   94 ++++++++++----------
 13 files changed, 339 insertions(+), 337 deletions(-)

diff --git a/include/++dfb/++dfb.h b/include/++dfb/++dfb.h
index 7d67b6f..83ad491 100644
--- a/include/++dfb/++dfb.h
+++ b/include/++dfb/++dfb.h
@@ -44,13 +44,17 @@
 // that uses this DLL. This way any other project whose source files include this file see 
 // PPDFB_API functions as being imported from a DLL, whereas this DLL sees symbols
 // defined with this macro as being exported.
-#ifdef PPDFB_EXPORTS
-#define PPDFB_API __declspec(dllexport)
+# ifdef PPDFB_EXPORTS
+#  define PPDFB_API __declspec(dllexport)
+# else
+#  define PPDFB_API __declspec(dllimport)
+# endif
 #else
-#define PPDFB_API __declspec(dllimport)
-#endif
-#else
-#define PPDFB_API
+# if __GNUC__ >= 4
+#  define PPDFB_API __attribute__((visibility("default")))
+# else
+#  define PPDFB_API
+# endif
 #endif
 
 
@@ -61,13 +65,13 @@
 #include "++dfb_unmangle.h"
 
 
-class DFBException {
+class PPDFB_API DFBException {
 public:
-     PPDFB_API DFBException (const char *action, DFBResult result_code);
+     DFBException (const char *action, DFBResult result_code);
 
-     const char PPDFB_API *GetAction() const;
-     const char PPDFB_API *GetResult() const;
-     DFBResult  PPDFB_API  GetResultCode() const;
+     const char *GetAction() const;
+     const char *GetResult() const;
+     DFBResult   GetResultCode() const;
 
      friend std::ostream PPDFB_API &operator << (std::ostream &stream, DFBException *ex);
 
@@ -87,7 +91,7 @@ private:
 
 
 template <class IMPLEMENTINGCLASS, class IPPAny_C>
-class IPPAny
+class PPDFB_API IPPAny
 {
 	protected:
 		IPPAny(IPPAny_C *iface) {
@@ -131,8 +135,7 @@ class IPPAny
 			iface = other_iface;
 			if (old_iface)
 				PPDFB_DFBCHECK( old_iface->Release( old_iface ) );
-			//return dynamic_cast<IMPLEMENTINGCLASS&>(*this);
-			return reinterpret_cast<IMPLEMENTINGCLASS&>(*this);
+			return dynamic_cast<IMPLEMENTINGCLASS&>(*this);
 		}
 		inline IMPLEMENTINGCLASS &operator = (IPPAny_C *other_iface) {
                IPPAny_C *old_iface = iface;
@@ -141,8 +144,7 @@ class IPPAny
 			iface = other_iface;
 			if (old_iface)
 				PPDFB_DFBCHECK( old_iface->Release( old_iface ) );
-			//return dynamic_cast<IMPLEMENTINGCLASS&>(*this);
-			return reinterpret_cast<IMPLEMENTINGCLASS&>(*this);
+			return dynamic_cast<IMPLEMENTINGCLASS&>(*this);
 		}
 };
 
diff --git a/include/++dfb/idirectfb.h b/include/++dfb/idirectfb.h
index 818c2cb..bc26d70 100644
--- a/include/++dfb/idirectfb.h
+++ b/include/++dfb/idirectfb.h
@@ -36,66 +36,66 @@
 #error Please include ++dfb.h only.
 #endif
 
-class IDirectFB :public IPPAny<IDirectFB, IDirectFB_C>{
+class PPDFB_API IDirectFB :public IPPAny<IDirectFB, IDirectFB_C>{
 public:
-     PPDFB_API IDirectFB(IDirectFB_C *myptr = NULL):IPPAny<IDirectFB, IDirectFB_C>(myptr){}
-     PPDFB_API ~IDirectFB(){}
-     void                    PPDFB_API SetCooperativeLevel    (DFBCooperativeLevel         level);
-     void                    PPDFB_API SetVideoMode           (unsigned int                width,
+     IDirectFB(IDirectFB_C *myptr = NULL):IPPAny<IDirectFB, IDirectFB_C>(myptr){}
+     ~IDirectFB(){}
+     void                    SetCooperativeLevel    (DFBCooperativeLevel         level);
+     void                    SetVideoMode           (unsigned int                width,
                                                                unsigned int                height,
                                                                unsigned int                bpp);
 
-     void                    PPDFB_API GetDeviceDescription   (DFBGraphicsDeviceDescription *desc);
-     void                    PPDFB_API EnumVideoModes         (DFBVideoModeCallback        callback,
+     void                    GetDeviceDescription   (DFBGraphicsDeviceDescription *desc);
+     void                    EnumVideoModes         (DFBVideoModeCallback        callback,
                                                                void                       *callbackdata);
 
-     IDirectFBSurface        PPDFB_API CreateSurface          (DFBSurfaceDescription      &desc) const;
-     IDirectFBPalette        PPDFB_API CreatePalette          (DFBPaletteDescription      &desc);
+     IDirectFBSurface        CreateSurface          (DFBSurfaceDescription      &desc) const;
+     IDirectFBPalette        CreatePalette          (DFBPaletteDescription      &desc);
 
-     void                    PPDFB_API EnumScreens            (DFBScreenCallback           callback,
+     void                    EnumScreens            (DFBScreenCallback           callback,
                                                                void                       *callbackdata);
-     IDirectFBScreen         PPDFB_API GetScreen              (DFBScreenID                 screen_id);
+     IDirectFBScreen         GetScreen              (DFBScreenID                 screen_id);
 
-     void                    PPDFB_API EnumDisplayLayers      (DFBDisplayLayerCallback     callback,
+     void                    EnumDisplayLayers      (DFBDisplayLayerCallback     callback,
                                                                void                       *callbackdata);
-     IDirectFBDisplayLayer   PPDFB_API GetDisplayLayer        (DFBDisplayLayerID           layer_id);
+     IDirectFBDisplayLayer   GetDisplayLayer        (DFBDisplayLayerID           layer_id);
 
-     void                    PPDFB_API EnumInputDevices       (DFBInputDeviceCallback      callback,
+     void                    EnumInputDevices       (DFBInputDeviceCallback      callback,
                                                                void                       *callbackdata) const;
-     IDirectFBInputDevice    PPDFB_API GetInputDevice         (DFBInputDeviceID            device_id) const;
-     IDirectFBEventBuffer    PPDFB_API CreateEventBuffer      () const;
-     IDirectFBEventBuffer    PPDFB_API CreateInputEventBuffer (DFBInputDeviceCapabilities caps,
+     IDirectFBInputDevice    GetInputDevice         (DFBInputDeviceID            device_id) const;
+     IDirectFBEventBuffer    CreateEventBuffer      () const;
+     IDirectFBEventBuffer    CreateInputEventBuffer (DFBInputDeviceCapabilities caps,
                                                                DFBBoolean                 global = DFB_FALSE);
 
-     IDirectFBImageProvider  PPDFB_API CreateImageProvider    (const char                 *filename) const;
-     IDirectFBVideoProvider  PPDFB_API CreateVideoProvider    (const char                 *filename);
-     IDirectFBFont           PPDFB_API CreateFont             (const char                 *filename,
+     IDirectFBImageProvider  CreateImageProvider    (const char                 *filename) const;
+     IDirectFBVideoProvider  CreateVideoProvider    (const char                 *filename);
+     IDirectFBFont           CreateFont             (const char                 *filename,
                                                                DFBFontDescription         &desc) const ;
-     IDirectFBDataBuffer     PPDFB_API CreateDataBuffer       (DFBDataBufferDescription   &desc);
+     IDirectFBDataBuffer     CreateDataBuffer       (DFBDataBufferDescription   &desc);
 
-     struct timeval          PPDFB_API SetClipboardData       (const char                 *mime_type,
+     struct timeval          SetClipboardData       (const char                 *mime_type,
                                                                const void                 *data,
                                                                unsigned int                size);
-     void                    PPDFB_API GetClipboardData       (char                      **mime_type,
+     void                    GetClipboardData       (char                      **mime_type,
                                                                void                      **data,
                                                                unsigned int               *size);
-     struct timeval          PPDFB_API GetClipboardTimeStamp  ();
+     struct timeval          GetClipboardTimeStamp  ();
 
-     void                    PPDFB_API Suspend                ();
-     void                    PPDFB_API Resume                 ();
-     void                    PPDFB_API WaitIdle               ();
-     void                    PPDFB_API WaitForSync            ();
+     void                    Suspend                ();
+     void                    Resume                 ();
+     void                    WaitIdle               ();
+     void                    WaitForSync            ();
 
-     void                   PPDFB_API *GetInterface           (const char                 *type,
+     void                   *GetInterface           (const char                 *type,
                                                                const char                 *implementation,
                                                                void                       *arg);
 
-     IDirectFBSurface        PPDFB_API GetSurface             (DFBSurfaceID                surface_id) const;
+     IDirectFBSurface        GetSurface             (DFBSurfaceID                surface_id) const;
 
-     inline IDirectFB PPDFB_API & operator = (const IDirectFB& other){
+     inline IDirectFB & operator = (const IDirectFB& other){
           return IPPAny<IDirectFB, IDirectFB_C>::operator =(other);
      }
-     inline IDirectFB PPDFB_API & operator = (IDirectFB_C* other){
+     inline IDirectFB & operator = (IDirectFB_C* other){
           return IPPAny<IDirectFB, IDirectFB_C>::operator =(other);
      }
 };
-- 
1.7.10.4

