Ejemplo n.º 1
0
    /* Searches for a control in Window->vecControls
     * If we can't find any but the window has the controlId (in case of a not python window)
     * we create a new control with basic functionality
     */
    Control* Window::GetControlById(int iControlId, CCriticalSection* gc)
    {
      XBMC_TRACE;

      // find in window vector first!!!
      // this saves us from creating a complete new control
      std::vector<AddonClass::Ref<Control> >::iterator it = vecControls.begin();
      while (it != vecControls.end())
      {
        AddonClass::Ref<Control> control = (*it);
        if (control->iControlId == iControlId)
        {
          return control.get();
        } else ++it;
      }

      // lock xbmc GUI before accessing data from it
      MaybeLock lock(gc);

      // check if control exists
      CGUIControl* pGUIControl = (CGUIControl*)ref(window)->GetControl(iControlId); 
      if (!pGUIControl)
      {
        // control does not exist.
        throw WindowException("Non-Existent Control %d",iControlId);
      }

      // allocate a new control with a new reference
      CLabelInfo li;

      Control* pControl = NULL;

      // TODO: Yuck! Should probably be done with a Factory pattern
      switch(pGUIControl->GetControlType())
      {
      case CGUIControl::GUICONTROL_BUTTON:
        pControl = new ControlButton();

        li = ((CGUIButtonControl *)pGUIControl)->GetLabelInfo();

        // note: conversion from infocolors -> plain colors here
        ((ControlButton*)pControl)->disabledColor = li.disabledColor;
        ((ControlButton*)pControl)->focusedColor  = li.focusedColor;
        ((ControlButton*)pControl)->textColor  = li.textColor;
        ((ControlButton*)pControl)->shadowColor   = li.shadowColor;
        if (li.font) ((ControlButton*)pControl)->strFont = li.font->GetFontName();
        ((ControlButton*)pControl)->align = li.align;
        break;
      case CGUIControl::GUICONTROL_CHECKMARK:
        pControl = new ControlCheckMark();

        li = ((CGUICheckMarkControl *)pGUIControl)->GetLabelInfo();

        // note: conversion to plain colors from infocolors.
        ((ControlCheckMark*)pControl)->disabledColor = li.disabledColor;
        //((ControlCheckMark*)pControl)->shadowColor = li.shadowColor;
        ((ControlCheckMark*)pControl)->textColor  = li.textColor;
        if (li.font) ((ControlCheckMark*)pControl)->strFont = li.font->GetFontName();
        ((ControlCheckMark*)pControl)->align = li.align;
        break;
      case CGUIControl::GUICONTROL_LABEL:
        pControl = new ControlLabel();
        break;
      case CGUIControl::GUICONTROL_SPIN:
        pControl = new ControlSpin();
        break;
      case CGUIControl::GUICONTROL_FADELABEL:
        pControl = new ControlFadeLabel();
        break;
      case CGUIControl::GUICONTROL_TEXTBOX:
        pControl = new ControlTextBox();
        break;
      case CGUIControl::GUICONTROL_IMAGE:
        pControl = new ControlImage();
        break;
      case CGUIControl::GUICONTROL_PROGRESS:
        pControl = new ControlProgress();
        break;
      case CGUIControl::GUICONTROL_SLIDER:
        pControl = new ControlSlider();
        break;			
      case CGUIControl::GUICONTAINER_LIST:
      case CGUIControl::GUICONTAINER_WRAPLIST:
      case CGUIControl::GUICONTAINER_FIXEDLIST:
      case CGUIControl::GUICONTAINER_PANEL:
        pControl = new ControlList();
        // create a python spin control
        ((ControlList*)pControl)->pControlSpin = new ControlSpin();
        break;
      case CGUIControl::GUICONTROL_GROUP:
        pControl = new ControlGroup();
        break;
      case CGUIControl::GUICONTROL_RADIO:
        pControl = new ControlRadioButton();

        li = ((CGUIRadioButtonControl *)pGUIControl)->GetLabelInfo();

        // note: conversion from infocolors -> plain colors here
        ((ControlRadioButton*)pControl)->disabledColor = li.disabledColor;
        ((ControlRadioButton*)pControl)->focusedColor  = li.focusedColor;
        ((ControlRadioButton*)pControl)->textColor  = li.textColor;
        ((ControlRadioButton*)pControl)->shadowColor   = li.shadowColor;
        if (li.font) ((ControlRadioButton*)pControl)->strFont = li.font->GetFontName();
        ((ControlRadioButton*)pControl)->align = li.align;
        break;
      case CGUIControl::GUICONTROL_EDIT:
        pControl = new ControlEdit();

        li = ((CGUIEditControl *)pGUIControl)->GetLabelInfo();

        // note: conversion from infocolors -> plain colors here
        ((ControlEdit*)pControl)->disabledColor = li.disabledColor;
        ((ControlEdit*)pControl)->textColor  = li.textColor;
        if (li.font) ((ControlEdit*)pControl)->strFont = li.font->GetFontName();
        ((ControlButton*)pControl)->align = li.align;
        break;
      default:
        break;
      }

      if (!pControl)
        // throw an exeption
        throw WindowException("Unknown control type for python");

      // we have a valid control here, fill in all the 'Control' data
      pControl->pGUIControl = pGUIControl;
      pControl->iControlId = pGUIControl->GetID();
      pControl->iParentId = iWindowId;
      pControl->dwHeight = (int)pGUIControl->GetHeight();
      pControl->dwWidth = (int)pGUIControl->GetWidth();
      pControl->dwPosX = (int)pGUIControl->GetXPosition();
      pControl->dwPosY = (int)pGUIControl->GetYPosition();
      pControl->iControlUp = pGUIControl->GetNavigateAction(ACTION_MOVE_UP).GetNavigation();
      pControl->iControlDown = pGUIControl->GetNavigateAction(ACTION_MOVE_DOWN).GetNavigation();
      pControl->iControlLeft = pGUIControl->GetNavigateAction(ACTION_MOVE_LEFT).GetNavigation();
      pControl->iControlRight = pGUIControl->GetNavigateAction(ACTION_MOVE_RIGHT).GetNavigation();

      // It got this far so means the control isn't actually in the vector of controls
      // so lets add it to save doing all that next time
      vecControls.push_back(AddonClass::Ref<Control>(pControl));

      // return the control with increased reference (+1)
      return pControl;
    }
