expose GUIRenderingControl to addongui lib
authorxbmc <fernetmenta@online.de>
Tue, 20 Nov 2012 07:57:01 +0000 (08:57 +0100)
committerxbmc <fernetmenta@online.de>
Fri, 1 Mar 2013 12:24:00 +0000 (13:24 +0100)
addons/library.xbmc.gui/libXBMC_gui.h
lib/addons/library.xbmc.gui/libXBMC_gui.cpp
xbmc/addons/AddonCallbacks.h
xbmc/addons/AddonCallbacksGUI.cpp
xbmc/addons/AddonCallbacksGUI.h
xbmc/guilib/GUIControlFactory.cpp

index 3fccaf0..87a9f79 100644 (file)
@@ -43,6 +43,7 @@ class CAddonGUISpinControl;
 class CAddonGUIRadioButton;
 class CAddonGUIProgressControl;
 class CAddonListItem;
+class CAddonGUIRenderingControl;
 
 class CHelper_libXBMC_gui
 {
@@ -154,6 +155,14 @@ public:
       dlsym(m_libXBMC_gui, "GUI_ListItem_destroy");
     if (GUI_ListItem_destroy == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; }
 
+    GUI_control_get_rendering = (CAddonGUIRenderingControl* (*)(void *HANDLE, void *CB, CAddonGUIWindow *window, int controlId))
+      dlsym(m_libXBMC_gui, "GUI_control_get_rendering");
+    if (GUI_control_get_rendering == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; }
+
+    GUI_control_release_rendering = (void (*)(CAddonGUIRenderingControl* p))
+      dlsym(m_libXBMC_gui, "GUI_control_release_rendering");
+    if (GUI_control_release_rendering == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; }
+
 
     m_Callbacks = GUI_register_me(m_Handle);
     return m_Callbacks != NULL;
@@ -234,6 +243,16 @@ public:
     return GUI_ListItem_destroy(p);
   }
 
+  CAddonGUIRenderingControl* Control_getRendering(CAddonGUIWindow *window, int controlId)
+  {
+    return GUI_control_get_rendering(m_Handle, m_Callbacks, window, controlId);
+  }
+
+  void Control_releaseRendering(CAddonGUIRenderingControl* p)
+  {
+    return GUI_control_release_rendering(p);
+  }
+
 protected:
   void* (*GUI_register_me)(void *HANDLE);
   void (*GUI_unregister_me)(void *HANDLE, void* CB);
@@ -252,6 +271,8 @@ protected:
   void (*GUI_control_release_progress)(CAddonGUIProgressControl* p);
   CAddonListItem* (*GUI_ListItem_create)(void *HANDLE, void* CB, const char *label, const char *label2, const char *iconImage, const char *thumbnailImage, const char *path);
   void (*GUI_ListItem_destroy)(CAddonListItem* p);
+  CAddonGUIRenderingControl* (*GUI_control_get_rendering)(void *HANDLE, void* CB, CAddonGUIWindow *window, int controlId);
+  void (*GUI_control_release_rendering)(CAddonGUIRenderingControl* p);
 
 private:
   void *m_libXBMC_gui;
@@ -355,6 +376,7 @@ class CAddonGUIWindow
 friend class CAddonGUISpinControl;
 friend class CAddonGUIRadioButton;
 friend class CAddonGUIProgressControl;
+friend class CAddonGUIRenderingControl;
 
 public:
   CAddonGUIWindow(void *hdl, void *cb, const char *xmlFilename, const char *defaultSkin, bool forceFallback, bool asDialog);
@@ -385,6 +407,7 @@ public:
   virtual void         SetCurrentListPosition(int listPos);
   virtual int          GetCurrentListPosition();
   virtual void         SetControlLabel(int controlId, const char *label);
+  virtual void         MarkDirtyRegion();
 
   virtual bool         OnClick(int controlId);
   virtual bool         OnFocus(int controlId);
@@ -402,3 +425,29 @@ protected:
   void *m_Handle;
   void *m_cb;
 };
