Esempio n. 1
0
bool CCPUInfo::getTemperature(CTemperature& temperature)
{
  int         value = 0;
  char        scale = 0;
  
#ifdef TARGET_POSIX
#if defined(TARGET_DARWIN_OSX)
  value = SMCGetTemperature(SMC_KEY_CPU_TEMP);
  scale = 'c';
#else
  int         ret   = 0;
  FILE        *p    = NULL;
  CStdString  cmd   = g_advancedSettings.m_cpuTempCmd;

  temperature.SetState(CTemperature::invalid);

  if (cmd.empty() && m_fProcTemperature == NULL)
    return false;

  if (!cmd.empty())
  {
    p = popen (cmd.c_str(), "r");
    if (p)
    {
      ret = fscanf(p, "%d %c", &value, &scale);
      pclose(p);
    }
  }
  else
  {
    // procfs is deprecated in the linux kernel, we should move away from
    // using it for temperature data.  It doesn't seem that sysfs has a
    // general enough interface to bother implementing ATM.
    
    rewind(m_fProcTemperature);
    fflush(m_fProcTemperature);
    ret = fscanf(m_fProcTemperature, "temperature: %d %c", &value, &scale);
    
    // read from the temperature file of the new kernels
    if (!ret)
    {
      ret = fscanf(m_fProcTemperature, "%d", &value);
      value = value / 1000;
      scale = 'c';
      ret++;
    }
  }

  if (ret != 2)
    return false; 
#endif
#endif // TARGET_POSIX

  if (scale == 'C' || scale == 'c')
    temperature = CTemperature::CreateFromCelsius(value);
  else if (scale == 'F' || scale == 'f')
    temperature = CTemperature::CreateFromFahrenheit(value);
  else
    return false;
  
  return true;
}
Esempio n. 2
0
void CRssReader::Process()
{
  while (GetQueueSize())
  {
    CSingleLock lock(m_critical);

    int iFeed = m_vecQueue.front();
    m_vecQueue.erase(m_vecQueue.begin());

    m_strFeed[iFeed] = "";
    m_strColors[iFeed] = "";

    CCurlFile http;
    http.SetUserAgent(g_advancedSettings.m_userAgent);
    http.SetTimeout(2);
    CStdString strXML;
    CStdString strUrl = m_vecUrls[iFeed];
    lock.Leave();

    int nRetries = 3;
    CURL url(strUrl);
    std::string fileCharset;

    // we wait for the network to come up
    if ((url.GetProtocol() == "http" || url.GetProtocol() == "https") &&
        !g_application.getNetwork().IsAvailable(true))
    {
      CLog::Log(LOGWARNING, "RSS: No network connection");
      strXML = "<rss><item><title>"+g_localizeStrings.Get(15301)+"</title></item></rss>";
    }
    else
    {
      XbmcThreads::EndTime timeout(15000);
      while (!m_bStop && nRetries > 0)
      {
        if (timeout.IsTimePast())
        {
          CLog::Log(LOGERROR, "Timeout whilst retrieving %s", strUrl.c_str());
          http.Cancel();
          break;
        }
        nRetries--;

        if (url.GetProtocol() != "http" && url.GetProtocol() != "https")
        {
          CFile file;
          auto_buffer buffer;
          if (file.LoadFile(strUrl, buffer))
          {
            strXML.assign(buffer.get(), buffer.length());
            break;
          }
        }
        else
          if (http.Get(strUrl, strXML))
          {
            fileCharset = http.GetServerReportedCharset();
            CLog::Log(LOGDEBUG, "Got rss feed: %s", strUrl.c_str());
            break;
          }
      }
      http.Cancel();
    }
    if (!strXML.empty() && m_pObserver)
    {
      // erase any <content:encoded> tags (also unsupported by tinyxml)
      size_t iStart = strXML.find("<content:encoded>");
      size_t iEnd = 0;
      while (iStart != std::string::npos)
      {
        // get <content:encoded> end position
        iEnd = strXML.find("</content:encoded>", iStart) + 18;

        // erase the section
        strXML = strXML.erase(iStart, iEnd - iStart);

        iStart = strXML.find("<content:encoded>");
      }

      if (Parse(strXML, iFeed, fileCharset))
        CLog::Log(LOGDEBUG, "Parsed rss feed: %s", strUrl.c_str());
    }
  }
  UpdateObserver();
}
Esempio n. 3
0
void CAddon::UpdateSetting(const CStdString& key, const CStdString& value)
{
  LoadSettings();
  if (key.empty()) return;
  m_settings[key] = value;
}
Esempio n. 4
0
void COptions::SetOption(int nOptionID, LPCTSTR value, bool save /*=true*/)
{
	CStdString str = value;
	Init();

	switch (nOptionID)
	{
	case OPTION_SERVERPORT:
	case OPTION_TLSPORTS:
		{
			std::set<int> portSet;

			str.TrimLeft(_T(" ,"));

			int pos = str.FindOneOf(_T(" ,"));
			while (pos != -1)
			{
				int port = _ttoi(str.Left(pos));
				if (port >= 1 && port <= 65535)
					portSet.insert(port);
				str = str.Mid(pos + 1);
				str.TrimLeft(_T(" ,"));
				pos = str.FindOneOf(_T(" ,"));
			}
			if (str != _T(""))
			{
				int port = _ttoi(str);
				if (port >= 1 && port <= 65535)
					portSet.insert(port);
			}

			str = _T("");
			for (std::set<int>::const_iterator iter = portSet.begin(); iter != portSet.end(); iter++)
			{
				CStdString tmp;
				tmp.Format(_T("%d "), *iter);
				str += tmp;
			}
			str.TrimRight(' ');
		}
		break;
	case OPTION_WELCOMEMESSAGE:
		{
			std::vector<CStdString> msgLines;
			int oldpos = 0;
			str.Replace(_T("\r\n"), _T("\n"));
			int pos = str.Find(_T("\n"));
			CStdString line;
			while (pos != -1)
			{
				if (pos)
				{
					line = str.Mid(oldpos, pos - oldpos);
					line = line.Left(CONST_WELCOMEMESSAGE_LINESIZE);
					line.TrimRight(_T(" "));
					if (msgLines.size() || line != _T(""))
						msgLines.push_back(line);
				}
				oldpos = pos + 1;
				pos = str.Find(_T("\n"), oldpos);
			}
			line = str.Mid(oldpos);
			if (line != _T(""))
			{
				line = line.Left(CONST_WELCOMEMESSAGE_LINESIZE);
				msgLines.push_back(line);
			}
			str = _T("");
			for (unsigned int i = 0; i < msgLines.size(); i++)
				str += msgLines[i] + _T("\r\n");
			str.TrimRight(_T("\r\n"));
			if (str == _T(""))
			{
				str = _T("%v");
				str += _T("\r\nwritten by Tim Kosse ([email protected])");
				str += _T("\r\nPlease visit https://filezilla-project.org/");
			}
		}
		break;
	case OPTION_ADMINIPBINDINGS:
		{
			CStdString sub;
			std::list<CStdString> ipBindList;
			for (unsigned int i = 0; i<_tcslen(value); i++)
			{
				TCHAR cur = value[i];
				if ((cur < '0' || cur > '9') && cur != '.' && cur != ':')
				{
					if (sub == _T("") && cur == '*')
					{
						ipBindList.clear();
						ipBindList.push_back(_T("*"));
						break;
					}

					if (sub != _T(""))
					{
						if (IsIpAddress(sub))
							ipBindList.push_back(sub);
						sub = _T("");
					}
				}
				else
					sub += cur;
			}
			if (sub != _T(""))
			{
				if (IsIpAddress(sub))
					ipBindList.push_back(sub);
			}
			str = _T("");
			for (std::list<CStdString>::iterator iter = ipBindList.begin(); iter!=ipBindList.end(); iter++)
				if (!IsLocalhost(*iter))
					str += *iter + _T(" ");

			str.TrimRight(_T(" "));
		}
		break;
	case OPTION_ADMINPASS:
		if (str != _T("") && str.GetLength() < 6)
			return;
		break;
	case OPTION_MODEZ_DISALLOWED_IPS:
	case OPTION_IPFILTER_ALLOWED:
	case OPTION_IPFILTER_DISALLOWED:
	case OPTION_ADMINIPADDRESSES:
		{
			str.Replace('\r', ' ');
			str.Replace('\n', ' ');
			str.Replace('\r', ' ');
			while (str.Replace(_T("  "), _T(" ")));
			str += _T(" ");

			CStdString ips;

			int pos = str.Find(' ');
			while (pos != -1)
			{
				CStdString sub = str.Left(pos);
				str = str.Mid(pos + 1);
				str.TrimLeft(' ');

				if (sub == _T("*"))
					ips += _T(" ") + sub;
				else
				{
					if (IsValidAddressFilter(sub))
						ips += " " + sub;
					pos = str.Find(' ');
				}
			}
			ips.TrimLeft(' ');

			str = ips;
		}
		break;
	case OPTION_IPBINDINGS:
		{
			std::list<CStdString> ipBindList;

			str += _T(" ");
			while (!str.empty()) {
				int pos  = str.Find(' ');
				if (pos < 0) {
					break;
				}
				CStdString sub = str.Left(pos);
				str = str.Mid(pos + 1);

				if (sub == _T("*")) {
					ipBindList.clear();
					ipBindList.push_back(_T("*"));
					break;
				}
				else if (IsIpAddress(sub, true)) {
					ipBindList.push_back(sub);
				}
			}

			if (ipBindList.empty())
				ipBindList.push_back(_T("*"));

			str.clear();
			for (auto const& ip : ipBindList) {
				str += ip + _T(" ");
			}

			str.TrimRight(_T(" "));
		}
		break;
	case OPTION_CUSTOMPASVIPSERVER:
		if (str.Find(_T("filezilla.sourceforge.net")) != -1)
			str = _T("http://ip.filezilla-project.org/ip.php");
		break;
	}

	{
		simple_lock lock(m_mutex);
		m_sOptionsCache[nOptionID-1].bCached = TRUE;
		m_sOptionsCache[nOptionID-1].nType = 0;
		m_sOptionsCache[nOptionID-1].str = str;
		m_OptionsCache[nOptionID-1]=m_sOptionsCache[nOptionID-1];
	}

	if (!save)
		return;

	USES_CONVERSION;
	CStdString xmlFileName = GetExecutableDirectory() + _T("FileZilla Server.xml");
	char* bufferA = T2A(xmlFileName);
	if (!bufferA)
		return;

	TiXmlDocument document;
	if (!document.LoadFile(bufferA))
		return;

	TiXmlElement* pRoot = document.FirstChildElement("FileZillaServer");
	if (!pRoot)
		return;

	TiXmlElement* pSettings = pRoot->FirstChildElement("Settings");
	if (!pSettings)
		pSettings = pRoot->LinkEndChild(new TiXmlElement("Settings"))->ToElement();

	TiXmlElement* pItem;
	for (pItem = pSettings->FirstChildElement("Item"); pItem; pItem = pItem->NextSiblingElement("Item"))
	{
		const char* pName = pItem->Attribute("name");
		if (!pName)
			continue;
		CStdString name(pName);
		if (name != m_Options[nOptionID-1].name)
			continue;

		break;
	}

	if (!pItem)
		pItem = pSettings->LinkEndChild(new TiXmlElement("Item"))->ToElement();
	pItem->Clear();
	pItem->SetAttribute("name", ConvToNetwork(m_Options[nOptionID - 1].name).c_str());
	pItem->SetAttribute("type", "string");
	pItem->LinkEndChild(new TiXmlText(ConvToNetwork(value).c_str()));

	document.SaveFile(bufferA);
}
Esempio n. 5
0
bool CMusicInfoScanner::DownloadArtistInfo(const CStdString& strPath, const CStdString& strArtist, bool& bCanceled, CGUIDialogProgress* pDialog)
{
  XFILE::MUSICDATABASEDIRECTORY::CQueryParams params;
  XFILE::MUSICDATABASEDIRECTORY::CDirectoryNode::GetDatabaseInfo(strPath, params);
  bCanceled = false;
  CArtist artist;
  m_musicDatabase.Open();
  if (m_musicDatabase.GetArtistInfo(params.GetArtistId(),artist)) // already got the info
    return true;

  // find artist info
  ADDON::ScraperPtr info;
  if (!m_musicDatabase.GetScraperForPath(strPath, info, ADDON::ADDON_SCRAPER_ARTISTS) || !info)
  {
    m_musicDatabase.Close();
    return false;
  }

  // clear our scraper cache
  info->ClearCache();

  if (m_pObserver)
  {
    m_pObserver->OnStateChanged(DOWNLOADING_ARTIST_INFO);
    m_pObserver->OnDirectoryChanged(strArtist);
  }

  CMusicInfoScraper scraper(info);
  // handle nfo files
  CStdString strArtistPath, strNfo;
  m_musicDatabase.GetArtistPath(params.GetArtistId(),strArtistPath);
  URIUtils::AddFileToFolder(strArtistPath,"artist.nfo",strNfo);
  CNfoFile::NFOResult result=CNfoFile::NO_NFO;
  CNfoFile nfoReader;
  if (XFILE::CFile::Exists(strNfo))
  {
    CLog::Log(LOGDEBUG,"Found matching nfo file: %s", strNfo.c_str());
    result = nfoReader.Create(strNfo, info);
    if (result == CNfoFile::FULL_NFO)
    {
      CLog::Log(LOGDEBUG, "%s Got details from nfo", __FUNCTION__);
      CArtist artist;
      nfoReader.GetDetails(artist);
      m_musicDatabase.SetArtistInfo(params.GetArtistId(), artist);
      map<string, string> artwork = GetArtistArtwork(params.GetArtistId(), &artist);
      m_musicDatabase.SetArtForItem(params.GetArtistId(), "artist", artwork);
      m_musicDatabase.Close();
      return true;
    }
    else if (result == CNfoFile::URL_NFO || result == CNfoFile::COMBINED_NFO)
    {
      CScraperUrl scrUrl(nfoReader.ScraperUrl());
      CMusicArtistInfo artist("nfo",scrUrl);
      info = nfoReader.GetScraperInfo();
      CLog::Log(LOGDEBUG,"-- nfo-scraper: %s",info->Name().c_str());
      CLog::Log(LOGDEBUG,"-- nfo url: %s", scrUrl.m_url[0].m_url.c_str());
      scraper.SetScraperInfo(info);
      scraper.GetArtists().push_back(artist);
    }
    else
      CLog::Log(LOGERROR,"Unable to find an url in nfo file: %s", strNfo.c_str());
  }

  if (!scraper.GetArtistCount())
  {
    scraper.FindArtistInfo(strArtist);

    while (!scraper.Completed())
    {
      if (m_bStop)
      {
        scraper.Cancel();
        bCanceled = true;
      }
      Sleep(1);
    }
  }

  int iSelectedArtist = 0;
  if (result == CNfoFile::NO_NFO)
  {
    if (scraper.Succeeded() && scraper.GetArtistCount() >= 1)
    {
      // now load the first match
      if (pDialog && scraper.GetArtistCount() > 1)
      {
        // if we found more then 1 album, let user choose one
        CGUIDialogSelect *pDlg = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
        if (pDlg)
        {
          pDlg->SetHeading(g_localizeStrings.Get(21890));
          pDlg->Reset();
          pDlg->EnableButton(true, 413); // manual

          for (int i = 0; i < scraper.GetArtistCount(); ++i)
          {
            // set the label to artist
            CFileItem item(scraper.GetArtist(i).GetArtist());
            CStdString strTemp=scraper.GetArtist(i).GetArtist().strArtist;
            if (!scraper.GetArtist(i).GetArtist().strBorn.IsEmpty())
              strTemp += " ("+scraper.GetArtist(i).GetArtist().strBorn+")";
            if (!scraper.GetArtist(i).GetArtist().genre.empty())
            {
              CStdString genres = StringUtils::Join(scraper.GetArtist(i).GetArtist().genre, g_advancedSettings.m_musicItemSeparator);
              if (!genres.empty())
                strTemp.Format("[%s] %s", genres.c_str(), strTemp.c_str());
            }
            item.SetLabel(strTemp);
            item.m_idepth = i; // use this to hold the index of the album in the scraper
            pDlg->Add(&item);
          }
          pDlg->DoModal();

          // and wait till user selects one
          if (pDlg->GetSelectedLabel() < 0)
          { // none chosen
            if (!pDlg->IsButtonPressed())
            {
              bCanceled = true;
              return false;
            }
            // manual button pressed
            CStdString strNewArtist = strArtist;
            if (!CGUIKeyboardFactory::ShowAndGetInput(strNewArtist, g_localizeStrings.Get(16025), false)) return false;

            if (pDialog)
            {
              pDialog->SetLine(0, strNewArtist);
              pDialog->Progress();
            }
            m_musicDatabase.Close();
            return DownloadArtistInfo(strPath,strNewArtist,bCanceled,pDialog);
          }
          iSelectedArtist = pDlg->GetSelectedItem()->m_idepth;
        }
      }
    }
    else
    {
      m_musicDatabase.Close();
      return false;
    }
  }

  scraper.LoadArtistInfo(iSelectedArtist, strArtist);
  while (!scraper.Completed())
  {
    if (m_bStop)
    {
      scraper.Cancel();
      bCanceled = true;
    }
    Sleep(1);
  }

  if (scraper.Succeeded())
  {
    artist = scraper.GetArtist(iSelectedArtist).GetArtist();
    if (result == CNfoFile::COMBINED_NFO)
      nfoReader.GetDetails(artist,NULL,true);
    m_musicDatabase.SetArtistInfo(params.GetArtistId(), artist);
  }

  // check thumb stuff
  map<string, string> artwork = GetArtistArtwork(params.GetArtistId(), &artist);
  m_musicDatabase.SetArtForItem(params.GetArtistId(), "artist", artwork);

  m_musicDatabase.Close();
  return true;
}
Esempio n. 6
0
bool CAirTunesServer::Initialize(const CStdString &password)
{
  bool ret = false;

  Deinitialize();

#if defined(HAVE_LIBSHAIRPLAY)
  if (m_pLibShairplay->Load())
  {

    raop_callbacks_t ao;
    ao.cls                  = m_pPipe;
    ao.audio_init           = AudioOutputFunctions::audio_init;
    ao.audio_set_volume     = AudioOutputFunctions::audio_set_volume;
    ao.audio_set_metadata   = AudioOutputFunctions::audio_set_metadata;
    ao.audio_set_coverart   = AudioOutputFunctions::audio_set_coverart;
    ao.audio_process        = AudioOutputFunctions::audio_process;
    ao.audio_flush          = AudioOutputFunctions::audio_flush;
    ao.audio_destroy        = AudioOutputFunctions::audio_destroy;
    m_pLibShairplay->EnableDelayedUnload(false);
    m_pRaop = m_pLibShairplay->raop_init(1, &ao, RSA_KEY);//1 - we handle one client at a time max
    ret = m_pRaop != NULL;    

    if(ret)
    {
      char macAdr[6];    
      unsigned short port = (unsigned short)m_port;
      
      m_pLibShairplay->raop_set_log_level(m_pRaop, RAOP_LOG_WARNING);
      if(g_advancedSettings.m_logEnableAirtunes)
      {
        m_pLibShairplay->raop_set_log_level(m_pRaop, RAOP_LOG_DEBUG);
      }

      m_pLibShairplay->raop_set_log_callback(m_pRaop, shairplay_log, NULL);

      CNetworkInterface *net = g_application.getNetwork().GetFirstConnectedInterface();

      if (net)
      {
        net->GetMacAddressRaw(macAdr);
      }

      ret = m_pLibShairplay->raop_start(m_pRaop, &port, macAdr, 6, password.c_str()) >= 0;
    }
  }

#else

  int numArgs = 3;
  CStdString hwStr;
  CStdString pwStr;
  CStdString portStr;

  hwStr.Format("--mac=%s", m_macAddress.c_str());
  pwStr.Format("--password=%s",password.c_str());
  portStr.Format("--server_port=%d",m_port);

  if (!password.empty())
  {
    numArgs++;
  }

  char *argv[] = { "--apname=XBMC", (char*) portStr.c_str(), (char*) hwStr.c_str(), (char *)pwStr.c_str(), NULL };

  if (m_pLibShairport->Load())
  {

    struct AudioOutput ao;
    ao.ao_initialize = AudioOutputFunctions::ao_initialize;
    ao.ao_play = AudioOutputFunctions::ao_play;
    ao.ao_default_driver_id = AudioOutputFunctions::ao_default_driver_id;
    ao.ao_open_live = AudioOutputFunctions::ao_open_live;
    ao.ao_close = AudioOutputFunctions::ao_close;
    ao.ao_append_option = AudioOutputFunctions::ao_append_option;
    ao.ao_free_options = AudioOutputFunctions::ao_free_options;
    ao.ao_get_option = AudioOutputFunctions::ao_get_option;
#ifdef HAVE_STRUCT_AUDIOOUTPUT_AO_SET_METADATA
    ao.ao_set_metadata = AudioOutputFunctions::ao_set_metadata;    
    ao.ao_set_metadata_coverart = AudioOutputFunctions::ao_set_metadata_coverart;        
#endif
#if defined(SHAIRPORT_AUDIOOUTPUT_VERSION)
#if   SHAIRPORT_AUDIOOUTPUT_VERSION >= 2
    ao.ao_set_volume = AudioOutputFunctions::ao_set_volume;
#endif
#endif
    struct printfPtr funcPtr;
    funcPtr.extprintf = shairport_log;

    m_pLibShairport->EnableDelayedUnload(false);
    m_pLibShairport->shairport_set_ao(&ao);
    m_pLibShairport->shairport_set_printf(&funcPtr);
    m_pLibShairport->shairport_main(numArgs, argv);
    ret = true;
  }
#endif
  return ret;
}
Esempio n. 7
0
void CGUIDialogMediaSource::OnPathBrowse(int item)
{
  if (item < 0 || item > m_paths->Size()) return;
  // Browse is called.  Open the filebrowser dialog.
  // Ignore current path is best at this stage??
  CStdString path;
  bool allowNetworkShares(m_type != "programs");
  VECSOURCES extraShares;

  if (m_name != CUtil::GetTitleFromPath(m_paths->Get(item)->GetPath()))
    m_bNameChanged=true;

  if (m_type == "music")
  {
    CMediaSource share1;
#if defined(TARGET_ANDROID)
    // add the default android music directory
    std::string path;
    if (CXBMCApp::GetExternalStorage(path, "music") && !path.empty() && CFile::Exists(path))
    {
      share1.strPath = path;
      share1.strName = g_localizeStrings.Get(20240);
      share1.m_ignore = true;
      extraShares.push_back(share1);
    }
#endif

    // add the music playlist location
    share1.strPath = "special://musicplaylists/";
    share1.strName = g_localizeStrings.Get(20011);
    share1.m_ignore = true;
    extraShares.push_back(share1);

    share1.strPath = "sap://";
    share1.strName = "SAP Streams";
    extraShares.push_back(share1);

    if (g_guiSettings.GetString("audiocds.recordingpath",false) != "")
    {
      share1.strPath = "special://recordings/";
      share1.strName = g_localizeStrings.Get(21883);
      extraShares.push_back(share1);
    }

 }
  else if (m_type == "video")
  {
    CMediaSource share1;
#if defined(TARGET_ANDROID)
    // add the default android video directory
    std::string path;
    if (CXBMCApp::GetExternalStorage(path, "videos") && !path.empty() && CFile::Exists(path))
    {
      share1.strPath = path;
      share1.strName = g_localizeStrings.Get(20241);
      share1.m_ignore = true;
      extraShares.push_back(share1);
    }
#endif

    // add the video playlist location
    share1.m_ignore = true;
    share1.strPath = "special://videoplaylists/";
    share1.strName = g_localizeStrings.Get(20012);
    extraShares.push_back(share1);

    share1.strPath = "rtv://*/";
    share1.strName = "ReplayTV Devices";
    extraShares.push_back(share1);

    share1.strPath = "hdhomerun://";
    share1.strName = "HDHomerun Devices";
    extraShares.push_back(share1);

    share1.strPath = "sap://";
    share1.strName = "SAP Streams";
    extraShares.push_back(share1);

    // add the recordings dir as needed
    if (CPVRDirectory::HasRecordings())
    {
      share1.strPath = "pvr://recordings/";
      share1.strName = g_localizeStrings.Get(19017); // TV Recordings
      extraShares.push_back(share1);
    }
  }
  else if (m_type == "pictures")
  {
    CMediaSource share1;
#if defined(TARGET_ANDROID)
    // add the default android music directory
    std::string path;
    if (CXBMCApp::GetExternalStorage(path, "pictures") && !path.empty() &&  CFile::Exists(path))
    {
      share1.strPath = path;
      share1.strName = g_localizeStrings.Get(20242);
      share1.m_ignore = true;
      extraShares.push_back(share1);
    }

    path.clear();
    if (CXBMCApp::GetExternalStorage(path, "photos") && !path.empty() &&  CFile::Exists(path))
    {
      share1.strPath = path;
      share1.strName = g_localizeStrings.Get(20243);
      share1.m_ignore = true;
      extraShares.push_back(share1);
    }
#endif

    share1.m_ignore = true;
    if (g_guiSettings.GetString("debug.screenshotpath",false)!= "")
    {
      share1.strPath = "special://screenshots/";
      share1.strName = g_localizeStrings.Get(20008);
      extraShares.push_back(share1);
    }
  }
  else if (m_type == "programs")
  {
    // nothing to add
  }
  if (CGUIDialogFileBrowser::ShowAndGetSource(path, allowNetworkShares, extraShares.size()==0?NULL:&extraShares))
  {
    if (item < m_paths->Size()) // if the skin does funky things, m_paths may have been cleared
      m_paths->Get(item)->SetPath(path);
    if (!m_bNameChanged || m_name.IsEmpty())
    {
      CURL url(path);
      m_name = url.GetWithoutUserDetails();
      URIUtils::RemoveSlashAtEnd(m_name);
      m_name = CUtil::GetTitleFromPath(m_name);
    }
    UpdateButtons();
  }
}
Esempio n. 8
0
void CPeripheralCecAdapter::Process(void)
{
  if (!GetSettingBool("enabled"))
  {
    CLog::Log(LOGDEBUG, "%s - CEC adapter is disabled in peripheral settings", __FUNCTION__);
    m_bStarted = false;
    return;
  }
  
  CStdString strPort = GetComPort();
  if (strPort.empty())
    return;

  // set correct physical address from peripheral settings
  int iHdmiPort = GetSettingInt("cec_hdmi_port");
  SetHdmiPort(iHdmiPort);
  FlushLog();

  // open the CEC adapter
  CLog::Log(LOGDEBUG, "%s - opening a connection to the CEC adapter: %s", __FUNCTION__, strPort.c_str());

  // scanning the CEC bus takes about 5 seconds, so display a notification to inform users that we're busy
  CStdString strMessage;
  strMessage.Format(g_localizeStrings.Get(21336), g_localizeStrings.Get(36000));
  CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(36000), strMessage);

  if (!m_cecAdapter->Open(strPort.c_str(), 10000))
  {
    FlushLog();
    CLog::Log(LOGERROR, "%s - could not opening a connection to the CEC adapter", __FUNCTION__);
    CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(36000), g_localizeStrings.Get(36012));
    m_bStarted = false;
    return;
  }

  CLog::Log(LOGDEBUG, "%s - connection to the CEC adapter opened", __FUNCTION__);
  m_bIsReady = true;
  CAnnouncementManager::AddAnnouncer(this);

  if (GetSettingBool("cec_power_on_startup"))
  {
    PowerOnCecDevices(CECDEVICE_TV);
    FlushLog();
  }

  if (GetSettingBool("use_tv_menu_language"))
  {
    cec_menu_language language;
    if (m_cecAdapter->GetDeviceMenuLanguage(CECDEVICE_TV, &language))
      SetMenuLanguage(language.language);
  }

  m_cecAdapter->SetOSDString(CECDEVICE_TV, CEC_DISPLAY_CONTROL_DISPLAY_FOR_DEFAULT_TIME, g_localizeStrings.Get(36016).c_str());
  CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(36000), g_localizeStrings.Get(36016));

  while (!m_bStop)
  {
    FlushLog();
    if (!m_bStop)
      ProcessNextCommand();
    if (!m_bStop)
      Sleep(5);
  }

  m_cecAdapter->Close();

  CLog::Log(LOGDEBUG, "%s - CEC adapter processor thread ended", __FUNCTION__);
  m_bStarted = false;
}
Esempio n. 9
0
AddonPtr CAddonMgr::Factory(const cp_extension_t *props)
{
  if (!PlatformSupportsAddon(props->plugin))
    return AddonPtr();

  /* Check if user directories need to be created */
  const cp_cfg_element_t *settings = GetExtElement(props->configuration, "settings");
  if (settings)
    CheckUserDirs(settings);

  const TYPE type = TranslateType(props->ext_point_id);
  switch (type)
  {
    case ADDON_PLUGIN:
    case ADDON_SCRIPT:
      return AddonPtr(new CPluginSource(props));
    case ADDON_SCRIPT_LIBRARY:
    case ADDON_SCRIPT_LYRICS:
    case ADDON_SCRIPT_SUBTITLES:
    case ADDON_SCRIPT_MODULE:
    case ADDON_WEB_INTERFACE:
      return AddonPtr(new CAddon(props));
    case ADDON_SCRIPT_WEATHER:
      {
        // Eden (API v2.0) broke old weather add-ons
        AddonPtr result(new CAddon(props));
        AddonVersion ver1 = AddonVersion(GetXbmcApiVersionDependency(result));
        AddonVersion ver2 = AddonVersion("2.0");
        if (ver1 < ver2)
        {
          CLog::Log(LOGINFO,"%s: Weather add-ons for api < 2.0 unsupported (%s)",__FUNCTION__,result->ID().c_str());
          return AddonPtr();
        }
        return result;
      }
    case ADDON_SERVICE:
      return AddonPtr(new CService(props));
    case ADDON_SCRAPER_ALBUMS:
    case ADDON_SCRAPER_ARTISTS:
    case ADDON_SCRAPER_MOVIES:
    case ADDON_SCRAPER_MUSICVIDEOS:
    case ADDON_SCRAPER_TVSHOWS:
    case ADDON_SCRAPER_LIBRARY:
      return AddonPtr(new CScraper(props));
    case ADDON_VIZ:
    case ADDON_SCREENSAVER:
      { // begin temporary platform handling for Dlls
        // ideally platforms issues will be handled by C-Pluff
        // this is not an attempt at a solution
        CStdString value;
        if (type == ADDON_SCREENSAVER && 0 == strnicmp(props->plugin->identifier, "screensaver.xbmc.builtin.", 25))
        { // built in screensaver
          return AddonPtr(new CAddon(props));
        }
#if defined(_LINUX) && !defined(TARGET_DARWIN)
        if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_linux")) && value.empty())
          break;
#elif defined(_WIN32) && defined(HAS_SDL_OPENGL)
        if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_wingl")) && value.empty())
          break;
#elif defined(_WIN32) && defined(HAS_DX)
        if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_windx")) && value.empty())
          break;
#elif defined(TARGET_DARWIN)
        if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_osx")) && value.empty())
          break;
#endif
        if (type == ADDON_VIZ)
        {
#if defined(HAS_VISUALISATION)
          return AddonPtr(new CVisualisation(props));
#endif
        }
        else
          return AddonPtr(new CScreenSaver(props));
      }
    case ADDON_SKIN:
      return AddonPtr(new CSkinInfo(props));
    case ADDON_VIZ_LIBRARY:
      return AddonPtr(new CAddonLibrary(props));
    case ADDON_REPOSITORY:
      return AddonPtr(new CRepository(props));
    default:
      break;
  }
  return AddonPtr();
}
Esempio n. 10
0
void CScreenShot::TakeScreenshot()
{
  static bool savingScreenshots = false;
  static vector<CStdString> screenShots;
  bool promptUser = false;
  CStdString strDir;

  // check to see if we have a screenshot folder yet
  CSettingPath *screenshotSetting = (CSettingPath*)CSettings::Get().GetSetting("debug.screenshotpath");
  if (screenshotSetting != NULL)
  {
    strDir = screenshotSetting->GetValue();
    if (strDir.empty())
    {
      if (CGUIControlButtonSetting::GetPath(screenshotSetting))
        strDir = screenshotSetting->GetValue();
    }
  }

  if (strDir.IsEmpty())
  {
    strDir = "special://temp/";
    if (!savingScreenshots)
    {
      promptUser = true;
      savingScreenshots = true;
      screenShots.clear();
    }
  }
  URIUtils::RemoveSlashAtEnd(strDir);

  if (!strDir.IsEmpty())
  {
    CStdString file = CUtil::GetNextFilename(URIUtils::AddFileToFolder(strDir, "screenshot%03d.png"), 999);

    if (!file.IsEmpty())
    {
      TakeScreenshot(file, false);
      if (savingScreenshots)
        screenShots.push_back(file);
      if (promptUser)
      { // grab the real directory
        CStdString newDir;
        if (screenshotSetting != NULL)
        {
          newDir = screenshotSetting->GetValue();
          if (newDir.empty())
          {
            if (CGUIControlButtonSetting::GetPath(screenshotSetting))
              newDir = screenshotSetting->GetValue();
          }
        }

        if (!newDir.IsEmpty())
        {
          for (unsigned int i = 0; i < screenShots.size(); i++)
          {
            CStdString file = CUtil::GetNextFilename(URIUtils::AddFileToFolder(newDir, "screenshot%03d.png"), 999);
            CFile::Cache(screenShots[i], file);
          }
          screenShots.clear();
        }
        savingScreenshots = false;
      }
    }
    else
    {
      CLog::Log(LOGWARNING, "Too many screen shots or invalid folder");
    }
  }
}
Esempio n. 11
0
bool CFileOperations::FillFileItemList(const CVariant &parameterObject, CFileItemList &list)
{
  if (parameterObject.isMember("directory"))
  {
    CStdString media =  parameterObject["media"].asString();
    media = media.ToLower();

    CStdString strPath = parameterObject["directory"].asString();
    if (!strPath.empty())
    {
      CFileItemList items;
      CStdString extensions = "";
      CStdStringArray regexps;

      if (media.Equals("video"))
      {
        regexps = g_advancedSettings.m_videoExcludeFromListingRegExps;
        extensions = g_settings.m_videoExtensions;
      }
      else if (media.Equals("music"))
      {
        regexps = g_advancedSettings.m_audioExcludeFromListingRegExps;
        extensions = g_settings.m_musicExtensions;
      }
      else if (media.Equals("pictures"))
      {
        regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps;
        extensions = g_settings.m_pictureExtensions;
      }

      CDirectory directory;
      if (directory.GetDirectory(strPath, items, extensions))
      {
        items.Sort(SORT_METHOD_FILE, SortOrderAscending);
        CFileItemList filteredDirectories;
        for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
        {
          if (CUtil::ExcludeFileOrFolder(items[i]->GetPath(), regexps))
            continue;

          if (items[i]->m_bIsFolder)
            filteredDirectories.Add(items[i]);
          else if ((media == "video" && items[i]->HasVideoInfoTag()) ||
                   (media == "music" && items[i]->HasMusicInfoTag()))
            list.Add(items[i]);
          else
          {
            CFileItem fileItem;
            if (FillFileItem(items[i], fileItem, media, parameterObject))
              list.Add(CFileItemPtr(new CFileItem(fileItem)));
            else if (media == "files")
              list.Add(items[i]);
          }
        }

        if (parameterObject.isMember("recursive") && parameterObject["recursive"].isBoolean())
        {
          for (int i = 0; i < filteredDirectories.Size(); i++)
          {
            CVariant val = parameterObject;
            val["directory"] = filteredDirectories[i]->GetPath();
            FillFileItemList(val, list);
          }
        }

        return true;
      }
    }
  }

  return false;
}
Esempio n. 12
0
bool CLibraryDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
  std::string libNode = GetNode(url);
  if (libNode.empty())
    return false;

  if (URIUtils::HasExtension(libNode, ".xml"))
  { // a filter or folder node
    TiXmlElement *node = LoadXML(libNode);
    if (node)
    {
      CStdString type = node->Attribute("type");
      if (type == "filter")
      {
        CSmartPlaylist playlist;
        CStdString type, label;
        XMLUtils::GetString(node, "content", type);
        if (type.empty())
        {
          CLog::Log(LOGERROR, "<content> tag must not be empty for type=\"filter\" node '%s'", libNode.c_str());
          return false;
        }
        if (XMLUtils::GetString(node, "label", label))
          label = CGUIControlFactory::FilterLabel(label);
        playlist.SetType(type);
        playlist.SetName(label);
        if (playlist.LoadFromXML(node) &&
            CSmartPlaylistDirectory::GetDirectory(playlist, items))
        {
          items.SetProperty("library.filter", "true");
          items.SetPath(items.GetProperty("path.db").asString());
          return true;
        }
      }
      else if (type == "folder")
      {
        CStdString path;
        XMLUtils::GetPath(node, "path", path);
        if (!path.empty())
        {
          URIUtils::AddSlashAtEnd(path);
          return CDirectory::GetDirectory(path, items, m_strFileMask, m_flags);
        }
      }
    }
    return false;
  }

  // just a plain node - read the folder for XML nodes and other folders
  CFileItemList nodes;
  if (!CDirectory::GetDirectory(libNode, nodes, ".xml", DIR_FLAG_NO_FILE_DIRS))
    return false;

  // iterate over our nodes
  std::string basePath = url.Get();
  for (int i = 0; i < nodes.Size(); i++)
  {
    const TiXmlElement *node = NULL;
    CStdString xml = nodes[i]->GetPath();
    if (nodes[i]->m_bIsFolder)
      node = LoadXML(URIUtils::AddFileToFolder(xml, "index.xml"));
    else
    {
      node = LoadXML(xml);
      if (node && URIUtils::GetFileName(xml).Equals("index.xml"))
      { // set the label on our items
        CStdString label;
        if (XMLUtils::GetString(node, "label", label))
          label = CGUIControlFactory::FilterLabel(label);
        items.SetLabel(label);
        continue;
      }
    }
    if (node)
    {
      CStdString label, icon;
      if (XMLUtils::GetString(node, "label", label))
        label = CGUIControlFactory::FilterLabel(label);
      XMLUtils::GetString(node, "icon", icon);
      int order = 0;
      node->Attribute("order", &order);

      // create item
      URIUtils::RemoveSlashAtEnd(xml);
      CStdString folder = URIUtils::GetFileName(xml);
      CFileItemPtr item(new CFileItem(URIUtils::AddFileToFolder(basePath, folder), true));

      item->SetLabel(label);
      if (!icon.empty() && g_TextureManager.HasTexture(icon))
        item->SetIconImage(icon);
      item->m_iprogramCount = order;
      items.Add(item);
    }
  }
  items.Sort(SortByPlaylistOrder, SortOrderAscending);
  return true;
}
Esempio n. 13
0
std::string DatabaseUtils::GetField(Field field, MediaType mediaType, DatabaseQueryPart queryPart)
{
    if (field == FieldNone || mediaType == MediaTypeNone)
        return "";

    if (mediaType == MediaTypeAlbum)
    {
        if (field == FieldId) return "albumview.idAlbum";
        else if (field == FieldAlbum) return "albumview.strAlbum";
        else if (field == FieldArtist || field == FieldAlbumArtist) return "albumview.strArtists";
        else if (field == FieldGenre) return "albumview.strGenre";
        else if (field == FieldYear) return "albumview.iYear";
        else if (field == FieldMoods) return "albumview.strMoods";
        else if (field == FieldStyles) return "albumview.strStyles";
        else if (field == FieldThemes) return "albumview.strThemes";
        else if (field == FieldReview) return "albumview.strReview";
        else if (field == FieldMusicLabel) return "albumview.strLabel";
        else if (field == FieldAlbumType) return "albumview.strType";
        else if (field == FieldRating) return "albumview.iRating";
        else if (field == FieldDateAdded && queryPart == DatabaseQueryPartOrderBy) return "albumview.idalbum";    // only used for order clauses
        else if (field == FieldPlaycount) return "albumview.iTimesPlayed";
    }
    else if (mediaType == MediaTypeSong)
    {
        if (field == FieldId) return "songview.idSong";
        else if (field == FieldTitle) return "songview.strTitle";
        else if (field == FieldTrackNumber) return "songview.iTrack";
        else if (field == FieldTime) return "songview.iDuration";
        else if (field == FieldYear) return "songview.iYear";
        else if (field == FieldFilename) return "songview.strFilename";
        else if (field == FieldPlaycount) return "songview.iTimesPlayed";
        else if (field == FieldStartOffset) return "songview.iStartOffset";
        else if (field == FieldEndOffset) return "songview.iEndOffset";
        else if (field == FieldLastPlayed) return "songview.lastPlayed";
        else if (field == FieldRating) return "songview.rating";
        else if (field == FieldComment) return "songview.comment";
        else if (field == FieldAlbum) return "songview.strAlbum";
        else if (field == FieldPath) return "songview.strPath";
        else if (field == FieldArtist || field == FieldAlbumArtist) return "songview.strArtists";
        else if (field == FieldGenre) return "songview.strGenre";
        else if (field == FieldDateAdded && queryPart == DatabaseQueryPartOrderBy) return "songview.idSong";     // only used for order clauses
    }
    else if (mediaType == MediaTypeArtist)
    {
        if (field == FieldId) return "artistview.idArtist";
        else if (field == FieldArtist) return "artistview.strArtist";
        else if (field == FieldGenre) return "artistview.strGenres";
        else if (field == FieldMoods) return "artistview.strMoods";
        else if (field == FieldStyles) return "artistview.strStyles";
        else if (field == FieldInstruments) return "artistview.strInstruments";
        else if (field == FieldBiography) return "artistview.strBiography";
        else if (field == FieldBorn) return "artistview.strBorn";
        else if (field == FieldBandFormed) return "artistview.strFormed";
        else if (field == FieldDisbanded) return "artistview.strDisbanded";
        else if (field == FieldDied) return "artistview.strDied";
    }
    else if (mediaType == MediaTypeMusicVideo)
    {
        CStdString result;
        if (field == FieldId) return "musicvideoview.idMVideo";
        else if (field == FieldTitle) result.Format("musicvideoview.c%02d",VIDEODB_ID_MUSICVIDEO_TITLE);
        else if (field == FieldTime) result.Format("musicvideoview.c%02d", VIDEODB_ID_MUSICVIDEO_RUNTIME);
        else if (field == FieldDirector) result.Format("musicvideoview.c%02d", VIDEODB_ID_MUSICVIDEO_DIRECTOR);
        else if (field == FieldStudio) result.Format("musicvideoview.c%02d", VIDEODB_ID_MUSICVIDEO_STUDIOS);
        else if (field == FieldYear) result.Format("musicvideoview.c%02d",VIDEODB_ID_MUSICVIDEO_YEAR);
        else if (field == FieldPlot) result.Format("musicvideoview.c%02d", VIDEODB_ID_MUSICVIDEO_PLOT);
        else if (field == FieldAlbum) result.Format("musicvideoview.c%02d",VIDEODB_ID_MUSICVIDEO_ALBUM);
        else if (field == FieldArtist) result.Format("musicvideoview.c%02d", VIDEODB_ID_MUSICVIDEO_ARTIST);
        else if (field == FieldGenre) result.Format("musicvideoview.c%02d", VIDEODB_ID_MUSICVIDEO_GENRE);
        else if (field == FieldTrackNumber) result.Format("musicvideoview.c%02d", VIDEODB_ID_MUSICVIDEO_TRACK);
        else if (field == FieldFilename) return "musicvideoview.strFilename";
        else if (field == FieldPath) return "musicvideoview.strPath";
        else if (field == FieldPlaycount) return "musicvideoview.playCount";
        else if (field == FieldLastPlayed) return "musicvideoview.lastPlayed";
        else if (field == FieldDateAdded) return "musicvideoview.dateAdded";

        if (!result.empty())
            return result;
    }
    else if (mediaType == MediaTypeMovie)
    {
        CStdString result;
        if (field == FieldId) return "movieview.idMovie";
        else if (field == FieldTitle)
        {
            // We need some extra logic to get the title value if sorttitle isn't set
            if (queryPart == DatabaseQueryPartOrderBy)
                result.Format("CASE WHEN length(movieview.c%02d) > 0 THEN movieview.c%02d ELSE movieview.c%02d END", VIDEODB_ID_SORTTITLE, VIDEODB_ID_SORTTITLE, VIDEODB_ID_TITLE);
            else
                result.Format("movieview.c%02d", VIDEODB_ID_TITLE);
        }
        else if (field == FieldPlot) result.Format("movieview.c%02d", VIDEODB_ID_PLOT);
        else if (field == FieldPlotOutline) result.Format("movieview.c%02d", VIDEODB_ID_PLOTOUTLINE);
        else if (field == FieldTagline) result.Format("movieview.c%02d", VIDEODB_ID_TAGLINE);
        else if (field == FieldVotes) result.Format("movieview.c%02d", VIDEODB_ID_VOTES);
        else if (field == FieldRating)
        {
            if (queryPart == DatabaseQueryPartOrderBy)
                result.Format("CAST(movieview.c%02d as DECIMAL(5,3))", VIDEODB_ID_RATING);
            else
                result.Format("movieview.c%02d", VIDEODB_ID_RATING);
        }
        else if (field == FieldWriter) result.Format("movieview.c%02d", VIDEODB_ID_CREDITS);
        else if (field == FieldYear) result.Format("movieview.c%02d", VIDEODB_ID_YEAR);
        else if (field == FieldSortTitle) result.Format("movieview.c%02d", VIDEODB_ID_SORTTITLE);
        else if (field == FieldTime) result.Format("movieview.c%02d", VIDEODB_ID_RUNTIME);
        else if (field == FieldMPAA) result.Format("movieview.c%02d", VIDEODB_ID_MPAA);
        else if (field == FieldTop250) result.Format("movieview.c%02d", VIDEODB_ID_TOP250);
        else if (field == FieldSet) return "movieview.strSet";
        else if (field == FieldGenre) result.Format("movieview.c%02d", VIDEODB_ID_GENRE);
        else if (field == FieldDirector) result.Format("movieview.c%02d", VIDEODB_ID_DIRECTOR);
        else if (field == FieldStudio) result.Format("movieview.c%02d", VIDEODB_ID_STUDIOS);
        else if (field == FieldTrailer) result.Format("movieview.c%02d", VIDEODB_ID_TRAILER);
        else if (field == FieldCountry) result.Format("movieview.c%02d", VIDEODB_ID_COUNTRY);
        else if (field == FieldFilename) return "movieview.strFilename";
        else if (field == FieldPath) return "movieview.strPath";
        else if (field == FieldPlaycount) return "movieview.playCount";
        else if (field == FieldLastPlayed) return "movieview.lastPlayed";
        else if (field == FieldDateAdded) return "movieview.dateAdded";

        if (!result.empty())
            return result;
    }
    else if (mediaType == MediaTypeTvShow)
    {
        CStdString result;
        if (field == FieldId) return "tvshowview.idShow";
        else if (field == FieldTitle)
        {
            // We need some extra logic to get the title value if sorttitle isn't set
            if (queryPart == DatabaseQueryPartOrderBy)
                result.Format("CASE WHEN length(tvshowview.c%02d) > 0 THEN tvshowview.c%02d ELSE tvshowview.c%02d END", VIDEODB_ID_TV_SORTTITLE, VIDEODB_ID_TV_SORTTITLE, VIDEODB_ID_TV_TITLE);
            else
                result.Format("tvshowview.c%02d", VIDEODB_ID_TV_TITLE);
        }
        else if (field == FieldPlot) result.Format("tvshowview.c%02d", VIDEODB_ID_TV_PLOT);
        else if (field == FieldTvShowStatus) result.Format("tvshowview.c%02d", VIDEODB_ID_TV_STATUS);
        else if (field == FieldVotes) result.Format("tvshowview.c%02d", VIDEODB_ID_TV_VOTES);
        else if (field == FieldRating) result.Format("tvshowview.c%02d", VIDEODB_ID_TV_RATING);
        else if (field == FieldYear) result.Format("tvshowview.c%02d", VIDEODB_ID_TV_PREMIERED);
        else if (field == FieldGenre) result.Format("tvshowview.c%02d", VIDEODB_ID_TV_GENRE);
        else if (field == FieldMPAA) result.Format("tvshowview.c%02d", VIDEODB_ID_TV_MPAA);
        else if (field == FieldStudio) result.Format("tvshowview.c%02d", VIDEODB_ID_TV_STUDIOS);
        else if (field == FieldSortTitle) result.Format("tvshowview.c%02d", VIDEODB_ID_TV_SORTTITLE);
        else if (field == FieldPath) return "tvshowview.strPath";
        else if (field == FieldDateAdded) return "tvshowview.dateAdded";
        else if (field == FieldLastPlayed) return "tvshowview.lastPlayed";
        else if (field == FieldSeason) return "tvshowview.totalSeasons";
        else if (field == FieldNumberOfEpisodes) return "tvshowview.totalCount";
        else if (field == FieldNumberOfWatchedEpisodes) return "tvshowview.watchedcount";

        if (!result.empty())
            return result;
    }
    else if (mediaType == MediaTypeEpisode)
    {
        CStdString result;
        if (field == FieldId) return "episodeview.idEpisode";
        else if (field == FieldTitle) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_TITLE);
        else if (field == FieldPlot) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_PLOT);
        else if (field == FieldVotes) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_VOTES);
        else if (field == FieldRating) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_RATING);
        else if (field == FieldWriter) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_CREDITS);
        else if (field == FieldAirDate) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_AIRED);
        else if (field == FieldTime) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_RUNTIME);
        else if (field == FieldDirector) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_DIRECTOR);
        else if (field == FieldSeason) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_SEASON);
        else if (field == FieldEpisodeNumber) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_EPISODE);
        else if (field == FieldUniqueId) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_UNIQUEID);
        else if (field == FieldEpisodeNumberSpecialSort) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_SORTEPISODE);
        else if (field == FieldSeasonSpecialSort) result.Format("episodeview.c%02d", VIDEODB_ID_EPISODE_SORTSEASON);
        else if (field == FieldFilename) return "episodeview.strFilename";
        else if (field == FieldPath) return "episodeview.strPath";
        else if (field == FieldPlaycount) return "episodeview.playCount";
        else if (field == FieldLastPlayed) return "episodeview.lastPlayed";
        else if (field == FieldDateAdded) return "episodeview.dateAdded";
        else if (field == FieldTvShowTitle) return "episodeview.strTitle";
        else if (field == FieldYear) return "episodeview.premiered";
        else if (field == FieldMPAA) return "episodeview.mpaa";
        else if (field == FieldStudio) return "episodeview.strStudio";

        if (!result.empty())
            return result;
    }

    if (field == FieldRandom && queryPart == DatabaseQueryPartOrderBy)
        return "RANDOM()";

    return "";
}
Esempio n. 14
0
void CPeripherals::GetSettingsFromMappingsFile(TiXmlElement *xmlNode, map<CStdString, PeripheralDeviceSetting> &settings)
{
  TiXmlElement *currentNode = xmlNode->FirstChildElement("setting");
  int iMaxOrder = 0;

  while (currentNode)
  {
    CSetting *setting = NULL;
    CStdString strKey = XMLUtils::GetAttribute(currentNode, "key");
    if (strKey.empty())
      continue;

    CStdString strSettingsType = XMLUtils::GetAttribute(currentNode, "type");
    int iLabelId = currentNode->Attribute("label") ? atoi(currentNode->Attribute("label")) : -1;
    const std::string config = XMLUtils::GetAttribute(currentNode, "configurable");
    bool bConfigurable = (config.empty() || (config != "no" && config != "false" && config != "0"));
    if (strSettingsType.Equals("bool"))
    {
      const std::string value = XMLUtils::GetAttribute(currentNode, "value");
      bool bValue = (value != "no" && value != "false" && value != "0");
      setting = new CSettingBool(strKey, iLabelId, bValue);
    }
    else if (strSettingsType.Equals("int"))
    {
      int iValue = currentNode->Attribute("value") ? atoi(currentNode->Attribute("value")) : 0;
      int iMin   = currentNode->Attribute("min") ? atoi(currentNode->Attribute("min")) : 0;
      int iStep  = currentNode->Attribute("step") ? atoi(currentNode->Attribute("step")) : 1;
      int iMax   = currentNode->Attribute("max") ? atoi(currentNode->Attribute("max")) : 255;
      setting = new CSettingInt(strKey, iLabelId, iValue, iMin, iStep, iMax);
    }
    else if (strSettingsType.Equals("float"))
    {
      float fValue = currentNode->Attribute("value") ? (float) atof(currentNode->Attribute("value")) : 0;
      float fMin   = currentNode->Attribute("min") ? (float) atof(currentNode->Attribute("min")) : 0;
      float fStep  = currentNode->Attribute("step") ? (float) atof(currentNode->Attribute("step")) : 0;
      float fMax   = currentNode->Attribute("max") ? (float) atof(currentNode->Attribute("max")) : 0;
      setting = new CSettingNumber(strKey, iLabelId, fValue, fMin, fStep, fMax);
    }
    else if (strSettingsType.Equals("enum"))
    {
      CStdString strEnums = XMLUtils::GetAttribute(currentNode, "lvalues");
      if (!strEnums.empty())
      {
        vector< pair<int,int> > enums;
        vector<std::string> valuesVec;
        StringUtils::Tokenize(strEnums, valuesVec, "|");
        for (unsigned int i = 0; i < valuesVec.size(); i++)
          enums.push_back(make_pair(atoi(valuesVec[i].c_str()), atoi(valuesVec[i].c_str())));
        int iValue = currentNode->Attribute("value") ? atoi(currentNode->Attribute("value")) : 0;
        setting = new CSettingInt(strKey, iLabelId, iValue, enums);
      }
    }
    else
    {
      CStdString strValue = XMLUtils::GetAttribute(currentNode, "value");
      setting = new CSettingString(strKey, iLabelId, strValue);
    }

    if (setting)
    {
      //TODO add more types if needed

      /* set the visibility */
      setting->SetVisible(bConfigurable);

      /* set the order */
      int iOrder = 0;
      currentNode->Attribute("order", &iOrder);
      /* if the order attribute is invalid or 0, then the setting will be added at the end */
      if (iOrder < 0)
        iOrder = 0;
      if (iOrder > iMaxOrder)
       iMaxOrder = iOrder;

      /* and add this new setting */
      PeripheralDeviceSetting deviceSetting = { setting, iOrder };
      settings[strKey] = deviceSetting;
    }

    currentNode = currentNode->NextSiblingElement("setting");
  }

  /* add the settings without an order attribute or an invalid order attribute set at the end */
  for (map<CStdString, PeripheralDeviceSetting>::iterator it = settings.begin(); it != settings.end(); ++it)
  {
    if (it->second.m_order == 0)
      it->second.m_order = ++iMaxOrder;
  }
}
Esempio n. 15
0
void CMythSession::SetFileItemMetaData(CFileItem &item, cmyth_proginfo_t program)
{
  if (!program)
    return;

  /*
   * Set the FileItem meta-data.
   */
  CStdString title        = GetValue(m_dll->proginfo_title(program)); // e.g. Mythbusters
  CStdString subtitle     = GetValue(m_dll->proginfo_subtitle(program)); // e.g. The Pirate Special
  item.m_strTitle         = title;
  if (!subtitle.empty())
    item.m_strTitle      += " - \"" + subtitle + "\""; // e.g. Mythbusters - "The Pirate Special"
  item.m_dateTime         = GetValue(m_dll->proginfo_rec_start(program));
  item.m_dwSize           = m_dll->proginfo_length(program); // size in bytes

  /*
   * Set the VideoInfoTag meta-data so it matches the FileItem meta-data where possible.
   */
  CVideoInfoTag* tag      = item.GetVideoInfoTag();
  tag->m_strTitle         = subtitle; // The title is just supposed to be the episode title.
  tag->m_strShowTitle     = title;
  tag->m_strOriginalTitle = title;
  tag->m_strPlotOutline   = subtitle;
  tag->m_strPlot          = GetValue(m_dll->proginfo_description(program));
  /*
   * TODO: Strip out the subtitle from the description if it is present at the start? OR add the
   * subtitle to the start of the plot if not already as it used to? Seems strange, should be
   * handled by skin?
   *
  if (tag->m_strPlot.Left(tag->m_strPlotOutline.length()) != tag->m_strPlotOutline && !tag->m_strPlotOutline.empty())
    tag->m_strPlot = tag->m_strPlotOutline + '\n' + tag->m_strPlot;
   */
  tag->m_genre            = StringUtils::Split(GetValue(m_dll->proginfo_category(program)), g_advancedSettings.m_videoItemSeparator); // e.g. Sports
  tag->m_strAlbum         = GetValue(m_dll->proginfo_chansign(program)); // e.g. TV3
  tag->m_duration         = m_dll->proginfo_length_sec(program);
  
  SetSeasonAndEpisode(program, &tag->m_iSeason, &tag->m_iEpisode);

  /*
   * Original air date is used by the VideoInfoScanner to scrape the TV Show information into the
   * Video Library. If the original air date is empty the date returned will be the epoch.
   */
  CStdString originalairdate = GetValue(m_dll->proginfo_originalairdate(program)).GetAsDBDate();
  if (originalairdate != "1970-01-01"
  &&  originalairdate != "1969-12-31")
  tag->m_firstAired.SetFromDateString(originalairdate);

  /*
   * Video sort title is the raw title with the date appended on the end in a sortable format so
   * when the "All Recordings" listing is sorted by "Name" rather than "Date", all of the episodes
   * for a given show are still presented in date order (even though some may have a subtitle that
   * would cause it to be shown in a different position if it was indeed strictly sorting by
   * what is displayed in the list).
   */
  tag->m_strSortTitle = title + " " + item.m_dateTime.GetAsDBDateTime(); // e.g. Mythbusters 2009-12-13 12:23:14

  /*
   * Set further FileItem and VideoInfoTag meta-data based on whether it is LiveTV or not.
   */
  CURL url(item.GetPath());
  if (StringUtils::StartsWith(url.GetFileName(), "channels/"))
  {
    /*
     * Prepend the channel number onto the FileItem title for the listing so it's clear what is
     * playing on each channel without using up as much room as the channel name.
     */
    CStdString number = GetValue(m_dll->proginfo_chanstr(program));
    item.m_strTitle = number + " - " + item.m_strTitle;

    /*
     * Append the channel name onto the end of the tag title for the OSD so it's clear what LiveTV
     * channel is currently being watched to give some context for Next or Previous channel. Added
     * to the end so sorting by title will work, and it's not really as important as the title
     * within the OSD.
     */
    CStdString name = GetValue(m_dll->proginfo_chansign(program));
    if (!name.empty())
      tag->m_strTitle += " - " + name;

    /*
     * Set the sort title to be the channel number.
     */
    tag->m_strSortTitle = number;

    /*
     * Set the status so XBMC treats the content as LiveTV.
     */
    tag->m_strStatus = "livetv";

    /*
     * Update the path and channel icon for LiveTV in case the channel has changed through
     * NextChannel(), PreviousChannel() or SetChannel().
     */
    if (!number.empty())
    {
      url.SetFileName("channels/" + number + ".ts"); // e.g. channels/3.ts
      item.SetPath(url.Get());
    }
    CStdString chanicon = GetValue(m_dll->proginfo_chanicon(program));
    if (!chanicon.empty())
    {
      url.SetFileName("files/channels/" + URIUtils::GetFileName(chanicon)); // e.g. files/channels/tv3.jpg
      item.SetArt("thumb", url.Get());
    }
  }
  else
  {
    /*
     * MythTV thumbnails aren't generated until a program has finished recording.
     */
    if (m_dll->proginfo_rec_status(program) == RS_RECORDED)
    {
      url.SetFileName("files/" + URIUtils::GetFileName(GetValue(m_dll->proginfo_pathname(program))) + ".png");
      item.SetArt("thumb", url.Get());
    }
  }
}
Esempio n. 16
0
void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char *resultname, CFileItemPtr item, const CVariant &parameterObject, const CVariant &validFields, CVariant &result, bool append /* = true */)
{
  CVariant object;
  bool hasFileField = false;
  bool hasThumbnailField = false;

  if (item.get())
  {
    for (unsigned int i = 0; i < validFields.size(); i++)
    {
      CStdString field = validFields[i].asString();

      if (field == "file")
        hasFileField = true;
      if (field == "thumbnail")
        hasThumbnailField = true;
    }

    if (allowFile && hasFileField)
    {
      if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->GetPath().IsEmpty())
          object["file"] = item->GetVideoInfoTag()->GetPath().c_str();
      if (item->HasMusicInfoTag() && !item->GetMusicInfoTag()->GetURL().IsEmpty())
        object["file"] = item->GetMusicInfoTag()->GetURL().c_str();

      if (!object.isMember("file"))
        object["file"] = item->GetPath().c_str();
    }

    if (ID)
    {
      if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > 0)
        object[ID] = (int)item->GetMusicInfoTag()->GetDatabaseId();
      else if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > 0)
        object[ID] = item->GetVideoInfoTag()->m_iDbId;

      if (stricmp(ID, "id") == 0)
      {
        if (item->HasMusicInfoTag())
        {
          if (item->m_bIsFolder && item->IsAlbum())
            object["type"] = "album";
          else
            object["type"] = "song";
        }
        else if (item->HasVideoInfoTag())
        {
          switch (item->GetVideoContentType())
          {
            case VIDEODB_CONTENT_EPISODES:
              object["type"] = "episode";
              break;

            case VIDEODB_CONTENT_MUSICVIDEOS:
              object["type"] = "musicvideo";
              break;

            case VIDEODB_CONTENT_MOVIES:
              object["type"] = "movie";
              break;

            default:
              break;
          }
        }
        else if (item->HasPictureInfoTag())
          object["type"] = "picture";

        if (!object.isMember("type"))
          object["type"] = "unknown";
      }
    }

    if (hasThumbnailField)
    {
      if (item->HasThumbnail())
        object["thumbnail"] = item->GetThumbnailImage().c_str();
      else if (item->HasVideoInfoTag())
      {
        CStdString strPath, strFileName;
        URIUtils::Split(item->GetCachedVideoThumb(), strPath, strFileName);
        CStdString cachedThumb = strPath + "auto-" + strFileName;

        if (CFile::Exists(cachedThumb))
          object["thumbnail"] = cachedThumb;
      }
      else if (item->HasPictureInfoTag())
      {
        CStdString thumb = CTextureCache::Get().CheckAndCacheImage(CTextureCache::GetWrappedThumbURL(item->GetPath()));
        if (!thumb.empty())
          object["thumbnail"] = thumb;
      }

      if (!object.isMember("thumbnail"))
        object["thumbnail"] = "";
    }

    if (item->HasVideoInfoTag())
      FillDetails(item->GetVideoInfoTag(), item, validFields, object);
    if (item->HasMusicInfoTag())
      FillDetails(item->GetMusicInfoTag(), item, validFields, object);
    if (item->HasPictureInfoTag())
      FillDetails(item->GetPictureInfoTag(), item, validFields, object);

    object["label"] = item->GetLabel().c_str();
  }
  else
    object = CVariant(CVariant::VariantTypeNull);

  if (resultname)
  {
    if (append)
      result[resultname].append(object);
    else
      result[resultname] = object;
  }
}
Esempio n. 17
0
void CMythSession::SetSeasonAndEpisode(const cmyth_proginfo_t &program, int *season, int *episode) {
  /*
   * A valid programid generated from an XMLTV source should look like:
   * [EP|MV|SH|SP][seriesid][episode][season]([partnumber][parttotal])
   * mythtv/trunk/programs/mytfilldatabaseline/xmltvparser.cpp - Line 522 onwards.
   * 
   * Season changed to a base36 character for XMLTV in Myth 0.24. http://svn.mythtv.org/trac/changeset/24724
   * 
   * A valid SchedulesDirect programid appears to have a similar format to the XMLTV programid but
   * doesn't have any obvious way to parse out the season and episode information. The number at the
   * end of the programid could possibly be the completely sequential number for the episode, but
   * even that doesn't seem to match up with TVDB. SchedulesDirect data does seem to have a valid
   * original air date though, so if we identify a SchedulesDirect programid, leave the season and
   * episode as 0. 
   */
  CStdString programid = GetValue(m_dll->proginfo_programid(program));
  CStdString seriesid = GetValue(m_dll->proginfo_seriesid(program));

  /*
   * Default the season and episode to 0 so XBMC treats the content as an episode and displays tag
   * information. If the season and episode can be parsed from the programid these will be
   * overwritten.
   */
  *season  = 0;
  *episode = 0;
  
  if (programid.empty() // Can't do anything if the program ID is empty
  ||  seriesid.empty()) // Can't figure out the end parsing if the series ID is empty  {
    return;
  
  CStdString category = programid.substr(0, 2); // Valid for both XMLTV and SchedulesDirect sources
  if (category != "MV"  // Movie
  &&  category != "EP"  // Series
  &&  category != "SH"  // TV Show
  &&  category != "SP") // Sports
    return;
  
  if (programid.substr(category.length(), seriesid.length()) != seriesid) // Series ID does not follow the category
    return;
  
  CStdString remainder = programid.substr(category.length() + seriesid.length()); // Whatever is after series ID
  
  /*
   * All SchedulesDirect remainders appear to be 4 characters and start with a 0. If the assumption
   * is correct that the number somehow relates to the sequential episode number across all seasons
   * then we can ignore remainders that start with 0. It will be very unlikely for a sequential
   * episode number for a series to be > 999.
   */
  if (remainder.length() == 4     // All SchedulesDirect codes seem to be 4 characters
  &&  remainder[0] == '0')        // Padded with 0's for low number. No valid XMLTV remainder will start with 0.
    return;
  
  /*
   * If the remainder is more than 5 characters, it must include the optional part number and total
   * number of parts. Strip off the last 2 characters assuming that there are ridiculously few
   * cases where the number of parts for a single episode is > 9.
   */
  if (remainder.length() >= 5) // Must include optional part number and total number of parts
    remainder = remainder.substr(0, remainder.length() - 2); // Assumes part number and total are both < 10

  /*
   * Now for some heuristic black magic.
   */
  if (remainder.length() == 2)  // Single character season and episode.
  {
    *season = atoi(remainder.substr(1, 1).c_str()); // TODO: Fix for base 36 in Myth 0.24. Assume season < 10
    *episode = atoi(remainder.substr(0, 1).c_str());
  }
  else if (remainder.length() == 3) // Ambiguous in Myth 0.23. Single character season in Myth 0.24
  {
    /*
     * Following heuristics are intended to work with largest possible number of cases. It won't be
     * perfect, but way better than just assuming the season is < 10.
     */
    if (remainder[2] == '0') // e.g. 610. Unlikely to have a season of 0 (specials) with more than 9 special episodes.
    {
      *season = atoi(remainder.substr(1, 2).c_str());
      *episode = atoi(remainder.substr(0, 1).c_str());
    }
    else if (remainder[1] == '0') // e.g. 203. Can't have a season start with 0. Must be end of episode.
    {
      *season = atoi(remainder.substr(2, 1).c_str()); // TODO: Fix for base 36 in Myth 0.24. Assume season < 10
      *episode = atoi(remainder.substr(0, 2).c_str());
    }
    else if (atoi(remainder.substr(0, 1).c_str()) > 3) // e.g. 412. Very unlikely to have more than 39 episodes per season if season > 9.
    {
      /*
       * TODO: See if a check for > 2 is better, e.g. is it still unlike to have more than 29 episodes
       * per season if season > 9?
       */
      *season = atoi(remainder.substr(1, 2).c_str());
      *episode = atoi(remainder.substr(0, 1).c_str());
    }
    else // e.g. 129. Assume season is < 10 or Myth 0.24 Base 36 season.
    {
      *season = atoi(remainder.substr(2, 1).c_str()); // TODO: Fix for base 36 in Myth 0.24. Assume season < 10
      *episode = atoi(remainder.substr(0, 2).c_str());
    }
  }
  else if (remainder.length() == 4) // Double digit season and episode in Myth 0.23 OR TODO: has part number and total number of parts
  {
    *season = atoi(remainder.substr(2, 2).c_str());
    *episode = atoi(remainder.substr(0, 2).c_str());
  }
  return;
}
Esempio n. 18
0
bool CAirPlayServer::CTCPClient::checkAuthorization(const CStdString& authStr,
                                                    const CStdString& method,
                                                    const CStdString& uri)
{
  bool authValid = true;

  CStdString username;

  if (authStr.empty())
    return false;

  //first get username - we allow all usernames for airplay (usually it is AirPlay)
  username = getFieldFromString(authStr, "username");
  if (username.empty())
  {
    authValid = false;
  }

  //second check realm
  if (authValid)
  {
    if (getFieldFromString(authStr, "realm") != AUTH_REALM)
    {
      authValid = false;
    }
  }

  //third check nonce
  if (authValid)
  {
    if (getFieldFromString(authStr, "nonce") != m_authNonce)
    {
      authValid = false;
    }
  }

  //forth check uri
  if (authValid)
  {
    if (getFieldFromString(authStr, "uri") != uri)
    {
      authValid = false;
    }
  }

  //last check response
  if (authValid)
  {
     CStdString realm = AUTH_REALM;
     CStdString ourResponse = calcResponse(username, ServerInstance->m_password, realm, method, uri, m_authNonce);
     CStdString theirResponse = getFieldFromString(authStr, "response");
     if (!theirResponse.Equals(ourResponse, false))
     {
       authValid = false;
       CLog::Log(LOGDEBUG,"AirAuth: response mismatch - our: %s theirs: %s",ourResponse.c_str(), theirResponse.c_str());
     }
     else
     {
       CLog::Log(LOGDEBUG, "AirAuth: successfull authentication from AirPlay client");
     }
  }
  m_bAuthenticated = authValid;
  return m_bAuthenticated;
}
Esempio n. 19
0
File: File.cpp Progetto: Jdad/xbmc
// This *looks* like a copy function, therefor the name "Cache" is misleading
bool CFile::Cache(const CStdString& strFileName, const CStdString& strDest, XFILE::IFileCallback* pCallback, void* pContext)
{
  CFile file;

  if (strFileName.empty() || strDest.empty())
    return false;

  // special case for zips - ignore caching
  CURL url(strFileName);
  if (URIUtils::IsInZIP(strFileName) || URIUtils::IsInAPK(strFileName))
    url.SetOptions("?cache=no");
  if (file.Open(url.Get(), READ_TRUNCATED))
  {

    CFile newFile;
    if (URIUtils::IsHD(strDest)) // create possible missing dirs
    {
      vector<CStdString> tokens;
      CStdString strDirectory;
      URIUtils::GetDirectory(strDest,strDirectory);
      URIUtils::RemoveSlashAtEnd(strDirectory);  // for the test below
      if (!(strDirectory.size() == 2 && strDirectory[1] == ':'))
      {
        CURL url(strDirectory);
        CStdString pathsep;
#ifndef _LINUX
        pathsep = "\\";
#else
        pathsep = "/";
#endif
        CUtil::Tokenize(url.GetFileName(),tokens,pathsep.c_str());
        CStdString strCurrPath;
        // Handle special
        if (!url.GetProtocol().IsEmpty()) {
          pathsep = "/";
          strCurrPath += url.GetProtocol() + "://";
        } // If the directory has a / at the beginning, don't forget it
        else if (strDirectory[0] == pathsep[0])
          strCurrPath += pathsep;
        for (vector<CStdString>::iterator iter=tokens.begin();iter!=tokens.end();++iter)
        {
          strCurrPath += *iter+pathsep;
          CDirectory::Create(strCurrPath);
        }
      }
    }
    if (CFile::Exists(strDest))
      CFile::Delete(strDest);
    if (!newFile.OpenForWrite(strDest, true))  // overwrite always
    {
      file.Close();
      return false;
    }

    int iBufferSize = 128 * 1024;

    CAutoBuffer buffer(iBufferSize);
    int iRead, iWrite;

    UINT64 llFileSize = file.GetLength();
    UINT64 llPos = 0;

    CStopWatch timer;
    timer.StartZero();
    float start = 0.0f;
    while (true)
    {
      g_application.ResetScreenSaver();

      iRead = file.Read(buffer.get(), iBufferSize);
      if (iRead == 0) break;
      else if (iRead < 0)
      {
        CLog::Log(LOGERROR, "%s - Failed read from file %s", __FUNCTION__, strFileName.c_str());
        llFileSize = (uint64_t)-1;
        break;
      }

      /* write data and make sure we managed to write it all */
      iWrite = 0;
      while(iWrite < iRead)
      {
        int iWrite2 = newFile.Write(buffer.get()+iWrite, iRead-iWrite);
        if(iWrite2 <=0)
          break;
        iWrite+=iWrite2;
      }

      if (iWrite != iRead)
      {
        CLog::Log(LOGERROR, "%s - Failed write to file %s", __FUNCTION__, strDest.c_str());
        llFileSize = (uint64_t)-1;
        break;
      }

      llPos += iRead;

      // calculate the current and average speeds
      float end = timer.GetElapsedSeconds();

      if (pCallback && end - start > 0.5 && end)
      {
        start = end;

        float averageSpeed = llPos / end;
        int ipercent = 0;
        if(llFileSize)
          ipercent = 100 * llPos / llFileSize;

        if(!pCallback->OnFileCallback(pContext, ipercent, averageSpeed))
        {
          CLog::Log(LOGERROR, "%s - User aborted copy", __FUNCTION__);
          llFileSize = (uint64_t)-1;
          break;
        }
      }
    }

    /* close both files */
    newFile.Close();
    file.Close();

    /* verify that we managed to completed the file */
    if (llFileSize && llPos != llFileSize)
    {
      CFile::Delete(strDest);
      return false;
    }
    return true;
  }
  return false;
}
Esempio n. 20
0
bool CGUIWindowAddonBrowser::GetDirectory(const CStdString& strDirectory,
        CFileItemList& items)
{
    bool result;
    if (strDirectory.Equals("addons://downloading/"))
    {
        VECADDONS addons;
        CAddonInstaller::Get().GetInstallList(addons);

        CURL url(strDirectory);
        CAddonsDirectory::GenerateListing(url,addons,items);
        result = true;
        items.SetProperty("reponame",g_localizeStrings.Get(24067));
        items.SetPath(strDirectory);

        if (m_guiState.get() && !m_guiState->HideParentDirItems())
        {
            CFileItemPtr pItem(new CFileItem(".."));
            pItem->SetPath(m_history.GetParentPath());
            pItem->m_bIsFolder = true;
            pItem->m_bIsShareOrDrive = false;
            items.AddFront(pItem, 0);
        }

    }
    else
    {
        result = CGUIMediaWindow::GetDirectory(strDirectory,items);
        if (CSettings::Get().GetBool("general.addonforeignfilter"))
        {
            int i=0;
            while (i < items.Size())
            {
                if (!FilterVar(CSettings::Get().GetBool("general.addonforeignfilter"),
                               items[i]->GetProperty("Addon.Language"), "en") ||
                        !FilterVar(CSettings::Get().GetBool("general.addonforeignfilter"),
                                   items[i]->GetProperty("Addon.Language"),
                                   g_langInfo.GetLanguageLocale()))
                {
                    i++;
                }
                else
                    items.Remove(i);
            }
        }
    }

    if (strDirectory.empty() && CAddonInstaller::Get().IsDownloading())
    {
        CFileItemPtr item(new CFileItem("addons://downloading/",true));
        item->SetLabel(g_localizeStrings.Get(24067));
        item->SetLabelPreformated(true);
        item->SetIconImage("DefaultNetwork.png");
        items.Add(item);
    }

    items.SetContent("addons");

    for (int i=0; i<items.Size(); ++i)
        SetItemLabel2(items[i]);

    return result;
}
Esempio n. 21
0
// Allow user to select a Fanart
void CGUIDialogMusicInfo::OnGetFanart()
{
  CFileItemList items;

  if (m_albumItem->HasArt("fanart"))
  {
    CFileItemPtr itemCurrent(new CFileItem("fanart://Current",false));
    itemCurrent->SetArt("thumb", m_albumItem->GetArt("fanart"));
    itemCurrent->SetLabel(g_localizeStrings.Get(20440));
    items.Add(itemCurrent);
  }

  // Grab the thumbnails from the web
  for (unsigned int i = 0; i < m_artist.fanart.GetNumFanarts(); i++)
  {
    CStdString strItemPath;
    strItemPath.Format("fanart://Remote%i",i);
    CFileItemPtr item(new CFileItem(strItemPath, false));
    CStdString thumb = m_artist.fanart.GetPreviewURL(i);
    item->SetArt("thumb", CTextureCache::GetWrappedThumbURL(thumb));
    item->SetIconImage("DefaultPicture.png");
    item->SetLabel(g_localizeStrings.Get(20441));

    // TODO: Do we need to clear the cached image?
    //    CTextureCache::Get().ClearCachedImage(thumb);
    items.Add(item);
  }

  // Grab a local thumb
  CMusicDatabase database;
  database.Open();
  CStdString strArtistPath;
  database.GetArtistPath(m_artist.idArtist,strArtistPath);
  CFileItem item(strArtistPath,true);
  CStdString strLocal = item.GetLocalFanart();
  if (!strLocal.IsEmpty())
  {
    CFileItemPtr itemLocal(new CFileItem("fanart://Local",false));
    itemLocal->SetArt("thumb", strLocal);
    itemLocal->SetLabel(g_localizeStrings.Get(20438));

    // TODO: Do we need to clear the cached image?
    CTextureCache::Get().ClearCachedImage(strLocal);
    items.Add(itemLocal);
  }
  else
  {
    CFileItemPtr itemNone(new CFileItem("fanart://None", false));
    itemNone->SetIconImage("DefaultArtist.png");
    itemNone->SetLabel(g_localizeStrings.Get(20439));
    items.Add(itemNone);
  }

  CStdString result;
  VECSOURCES sources(*CMediaSourceSettings::Get().GetSources("music"));
  g_mediaManager.GetLocalDrives(sources);
  bool flip=false;
  if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(20437), result, &flip, 20445))
    return;   // user cancelled

  // delete the thumbnail if that's what the user wants, else overwrite with the
  // new thumbnail
  if (result.Equals("fanart://Current"))
   return;

  if (result.Equals("fanart://Local"))
    result = strLocal;

  if (result.Left(15)  == "fanart://Remote")
  {
    int iFanart = atoi(result.Mid(15).c_str());
    m_artist.fanart.SetPrimaryFanart(iFanart);
    result = m_artist.fanart.GetImageURL();
  }
  else if (result.Equals("fanart://None") || !CFile::Exists(result))
    result.clear();

  if (flip && !result.empty())
    result = CTextureCache::GetWrappedImageURL(result, "", "flipped");

  // update thumb in the database
  CMusicDatabase db;
  if (db.Open())
  {
    db.SetArtForItem(m_albumItem->GetMusicInfoTag()->GetDatabaseId(), m_albumItem->GetMusicInfoTag()->GetType(), "fanart", result);
    db.Close();
  }

  m_albumItem->SetArt("fanart", result);
  m_hasUpdatedThumb = true;
  // tell our GUI to completely reload all controls (as some of them
  // are likely to have had this image in use so will need refreshing)
  CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
  g_windowManager.SendMessage(msg);
  // Update our screen
  Update();
}
Esempio n. 22
0
int CGUIWindowAddonBrowser::SelectAddonID(const vector<ADDON::TYPE> &types, CStdStringArray &addonIDs, bool showNone /*= false*/, bool multipleSelection /*= true*/)
{
    CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
    if (!dialog)
        return 0;

    CFileItemList items;
    CStdString heading;
    int iTypes = 0;
    for (vector<ADDON::TYPE>::const_iterator it = types.begin(); it != types.end(); ++it)
    {
        if (*it == ADDON_UNKNOWN)
            continue;
        ADDON::VECADDONS addons;
        iTypes++;
        if (*it == ADDON_AUDIO)
            CAddonsDirectory::GetScriptsAndPlugins("audio",addons);
        else if (*it == ADDON_EXECUTABLE)
            CAddonsDirectory::GetScriptsAndPlugins("executable",addons);
        else if (*it == ADDON_IMAGE)
            CAddonsDirectory::GetScriptsAndPlugins("image",addons);
        else if (*it == ADDON_VIDEO)
            CAddonsDirectory::GetScriptsAndPlugins("video",addons);
        else
            CAddonMgr::Get().GetAddons(*it, addons);
        for (ADDON::IVECADDONS it2 = addons.begin() ; it2 != addons.end() ; ++it2)
        {
            CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*it2, ""));
            if (!items.Contains(item->GetPath()))
                items.Add(item);
        }

        if (!heading.empty())
            heading += ", ";
        heading += TranslateType(*it, true);
    }

    if (iTypes == 0)
        return 0;

    dialog->SetHeading(heading);
    dialog->Reset();
    dialog->SetUseDetails(true);
    if (multipleSelection)
        showNone = false;
    if (multipleSelection || iTypes > 1)
        dialog->EnableButton(true, 186);
    else
        dialog->EnableButton(true, 21452);
    if (showNone)
    {
        CFileItemPtr item(new CFileItem("", false));
        item->SetLabel(g_localizeStrings.Get(231));
        item->SetLabel2(g_localizeStrings.Get(24040));
        item->SetIconImage("DefaultAddonNone.png");
        item->SetSpecialSort(SortSpecialOnTop);
        items.Add(item);
    }
    items.Sort(SortByLabel, SortOrderAscending);

    if (addonIDs.size() > 0)
    {
        for (CStdStringArray::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; it++)
        {
            CFileItemPtr item = items.Get(*it);
            if (item)
                item->Select(true);
        }
    }
    dialog->SetItems(&items);
    dialog->SetMultiSelection(multipleSelection);
    dialog->DoModal();
    if (!multipleSelection && iTypes == 1 && dialog->IsButtonPressed())
    {   // switch to the addons browser.
        vector<CStdString> params;
        params.push_back("addons://all/"+TranslateType(types[0],false)+"/");
        params.push_back("return");
        g_windowManager.ActivateWindow(WINDOW_ADDON_BROWSER, params);
        return 2;
    }
    if (!dialog->IsConfirmed())
        return 0;
    addonIDs.clear();
    const CFileItemList& list = dialog->GetSelectedItems();
    for (int i = 0 ; i < list.Size() ; i++)
        addonIDs.push_back(list.Get(i)->GetPath());
    return 1;
}
Esempio n. 23
0
void GUIFontManager::LoadFonts(const CStdString& strFontSet)
{
  CXBMCTinyXML xmlDoc;
  if (!OpenFontFile(xmlDoc))
    return;

  TiXmlElement* pRootElement = xmlDoc.RootElement();
  const TiXmlNode *pChild = pRootElement->FirstChild();

  // If there are no fontset's defined in the XML (old skin format) run in backward compatibility
  // and ignore the fontset request
  CStdString strValue = pChild->Value();
  if (strValue == "fontset")
  {
    CStdString foundTTF;
    while (pChild)
    {
      strValue = pChild->Value();
      if (strValue == "fontset")
      {
        const char* idAttr = ((TiXmlElement*) pChild)->Attribute("id");

        const char* unicodeAttr = ((TiXmlElement*) pChild)->Attribute("unicode");

        if (foundTTF.empty() && idAttr != NULL && unicodeAttr != NULL && stricmp(unicodeAttr, "true") == 0)
          foundTTF = idAttr;

        // Check if this is the fontset that we want
        if (idAttr != NULL && stricmp(strFontSet.c_str(), idAttr) == 0)
        {
          m_fontsetUnicode=false;
          // Check if this is the a ttf fontset
          if (unicodeAttr != NULL && stricmp(unicodeAttr, "true") == 0)
            m_fontsetUnicode=true;

          if (m_fontsetUnicode)
          {
            LoadFonts(pChild->FirstChild());
            break;
          }
        }

      }

      pChild = pChild->NextSibling();
    }

    // If no fontset was loaded
    if (pChild == NULL)
    {
      CLog::Log(LOGWARNING, "file doesnt have <fontset> with name '%s', defaulting to first fontset", strFontSet.c_str());
      if (!foundTTF.empty())
        LoadFonts(foundTTF);
    }
  }
  else
  {
    CLog::Log(LOGERROR, "file doesnt have <fontset> in <fonts>, but rather %s", strValue.c_str());
    return ;
  }
}
Esempio n. 24
0
void CGUIDialogVideoInfo::SetMovie(const CFileItem *item)
{
  *m_movieItem = *item;
  // setup cast list + determine type.  We need to do this here as it makes
  // sure that content type (among other things) is set correctly for the
  // old fixed id labels that we have floating around (they may be using
  // content type to determine visibility, so we'll set the wrong label)
  ClearCastList();
  VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)m_movieItem->GetVideoContentType();
  if (type == VIDEODB_CONTENT_MUSICVIDEOS)
  { // music video
    CMusicDatabase database;
    database.Open();
    const std::vector<std::string> &artists = m_movieItem->GetVideoInfoTag()->m_artist;
    for (std::vector<std::string>::const_iterator it = artists.begin(); it != artists.end(); ++it)
    {
      int idArtist = database.GetArtistByName(*it);
      CStdString thumb = database.GetArtForItem(idArtist, "artist", "thumb");
      CFileItemPtr item(new CFileItem(*it));
      if (!thumb.empty())
        item->SetArt("thumb", thumb);
      item->SetIconImage("DefaultArtist.png");
      m_castList->Add(item);
    }
    m_castList->SetContent("musicvideos");
  }
  else
  { // movie/show/episode
    for (CVideoInfoTag::iCast it = m_movieItem->GetVideoInfoTag()->m_cast.begin(); it != m_movieItem->GetVideoInfoTag()->m_cast.end(); ++it)
    {
      CStdString character;
      if (it->strRole.IsEmpty())
        character = it->strName;
      else
        character.Format("%s %s %s", it->strName.c_str(), g_localizeStrings.Get(20347).c_str(), it->strRole.c_str());
      CFileItemPtr item(new CFileItem(it->strName));
      if (!it->thumb.IsEmpty())
        item->SetArt("thumb", it->thumb);
      else if (g_guiSettings.GetBool("videolibrary.actorthumbs"))
      { // backward compatibility
        CStdString thumb = CScraperUrl::GetThumbURL(it->thumbUrl.GetFirstThumb());
        if (!thumb.IsEmpty())
        {
          item->SetArt("thumb", thumb);
          CTextureCache::Get().BackgroundCacheImage(thumb);
        }
      }
      item->SetIconImage("DefaultActor.png");
      item->SetLabel(character);
      m_castList->Add(item);
    }
    // determine type:
    if (type == VIDEODB_CONTENT_TVSHOWS)
    {
      m_castList->SetContent("tvshows");
      // special case stuff for shows (not currently retrieved from the library in filemode (ref: GetTvShowInfo vs GetTVShowsByWhere)
      m_movieItem->m_dateTime = m_movieItem->GetVideoInfoTag()->m_premiered;
      if(m_movieItem->GetVideoInfoTag()->m_iYear == 0 && m_movieItem->m_dateTime.IsValid())
        m_movieItem->GetVideoInfoTag()->m_iYear = m_movieItem->m_dateTime.GetYear();
      m_movieItem->SetProperty("totalepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode);
      m_movieItem->SetProperty("numepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode); // info view has no concept of current watched/unwatched filter as we could come here from files view, but set for consistency
      m_movieItem->SetProperty("watchedepisodes", m_movieItem->GetVideoInfoTag()->m_playCount);
      m_movieItem->SetProperty("unwatchedepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode - m_movieItem->GetVideoInfoTag()->m_playCount);
      m_movieItem->GetVideoInfoTag()->m_playCount = (m_movieItem->GetVideoInfoTag()->m_iEpisode == m_movieItem->GetVideoInfoTag()->m_playCount) ? 1 : 0;
    }
    else if (type == VIDEODB_CONTENT_EPISODES)
    {
      m_castList->SetContent("episodes");
      // special case stuff for episodes (not currently retrieved from the library in filemode (ref: GetEpisodeInfo vs GetEpisodesByWhere)
      m_movieItem->m_dateTime = m_movieItem->GetVideoInfoTag()->m_firstAired;
      if(m_movieItem->GetVideoInfoTag()->m_iYear == 0 && m_movieItem->m_dateTime.IsValid())
        m_movieItem->GetVideoInfoTag()->m_iYear = m_movieItem->m_dateTime.GetYear();
      // retrieve the season thumb.
      // TODO: should we use the thumbloader for this?
      CVideoDatabase db;
      if (db.Open())
      {
        if (m_movieItem->GetVideoInfoTag()->m_iSeason > -1)
        {
          int seasonID = m_movieItem->GetVideoInfoTag()->m_iIdSeason;
          if (seasonID < 0)
            seasonID = db.GetSeasonId(m_movieItem->GetVideoInfoTag()->m_iIdShow,
                                      m_movieItem->GetVideoInfoTag()->m_iSeason);
          CGUIListItem::ArtMap thumbs;
          if (db.GetArtForItem(seasonID, "season", thumbs))
          {
            for (CGUIListItem::ArtMap::iterator i = thumbs.begin(); i != thumbs.end(); i++)
              m_movieItem->SetArt("season." + i->first, i->second);
          }
        }
        db.Close();
      }
    }
    else if (type == VIDEODB_CONTENT_MOVIES)
    {
      m_castList->SetContent("movies");

      // local trailers should always override non-local, so check 
      // for a local one if the registered trailer is online
      if (m_movieItem->GetVideoInfoTag()->m_strTrailer.IsEmpty() ||
          URIUtils::IsInternetStream(m_movieItem->GetVideoInfoTag()->m_strTrailer))
      {
        CStdString localTrailer = m_movieItem->FindTrailer();
        if (!localTrailer.IsEmpty())
        {
          m_movieItem->GetVideoInfoTag()->m_strTrailer = localTrailer;
          CVideoDatabase database;
          if(database.Open())
          {
            database.SetDetail(m_movieItem->GetVideoInfoTag()->m_strTrailer,
                               m_movieItem->GetVideoInfoTag()->m_iDbId,
                               VIDEODB_ID_TRAILER, VIDEODB_CONTENT_MOVIES);
            database.Close();
            CUtil::DeleteVideoDatabaseDirectoryCache();
          }
        }
      }
    }
  }
  CVideoThumbLoader loader;
  loader.LoadItem(m_movieItem.get());
}
Esempio n. 25
0
  CStdString CStackDirectory::GetStackedTitlePath(const CStdString &strPath, VECCREGEXP& RegExps)
  {
    CStackDirectory stack;
    CFileItemList   files;
    CStdString      strStackTitlePath,
                    strCommonDir        = URIUtils::GetParentPath(strPath);

    stack.GetDirectory(strPath, files);

    if (files.Size() > 1)
    {
      CStdString strStackTitle;

      CStdString File1 = URIUtils::GetFileName(files[0]->GetPath());
      CStdString File2 = URIUtils::GetFileName(files[1]->GetPath());
      // Check if source path uses URL encoding
      if (URIUtils::ProtocolHasEncodedFilename(CURL(strCommonDir).GetProtocol()))
      {
        CURL::Decode(File1);
        CURL::Decode(File2);
      }

      std::vector<CRegExp>::iterator itRegExp = RegExps.begin();
      int offset = 0;

      while (itRegExp != RegExps.end())
      {
        if (itRegExp->RegFind(File1, offset) != -1)
        {
          CStdString Title1     = itRegExp->GetMatch(1),
                     Volume1    = itRegExp->GetMatch(2),
                     Ignore1    = itRegExp->GetMatch(3),
                     Extension1 = itRegExp->GetMatch(4);
          if (offset)
            Title1 = File1.substr(0, itRegExp->GetSubStart(2));
          if (itRegExp->RegFind(File2, offset) != -1)
          {
            CStdString Title2     = itRegExp->GetMatch(1),
                       Volume2    = itRegExp->GetMatch(2),
                       Ignore2    = itRegExp->GetMatch(3),
                       Extension2 = itRegExp->GetMatch(4);
            if (offset)
              Title2 = File2.substr(0, itRegExp->GetSubStart(2));
            if (Title1.Equals(Title2))
            {
              if (!Volume1.Equals(Volume2))
              {
                if (Ignore1.Equals(Ignore2) && Extension1.Equals(Extension2))
                {
                  // got it
                  strStackTitle = Title1 + Ignore1 + Extension1;
                  // Check if source path uses URL encoding
                  if (URIUtils::ProtocolHasEncodedFilename(CURL(strCommonDir).GetProtocol()))
                    CURL::Encode(strStackTitle);

                  itRegExp = RegExps.end();
                  break;
                }
                else // Invalid stack
                  break;
              }
              else // Early match, retry with offset
              {
                offset = itRegExp->GetSubStart(3);
                continue;
              }
            }
          }
        }
        offset = 0;
        itRegExp++;
      }
      if (!strCommonDir.empty() && !strStackTitle.empty())
        strStackTitlePath = strCommonDir + strStackTitle;
    }

    return strStackTitlePath;
  }
Esempio n. 26
0
void CGUIDialogVideoInfo::OnGetArt()
{
  map<string, string> currentArt;
  string type = ChooseArtType(*m_movieItem, currentArt);
  if (type.empty())
    return; // cancelled

  // TODO: this can be removed once these are unified.
  if (type == "fanart")
    OnGetFanart();
  else
  {
    CFileItemList items;

    // Current thumb
    if (m_movieItem->HasArt(type))
    {
      CFileItemPtr item(new CFileItem("thumb://Current", false));
      item->SetArt("thumb", m_movieItem->GetArt(type));
      item->SetLabel(g_localizeStrings.Get(13512));
      items.Add(item);
    }
    else if ((type == "poster" || type == "banner") && currentArt.find("thumb") != currentArt.end())
    { // add the 'thumb' type in
      CFileItemPtr item(new CFileItem("thumb://Thumb", false));
      item->SetArt("thumb", currentArt["thumb"]);
      item->SetLabel(g_localizeStrings.Get(13512));
      items.Add(item);
    }

    // Grab the thumbnails from the web
    vector<CStdString> thumbs;
    int season = (m_movieItem->GetVideoInfoTag()->m_type == "season") ? m_movieItem->GetVideoInfoTag()->m_iSeason : -1;
    m_movieItem->GetVideoInfoTag()->m_strPictureURL.GetThumbURLs(thumbs, type, season);

    for (unsigned int i = 0; i < thumbs.size(); ++i)
    {
      CStdString strItemPath;
      strItemPath.Format("thumb://Remote%i", i);
      CFileItemPtr item(new CFileItem(strItemPath, false));
      item->SetArt("thumb", thumbs[i]);
      item->SetIconImage("DefaultPicture.png");
      item->SetLabel(g_localizeStrings.Get(13513));

      // TODO: Do we need to clear the cached image?
      //    CTextureCache::Get().ClearCachedImage(thumb);
      items.Add(item);
    }

    CStdString localThumb = CVideoThumbLoader::GetLocalArt(*m_movieItem, type);
    if (!localThumb.empty())
    {
      CFileItemPtr item(new CFileItem("thumb://Local", false));
      item->SetArt("thumb", localThumb);
      item->SetLabel(g_localizeStrings.Get(13514));
      items.Add(item);
    }
    else
    { // no local thumb exists, so we are just using the IMDb thumb or cached thumb
      // which is probably the IMDb thumb.  These could be wrong, so allow the user
      // to delete the incorrect thumb
      CFileItemPtr item(new CFileItem("thumb://None", false));
      item->SetIconImage("DefaultVideo.png");
      item->SetLabel(g_localizeStrings.Get(13515));
      items.Add(item);
    }

    CStdString result;
    VECSOURCES sources(*CMediaSourceSettings::Get().GetSources("video"));
    AddItemPathToFileBrowserSources(sources, *m_movieItem);
    g_mediaManager.GetLocalDrives(sources);
    if (CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(13511), result) &&
        result != "thumb://Current") // user didn't choose the one they have
    {
      CStdString newThumb;
      if (result.Left(14) == "thumb://Remote")
      {
        int number = atoi(result.Mid(14));
        newThumb = thumbs[number];
      }
      else if (result == "thumb://Thumb")
        newThumb = currentArt["thumb"];
      else if (result == "thumb://Local")
        newThumb = localThumb;
      else if (CFile::Exists(result))
        newThumb = result;
      else // none
        newThumb.clear();

      // update thumb in the database
      CVideoDatabase db;
      if (db.Open())
      {
        db.SetArtForItem(m_movieItem->GetVideoInfoTag()->m_iDbId, m_movieItem->GetVideoInfoTag()->m_type, type, newThumb);
        db.Close();
      }
      CUtil::DeleteVideoDatabaseDirectoryCache(); // to get them new thumbs to show
      m_movieItem->SetArt(type, newThumb);
      if (m_movieItem->HasProperty("set_folder_thumb"))
      { // have a folder thumb to set as well
        VIDEO::CVideoInfoScanner::ApplyThumbToFolder(m_movieItem->GetProperty("set_folder_thumb").asString(), newThumb);
      }
      m_hasUpdatedThumb = true;
    }
  }

  // Update our screen
  Update();

  // re-open the art selection dialog as we come back from
  // the image selection dialog
  OnGetArt();
}
Esempio n. 27
0
void CDVDPlayerVideo::Process()
{
  CLog::Log(LOGNOTICE, "running thread: video_thread");

  DVDVideoPicture picture;
  CPulldownCorrection pulldown;
  CDVDVideoPPFFmpeg mPostProcess("");
  CStdString sPostProcessType;

  memset(&picture, 0, sizeof(DVDVideoPicture));

  double pts = 0;
  double frametime = (double)DVD_TIME_BASE / m_fFrameRate;

  int iDropped = 0; //frames dropped in a row
  bool bRequestDrop = false;

  m_videoStats.Start();

  while (!m_bStop)
  {
    int iQueueTimeOut = (int)(m_stalled ? frametime / 4 : frametime * 10) / 1000;
    int iPriority = (m_speed == DVD_PLAYSPEED_PAUSE && m_started) ? 1 : 0;

    CDVDMsg* pMsg;
    MsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, iQueueTimeOut, iPriority);

    if (MSGQ_IS_ERROR(ret) || ret == MSGQ_ABORT)
    {
      CLog::Log(LOGERROR, "Got MSGQ_ABORT or MSGO_IS_ERROR return true");
      break;
    }
    else if (ret == MSGQ_TIMEOUT)
    {
      // if we only wanted priority messages, this isn't a stall
      if( iPriority )
        continue;

      //Okey, start rendering at stream fps now instead, we are likely in a stillframe
      if( !m_stalled )
      {
        if(m_started)
          CLog::Log(LOGINFO, "CDVDPlayerVideo - Stillframe detected, switching to forced %f fps", m_fFrameRate);
        m_stalled = true;
        pts+= frametime*4;
      }

      //Waiting timed out, output last picture
      if( picture.iFlags & DVP_FLAG_ALLOCATED )
      {
        //Remove interlaced flag before outputting
        //no need to output this as if it was interlaced
        picture.iFlags &= ~DVP_FLAG_INTERLACED;
        picture.iFlags |= DVP_FLAG_NOSKIP;
        OutputPicture(&picture, pts);
        pts+= frametime;
      }

      continue;
    }

    if (pMsg->IsType(CDVDMsg::GENERAL_SYNCHRONIZE))
    {
      ((CDVDMsgGeneralSynchronize*)pMsg)->Wait( &m_bStop, SYNCSOURCE_VIDEO );
      CLog::Log(LOGDEBUG, "CDVDPlayerVideo - CDVDMsg::GENERAL_SYNCHRONIZE");
      pMsg->Release();

      /* we may be very much off correct pts here, but next picture may be a still*/
      /* make sure it isn't dropped */
      m_iNrOfPicturesNotToSkip = 5;
      continue;
    }
    else if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC))
    {
      CDVDMsgGeneralResync* pMsgGeneralResync = (CDVDMsgGeneralResync*)pMsg;

      if(pMsgGeneralResync->m_timestamp != DVD_NOPTS_VALUE)
        pts = pMsgGeneralResync->m_timestamp;

      double delay = m_FlipTimeStamp - m_pClock->GetAbsoluteClock();
      if( delay > frametime ) delay = frametime;
      else if( delay < 0 )    delay = 0;

      if(pMsgGeneralResync->m_clock)
      {
        CLog::Log(LOGDEBUG, "CDVDPlayerVideo - CDVDMsg::GENERAL_RESYNC(%f, 1)", pts);
        m_pClock->Discontinuity(pts - delay);
      }
      else
        CLog::Log(LOGDEBUG, "CDVDPlayerVideo - CDVDMsg::GENERAL_RESYNC(%f, 0)", pts);

      pMsgGeneralResync->Release();
      continue;
    }
    else if (pMsg->IsType(CDVDMsg::GENERAL_DELAY))
    {
      if (m_speed != DVD_PLAYSPEED_PAUSE)
      {
        double timeout = static_cast<CDVDMsgDouble*>(pMsg)->m_value;

        CLog::Log(LOGDEBUG, "CDVDPlayerVideo - CDVDMsg::GENERAL_DELAY(%f)", timeout);

        timeout *= (double)DVD_PLAYSPEED_NORMAL / abs(m_speed);
        timeout += CDVDClock::GetAbsoluteClock();

        while(!m_bStop && CDVDClock::GetAbsoluteClock() < timeout)
          Sleep(1);
      }
    }
    else if (pMsg->IsType(CDVDMsg::VIDEO_SET_ASPECT))
    {
      CLog::Log(LOGDEBUG, "CDVDPlayerVideo - CDVDMsg::VIDEO_SET_ASPECT");
      m_fForcedAspectRatio = *((CDVDMsgDouble*)pMsg);
    }
    else if (pMsg->IsType(CDVDMsg::GENERAL_RESET))
    {
      if(m_pVideoCodec)
        m_pVideoCodec->Reset();
      m_packets.clear();
      m_started = false;
    }
    else if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH)) // private message sent by (CDVDPlayerVideo::Flush())
    {
      if(m_pVideoCodec)
        m_pVideoCodec->Reset();
      m_packets.clear();

      m_pullupCorrection.Flush();
      //we need to recalculate the framerate
      //TODO: this needs to be set on a streamchange instead
      ResetFrameRateCalc();

      m_stalled = true;
      m_started = false;
    }
    else if (pMsg->IsType(CDVDMsg::VIDEO_NOSKIP))
    {
      // libmpeg2 is also returning incomplete frames after a dvd cell change
      // so the first few pictures are not the correct ones to display in some cases
      // just display those together with the correct one.
      // (setting it to 2 will skip some menu stills, 5 is working ok for me).
      m_iNrOfPicturesNotToSkip = 5;
    }
    else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED))
    {
      m_speed = static_cast<CDVDMsgInt*>(pMsg)->m_value;
      if(m_speed == DVD_PLAYSPEED_PAUSE)
        m_iNrOfPicturesNotToSkip = 0;
    }
    else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED))
    {
      if(m_started)
        m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_VIDEO));
    }
    else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE))
    {
      CDVDMsgVideoCodecChange* msg(static_cast<CDVDMsgVideoCodecChange*>(pMsg));
      OpenStream(msg->m_hints, msg->m_codec);
      msg->m_codec = NULL;
      picture.iFlags &= ~DVP_FLAG_ALLOCATED;
    }

    if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET))
    {
      DemuxPacket* pPacket = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacket();
      bool bPacketDrop     = ((CDVDMsgDemuxerPacket*)pMsg)->GetPacketDrop();

      if (m_stalled)
      {
        CLog::Log(LOGINFO, "CDVDPlayerVideo - Stillframe left, switching to normal playback");
        m_stalled = false;

        //don't allow the first frames after a still to be dropped
        //sometimes we get multiple stills (long duration frames) after each other
        //in normal mpegs
        m_iNrOfPicturesNotToSkip = 5;
      }
      else if( iDropped*frametime > DVD_MSEC_TO_TIME(100) && m_iNrOfPicturesNotToSkip == 0 )
      { // if we dropped too many pictures in a row, insert a forced picture
        m_iNrOfPicturesNotToSkip = 1;
      }

#ifdef PROFILE
      bRequestDrop = false;
#else
      if (m_messageQueue.GetDataSize() == 0
      ||  m_speed < 0)
      {
        bRequestDrop = false;
        m_iDroppedRequest = 0;
        m_iLateFrames     = 0;
      }
#endif

      // if player want's us to drop this packet, do so nomatter what
      if(bPacketDrop)
        bRequestDrop = true;

      // tell codec if next frame should be dropped
      // problem here, if one packet contains more than one frame
      // both frames will be dropped in that case instead of just the first
      // decoder still needs to provide an empty image structure, with correct flags
      m_pVideoCodec->SetDropState(bRequestDrop);

      // ask codec to do deinterlacing if possible
      EINTERLACEMETHOD mInt = g_settings.m_currentVideoSettings.m_InterlaceMethod;
      unsigned int     mFilters = 0;

      if(mInt == VS_INTERLACEMETHOD_DEINTERLACE)
        mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY;
      else if(mInt == VS_INTERLACEMETHOD_DEINTERLACE_HALF)
        mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY | CDVDVideoCodec::FILTER_DEINTERLACE_HALFED;
      else if(mInt == VS_INTERLACEMETHOD_AUTO)
        mFilters = CDVDVideoCodec::FILTER_DEINTERLACE_ANY | CDVDVideoCodec::FILTER_DEINTERLACE_FLAGGED;

      mFilters = m_pVideoCodec->SetFilters(mFilters);

      int iDecoderState = m_pVideoCodec->Decode(pPacket->pData, pPacket->iSize, pPacket->dts, pPacket->pts);

      // buffer packets so we can recover should decoder flush for some reason
      if(m_pVideoCodec->GetConvergeCount() > 0)
      {
        m_packets.push_back(DVDMessageListItem(pMsg, 0));
        if(m_packets.size() > m_pVideoCodec->GetConvergeCount() 
        || m_packets.size() * frametime > DVD_SEC_TO_TIME(10))
          m_packets.pop_front();
      }

      m_videoStats.AddSampleBytes(pPacket->iSize);
      // assume decoder dropped a picture if it didn't give us any
      // picture from a demux packet, this should be reasonable
      // for libavformat as a demuxer as it normally packetizes
      // pictures when they come from demuxer
      if(bRequestDrop && !bPacketDrop && (iDecoderState & VC_BUFFER) && !(iDecoderState & VC_PICTURE))
      {
        m_iDroppedFrames++;
        iDropped++;
      }

      // loop while no error
      while (!m_bStop)
      {

        // if decoder was flushed, we need to seek back again to resume rendering
        if (iDecoderState & VC_FLUSHED)
        {
          CLog::Log(LOGDEBUG, "CDVDPlayerVideo - video decoder was flushed");
          while(!m_packets.empty())
          {
            CDVDMsgDemuxerPacket* msg = (CDVDMsgDemuxerPacket*)m_packets.front().message->Acquire();
            m_packets.pop_front();

            // all packets except the last one should be dropped
            // if prio packets and current packet should be dropped, this is likely a new reset
            msg->m_drop = !m_packets.empty() || (iPriority > 0 && bPacketDrop);
            m_messageQueue.Put(msg, iPriority + 10);
          }

          m_pVideoCodec->Reset();
          m_packets.clear();
          break;
        }

        // if decoder had an error, tell it to reset to avoid more problems
        if (iDecoderState & VC_ERROR)
        {
          CLog::Log(LOGDEBUG, "CDVDPlayerVideo - video decoder returned error");
          break;
        }

        // check for a new picture
        if (iDecoderState & VC_PICTURE)
        {

          // try to retrieve the picture (should never fail!), unless there is a demuxer bug ofcours
          m_pVideoCodec->ClearPicture(&picture);
          if (m_pVideoCodec->GetPicture(&picture))
          {
            sPostProcessType.clear();

            picture.iGroupId = pPacket->iGroupId;

            if(picture.iDuration == 0.0)
              picture.iDuration = frametime;

            if(bPacketDrop)
              picture.iFlags |= DVP_FLAG_DROPPED;

            if (m_iNrOfPicturesNotToSkip > 0)
            {
              picture.iFlags |= DVP_FLAG_NOSKIP;
              m_iNrOfPicturesNotToSkip--;
            }

            // validate picture timing, 
            // if both dts/pts invalid, use pts calulated from picture.iDuration
            // if pts invalid use dts, else use picture.pts as passed
            if (picture.dts == DVD_NOPTS_VALUE && picture.pts == DVD_NOPTS_VALUE)
              picture.pts = pts;
            else if (picture.pts == DVD_NOPTS_VALUE)
              picture.pts = picture.dts;

            /* use forced aspect if any */
            if( m_fForcedAspectRatio != 0.0f )
              picture.iDisplayWidth = (int) (picture.iDisplayHeight * m_fForcedAspectRatio);

            //Deinterlace if codec said format was interlaced or if we have selected we want to deinterlace
            //this video
            if(!(mFilters & CDVDVideoCodec::FILTER_DEINTERLACE_ANY))
            {
              if((mInt == VS_INTERLACEMETHOD_DEINTERLACE)
              || (mInt == VS_INTERLACEMETHOD_AUTO && (picture.iFlags & DVP_FLAG_INTERLACED)
                                                  && !g_renderManager.Supports(VS_INTERLACEMETHOD_RENDER_BOB)))
              {
                if (!sPostProcessType.empty())
                  sPostProcessType += ",";
                sPostProcessType += g_advancedSettings.m_videoPPFFmpegDeint;
              }
            }

            if (g_settings.m_currentVideoSettings.m_PostProcess)
            {
              if (!sPostProcessType.empty())
                sPostProcessType += ",";
              // This is what mplayer uses for its "high-quality filter combination"
              sPostProcessType += g_advancedSettings.m_videoPPFFmpegPostProc;
            }

            if (!sPostProcessType.empty())
            {
              mPostProcess.SetType(sPostProcessType);
              if (mPostProcess.Process(&picture))
                mPostProcess.GetPicture(&picture);
            }

            /* if frame has a pts (usually originiating from demux packet), use that */
            if(picture.pts != DVD_NOPTS_VALUE)
            {
              if(pulldown.enabled())
                picture.pts += pulldown.pts();

              pts = picture.pts;
            }

            if(pulldown.enabled())
            {
              picture.iDuration = pulldown.dur();
              pulldown.next();
            }

            if (picture.iRepeatPicture)
              picture.iDuration *= picture.iRepeatPicture + 1;

#if 1
            int iResult = OutputPicture(&picture, pts);
#elif 0
            // testing NV12 rendering functions
            DVDVideoPicture* pTempNV12Picture = CDVDCodecUtils::ConvertToNV12Picture(&picture);
            int iResult = OutputPicture(pTempNV12Picture, pts);
            CDVDCodecUtils::FreePicture(pTempNV12Picture);
#elif 0
            // testing YUY2 or UYVY rendering functions
            // WARNING: since this scales a full YV12 frame, weaving artifacts will show on interlaced content
            // even with the deinterlacer on
            DVDVideoPicture* pTempYUVPackedPicture = CDVDCodecUtils::ConvertToYUV422PackedPicture(&picture, DVDVideoPicture::FMT_UYVY);
            //DVDVideoPicture* pTempYUVPackedPicture = CDVDCodecUtils::ConvertToYUV422PackedPicture(&picture, DVDVideoPicture::FMT_YUY2);
            int iResult = OutputPicture(pTempYUVPackedPicture, pts);
            CDVDCodecUtils::FreePicture(pTempYUVPackedPicture);
#endif

            if(m_started == false)
            {
              m_codecname = m_pVideoCodec->GetName();
              m_started = true;
              m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_VIDEO));
            }

            // guess next frame pts. iDuration is always valid
            if (m_speed != 0)
              pts += picture.iDuration * m_speed / abs(m_speed);

            if( iResult & EOS_ABORT )
            {
              //if we break here and we directly try to decode again wihout
              //flushing the video codec things break for some reason
              //i think the decoder (libmpeg2 atleast) still has a pointer
              //to the data, and when the packet is freed that will fail.
              iDecoderState = m_pVideoCodec->Decode(NULL, 0, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);
              break;
            }

            if( (iResult & EOS_DROPPED) && !bPacketDrop )
            {
              m_iDroppedFrames++;
              iDropped++;
            }
            else
              iDropped = 0;

            bRequestDrop = (iResult & EOS_VERYLATE) == EOS_VERYLATE;
          }
          else
          {
            CLog::Log(LOGWARNING, "Decoder Error getting videoPicture.");
            m_pVideoCodec->Reset();
          }
        }

        /*
        if (iDecoderState & VC_USERDATA)
        {
          // found some userdata while decoding a frame
          // could be closed captioning
          DVDVideoUserData videoUserData;
          if (m_pVideoCodec->GetUserData(&videoUserData))
          {
            ProcessVideoUserData(&videoUserData, pts);
          }
        }
        */

        // if the decoder needs more data, we just break this loop
        // and try to get more data from the videoQueue
        if (iDecoderState & VC_BUFFER)
          break;

        // the decoder didn't need more data, flush the remaning buffer
        iDecoderState = m_pVideoCodec->Decode(NULL, 0, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);
      }
    }

    // all data is used by the decoder, we can safely free it now
    pMsg->Release();
  }
}
bool CWIN32Util::XBMCShellExecute(const CStdString &strPath, bool bWaitForScriptExit)
{
  CStdString strCommand = strPath;
  CStdString strExe = strPath;
  CStdString strParams;
  CStdString strWorkingDir;

  StringUtils::Trim(strCommand);
  if (strCommand.empty())
  {
    return false;
  }
  size_t iIndex = std::string::npos;
  char split = ' ';
  if (strCommand[0] == '\"')
  {
    split = '\"';
  }
  iIndex = strCommand.find(split, 1);
  if (iIndex != std::string::npos)
  {
    strExe = strCommand.substr(0, iIndex + 1);
    strParams = strCommand.substr(iIndex + 1);
  }

  StringUtils::Replace(strExe, "\"", "");

  strWorkingDir = strExe;
  iIndex = strWorkingDir.rfind('\\');
  if(iIndex != std::string::npos)
  {
    strWorkingDir[iIndex+1] = '\0';
  }

  CStdStringW WstrExe, WstrParams, WstrWorkingDir;
  g_charsetConverter.utf8ToW(strExe, WstrExe);
  g_charsetConverter.utf8ToW(strParams, WstrParams);
  g_charsetConverter.utf8ToW(strWorkingDir, WstrWorkingDir);

  bool ret;
  SHELLEXECUTEINFOW ShExecInfo = {0};
  ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
  ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
  ShExecInfo.hwnd = NULL;
  ShExecInfo.lpVerb = NULL;
  ShExecInfo.lpFile = WstrExe.c_str();
  ShExecInfo.lpParameters = WstrParams.c_str();
  ShExecInfo.lpDirectory = WstrWorkingDir.c_str();
  ShExecInfo.nShow = SW_SHOW;
  ShExecInfo.hInstApp = NULL;

  g_windowHelper.StopThread();

  LockSetForegroundWindow(LSFW_UNLOCK);
  ShowWindow(g_hWnd,SW_MINIMIZE);
  ret = ShellExecuteExW(&ShExecInfo) == TRUE;
  g_windowHelper.SetHANDLE(ShExecInfo.hProcess);

  // ShellExecute doesn't return the window of the started process
  // we need to gather it from somewhere to allow switch back to XBMC
  // when a program is minimized instead of stopped.
  //g_windowHelper.SetHWND(ShExecInfo.hwnd);
  g_windowHelper.Create();

  if(bWaitForScriptExit)
  {
    // Todo: Pause music and video playback
    WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
  }

  return ret;
}
Esempio n. 29
0
void CButtonTranslator::MapWindowActions(TiXmlNode *pWindow, int windowID)
{
  if (!pWindow || windowID == WINDOW_INVALID) 
    return;

  TiXmlNode* pDevice;

  const char* types[] = {"gamepad", "remote", "universalremote", "keyboard", "mouse", "appcommand", NULL};
  for (int i = 0; types[i]; ++i)
  {
    CStdString type(types[i]);
    if (HasDeviceType(pWindow, type))
    {
      pDevice = pWindow->FirstChild(type);
      TiXmlElement *pDeviceElement = pDevice->ToElement();
      //check if exists, if not use "default"
      CStdString deviceName = pDeviceElement->Attribute("name");
      if (deviceName.empty())
        deviceName = "default";

      std::map<CStdString, std::map<int, buttonMap> >::iterator deviceMapIt = deviceMappings.find(deviceName);
      if (deviceMapIt == deviceMappings.end())
      {
        //First time encountering this device, lets initialise the buttonMap for it.
        deviceMapIt = deviceMappings.insert(pair<CStdString, std::map<int, buttonMap> >(deviceName, std::map<int, buttonMap>())).first;
      }
      
      std::map<int, buttonMap>::iterator windowIt = deviceMapIt->second.find(windowID);
      if (windowIt == deviceMapIt->second.end())
      {
        //add it now
        windowIt = deviceMapIt->second.insert(pair<int, buttonMap>(windowID, buttonMap())).first;
      }
      buttonMap& windowMap = windowIt->second;

      TiXmlElement *pButton = pDevice->FirstChildElement();

      while (pButton)
      {
        uint32_t buttonCode=0;
        if (type == "gamepad")
            buttonCode = TranslateGamepadString(pButton->Value());
        else if (type == "remote")
            buttonCode = TranslateRemoteString(pButton->Value());
        else if (type == "universalremote")
            buttonCode = TranslateUniversalRemoteString(pButton->Value());
        else if (type == "keyboard")
            buttonCode = TranslateKeyboardButton(pButton);
        else if (type == "mouse")
            buttonCode = TranslateMouseCommand(pButton->Value());
        else if (type == "appcommand")
            buttonCode = TranslateAppCommand(pButton->Value());

        if (buttonCode && pButton->FirstChild())
          MapAction(buttonCode, pButton->FirstChild()->Value(), windowMap);
        pButton = pButton->NextSiblingElement();
      }
    }
  }

#if defined(HAS_SDL_JOYSTICK) || defined(HAS_EVENT_SERVER)
  if ((pDevice = pWindow->FirstChild("joystick")) != NULL)
  {
    // map joystick actions
    while (pDevice)
    {
      MapJoystickActions(windowID, pDevice);
      pDevice = pDevice->NextSibling("joystick");
    }
  }
#endif
}
Esempio n. 30
0
LRESULT CALLBACK CWinEventsWin32::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  XBMC_Event newEvent;
  ZeroMemory(&newEvent, sizeof(newEvent));
  static HDEVNOTIFY hDeviceNotify;

  if (uMsg == WM_CREATE)
  {
    g_hWnd = hWnd;
    SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)(((LPCREATESTRUCT)lParam)->lpCreateParams));
    DIB_InitOSKeymap();
    g_uQueryCancelAutoPlay = RegisterWindowMessage(TEXT("QueryCancelAutoPlay"));
    shcne.pidl = NULL;
    shcne.fRecursive = TRUE;
    long fEvents = SHCNE_DRIVEADD | SHCNE_DRIVEREMOVED | SHCNE_MEDIAREMOVED | SHCNE_MEDIAINSERTED;
    SHChangeNotifyRegister(hWnd, SHCNRF_ShellLevel | SHCNRF_NewDelivery, fEvents, WM_MEDIA_CHANGE, 1, &shcne);
    RegisterDeviceInterfaceToHwnd(USB_HID_GUID, hWnd, &hDeviceNotify);
    return 0;
  }

  if (uMsg == WM_DESTROY)
    g_hWnd = NULL;

  m_pEventFunc = (PHANDLE_EVENT_FUNC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  if (!m_pEventFunc)
    return DefWindowProc(hWnd, uMsg, wParam, lParam);

  if(g_uQueryCancelAutoPlay != 0 && uMsg == g_uQueryCancelAutoPlay)
    return S_FALSE;

  switch (uMsg)
  {
    case WM_CLOSE:
    case WM_QUIT:
    case WM_DESTROY:
      if (hDeviceNotify)
        UnregisterDeviceNotification(hDeviceNotify);
      newEvent.type = XBMC_QUIT;
      m_pEventFunc(newEvent);
      break;
    case WM_SHOWWINDOW:
      {
        bool active = g_application.GetRenderGUI();
        g_application.SetRenderGUI(wParam != 0);
        if (g_application.GetRenderGUI() != active)
          g_Windowing.NotifyAppActiveChange(g_application.GetRenderGUI());
        CLog::Log(LOGDEBUG, __FUNCTION__"Window is %s", g_application.GetRenderGUI() ? "shown" : "hidden");
      }
      break;
    case WM_ACTIVATE:
      {
        if( WA_INACTIVE != wParam )
          g_Joystick.Reinitialize();

        bool active = g_application.GetRenderGUI();
        if (HIWORD(wParam))
        {
          g_application.SetRenderGUI(false);
        }
        else
        {
          WINDOWPLACEMENT lpwndpl;
          lpwndpl.length = sizeof(lpwndpl);
          if (LOWORD(wParam) != WA_INACTIVE)
          {
            if (GetWindowPlacement(hWnd, &lpwndpl))
              g_application.SetRenderGUI(lpwndpl.showCmd != SW_HIDE);
          }
          else
          {
            g_application.SetRenderGUI(g_Windowing.WindowedMode());
          }
        }
        if (g_application.GetRenderGUI() != active)
          g_Windowing.NotifyAppActiveChange(g_application.GetRenderGUI());
        CLog::Log(LOGDEBUG, __FUNCTION__"Window is %s", g_application.GetRenderGUI() ? "active" : "inactive");
      }
      break;
    case WM_SETFOCUS:
    case WM_KILLFOCUS:
      g_application.m_AppFocused = uMsg == WM_SETFOCUS;
      g_Windowing.NotifyAppFocusChange(g_application.m_AppFocused);
      if (uMsg == WM_KILLFOCUS)
      {
        CStdString procfile;
        if (CWIN32Util::GetFocussedProcess(procfile))
          CLog::Log(LOGDEBUG, __FUNCTION__": Focus switched to process %s", procfile.c_str());
      }
      break;
    /* needs to be reviewed after frodo. we reset the system idle timer
       and the display timer directly now (see m_screenSaverTimer).
    case WM_SYSCOMMAND:
      switch( wParam&0xFFF0 )
      {
        case SC_MONITORPOWER:
          if (g_application.IsPlaying() || g_application.IsPaused())
            return 0;
          else if(CSettings::Get().GetInt("powermanagement.displaysoff") == 0)
            return 0;
          break;
        case SC_SCREENSAVE:
          return 0;
      }
      break;*/
    case WM_SYSKEYDOWN:
      switch (wParam)
      {
        case VK_F4: //alt-f4, default event quit.
          return(DefWindowProc(hWnd, uMsg, wParam, lParam));
        case VK_RETURN: //alt-return
          if ((lParam & REPEATED_KEYMASK) == 0)
            g_graphicsContext.ToggleFullScreenRoot();
          return 0;
      }
      //deliberate fallthrough
    case WM_KEYDOWN:
    {
      switch (wParam)
      {
        case VK_V:
          if(GetKeyState(VK_CONTROL) & 0x8000)
          {
            // CTRL+V
            if(OpenClipboard(NULL))
            {
              CStdString strtext;
              HANDLE htext = GetClipboardData(CF_UNICODETEXT);
              CStdStringW strwtext = (WCHAR*)htext;
              g_charsetConverter.wToUTF8(strwtext, strtext);
              if(!strtext.empty())
              {
                CGUIMessage msg(GUI_MSG_INPUT_TEXT, 0, 0);
                msg.SetLabel(strtext);
                g_windowManager.SendMessage(msg, g_windowManager.GetFocusedWindow());
              }
              CloseClipboard();
              return(0);
            }
          }
          break;
        case VK_CONTROL:
          if ( lParam & EXTENDED_KEYMASK )
            wParam = VK_RCONTROL;
          else
            wParam = VK_LCONTROL;
          break;
        case VK_SHIFT:
          /* EXTENDED trick doesn't work here */
          if (GetKeyState(VK_LSHIFT) & 0x8000)
            wParam = VK_LSHIFT;
          else if (GetKeyState(VK_RSHIFT) & 0x8000)
            wParam = VK_RSHIFT;
          break;
        case VK_MENU:
          if ( lParam & EXTENDED_KEYMASK )
            wParam = VK_RMENU;
          else
            wParam = VK_LMENU;
          break;
      }
      XBMC_keysym keysym;
      TranslateKey(wParam, HIWORD(lParam), &keysym, 1);

      newEvent.type = XBMC_KEYDOWN;
      newEvent.key.keysym = keysym;
      m_pEventFunc(newEvent);
    }
    return(0);

    case WM_SYSKEYUP:
    case WM_KEYUP:
      {
      switch (wParam)
      {
        case VK_CONTROL:
          if ( lParam&EXTENDED_KEYMASK )
            wParam = VK_RCONTROL;
          else
            wParam = VK_LCONTROL;
          break;
        case VK_SHIFT:
          {
            uint32_t scanCodeL = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
            uint32_t scanCodeR = MapVirtualKey(VK_RSHIFT, MAPVK_VK_TO_VSC);
            uint32_t keyCode = (uint32_t)((lParam & 0xFF0000) >> 16);
            if (keyCode == scanCodeL)
              wParam = VK_LSHIFT;
            else if (keyCode == scanCodeR)
              wParam = VK_RSHIFT;
          }
          break;
        case VK_MENU:
          if ( lParam&EXTENDED_KEYMASK )
            wParam = VK_RMENU;
          else
            wParam = VK_LMENU;
          break;
      }
      XBMC_keysym keysym;
      TranslateKey(wParam, HIWORD(lParam), &keysym, 1);

      if (wParam == VK_SNAPSHOT)
        newEvent.type = XBMC_KEYDOWN;
      else
        newEvent.type = XBMC_KEYUP;
      newEvent.key.keysym = keysym;
      m_pEventFunc(newEvent);
    }
    return(0);
    case WM_APPCOMMAND: // MULTIMEDIA keys are mapped to APPCOMMANDS
    {
      CLog::Log(LOGDEBUG, "WinEventsWin32.cpp: APPCOMMAND %d", GET_APPCOMMAND_LPARAM(lParam));
      newEvent.appcommand.type = XBMC_APPCOMMAND;
      newEvent.appcommand.action = GET_APPCOMMAND_LPARAM(lParam);
      if (m_pEventFunc(newEvent))
        return TRUE;
      else
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    case WM_GESTURENOTIFY:
    {
      OnGestureNotify(hWnd, lParam);
      return DefWindowProc(hWnd, WM_GESTURENOTIFY, wParam, lParam);
    }
    case WM_GESTURE:
    {
      OnGesture(hWnd, lParam);
      return 0;
    }
    case WM_SYSCHAR:
      if (wParam == VK_RETURN) //stop system beep on alt-return
        return 0;
      break;
    case WM_SETCURSOR:
      if (HTCLIENT != LOWORD(lParam))
        g_Windowing.ShowOSMouse(true);
      break;
    case WM_MOUSEMOVE:
      newEvent.type = XBMC_MOUSEMOTION;
      newEvent.motion.x = GET_X_LPARAM(lParam);
      newEvent.motion.y = GET_Y_LPARAM(lParam);
      newEvent.motion.state = 0;
      m_pEventFunc(newEvent);
      return(0);
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
      newEvent.type = XBMC_MOUSEBUTTONDOWN;
      newEvent.button.state = XBMC_PRESSED;
      newEvent.button.x = GET_X_LPARAM(lParam);
      newEvent.button.y = GET_Y_LPARAM(lParam);
      newEvent.button.button = 0;
      if (uMsg == WM_LBUTTONDOWN) newEvent.button.button = XBMC_BUTTON_LEFT;
      else if (uMsg == WM_MBUTTONDOWN) newEvent.button.button = XBMC_BUTTON_MIDDLE;
      else if (uMsg == WM_RBUTTONDOWN) newEvent.button.button = XBMC_BUTTON_RIGHT;
      m_pEventFunc(newEvent);
      return(0);
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
      newEvent.type = XBMC_MOUSEBUTTONUP;
      newEvent.button.state = XBMC_RELEASED;
      newEvent.button.x = GET_X_LPARAM(lParam);
      newEvent.button.y = GET_Y_LPARAM(lParam);
      newEvent.button.button = 0;
      if (uMsg == WM_LBUTTONUP) newEvent.button.button = XBMC_BUTTON_LEFT;
      else if (uMsg == WM_MBUTTONUP) newEvent.button.button = XBMC_BUTTON_MIDDLE;
      else if (uMsg == WM_RBUTTONUP) newEvent.button.button = XBMC_BUTTON_RIGHT;
      m_pEventFunc(newEvent);
      return(0);
    case WM_MOUSEWHEEL:
      {
        // SDL, which our events system is based off, sends a MOUSEBUTTONDOWN message
        // followed by a MOUSEBUTTONUP message.  As this is a momentary event, we just
        // react on the MOUSEBUTTONUP message, resetting the state after processing.
        newEvent.type = XBMC_MOUSEBUTTONDOWN;
        newEvent.button.state = XBMC_PRESSED;
        // the coordinates in WM_MOUSEWHEEL are screen, not client coordinates
        POINT point;
        point.x = GET_X_LPARAM(lParam);
        point.y = GET_Y_LPARAM(lParam);
        WindowFromScreenCoords(hWnd, &point);
        newEvent.button.x = (uint16_t)point.x;
        newEvent.button.y = (uint16_t)point.y;
        newEvent.button.button = GET_Y_LPARAM(wParam) > 0 ? XBMC_BUTTON_WHEELUP : XBMC_BUTTON_WHEELDOWN;
        m_pEventFunc(newEvent);
        newEvent.type = XBMC_MOUSEBUTTONUP;
        newEvent.button.state = XBMC_RELEASED;
        m_pEventFunc(newEvent);
      }
      return(0);
    case WM_SIZE:
      newEvent.type = XBMC_VIDEORESIZE;
      newEvent.resize.w = GET_X_LPARAM(lParam);
      newEvent.resize.h = GET_Y_LPARAM(lParam);

      CLog::Log(LOGDEBUG, __FUNCTION__": window resize event");

      if (!g_Windowing.IsAlteringWindow() && newEvent.resize.w > 0 && newEvent.resize.h > 0)
        m_pEventFunc(newEvent);

      return(0);
    case WM_MOVE:
      newEvent.type = XBMC_VIDEOMOVE;
      newEvent.move.x = GET_X_LPARAM(lParam);
      newEvent.move.y = GET_Y_LPARAM(lParam);

      CLog::Log(LOGDEBUG, __FUNCTION__": window move event");

      if (!g_Windowing.IsAlteringWindow())
        m_pEventFunc(newEvent);

      return(0);
    case WM_MEDIA_CHANGE:
      {
        // This event detects media changes of usb, sd card and optical media.
        // It only works if the explorer.exe process is started. Because this
        // isn't the case for all setups we use WM_DEVICECHANGE for usb and 
        // optical media because this event is also triggered without the 
        // explorer process. Since WM_DEVICECHANGE doesn't detect sd card changes
        // we still use this event only for sd.
        long lEvent;
        PIDLIST_ABSOLUTE *ppidl;
        HANDLE hLock = SHChangeNotification_Lock((HANDLE)wParam, (DWORD)lParam, &ppidl, &lEvent);

        if (hLock)
        {
          char drivePath[MAX_PATH+1];
          if (!SHGetPathFromIDList(ppidl[0], drivePath))
            break;

          switch(lEvent)
          {
            case SHCNE_DRIVEADD:
            case SHCNE_MEDIAINSERTED:
              if (GetDriveType(drivePath) != DRIVE_CDROM)
              {
                CLog::Log(LOGDEBUG, __FUNCTION__": Drive %s Media has arrived.", drivePath);
                CWin32StorageProvider::SetEvent();
              }
              break;

            case SHCNE_DRIVEREMOVED:
            case SHCNE_MEDIAREMOVED:
              if (GetDriveType(drivePath) != DRIVE_CDROM)
              {
                CLog::Log(LOGDEBUG, __FUNCTION__": Drive %s Media was removed.", drivePath);
                CWin32StorageProvider::SetEvent();
              }
              break;
          }
          SHChangeNotification_Unlock(hLock);
        }
        break;
      }
    case WM_POWERBROADCAST:
      if (wParam==PBT_APMSUSPEND)
      {
        CLog::Log(LOGDEBUG,"WM_POWERBROADCAST: PBT_APMSUSPEND event was sent");
        CWin32PowerSyscall::SetOnSuspend();
      }
      else if(wParam==PBT_APMRESUMEAUTOMATIC)
      {
        CLog::Log(LOGDEBUG,"WM_POWERBROADCAST: PBT_APMRESUMEAUTOMATIC event was sent");
        CWin32PowerSyscall::SetOnResume();
      }
      break;
    case WM_DEVICECHANGE:
      {
        switch(wParam)
        {
          case DBT_DEVNODES_CHANGED:
            g_peripherals.TriggerDeviceScan(PERIPHERAL_BUS_USB);
            break;
          case DBT_DEVICEARRIVAL:
          case DBT_DEVICEREMOVECOMPLETE:
            if (((_DEV_BROADCAST_HEADER*) lParam)->dbcd_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
            {
              g_peripherals.TriggerDeviceScan(PERIPHERAL_BUS_USB);
              g_Joystick.Reinitialize();
            }
            // check if an usb or optical media was inserted or removed
            if (((_DEV_BROADCAST_HEADER*) lParam)->dbcd_devicetype == DBT_DEVTYP_VOLUME)
            {
              PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)((_DEV_BROADCAST_HEADER*) lParam);
              // optical medium
              if (lpdbv -> dbcv_flags & DBTF_MEDIA)
              {
                CStdString strdrive;
                strdrive.Format("%c:\\", CWIN32Util::FirstDriveFromMask(lpdbv ->dbcv_unitmask));
                if(wParam == DBT_DEVICEARRIVAL)
                {
                  CLog::Log(LOGDEBUG, __FUNCTION__": Drive %s Media has arrived.", strdrive.c_str());
                  CJobManager::GetInstance().AddJob(new CDetectDisc(strdrive, true), NULL);
                }
                else
                {
                  CLog::Log(LOGDEBUG, __FUNCTION__": Drive %s Media was removed.", strdrive.c_str());
                  CMediaSource share;
                  share.strPath = strdrive;
                  share.strName = share.strPath;
                  g_mediaManager.RemoveAutoSource(share);
                }
              }
              else
                CWin32StorageProvider::SetEvent();
            }
        }
        break;
      }
    case WM_PAINT:
      //some other app has painted over our window, mark everything as dirty
      g_windowManager.MarkDirty();
      break;
    case BONJOUR_EVENT:
      CZeroconf::GetInstance()->ProcessResults();
      break;
    case BONJOUR_BROWSER_EVENT:
      CZeroconfBrowser::GetInstance()->ProcessResults();
      break;
  }
  return(DefWindowProc(hWnd, uMsg, wParam, lParam));
}