Ejemplo n.º 2
0
  namespace Python
  {
    static AddonClass::Ref<PythonLanguageHook> instance;

    static CCriticalSection hooksMutex;
    static std::map<PyInterpreterState*,AddonClass::Ref<PythonLanguageHook> > hooks;

    // vtab instantiation
    PythonLanguageHook::~PythonLanguageHook()
    {
      XBMC_TRACE;
      XBMCAddon::LanguageHook::deallocating();
    }

    void PythonLanguageHook::MakePendingCalls()
    {
      XBMC_TRACE;
      PythonCallbackHandler::makePendingCalls();
    }

    void PythonLanguageHook::DelayedCallOpen()
    {
      XBMC_TRACE;
      PyGILLock::releaseGil();
    }

    void PythonLanguageHook::DelayedCallClose()
    {
      XBMC_TRACE;
      PyGILLock::acquireGil();
    }

    void PythonLanguageHook::RegisterMe()
    {
      XBMC_TRACE;
      CSingleLock lock(hooksMutex);
      hooks[m_interp] = AddonClass::Ref<PythonLanguageHook>(this);
    }

    void PythonLanguageHook::UnregisterMe()
    {
      XBMC_TRACE;
      CSingleLock lock(hooksMutex);
      hooks.erase(m_interp);
    }

    static AddonClass::Ref<XBMCAddon::Python::PythonLanguageHook> g_languageHook;

    // Ok ... we're going to get it even if it doesn't exist. If it doesn't exist then
    // we're going to assume we're not in control of the interpreter. This (apparently)
    // can be the case. E.g. Libspotify manages to call into a script using a ctypes
    // extension but under the control of an Interpreter we know nothing about. In
    // cases like this we're going to use a global interpreter
    AddonClass::Ref<PythonLanguageHook> PythonLanguageHook::GetIfExists(PyInterpreterState* interp)
    {
      XBMC_TRACE;
      CSingleLock lock(hooksMutex);
      std::map<PyInterpreterState*,AddonClass::Ref<PythonLanguageHook> >::iterator iter = hooks.find(interp);
      if (iter != hooks.end())
        return AddonClass::Ref<PythonLanguageHook>(iter->second);

      // if we got here then we need to use the global one.
      if (g_languageHook.isNull())
        g_languageHook = new XBMCAddon::Python::PythonLanguageHook();

      return g_languageHook;
    }

    bool PythonLanguageHook::IsAddonClassInstanceRegistered(AddonClass* obj)
    {
      for (std::map<PyInterpreterState*,AddonClass::Ref<PythonLanguageHook> >::iterator iter = hooks.begin();
           iter != hooks.end(); ++iter)
      {
        if ((iter->second)->HasRegisteredAddonClassInstance(obj))
          return true;
      }
      return false;
    }

    /**
     * PythonCallbackHandler expects to be instantiated PER AddonClass instance
     *  that is to be used as a callback. This is why this cannot be instantiated
     *  once.
     *
     * There is an expectation that this method is called from the Python thread
     *  that instantiated an AddonClass that has the potential for a callback.
     *
     * See RetardedAsyncCallbackHandler for more details.
     * See PythonCallbackHandler for more details
     * See PythonCallbackHandler::PythonCallbackHandler for more details
     */
    XBMCAddon::CallbackHandler* PythonLanguageHook::GetCallbackHandler()
    {
      XBMC_TRACE;
      return new PythonCallbackHandler();
    }

    String PythonLanguageHook::GetAddonId()
    {
      XBMC_TRACE;

      // Get a reference to the main module
      // and global dictionary
      PyObject* main_module = PyImport_AddModule((char*)"__main__");
      PyObject* global_dict = PyModule_GetDict(main_module);
      // Extract a reference to the function "func_name"
      // from the global dictionary
      PyObject* pyid = PyDict_GetItemString(global_dict, "__xbmcaddonid__");
      if (pyid)
        return PyString_AsString(pyid);
      return "";
    }

    String PythonLanguageHook::GetAddonVersion()
    {
      XBMC_TRACE;
      // Get a reference to the main module
      // and global dictionary
      PyObject* main_module = PyImport_AddModule((char*)"__main__");
      PyObject* global_dict = PyModule_GetDict(main_module);
      // Extract a reference to the function "func_name"
      // from the global dictionary
      PyObject* pyversion = PyDict_GetItemString(global_dict, "__xbmcapiversion__");
      if (pyversion)
        return PyString_AsString(pyversion);
      return "";
    }

    long PythonLanguageHook::GetInvokerId()
    {
      XBMC_TRACE;

      // Get a reference to the main module
      // and global dictionary
      PyObject* main_module = PyImport_AddModule((char*)"__main__");
      PyObject* global_dict = PyModule_GetDict(main_module);
      // Extract a reference to the function "func_name"
      // from the global dictionary
      PyObject* pyid = PyDict_GetItemString(global_dict, "__xbmcinvokerid__");
      if (pyid)
        return PyLong_AsLong(pyid);
      return -1;
    }


    void PythonLanguageHook::RegisterPlayerCallback(IPlayerCallback* player) { XBMC_TRACE; g_pythonParser.RegisterPythonPlayerCallBack(player); }
    void PythonLanguageHook::UnregisterPlayerCallback(IPlayerCallback* player) { XBMC_TRACE; g_pythonParser.UnregisterPythonPlayerCallBack(player); }
    void PythonLanguageHook::RegisterMonitorCallback(XBMCAddon::xbmc::Monitor* monitor) { XBMC_TRACE; g_pythonParser.RegisterPythonMonitorCallBack(monitor); }
    void PythonLanguageHook::UnregisterMonitorCallback(XBMCAddon::xbmc::Monitor* monitor) { XBMC_TRACE; g_pythonParser.UnregisterPythonMonitorCallBack(monitor); }

    bool PythonLanguageHook::WaitForEvent(CEvent& hEvent, unsigned int milliseconds)
    {
      XBMC_TRACE;
      return g_pythonParser.WaitForEvent(hEvent,milliseconds);
    }

    void PythonLanguageHook::RegisterAddonClassInstance(AddonClass* obj)
    {
      XBMC_TRACE;
      CSingleLock l(*this);
      obj->Acquire();
      currentObjects.insert(obj);
    }

    void PythonLanguageHook::UnregisterAddonClassInstance(AddonClass* obj)
    {
      XBMC_TRACE;
      CSingleLock l(*this);
      if (currentObjects.erase(obj) > 0)
        obj->Release();
    }

    bool PythonLanguageHook::HasRegisteredAddonClassInstance(AddonClass* obj)
    {
      XBMC_TRACE;
      CSingleLock l(*this);
      return currentObjects.find(obj) != currentObjects.end();
    }
  }