+
+class CAddonGUIRenderingControl
+{
+public:
+  CAddonGUIRenderingControl(void *hdl, void *cb, CAddonGUIWindow *window, int controlId);
+  virtual ~CAddonGUIRenderingControl();
+  virtual void Init();
+
+  virtual bool Create(int x, int y, int w, int h, void *device);
+  virtual void Render();
+  virtual void Stop();
+  virtual bool Dirty();
+
+  GUIHANDLE m_cbhdl;
+  bool (*CBCreate)(GUIHANDLE cbhdl, int x, int y, int w, int h, void *device);
+  void (*CBRender)(GUIHANDLE cbhdl);
+  void (*CBStop)(GUIHANDLE cbhdl);
+  bool (*CBDirty)(GUIHANDLE cbhdl);
+
+private:
+  CAddonGUIWindow *m_Window;
+  int         m_ControlId;
+  GUIHANDLE   m_RenderingHandle;
+  void *m_Handle;
+  void *m_cb;
+};
index c9765a3..7da98db 100644 (file)
@@ -300,6 +300,11 @@ void CAddonGUIWindow::SetControlLabel(int controlId, const char *label)
   ((CB_GUILib*)m_cb)->Window_SetControlLabel(((AddonCB*)m_Handle)->addonData, m_WindowHandle, controlId, label);
 }
 
+void CAddonGUIWindow::MarkDirtyRegion()
+{
+  ((CB_GUILib*)m_cb)->Window_MarkDirtyRegion(((AddonCB*)m_Handle)->addonData, m_WindowHandle);
+}
+
 ///-------------------------------------
 /// cGUISpinControl
 
@@ -555,5 +560,91 @@ void CAddonListItem::SetPath(const char *Path)
     ((CB_GUILib*)m_cb)->ListItem_SetPath(((AddonCB*)m_Handle)->addonData, m_ListItemHandle, Path);
 }
 
+///-------------------------------------
+/// cGUIRenderingControl
+
+DLLEXPORT CAddonGUIRenderingControl* GUI_control_get_rendering(void *hdl, void *cb, CAddonGUIWindow *window, int controlId)
+{
+  return new CAddonGUIRenderingControl(hdl, cb, window, controlId);
+}
+
+DLLEXPORT void GUI_control_release_rendering(CAddonGUIRenderingControl* p)
+{
+  delete p;
+}
+
+DLLEXPORT bool GUI_control_rendering_create(GUIHANDLE handle, int x, int y, int w, int h, void *device)
+{
+  CAddonGUIRenderingControl *pControl = (CAddonGUIRenderingControl*) handle;
+  return pControl->Create(x,y,w,h,device);
+}
+
+DLLEXPORT void GUI_control_rendering_render(GUIHANDLE handle)
+{
+  CAddonGUIRenderingControl *pControl = (CAddonGUIRenderingControl*) handle;
+  pControl->Render();
+}
+
+DLLEXPORT void GUI_control_rendering_stop(GUIHANDLE handle)
+{
+  CAddonGUIRenderingControl *pControl = (CAddonGUIRenderingControl*) handle;
+  pControl->Stop();
+}
+
+DLLEXPORT bool GUI_control_rendering_dirty(GUIHANDLE handle)
+{
+  CAddonGUIRenderingControl *pControl = (CAddonGUIRenderingControl*) handle;
+  return pControl->Dirty();
+}
+
+CAddonGUIRenderingControl::CAddonGUIRenderingControl(void *hdl, void *cb, CAddonGUIWindow *window, int controlId)
+ : m_Window(window)
+ , m_ControlId(controlId)
+ , m_Handle(hdl)
+ , m_cb(cb)
+{
+  m_RenderingHandle = ((CB_GUILib*)m_cb)->Window_GetControl_RenderAddon(((AddonCB*)m_Handle)->addonData, m_Window->m_WindowHandle, controlId);
+}
+
+CAddonGUIRenderingControl::~CAddonGUIRenderingControl()
+{
+  ((CB_GUILib*)m_cb)->RenderAddon_Delete(((AddonCB*)m_Handle)->addonData, m_RenderingHandle);
+}
+
+void CAddonGUIRenderingControl::Init()
+{
+  ((CB_GUILib*)m_cb)->RenderAddon_SetCallbacks(((AddonCB*)m_Handle)->addonData, m_RenderingHandle, this, GUI_control_rendering_create, GUI_control_rendering_render, GUI_control_rendering_stop, GUI_control_rendering_dirty);
+}
+
+bool CAddonGUIRenderingControl::Create(int x, int y, int w, int h, void *device)
+{
+  if (!CBCreate)
+    return false;
+
+  return CBCreate(m_cbhdl, x, y, w, h, device);
+}
+
+void CAddonGUIRenderingControl::Render()
+{
+  if (!CBRender)
+    return;
 
+  CBRender(m_cbhdl);
+}
+
+void CAddonGUIRenderingControl::Stop()
+{
+  if (!CBStop)
+    return;
+
+  CBStop(m_cbhdl);
+}
+
+bool CAddonGUIRenderingControl::Dirty()
+{
+  if (!CBDirty)
+    return true;
+
+  return CBDirty(m_cbhdl);
+}
 };
index c2d690b..d7c6fd0 100644 (file)
@@ -119,7 +119,9 @@ typedef GUIHANDLE   (*GUIWindow_GetControl_Button)(void *addonData, GUIHANDLE ha
 typedef GUIHANDLE   (*GUIWindow_GetControl_RadioButton)(void *addonData, GUIHANDLE handle, int controlId);
 typedef GUIHANDLE   (*GUIWindow_GetControl_Edit)(void *addonData, GUIHANDLE handle, int controlId);
 typedef GUIHANDLE   (*GUIWindow_GetControl_Progress)(void *addonData, GUIHANDLE handle, int controlId);
+typedef GUIHANDLE   (*GUIWindow_GetControl_RenderAddon)(void *addonData, GUIHANDLE handle, int controlId);
 typedef void        (*GUIWindow_SetControlLabel)(void *addonData, GUIHANDLE handle, int controlId, const char *label);
+typedef void        (*GUIWindow_MarkDirtyRegion)(void *addonData, GUIHANDLE handle);
 typedef void        (*GUIControl_Spin_SetVisible)(void *addonData, GUIHANDLE spinhandle, bool yesNo);
 typedef void        (*GUIControl_Spin_SetText)(void *addonData, GUIHANDLE spinhandle, const char *label);
 typedef void        (*GUIControl_Spin_Clear)(void *addonData, GUIHANDLE spinhandle);
@@ -146,6 +148,9 @@ typedef void        (*GUIListItem_SetInfo)(void *addonData, GUIHANDLE handle, co
 typedef void        (*GUIListItem_SetProperty)(void *addonData, GUIHANDLE handle, const char *key, const char *value);
 typedef const char* (*GUIListItem_GetProperty)(void *addonData, GUIHANDLE handle, const char *key);
 typedef void        (*GUIListItem_SetPath)(void *addonData, GUIHANDLE handle, const char *path);
+typedef void        (*GUIRenderAddon_SetCallbacks)(void *addonData, GUIHANDLE handle, GUIHANDLE clienthandle, bool (*createCB)(GUIHANDLE,int,int,int,int,void*), void (*renderCB)(GUIHANDLE), void (*stopCB)(GUIHANDLE), bool (*dirtyCB)(GUIHANDLE));
+typedef void        (*GUIRenderAddon_Delete)(void *addonData, GUIHANDLE handle);
+typedef void        (*GUIRenderAddon_MarkDirty)(void *addonData, GUIHANDLE handle);
 
 typedef struct CB_GUILib
 {
@@ -185,7 +190,9 @@ typedef struct CB_GUILib
   GUIWindow_GetControl_RadioButton    Window_GetControl_RadioButton;
   GUIWindow_GetControl_Edit           Window_GetControl_Edit;
   GUIWindow_GetControl_Progress       Window_GetControl_Progress;
+  GUIWindow_GetControl_RenderAddon    Window_GetControl_RenderAddon;
   GUIWindow_SetControlLabel           Window_SetControlLabel;
+  GUIWindow_MarkDirtyRegion           Window_MarkDirtyRegion;
   GUIControl_Spin_SetVisible          Control_Spin_SetVisible;
   GUIControl_Spin_SetText             Control_Spin_SetText;
   GUIControl_Spin_Clear               Control_Spin_Clear;
@@ -212,6 +219,8 @@ typedef struct CB_GUILib
   GUIListItem_SetProperty             ListItem_SetProperty;
   GUIListItem_GetProperty             ListItem_GetProperty;
   GUIListItem_SetPath                 ListItem_SetPath;
+  GUIRenderAddon_SetCallbacks         RenderAddon_SetCallbacks;
+  GUIRenderAddon_Delete               RenderAddon_Delete;
 
 } CB_GUILib;
 
index 13da1e7..b4a4678 100644 (file)
@@ -36,6 +36,7 @@
 #include "guilib/GUISettingsSliderControl.h"
 #include "guilib/GUIEditControl.h"
 #include "guilib/GUIProgressControl.h"
+#include "guilib/GUIRenderingControl.h"
 
 #define CONTROL_BTNVIEWASICONS  2
 #define CONTROL_BTNSORTBY       3
@@ -93,8 +94,10 @@ CAddonCallbacksGUI::CAddonCallbacksGUI(CAddon* addon)
   m_callbacks->Window_GetControl_RadioButton  = CAddonCallbacksGUI::Window_GetControl_RadioButton;
   m_callbacks->Window_GetControl_Edit         = CAddonCallbacksGUI::Window_GetControl_Edit;
   m_callbacks->Window_GetControl_Progress     = CAddonCallbacksGUI::Window_GetControl_Progress;
+  m_callbacks->Window_GetControl_RenderAddon  = CAddonCallbacksGUI::Window_GetControl_RenderAddon;
 
   m_callbacks->Window_SetControlLabel         = CAddonCallbacksGUI::Window_SetControlLabel;
+  m_callbacks->Window_MarkDirtyRegion         = CAddonCallbacksGUI::Window_MarkDirtyRegion;
 
   m_callbacks->Control_Spin_SetVisible        = CAddonCallbacksGUI::Control_Spin_SetVisible;
   m_callbacks->Control_Spin_SetText           = CAddonCallbacksGUI::Control_Spin_SetText;
@@ -125,6 +128,9 @@ CAddonCallbacksGUI::CAddonCallbacksGUI(CAddon* addon)
   m_callbacks->ListItem_SetProperty           = CAddonCallbacksGUI::ListItem_SetProperty;
   m_callbacks->ListItem_GetProperty           = CAddonCallbacksGUI::ListItem_GetProperty;
   m_callbacks->ListItem_SetPath               = CAddonCallbacksGUI::ListItem_SetPath;
+
+  m_callbacks->RenderAddon_SetCallbacks       = CAddonCallbacksGUI::RenderAddon_SetCallbacks;
+  m_callbacks->RenderAddon_Delete             = CAddonCallbacksGUI::RenderAddon_Delete;
 }
 
 CAddonCallbacksGUI::~CAddonCallbacksGUI()
@@ -927,6 +933,22 @@ GUIHANDLE CAddonCallbacksGUI::Window_GetControl_Progress(void *addonData, GUIHAN
   return pGUIControl;
 }
 
+GUIHANDLE CAddonCallbacksGUI::Window_GetControl_RenderAddon(void *addonData, GUIHANDLE handle, int controlId)
+{
+  CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
+  if (!helper || !handle)
+    return NULL;
+
+  CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
+  CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId);
+  if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_RENDERADDON)
+    return NULL;
+
+  CGUIAddonRenderingControl *pProxyControl;
+  pProxyControl = new CGUIAddonRenderingControl((CGUIRenderingControl*)pGUIControl);
+  return pProxyControl;
+}
+
 void CAddonCallbacksGUI::Window_SetControlLabel(void *addonData, GUIHANDLE handle, int controlId, const char *label)
 {
   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
@@ -940,6 +962,17 @@ void CAddonCallbacksGUI::Window_SetControlLabel(void *addonData, GUIHANDLE handl
   pAddonWindow->OnMessage(msg);
 }
 
+void CAddonCallbacksGUI::Window_MarkDirtyRegion(void *addonData, GUIHANDLE handle)
+{
+  CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
+  if (!helper || !handle)
+    return;
+
+  CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle;
+
+  pAddonWindow->MarkDirtyRegion();
+}
+
 void CAddonCallbacksGUI::Control_Spin_SetVisible(void *addonData, GUIHANDLE spinhandle, bool yesNo)
 {
   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
@@ -1218,9 +1251,37 @@ void CAddonCallbacksGUI::ListItem_SetPath(void *addonData, GUIHANDLE handle, con
   ((CFileItem*)handle)->SetPath(path);
 }
 
+void CAddonCallbacksGUI::RenderAddon_SetCallbacks(void *addonData, GUIHANDLE handle, GUIHANDLE clienthandle, bool (*createCB)(GUIHANDLE,int,int,int,int,void*), void (*renderCB)(GUIHANDLE), void (*stopCB)(GUIHANDLE), bool (*dirtyCB)(GUIHANDLE))
+{
+  CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
+  if (!helper || !handle)
+    return;
+
+  CGUIAddonRenderingControl *pAddonControl = (CGUIAddonRenderingControl*)handle;
 
+  Lock();
+  pAddonControl->m_clientHandle  = clienthandle;
+  pAddonControl->CBCreate        = createCB;
+  pAddonControl->CBRender        = renderCB;
+  pAddonControl->CBStop          = stopCB;
+  pAddonControl->CBDirty         = dirtyCB;
+  Unlock();
 
+  pAddonControl->m_pControl->InitCallback(pAddonControl);
+}
 
+void CAddonCallbacksGUI::RenderAddon_Delete(void *addonData, GUIHANDLE handle)
+{
+  CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
+  if (!helper || !handle)
+    return;
+
+  CGUIAddonRenderingControl *pAddonControl = (CGUIAddonRenderingControl*)handle;
+
+  Lock();
+  pAddonControl->Delete();
+  Unlock();
+}
 
 
 
@@ -1293,6 +1354,16 @@ bool CGUIAddonWindow::OnMessage(CGUIMessage& message)
       }
     }
     break;
+
+    case GUI_MSG_FOCUSED:
+    {
+      if (HasID(message.GetSenderId()) && CBOnFocus)
+      {
+        CBOnFocus(m_clientHandle, message.GetControlId());
+      }
+    }
+    break;
+
     case GUI_MSG_CLICKED:
     {
       int iControl=message.GetSenderId();
@@ -1537,4 +1608,61 @@ void CGUIAddonWindowDialog::Show_Internal(bool show /* = true */)
   }
 }
 
+CGUIAddonRenderingControl::CGUIAddonRenderingControl(CGUIRenderingControl *pControl)
+{
+  m_pControl = pControl;
+  m_refCount = 1;
+}
+
+bool CGUIAddonRenderingControl::Create(int x, int y, int w, int h, void *device)
+{
+  if (CBCreate)
+  {
+    if (CBCreate(m_clientHandle, x, y, w, h, device))
+    {
+      m_refCount++;
+      return true;
+    }
+  }
+  return false;
+}
+
+void CGUIAddonRenderingControl::Render()
+{
+  if (CBRender)
+  {
+    g_graphicsContext.BeginPaint();
+    CBRender(m_clientHandle);
+    g_graphicsContext.EndPaint();
+  }
+}
+
+void CGUIAddonRenderingControl::Stop()
+{
+  if (CBStop)
+  {
+    CBStop(m_clientHandle);
+  }
+  m_refCount--;
+  if (m_refCount <= 0)
+    delete this;
+}
+
+void CGUIAddonRenderingControl::Delete()
+{
+  m_refCount--;
+  if (m_refCount <= 0)
+    delete this;
+}
+
+bool CGUIAddonRenderingControl::IsDirty()
+{
+  bool ret = true;
+  if (CBDirty)
+  {
+    ret = CBDirty(m_clientHandle);
+  }
+  return ret;
+}
+
 }; /* namespace ADDON */
index edf04f8..6da862b 100644 (file)
 #include "AddonCallbacks.h"
 #include "windows/GUIMediaWindow.h"
 #include "threads/Event.h"
+#include "guilib/IRenderingCallback.h"
 
 class CGUISpinControlEx;
 class CGUIButtonControl;
 class CGUIRadioButtonControl;
 class CGUISettingsSliderControl;
 class CGUIEditControl;
+class CGUIRenderingControl;
 
 namespace ADDON
 {
@@ -79,7 +81,9 @@ public:
   static GUIHANDLE    Window_GetControl_RadioButton(void *addonData, GUIHANDLE handle, int controlId);
   static GUIHANDLE    Window_GetControl_Edit(void *addonData, GUIHANDLE handle, int controlId);
   static GUIHANDLE    Window_GetControl_Progress(void *addonData, GUIHANDLE handle, int controlId);
+  static GUIHANDLE    Window_GetControl_RenderAddon(void *addonData, GUIHANDLE handle, int controlId);
   static void         Window_SetControlLabel(void *addonData, GUIHANDLE handle, int controlId, const char *label);
+  static void         Window_MarkDirtyRegion(void *addonData, GUIHANDLE handle);
   static void         Control_Spin_SetVisible(void *addonData, GUIHANDLE spinhandle, bool yesNo);
   static void         Control_Spin_SetText(void *addonData, GUIHANDLE spinhandle, const char *label);
   static void         Control_Spin_Clear(void *addonData, GUIHANDLE spinhandle);
@@ -106,6 +110,9 @@ public:
   static void         ListItem_SetProperty(void *addonData, GUIHANDLE handle, const char *key, const char *value);
   static const char * ListItem_GetProperty(void *addonData, GUIHANDLE handle, const char *key);
   static void         ListItem_SetPath(void *addonData, GUIHANDLE handle, const char *path);
+  static void         RenderAddon_SetCallbacks(void *addonData, GUIHANDLE handle, GUIHANDLE clienthandle, bool (*createCB)(GUIHANDLE,int,int,int,int,void*), void (*renderCB)(GUIHANDLE), void (*stopCB)(GUIHANDLE), bool (*dirtyCB)(GUIHANDLE));
+  static void         RenderAddon_Delete(void *addonData, GUIHANDLE handle);
+  static void         RenderAddon_MarkDirty(void *addonData, GUIHANDLE handle);
 
 private:
   CB_GUILib    *m_callbacks;
@@ -178,4 +185,25 @@ private:
   bool             m_bRunning;
 };
 
+class CGUIAddonRenderingControl : public IRenderingCallback
+{
+friend class CAddonCallbacksGUI;
+public:
+  CGUIAddonRenderingControl(CGUIRenderingControl *pControl);
+  virtual bool Create(int x, int y, int w, int h, void *device);
+  virtual void Render();
+  virtual void Stop();
+  virtual bool IsDirty();
+  virtual void Delete();
+protected:
+  bool (*CBCreate) (GUIHANDLE cbhdl, int x, int y, int w, int h, void *device);
+  void (*CBRender)(GUIHANDLE cbhdl);
+  void (*CBStop)(GUIHANDLE cbhdl);
+  bool (*CBDirty)(GUIHANDLE cbhdl);
+
+  GUIHANDLE m_clientHandle;
+  CGUIRenderingControl *m_pControl;
+  int m_refCount;
+};
+
 }; /* namespace ADDON */
index 29698d3..6526f1d 100644 (file)
@@ -1323,6 +1323,10 @@ CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlEl
   {
     control = new CGUIVisualisationControl(parentID, id, posX, posY, width, height);
   }
+  else if (type == CGUIControl::GUICONTROL_RENDERADDON)
+  {
+    control = new CGUIRenderingControl(parentID, id, posX, posY, width, height);
+  }
 
   // things that apply to all controls
   if (control)