Merge pull request #704 from Quentangle/default_season_attribute
authorjmarshallnz <jcmarsha@gmail.com>
Fri, 30 Mar 2012 03:38:17 +0000 (20:38 -0700)
committerjmarshallnz <jcmarsha@gmail.com>
Fri, 30 Mar 2012 03:38:17 +0000 (20:38 -0700)
Add defaultseason attribute to TV Show regex

616 files changed:
Makefile.in
XBMC-ATV2.xcodeproj/project.pbxproj
XBMC-IOS.xcodeproj/project.pbxproj
XBMC.xcodeproj/project.pbxproj
addons/metadata.common.themoviedb.org/addon.xml
addons/metadata.common.themoviedb.org/tmdb.xml
addons/metadata.themoviedb.org/resources/language/Chinese (Simple)/strings.xml
addons/metadata.themoviedb.org/resources/language/Dutch/strings.xml
addons/metadata.themoviedb.org/resources/language/English/strings.xml
addons/metadata.themoviedb.org/resources/language/Finnish/strings.xml
addons/metadata.themoviedb.org/resources/language/German/strings.xml
addons/metadata.themoviedb.org/resources/language/Hungarian/strings.xml
addons/metadata.themoviedb.org/resources/language/Swedish/strings.xml
addons/repository.xbmc.org/addon.xml
addons/screensaver.rsxs.euphoria/addon.xml
addons/screensaver.rsxs.plasma/addon.xml
addons/screensaver.rsxs.solarwinds/addon.xml
addons/screensaver.xbmc.builtin.dim/resources/language/Romanian/strings.xml [new file with mode: 0644]
addons/screensaver.xbmc.builtin.slideshow/resources/language/Romanian/strings.xml [new file with mode: 0644]
addons/skin.confluence/720p/Home.xml
addons/skin.confluence/720p/IncludesCodecFlagging.xml
addons/skin.confluence/720p/IncludesHomeMenuItems.xml
addons/skin.confluence/720p/IncludesHomeRecentlyAdded.xml
addons/skin.confluence/720p/Settings.xml
addons/skin.confluence/720p/custom_SkinSetting_1111.xml
addons/skin.confluence/backgrounds/network.jpg [deleted file]
addons/skin.confluence/backgrounds/services.jpg [new file with mode: 0644]
addons/skin.confluence/language/Czech/strings.xml
addons/skin.confluence/language/English/strings.xml
addons/skin.confluence/language/German/strings.xml
addons/skin.confluence/language/Greek/strings.xml
addons/skin.confluence/language/Korean/strings.xml
addons/skin.confluence/language/Lithuanian/strings.xml
addons/skin.confluence/language/Portuguese (Brazil)/strings.xml
addons/skin.confluence/language/Romanian/strings.xml
addons/skin.confluence/media/flagging/audio/vorbis.png [new file with mode: 0644]
addons/skin.touched
addons/visualization.glspectrum/resources/language/Romanian/strings.xml [new file with mode: 0644]
addons/visualization.itunes/addon.xml
addons/visualization.projectm/addon.xml
addons/visualization.projectm/resources/language/Romanian/strings.xml [new file with mode: 0644]
addons/visualization.waveform/addon.xml
addons/weather.wunderground/addon.xml
addons/weather.wunderground/changelog.txt
addons/weather.wunderground/default.py
addons/weather.wunderground/resources/language/Chinese (Simple)/strings.xml
addons/weather.wunderground/resources/language/Dutch/strings.xml [new file with mode: 0644]
addons/webinterface.default/addon.xml
addons/webinterface.default/js/MediaLibrary.js
addons/webinterface.default/js/NowPlayingManager.js
addons/xbmc.addon/addon.xml
addons/xbmc.gui/addon.xml
addons/xbmc.json/addon.xml
configure.in
language/Chinese (Simple)/strings.xml
language/Chinese (Traditional)/strings.xml
language/Czech/strings.xml
language/Dutch/strings.xml
language/English/strings.xml
language/Finnish/strings.xml
language/French/langinfo.xml
language/French/strings.xml
language/German/strings.xml
language/Greek/strings.xml
language/Hebrew/langinfo.xml
language/Hebrew/strings.xml
language/Hungarian/strings.xml
language/Italian/strings.xml
language/Korean/strings.xml
language/Lithuanian/strings.xml
language/Polish/strings.xml
language/Portuguese (Brazil)/strings.xml
language/Romanian/strings.xml
language/Slovenian/strings.xml
language/Turkish/strings.xml
lib/UnrarXLib/os.hpp
lib/boost/uuid/sha1.hpp [new file with mode: 0644]
lib/cximage-6.0/CxImage/ximapng.cpp
lib/cximage-6.0/CxImage/ximapng.h
lib/ffmpeg/libavcodec/x86/h264_qpel_mmx.c
lib/ffmpeg/libavfilter/vf_yadif.c
lib/ffmpeg/libavfilter/x86/yadif_template.c
lib/ffmpeg/libavfilter/yadif.h
lib/ffmpeg/libavformat/matroskadec.c
lib/ffmpeg/patches/0062-fixed-crash-in-ffmpeg-matroskadec-with-some-files-fi.patch [new file with mode: 0644]
lib/ffmpeg/patches/0063-fixed-playing-mpegts-over-rtsp-caused-ffmpeg-to-read.patch [new file with mode: 0644]
lib/ffmpeg/patches/0064-ffmpeg-add-missing-check-for-NULL-pointer.patch [new file with mode: 0644]
lib/ffmpeg/patches/0065-changed-allow-yadif-deinterlacer-to-enable-and-disab.patch [new file with mode: 0644]
lib/ffmpeg/patches/0066-changed-updated-yadif-patch-to-same-as-will-be-appli.patch [new file with mode: 0644]
lib/ffmpeg/patches/0067-changed-updated-dxva-zigzag-workaround-for-ATI-based.patch [new file with mode: 0644]
lib/ffmpeg/patches/0068-fixed-yadif-should-copy-frame-properties-of-second-f.patch [new file with mode: 0644]
lib/ffmpeg/patches/0069-ffmpeg-silence-compiler-warnings.patch [new file with mode: 0644]
lib/ffmpeg/patches/0070-matroskadec-use-correct-compression-parameters-for-c.patch [new file with mode: 0644]
lib/ffmpeg/patches/0071-fixed-Typo.patch [new file with mode: 0644]
lib/ffmpeg/patches/0072-h264-Use-mismatching-frame-numbers-in-fields-to-sync.patch [new file with mode: 0644]
lib/ffmpeg/patches/0073-Don-t-fill-in-frame-gaps-with-copied-refs-after-flus.patch [new file with mode: 0644]
lib/ffmpeg/patches/0074-vaapi-do-not-assert-on-value-read-from-input-bitstre.patch [new file with mode: 0644]
lib/ffmpeg/patches/0075-fixed-playback-from-mmst-urls-would-halt-after-some-.patch [new file with mode: 0644]
lib/ffmpeg/patches/0076-Fix-dvb-subtitle-decoding-when-display-segment-is-mi.patch [new file with mode: 0644]
lib/ffmpeg/patches/0077-Change-yadif-to-not-use-out-of-picture-lines.-Fixes-.patch [new file with mode: 0644]
lib/ffmpeg/patches/0078-fixed-ffmpeg-build-with-gcc-4.7-on-x86.patch [new file with mode: 0644]
lib/libUPnP/Platinum/Source/Core/PltService.cpp
lib/libapetag/is_tag.c
lib/libass/Changelog
lib/libass/configure.ac
lib/libass/libass.pc.in
lib/libass/libass/Makefile.am
lib/libass/libass/ass.c
lib/libass/libass/ass.h
lib/libass/libass/ass_bitmap.c
lib/libass/libass/ass_bitmap.h
lib/libass/libass/ass_cache.c
lib/libass/libass/ass_cache.h
lib/libass/libass/ass_cache_template.h
lib/libass/libass/ass_drawing.c
lib/libass/libass/ass_drawing.h
lib/libass/libass/ass_font.c
lib/libass/libass/ass_font.h
lib/libass/libass/ass_library.c
lib/libass/libass/ass_parse.c
lib/libass/libass/ass_parse.h
lib/libass/libass/ass_render.c
lib/libass/libass/ass_render.h
lib/libass/libass/ass_render_api.c
lib/libass/libass/ass_shaper.c [new file with mode: 0644]
lib/libass/libass/ass_shaper.h [new file with mode: 0644]
lib/libass/libass/ass_types.h
lib/libass/libass/libass.sym
lib/libass/test/Makefile.am
lib/libass/test/test.c
lib/libass/xbmc/libass_win32/libass_win32_vs2010.vcxproj
lib/libcec/Makefile
lib/libdvd/Makefile.in
lib/libdvd/libdvdnav/src/searching.c
lib/libexif/ExifParse.cpp
lib/libexif/IptcParse.cpp
lib/libexif/libexif.h
lib/libid3tag/libid3tag/compat.gperf
lib/libid3tag/libid3tag/compat2.c
lib/libid3tag/libid3tag/metadata.c
media/Splash.png
media/weather.zip
project/BuildDependencies/scripts/boost_d.txt
project/BuildDependencies/scripts/get_mingw_env.bat
project/BuildDependencies/scripts/get_mingw_env.txt
project/BuildDependencies/scripts/libcec_d.bat
project/BuildDependencies/scripts/libcec_d.txt
project/BuildDependencies/scripts/libfribidi_d.txt
project/VS2010Express/XBMC.vcxproj
project/VS2010Express/XBMC.vcxproj.filters
system/keymaps/keyboard.xml
system/peripherals.xml
tools/Linux/FEH.py
tools/Linux/xbmc.desktop
tools/darwin/depends/libcec/Makefile
tools/darwin/depends/xbmc/Makefile
tools/darwin/packaging/xbmc-osx/Makefile
xbmc/Application.cpp
xbmc/Application.h
xbmc/ApplicationMessenger.cpp
xbmc/ApplicationMessenger.h
xbmc/Autorun.cpp
xbmc/FileItem.cpp
xbmc/FileItem.h
xbmc/GUIInfoManager.cpp
xbmc/GUIInfoManager.h
xbmc/GUIPassword.cpp
xbmc/PartyModeManager.cpp
xbmc/SortFileItem.cpp
xbmc/Util.cpp
xbmc/XBDateTime.cpp
xbmc/XBDateTime.h
xbmc/addons/AddonManager.cpp
xbmc/addons/AddonVersion.cpp
xbmc/addons/AddonVersion.h
xbmc/addons/GUIDialogAddonInfo.cpp
xbmc/addons/GUIDialogAddonSettings.cpp
xbmc/addons/GUIWindowAddonBrowser.cpp
xbmc/addons/Scraper.cpp
xbmc/addons/Scraper.h
xbmc/addons/ScreenSaver.cpp
xbmc/addons/Skin.cpp
xbmc/addons/Visualisation.cpp
xbmc/cdrip/CDDARipper.cpp
xbmc/cores/AudioRenderers/ALSADirectSound.cpp
xbmc/cores/AudioRenderers/AudioRendererFactory.cpp
xbmc/cores/AudioRenderers/CoreAudioRenderer.cpp
xbmc/cores/AudioRenderers/CoreAudioRenderer.h
xbmc/cores/AudioRenderers/Win32DirectSound.cpp
xbmc/cores/AudioRenderers/Win32WASAPI.cpp
xbmc/cores/DllLoader/DllLoader.cpp
xbmc/cores/DllLoader/SoLoader.cpp
xbmc/cores/DllLoader/Win32DllLoader.cpp
xbmc/cores/DllLoader/dll.cpp
xbmc/cores/DllLoader/exports/emu_kernel32.cpp
xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
xbmc/cores/DllLoader/exports/emu_socket/emu_socket.h
xbmc/cores/DllLoader/exports/emu_socket/getaddrinfo.c
xbmc/cores/DllLoader/exports/emu_socket/getnameinfo.c
xbmc/cores/ExternalPlayer/ExternalPlayer.cpp
xbmc/cores/VideoRenderers/LinuxRendererGL.cpp
xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
xbmc/cores/VideoRenderers/OverlayRendererGL.cpp
xbmc/cores/VideoRenderers/RenderManager.cpp
xbmc/cores/VideoRenderers/RenderManager.h
xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp
xbmc/cores/VideoRenderers/WinRenderer.cpp
xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlaySpu.h
xbmc/cores/dvdplayer/DVDCodecs/Video/CrystalHD.cpp
xbmc/cores/dvdplayer/DVDCodecs/Video/CrystalHD.h
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVideoToolBox.cpp
xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp
xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h
xbmc/cores/dvdplayer/DVDCodecs/Video/VDPAU.cpp
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
xbmc/cores/dvdplayer/DVDFileInfo.cpp
xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamHttp.cpp
xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamHttp.h
xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamTV.cpp
xbmc/cores/dvdplayer/DVDInputStreams/DVDStateSerializer.cpp
xbmc/cores/dvdplayer/DVDPlayer.cpp
xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
xbmc/cores/dvdplayer/DVDSubtitles/DVDSubtitlesLibass.cpp
xbmc/cores/dvdplayer/Edl.cpp
xbmc/cores/paplayer/CodecFactory.cpp
xbmc/cores/paplayer/Makefile.in
xbmc/cores/paplayer/PCMCodec.cpp [new file with mode: 0644]
xbmc/cores/paplayer/PCMCodec.h [new file with mode: 0644]
xbmc/cores/paplayer/TimidityCodec.cpp
xbmc/cores/playercorefactory/PlayerSelectionRule.cpp
xbmc/cores/playercorefactory/PlayerSelectionRule.h
xbmc/dbwrappers/Database.cpp
xbmc/dbwrappers/mysqldataset.cpp
xbmc/dbwrappers/sqlitedataset.cpp
xbmc/dialogs/GUIDialogMediaSource.cpp
xbmc/dialogs/GUIDialogMediaSource.h
xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp
xbmc/filesystem/AFPDirectory.cpp
xbmc/filesystem/AFPFile.cpp [new file with mode: 0644]
xbmc/filesystem/AFPFile.h [new file with mode: 0644]
xbmc/filesystem/AddonsDirectory.cpp
xbmc/filesystem/CDDAFile.cpp [new file with mode: 0644]
xbmc/filesystem/CDDAFile.h [new file with mode: 0644]
xbmc/filesystem/CacheCircular.cpp [deleted file]
xbmc/filesystem/CacheCircular.h [deleted file]
xbmc/filesystem/CacheMemBuffer.cpp [deleted file]
xbmc/filesystem/CacheMemBuffer.h [deleted file]
xbmc/filesystem/CircularCache.cpp [new file with mode: 0644]
xbmc/filesystem/CircularCache.h [new file with mode: 0644]
xbmc/filesystem/CurlFile.cpp [new file with mode: 0644]
xbmc/filesystem/CurlFile.h [new file with mode: 0644]
xbmc/filesystem/DAAPDirectory.cpp
xbmc/filesystem/DAAPFile.cpp [new file with mode: 0644]
xbmc/filesystem/DAAPFile.h [new file with mode: 0644]
xbmc/filesystem/DAVDirectory.cpp
xbmc/filesystem/Directory.cpp
xbmc/filesystem/DirectoryFactory.cpp [new file with mode: 0644]
xbmc/filesystem/DirectoryFactory.h [new file with mode: 0644]
xbmc/filesystem/DirectoryTuxBox.cpp [deleted file]
xbmc/filesystem/DirectoryTuxBox.h [deleted file]
xbmc/filesystem/FTPDirectory.cpp
xbmc/filesystem/FTPParse.cpp
xbmc/filesystem/FTPParse.h
xbmc/filesystem/FactoryDirectory.cpp [deleted file]
xbmc/filesystem/FactoryDirectory.h [deleted file]
xbmc/filesystem/FactoryFileDirectory.cpp [deleted file]
xbmc/filesystem/FactoryFileDirectory.h [deleted file]
xbmc/filesystem/File.cpp
xbmc/filesystem/File.h
xbmc/filesystem/FileAFP.cpp [deleted file]
xbmc/filesystem/FileAFP.h [deleted file]
xbmc/filesystem/FileCDDA.cpp [deleted file]
xbmc/filesystem/FileCDDA.h [deleted file]
xbmc/filesystem/FileCache.cpp
xbmc/filesystem/FileCache.h
xbmc/filesystem/FileCurl.cpp [deleted file]
xbmc/filesystem/FileCurl.h [deleted file]
xbmc/filesystem/FileDAAP.cpp [deleted file]
xbmc/filesystem/FileDAAP.h [deleted file]
xbmc/filesystem/FileDirectoryFactory.cpp [new file with mode: 0644]
xbmc/filesystem/FileDirectoryFactory.h [new file with mode: 0644]
xbmc/filesystem/FileFactory.cpp
xbmc/filesystem/FileFileReader.cpp [deleted file]
xbmc/filesystem/FileFileReader.h [deleted file]
xbmc/filesystem/FileHD.cpp [deleted file]
xbmc/filesystem/FileHD.h [deleted file]
xbmc/filesystem/FileISO.cpp [deleted file]
xbmc/filesystem/FileISO.h [deleted file]
xbmc/filesystem/FileLastFM.cpp [deleted file]
xbmc/filesystem/FileLastFM.h [deleted file]
xbmc/filesystem/FileMusicDatabase.cpp [deleted file]
xbmc/filesystem/FileMusicDatabase.h [deleted file]
xbmc/filesystem/FileNFS.cpp [deleted file]
xbmc/filesystem/FileNFS.h [deleted file]
xbmc/filesystem/FilePipe.cpp [deleted file]
xbmc/filesystem/FilePipe.h [deleted file]
xbmc/filesystem/FileRTV.cpp [deleted file]
xbmc/filesystem/FileRTV.h [deleted file]
xbmc/filesystem/FileRar.cpp [deleted file]
xbmc/filesystem/FileRar.h [deleted file]
xbmc/filesystem/FileReaderFile.cpp [new file with mode: 0644]
xbmc/filesystem/FileReaderFile.h [new file with mode: 0644]
xbmc/filesystem/FileSFTP.cpp [deleted file]
xbmc/filesystem/FileSFTP.h [deleted file]
xbmc/filesystem/FileShoutcast.cpp [deleted file]
xbmc/filesystem/FileShoutcast.h [deleted file]
xbmc/filesystem/FileSmb.cpp [deleted file]
xbmc/filesystem/FileSmb.h [deleted file]
xbmc/filesystem/FileSpecialProtocol.cpp [deleted file]
xbmc/filesystem/FileSpecialProtocol.h [deleted file]
xbmc/filesystem/FileTuxBox.cpp [deleted file]
xbmc/filesystem/FileTuxBox.h [deleted file]
xbmc/filesystem/FileUDF.cpp [deleted file]
xbmc/filesystem/FileUDF.h [deleted file]
xbmc/filesystem/FileUPnP.cpp [deleted file]
xbmc/filesystem/FileUPnP.h [deleted file]
xbmc/filesystem/FileZip.cpp [deleted file]
xbmc/filesystem/FileZip.h [deleted file]
xbmc/filesystem/HDDirectory.cpp
xbmc/filesystem/HDFile.cpp [new file with mode: 0644]
xbmc/filesystem/HDFile.h [new file with mode: 0644]
xbmc/filesystem/HDHomeRun.cpp [deleted file]
xbmc/filesystem/HDHomeRun.h [deleted file]
xbmc/filesystem/HDHomeRunDirectory.cpp [new file with mode: 0644]
xbmc/filesystem/HDHomeRunDirectory.h [new file with mode: 0644]
xbmc/filesystem/HDHomeRunFile.cpp [new file with mode: 0644]
xbmc/filesystem/HDHomeRunFile.h [new file with mode: 0644]
xbmc/filesystem/HTTPDirectory.cpp
xbmc/filesystem/IDirectory.h
xbmc/filesystem/ISOFile.cpp [new file with mode: 0644]
xbmc/filesystem/ISOFile.h [new file with mode: 0644]
xbmc/filesystem/LastFMDirectory.cpp
xbmc/filesystem/LastFMDirectory.h
xbmc/filesystem/LastFMFile.cpp [new file with mode: 0644]
xbmc/filesystem/LastFMFile.h [new file with mode: 0644]
xbmc/filesystem/Makefile.in
xbmc/filesystem/MemBufferCache.cpp [new file with mode: 0644]
xbmc/filesystem/MemBufferCache.h [new file with mode: 0644]
xbmc/filesystem/MusicDatabaseFile.cpp [new file with mode: 0644]
xbmc/filesystem/MusicDatabaseFile.h [new file with mode: 0644]
xbmc/filesystem/NFSDirectory.h
xbmc/filesystem/NFSFile.cpp [new file with mode: 0644]
xbmc/filesystem/NFSFile.h [new file with mode: 0644]
xbmc/filesystem/PipeFile.cpp [new file with mode: 0644]
xbmc/filesystem/PipeFile.h [new file with mode: 0644]
xbmc/filesystem/RSSDirectory.cpp
xbmc/filesystem/RTVDirectory.cpp
xbmc/filesystem/RTVFile.cpp [new file with mode: 0644]
xbmc/filesystem/RTVFile.h [new file with mode: 0644]
xbmc/filesystem/RarFile.cpp [new file with mode: 0644]
xbmc/filesystem/RarFile.h [new file with mode: 0644]
xbmc/filesystem/RarManager.cpp
xbmc/filesystem/SFTPDirectory.h
xbmc/filesystem/SFTPFile.cpp [new file with mode: 0644]
xbmc/filesystem/SFTPFile.h [new file with mode: 0644]
xbmc/filesystem/SMBDirectory.h
xbmc/filesystem/ShoutcastFile.cpp [new file with mode: 0644]
xbmc/filesystem/ShoutcastFile.h [new file with mode: 0644]
xbmc/filesystem/Slingbox.cpp [deleted file]
xbmc/filesystem/Slingbox.h [deleted file]
xbmc/filesystem/SlingboxDirectory.cpp [new file with mode: 0644]
xbmc/filesystem/SlingboxDirectory.h [new file with mode: 0644]
xbmc/filesystem/SlingboxFile.cpp [new file with mode: 0644]
xbmc/filesystem/SlingboxFile.h [new file with mode: 0644]
xbmc/filesystem/SmartPlaylistDirectory.cpp
xbmc/filesystem/SmbFile.cpp [new file with mode: 0644]
xbmc/filesystem/SmbFile.h [new file with mode: 0644]
xbmc/filesystem/SpecialProtocol.cpp
xbmc/filesystem/SpecialProtocol.h
xbmc/filesystem/SpecialProtocolFile.cpp [new file with mode: 0644]
xbmc/filesystem/SpecialProtocolFile.h [new file with mode: 0644]
xbmc/filesystem/TuxBoxDirectory.cpp [new file with mode: 0644]
xbmc/filesystem/TuxBoxDirectory.h [new file with mode: 0644]
xbmc/filesystem/TuxBoxFile.cpp [new file with mode: 0644]
xbmc/filesystem/TuxBoxFile.h [new file with mode: 0644]
xbmc/filesystem/UDFFile.cpp [new file with mode: 0644]
xbmc/filesystem/UDFFile.h [new file with mode: 0644]
xbmc/filesystem/UPnPFile.cpp [new file with mode: 0644]
xbmc/filesystem/UPnPFile.h [new file with mode: 0644]
xbmc/filesystem/VirtualDirectory.cpp
xbmc/filesystem/ZipFile.cpp [new file with mode: 0644]
xbmc/filesystem/ZipFile.h [new file with mode: 0644]
xbmc/filesystem/iso9660.cpp
xbmc/filesystem/windows/WINFileSMB.cpp [new file with mode: 0644]
xbmc/filesystem/windows/WINFileSMB.h [new file with mode: 0644]
xbmc/filesystem/windows/WINSMBDirectory.cpp [new file with mode: 0644]
xbmc/filesystem/windows/WINSMBDirectory.h [new file with mode: 0644]
xbmc/guilib/AnimatedGif.cpp
xbmc/guilib/GUIAction.cpp
xbmc/guilib/GUIAction.h
xbmc/guilib/GUIBaseContainer.cpp
xbmc/guilib/GUIColorManager.cpp
xbmc/guilib/GUIControl.cpp
xbmc/guilib/GUIControl.h
xbmc/guilib/GUIControlFactory.cpp
xbmc/guilib/GUIControlGroupList.cpp
xbmc/guilib/GUIFontManager.cpp
xbmc/guilib/GUIFontTTF.cpp
xbmc/guilib/GUIMessage.h
xbmc/guilib/GUIRenderingControl.cpp
xbmc/guilib/GUISound.cpp
xbmc/guilib/GUIStaticItem.h
xbmc/guilib/GUIVisualisationControl.cpp
xbmc/guilib/GUIVisualisationControl.h
xbmc/guilib/GUIWindow.cpp
xbmc/guilib/Key.cpp
xbmc/guilib/Key.h
xbmc/guilib/LocalizeStrings.cpp
xbmc/guilib/MatrixGLES.cpp
xbmc/guilib/MatrixGLES.h
xbmc/guilib/Shader.cpp
xbmc/guilib/TextureBundleXBT.cpp
xbmc/guilib/TextureBundleXPR.cpp
xbmc/guilib/TextureManager.cpp
xbmc/guilib/TextureManager.h
xbmc/guilib/XBTFReader.cpp
xbmc/input/ButtonTranslator.cpp
xbmc/input/ButtonTranslator.h
xbmc/input/InertialScrollingHandler.cpp
xbmc/input/SDLJoystick.cpp
xbmc/input/SDLJoystick.h
xbmc/interfaces/AnnouncementManager.cpp
xbmc/interfaces/AnnouncementManager.h
xbmc/interfaces/AnnouncementUtils.h [deleted file]
xbmc/interfaces/Builtins.cpp
xbmc/interfaces/IAnnouncer.h
xbmc/interfaces/http-api/XBMCConfiguration.cpp
xbmc/interfaces/http-api/XBMChttp.cpp
xbmc/interfaces/json-rpc/ApplicationOperations.cpp
xbmc/interfaces/json-rpc/ApplicationOperations.h
xbmc/interfaces/json-rpc/AudioLibrary.cpp
xbmc/interfaces/json-rpc/AudioLibrary.h
xbmc/interfaces/json-rpc/FileItemHandler.cpp
xbmc/interfaces/json-rpc/FileItemHandler.h
xbmc/interfaces/json-rpc/FileOperations.cpp
xbmc/interfaces/json-rpc/FileOperations.h
xbmc/interfaces/json-rpc/GUIOperations.cpp [new file with mode: 0644]
xbmc/interfaces/json-rpc/GUIOperations.h [new file with mode: 0644]
xbmc/interfaces/json-rpc/IJSONRPCAnnouncer.h [new file with mode: 0644]
xbmc/interfaces/json-rpc/ITransportLayer.h
xbmc/interfaces/json-rpc/InputOperations.cpp
xbmc/interfaces/json-rpc/InputOperations.h
xbmc/interfaces/json-rpc/JSONRPC.cpp
xbmc/interfaces/json-rpc/JSONRPC.h
xbmc/interfaces/json-rpc/JSONRPCUtils.h [new file with mode: 0644]
xbmc/interfaces/json-rpc/JSONServiceDescription.cpp
xbmc/interfaces/json-rpc/JSONServiceDescription.h
xbmc/interfaces/json-rpc/JSONUtils.h
xbmc/interfaces/json-rpc/Makefile
xbmc/interfaces/json-rpc/PlayerOperations.cpp
xbmc/interfaces/json-rpc/PlayerOperations.h
xbmc/interfaces/json-rpc/PlaylistOperations.cpp
xbmc/interfaces/json-rpc/PlaylistOperations.h
xbmc/interfaces/json-rpc/ServiceDescription.h
xbmc/interfaces/json-rpc/SystemOperations.cpp
xbmc/interfaces/json-rpc/SystemOperations.h
xbmc/interfaces/json-rpc/VideoLibrary.cpp
xbmc/interfaces/json-rpc/VideoLibrary.h
xbmc/interfaces/json-rpc/XBMCOperations.cpp
xbmc/interfaces/json-rpc/XBMCOperations.h
xbmc/interfaces/json-rpc/methods.json
xbmc/interfaces/json-rpc/notifications.json
xbmc/interfaces/json-rpc/types.json
xbmc/interfaces/python/XBPyThread.cpp
xbmc/interfaces/python/XBPython.cpp
xbmc/interfaces/python/xbmcmodule/dialog.cpp
xbmc/interfaces/python/xbmcmodule/listitem.cpp
xbmc/interfaces/python/xbmcmodule/window.cpp
xbmc/interfaces/python/xbmcmodule/window.h
xbmc/interfaces/python/xbmcmodule/winxml.cpp
xbmc/interfaces/python/xbmcmodule/winxmldialog.cpp
xbmc/interfaces/python/xbmcmodule/xbmcmodule.cpp
xbmc/linux/ConvUtils.cpp
xbmc/linux/ConvUtils.h
xbmc/linux/HALManager.cpp
xbmc/linux/PlatformDefs.h
xbmc/linux/XFileUtils.cpp
xbmc/music/LastFmManager.cpp
xbmc/music/dialogs/GUIDialogSongInfo.cpp
xbmc/music/infoscanner/MusicAlbumInfo.cpp
xbmc/music/infoscanner/MusicAlbumInfo.h
xbmc/music/infoscanner/MusicArtistInfo.cpp
xbmc/music/infoscanner/MusicArtistInfo.h
xbmc/music/infoscanner/MusicInfoScraper.h
xbmc/music/karaoke/GUIWindowKaraokeLyrics.cpp
xbmc/music/karaoke/karaokelyricscdg.cpp
xbmc/music/tags/MusicInfoTagLoaderMod.cpp
xbmc/music/windows/GUIWindowMusicBase.cpp
xbmc/music/windows/GUIWindowMusicNav.cpp
xbmc/network/AirPlayServer.cpp
xbmc/network/AirTunesServer.cpp
xbmc/network/AirTunesServer.h
xbmc/network/EventPacket.cpp
xbmc/network/TCPServer.cpp
xbmc/network/TCPServer.h
xbmc/network/UPnP.cpp
xbmc/network/WebServer.cpp
xbmc/network/WebServer.h
xbmc/network/cddb.cpp
xbmc/network/httprequesthandler/HTTPApiHandler.cpp [new file with mode: 0644]
xbmc/network/httprequesthandler/HTTPApiHandler.h [new file with mode: 0644]
xbmc/network/httprequesthandler/HTTPJsonRpcHandler.cpp [new file with mode: 0644]
xbmc/network/httprequesthandler/HTTPJsonRpcHandler.h [new file with mode: 0644]
xbmc/network/httprequesthandler/HTTPVfsHandler.cpp [new file with mode: 0644]
xbmc/network/httprequesthandler/HTTPVfsHandler.h [new file with mode: 0644]
xbmc/network/httprequesthandler/HTTPWebinterfaceAddonsHandler.cpp [new file with mode: 0644]
xbmc/network/httprequesthandler/HTTPWebinterfaceAddonsHandler.h [new file with mode: 0644]
xbmc/network/httprequesthandler/HTTPWebinterfaceHandler.cpp [new file with mode: 0644]
xbmc/network/httprequesthandler/HTTPWebinterfaceHandler.h [new file with mode: 0644]
xbmc/network/httprequesthandler/IHTTPRequestHandler.cpp [new file with mode: 0644]
xbmc/network/httprequesthandler/IHTTPRequestHandler.h [new file with mode: 0644]
xbmc/network/httprequesthandler/Makefile [new file with mode: 0644]
xbmc/network/libscrobbler/scrobbler.cpp
xbmc/network/libscrobbler/scrobbler.h
xbmc/network/linux/NetworkLinux.cpp
xbmc/network/websocket/Makefile [new file with mode: 0644]
xbmc/network/websocket/WebSocket.cpp [new file with mode: 0644]
xbmc/network/websocket/WebSocket.h [new file with mode: 0644]
xbmc/network/websocket/WebSocketManager.cpp [new file with mode: 0644]
xbmc/network/websocket/WebSocketManager.h [new file with mode: 0644]
xbmc/network/websocket/WebSocketV13.cpp [new file with mode: 0644]
xbmc/network/websocket/WebSocketV13.h [new file with mode: 0644]
xbmc/network/websocket/WebSocketV8.cpp [new file with mode: 0644]
xbmc/network/websocket/WebSocketV8.h [new file with mode: 0644]
xbmc/osx/CocoaInterface.mm
xbmc/osx/CoreAudio.cpp
xbmc/osx/CoreAudio.h
xbmc/osx/atv2/XBMCController.mm
xbmc/osx/ios/XBMCController.h
xbmc/osx/ios/XBMCController.mm
xbmc/osx/ios/XBMCEAGLView.mm
xbmc/peripherals/Peripherals.cpp
xbmc/peripherals/Peripherals.h
xbmc/peripherals/devices/Peripheral.cpp
xbmc/peripherals/devices/Peripheral.h
xbmc/peripherals/devices/PeripheralCecAdapter.cpp
xbmc/peripherals/devices/PeripheralCecAdapter.h
xbmc/peripherals/devices/PeripheralHID.cpp
xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp
xbmc/pictures/GUIWindowPictures.cpp
xbmc/pictures/GUIWindowSlideShow.cpp
xbmc/pictures/Picture.cpp
xbmc/pictures/PictureInfoTag.cpp
xbmc/playlists/SmartPlayList.cpp
xbmc/playlists/SmartPlayList.h
xbmc/settings/AdvancedSettings.cpp
xbmc/settings/AdvancedSettings.h
xbmc/settings/GUISettings.cpp
xbmc/settings/GUISettings.h
xbmc/settings/GUIWindowSettingsCategory.cpp
xbmc/settings/Settings.cpp
xbmc/storage/DetectDVDType.cpp
xbmc/storage/DetectDVDType.h
xbmc/storage/IoSupport.cpp
xbmc/storage/IoSupport.h
xbmc/storage/MediaManager.cpp
xbmc/storage/windows/Win32StorageProvider.cpp
xbmc/storage/windows/Win32StorageProvider.h
xbmc/system.h
xbmc/threads/platform/pthreads/Condition.h
xbmc/utils/AlarmClock.cpp
xbmc/utils/Base64.cpp [new file with mode: 0644]
xbmc/utils/Base64.h [new file with mode: 0644]
xbmc/utils/DownloadQueue.cpp
xbmc/utils/EndianSwap.h
xbmc/utils/Fanart.cpp
xbmc/utils/FileOperationJob.cpp
xbmc/utils/GLUtils.cpp
xbmc/utils/GLUtils.h
xbmc/utils/HttpResponse.cpp [new file with mode: 0644]
xbmc/utils/HttpResponse.h [new file with mode: 0644]
xbmc/utils/JobManager.cpp
xbmc/utils/LCDFactory.cpp
xbmc/utils/Makefile
xbmc/utils/Mime.cpp [new file with mode: 0644]
xbmc/utils/Mime.h [new file with mode: 0644]
xbmc/utils/RecentlyAddedJob.cpp
xbmc/utils/RssReader.cpp
xbmc/utils/ScraperUrl.cpp
xbmc/utils/ScraperUrl.h
xbmc/utils/SystemInfo.cpp
xbmc/utils/TuxBoxUtil.cpp
xbmc/utils/URIUtils.cpp
xbmc/utils/Weather.cpp
xbmc/utils/XMLUtils.cpp
xbmc/utils/XMLUtils.h
xbmc/utils/fastmemcpy-arm.S
xbmc/video/GUIViewStateVideo.cpp
xbmc/video/Teletext.cpp
xbmc/video/VideoDatabase.cpp
xbmc/video/VideoDatabase.h
xbmc/video/VideoInfoDownloader.h
xbmc/video/VideoInfoScanner.cpp
xbmc/video/VideoInfoTag.cpp
xbmc/video/VideoInfoTag.h
xbmc/video/VideoReferenceClock.cpp
xbmc/video/dialogs/GUIDialogTeletext.cpp
xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp
xbmc/video/windows/GUIWindowFullScreen.cpp
xbmc/video/windows/GUIWindowVideoBase.cpp
xbmc/video/windows/GUIWindowVideoBase.h
xbmc/visualizations/OpenGLSpectrum/Makefile.in
xbmc/visualizations/WaveForm/Makefile.in
xbmc/win32/WINFileSMB.cpp [deleted file]
xbmc/win32/WINFileSMB.h [deleted file]
xbmc/win32/WINSMBDirectory.cpp [deleted file]
xbmc/win32/WINSMBDirectory.h [deleted file]
xbmc/windowing/XBMC_events.h
xbmc/windowing/osx/WinEventsIOS.h
xbmc/windowing/osx/WinEventsIOS.mm
xbmc/windowing/windows/WinEventsWin32.cpp
xbmc/windows/GUIMediaWindow.cpp
xbmc/windows/GUIWindowHome.cpp
xbmc/windows/GUIWindowHome.h

index 9d850e4..354ec0b 100755 (executable)
@@ -61,6 +61,8 @@ DIRECTORY_ARCHIVES=$(DVDPLAYER_ARCHIVES) \
                    xbmc/music/tags/musictags.a \
                    xbmc/music/windows/musicwindows.a \
                    xbmc/network/libscrobbler/scrobbler.a \
+                   xbmc/network/httprequesthandler/httprequesthandlers.a \
+                   xbmc/network/websocket/websocket.a \
                    xbmc/network/network.a \
                    xbmc/peripherals/bus/peripheral-bus.a \
                    xbmc/peripherals/devices/peripheral-devices.a \
index 96b2a3f..2acf839 100644 (file)
@@ -8,10 +8,11 @@
 
 /* Begin PBXBuildFile section */
                1830216013B8E35300770920 /* controledit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1830215F13B8E35300770920 /* controledit.cpp */; };
-               18404DFB1396C43B00863BBA /* Slingbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18404DF91396C43B00863BBA /* Slingbox.cpp */; };
                18404DFD1396C44F00863BBA /* SlingboxLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18404DFC1396C44F00863BBA /* SlingboxLib.a */; };
                1840B796139968DB007C848B /* JSONVariantParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1840B792139968DB007C848B /* JSONVariantParser.cpp */; };
                1840B797139968DB007C848B /* JSONVariantWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1840B794139968DB007C848B /* JSONVariantWriter.cpp */; };
+               188F761015221809009870CE /* GUIOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 188F760E15221809009870CE /* GUIOperations.cpp */; };
+               188F76291522186C009870CE /* Mime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 188F76271522186C009870CE /* Mime.cpp */; };
                18968DE814155E1D005BA742 /* ApplicationOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18968DE614155E1D005BA742 /* ApplicationOperations.cpp */; };
                18ACF8E313597B0000B67371 /* RecentlyAddedJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18ACF8E113597B0000B67371 /* RecentlyAddedJob.cpp */; };
                18B7013C13A6ABBA0009C1AF /* AddonVersion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7013A13A6ABBA0009C1AF /* AddonVersion.cpp */; };
                7C0A7FC913A9E75400AFC2BD /* DirtyRegionTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7FC613A9E75400AFC2BD /* DirtyRegionTracker.cpp */; };
                7C0A7FCC13A9E76E00AFC2BD /* GUIWindowDebugInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7FCA13A9E76E00AFC2BD /* GUIWindowDebugInfo.cpp */; };
                7C89627013B702F3003631FE /* GUIWindowScreensaverDim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C89626E13B702F3003631FE /* GUIWindowScreensaverDim.cpp */; };
-               7C99B73F133D372300FC2B16 /* CacheCircular.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B73D133D372300FC2B16 /* CacheCircular.cpp */; };
                7C99B7AA134072CD00FC2B16 /* GUIDialogPlayEject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B7A8134072CD00FC2B16 /* GUIDialogPlayEject.cpp */; };
+               7CCFD9AA1514952700211D82 /* PCMCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCFD9A81514952700211D82 /* PCMCodec.cpp */; };
                7CEE2E6D13D6B7A8000ABF2A /* TimeSmoother.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEE2E6B13D6B7A8000ABF2A /* TimeSmoother.cpp */; };
                C807119F135DB842002F601B /* InputOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C807119D135DB842002F601B /* InputOperations.cpp */; };
                C8EC5D51136954E400CCC10D /* XBMC_keytable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C8EC5D4F136954E400CCC10D /* XBMC_keytable.cpp */; };
-               DF0DF16C13A3AF82008ED511 /* FileNFS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0DF16813A3AF82008ED511 /* FileNFS.cpp */; };
                DF0DF16D13A3AF82008ED511 /* NFSDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0DF16A13A3AF82008ED511 /* NFSDirectory.cpp */; };
                DF34890913FD96390026A711 /* GUIAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF34890713FD96390026A711 /* GUIAction.cpp */; };
                DF44852F140064F40069344B /* BXAcodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF44852D140064F40069344B /* BXAcodec.cpp */; };
-               DF4485341400651B0069344B /* FilePipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4485301400651B0069344B /* FilePipe.cpp */; };
                DF4485351400651B0069344B /* PipesManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4485321400651B0069344B /* PipesManager.cpp */; };
                DF4485381400654A0069344B /* AirTunesServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4485361400654A0069344B /* AirTunesServer.cpp */; };
-               DF673A251443769300A5A509 /* FileUPnP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF673A231443769300A5A509 /* FileUPnP.cpp */; };
+               DF527780151BAFD600B5B63B /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527777151BAFD600B5B63B /* WebSocket.cpp */; };
+               DF527781151BAFD600B5B63B /* WebSocketManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527779151BAFD600B5B63B /* WebSocketManager.cpp */; };
+               DF527782151BAFD600B5B63B /* WebSocketV13.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52777B151BAFD600B5B63B /* WebSocketV13.cpp */; };
+               DF527783151BAFD600B5B63B /* WebSocketV8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52777D151BAFD600B5B63B /* WebSocketV8.cpp */; };
+               DF527788151BAFEE00B5B63B /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527784151BAFEE00B5B63B /* Base64.cpp */; };
+               DF527789151BAFEE00B5B63B /* HttpResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527786151BAFEE00B5B63B /* HttpResponse.cpp */; };
+               DF93D7701444B09C007C6459 /* AFPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7381444B09C007C6459 /* AFPFile.cpp */; };
+               DF93D7731444B09C007C6459 /* CDDAFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D73E1444B09C007C6459 /* CDDAFile.cpp */; };
+               DF93D7741444B09C007C6459 /* CurlFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7401444B09C007C6459 /* CurlFile.cpp */; };
+               DF93D7751444B09C007C6459 /* DAAPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7421444B09C007C6459 /* DAAPFile.cpp */; };
+               DF93D7761444B09C007C6459 /* DirectoryFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7441444B09C007C6459 /* DirectoryFactory.cpp */; };
+               DF93D7771444B09C007C6459 /* FileDirectoryFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7461444B09C007C6459 /* FileDirectoryFactory.cpp */; };
+               DF93D7781444B09C007C6459 /* FileReaderFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7481444B09C007C6459 /* FileReaderFile.cpp */; };
+               DF93D7791444B09C007C6459 /* HDFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D74A1444B09C007C6459 /* HDFile.cpp */; };
+               DF93D77A1444B09C007C6459 /* ISOFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D74C1444B09C007C6459 /* ISOFile.cpp */; };
+               DF93D77B1444B09C007C6459 /* LastFMFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D74E1444B09C007C6459 /* LastFMFile.cpp */; };
+               DF93D77C1444B09C007C6459 /* MusicDatabaseFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7501444B09C007C6459 /* MusicDatabaseFile.cpp */; };
+               DF93D77D1444B09C007C6459 /* NFSFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7521444B09C007C6459 /* NFSFile.cpp */; };
+               DF93D77E1444B09C007C6459 /* PipeFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7541444B09C007C6459 /* PipeFile.cpp */; };
+               DF93D77F1444B09C007C6459 /* RarFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7561444B09C007C6459 /* RarFile.cpp */; };
+               DF93D7801444B09C007C6459 /* RTVFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7581444B09C007C6459 /* RTVFile.cpp */; };
+               DF93D7811444B09C007C6459 /* SFTPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D75A1444B09C007C6459 /* SFTPFile.cpp */; };
+               DF93D7821444B09C007C6459 /* ShoutcastFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D75C1444B09C007C6459 /* ShoutcastFile.cpp */; };
+               DF93D7831444B09C007C6459 /* SlingboxDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D75E1444B09C007C6459 /* SlingboxDirectory.cpp */; };
+               DF93D7841444B09C007C6459 /* SlingboxFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7601444B09C007C6459 /* SlingboxFile.cpp */; };
+               DF93D7851444B09C007C6459 /* SmbFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7621444B09C007C6459 /* SmbFile.cpp */; };
+               DF93D7861444B09C007C6459 /* SpecialProtocolFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7641444B09C007C6459 /* SpecialProtocolFile.cpp */; };
+               DF93D7871444B09C007C6459 /* TuxBoxDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7661444B09C007C6459 /* TuxBoxDirectory.cpp */; };
+               DF93D7881444B09C007C6459 /* TuxBoxFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7681444B09C007C6459 /* TuxBoxFile.cpp */; };
+               DF93D7891444B09C007C6459 /* UDFFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D76A1444B09C007C6459 /* UDFFile.cpp */; };
+               DF93D78A1444B09C007C6459 /* UPnPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D76C1444B09C007C6459 /* UPnPFile.cpp */; };
+               DF93D78B1444B09C007C6459 /* ZipFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D76E1444B09C007C6459 /* ZipFile.cpp */; };
+               DF93D8331444B88B007C6459 /* HDHomeRunDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D82F1444B88B007C6459 /* HDHomeRunDirectory.cpp */; };
+               DF93D8341444B88B007C6459 /* HDHomeRunFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D8311444B88B007C6459 /* HDHomeRunFile.cpp */; };
                DF98D9A81434F4B400A6EBE1 /* SkinVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF98D9A61434F4B400A6EBE1 /* SkinVariable.cpp */; };
                DFA6BE8713FED2A10048CC11 /* AirPlayServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA6BE8513FED2A10048CC11 /* AirPlayServer.cpp */; };
                DFA6BE8A13FED2B40048CC11 /* HttpParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA6BE8813FED2B40048CC11 /* HttpParser.cpp */; };
                DFAB04C113F8385F00B70BFB /* InertialScrollingHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAB04BF13F8385F00B70BFB /* InertialScrollingHandler.cpp */; };
+               DFCA6B0B15224684000BFAAE /* HTTPApiHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AFE15224684000BFAAE /* HTTPApiHandler.cpp */; };
+               DFCA6B0C15224684000BFAAE /* HTTPJsonRpcHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6B0015224684000BFAAE /* HTTPJsonRpcHandler.cpp */; };
+               DFCA6B0D15224684000BFAAE /* HTTPVfsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6B0215224684000BFAAE /* HTTPVfsHandler.cpp */; };
+               DFCA6B0E15224684000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6B0415224684000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp */; };
+               DFCA6B0F15224684000BFAAE /* HTTPWebinterfaceHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6B0615224684000BFAAE /* HTTPWebinterfaceHandler.cpp */; };
+               DFCA6B1015224684000BFAAE /* IHTTPRequestHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6B0815224684000BFAAE /* IHTTPRequestHandler.cpp */; };
                DFCFC53D1413F7F70004D0BF /* AFPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCFC5391413F7F70004D0BF /* AFPDirectory.cpp */; };
-               DFCFC53E1413F7F70004D0BF /* FileAFP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCFC53B1413F7F70004D0BF /* FileAFP.cpp */; };
                DFD4D22013D7286E00A47C47 /* Implementation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD4D21413D7286E00A47C47 /* Implementation.cpp */; };
                DFD4D22113D7286E00A47C47 /* README.platform in Resources */ = {isa = PBXBuildFile; fileRef = DFD4D21613D7286E00A47C47 /* README.platform */; };
                DFD4D22213D7286E00A47C47 /* SystemClock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD4D21C13D7286E00A47C47 /* SystemClock.cpp */; };
+               DFDB00491516408F005079A4 /* CircularCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDB00411516408F005079A4 /* CircularCache.cpp */; };
+               DFDB004A1516408F005079A4 /* DirectoryCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDB00431516408F005079A4 /* DirectoryCache.cpp */; };
+               DFDB004B1516408F005079A4 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDB00451516408F005079A4 /* FileCache.cpp */; };
+               DFDB004C1516408F005079A4 /* MemBufferCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDB00471516408F005079A4 /* MemBufferCache.cpp */; };
                F54D9E8E12B71457006870F9 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F54D9E8D12B71457006870F9 /* CoreAudio.framework */; };
                F56B15FB12CD6922009B4C96 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F56B15FA12CD6922009B4C96 /* CoreVideo.framework */; };
                F56B15FD12CD6930009B4C96 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F56B15FC12CD6930009B4C96 /* AudioToolbox.framework */; };
                F56C7971131EC154000AD0F6 /* ASAPFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C739F131EC151000AD0F6 /* ASAPFileDirectory.cpp */; };
                F56C7972131EC154000AD0F6 /* MusicFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73A1131EC151000AD0F6 /* MusicFileDirectory.cpp */; };
                F56C7973131EC154000AD0F6 /* MythSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73A3131EC151000AD0F6 /* MythSession.cpp */; };
-               F56C7974131EC154000AD0F6 /* FileSmb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73A4131EC151000AD0F6 /* FileSmb.cpp */; };
                F56C7975131EC154000AD0F6 /* SMBDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73A5131EC151000AD0F6 /* SMBDirectory.cpp */; };
                F56C7976131EC154000AD0F6 /* MythDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73A6131EC151000AD0F6 /* MythDirectory.cpp */; };
                F56C7977131EC154000AD0F6 /* MythFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73A8131EC151000AD0F6 /* MythFile.cpp */; };
-               F56C7978131EC154000AD0F6 /* FileShoutcast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73AA131EC151000AD0F6 /* FileShoutcast.cpp */; };
-               F56C7979131EC154000AD0F6 /* CacheMemBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73AB131EC151000AD0F6 /* CacheMemBuffer.cpp */; };
                F56C797A131EC154000AD0F6 /* CacheStrategy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73AD131EC151000AD0F6 /* CacheStrategy.cpp */; };
                F56C797B131EC154000AD0F6 /* CDDADirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73AF131EC151000AD0F6 /* CDDADirectory.cpp */; };
                F56C797C131EC154000AD0F6 /* DAAPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73B1131EC151000AD0F6 /* DAAPDirectory.cpp */; };
                F56C797D131EC154000AD0F6 /* DAVDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73B3131EC151000AD0F6 /* DAVDirectory.cpp */; };
                F56C797E131EC154000AD0F6 /* Directory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73B5131EC151000AD0F6 /* Directory.cpp */; };
-               F56C797F131EC154000AD0F6 /* DirectoryCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73B7131EC151000AD0F6 /* DirectoryCache.cpp */; };
                F56C7980131EC154000AD0F6 /* DirectoryHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73B9131EC151000AD0F6 /* DirectoryHistory.cpp */; };
-               F56C7981131EC154000AD0F6 /* DirectoryTuxBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73BB131EC151000AD0F6 /* DirectoryTuxBox.cpp */; };
                F56C7982131EC154000AD0F6 /* DllLibCurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73BD131EC151000AD0F6 /* DllLibCurl.cpp */; };
-               F56C7983131EC154000AD0F6 /* FactoryDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73BF131EC151000AD0F6 /* FactoryDirectory.cpp */; };
-               F56C7984131EC154000AD0F6 /* FactoryFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73C1131EC151000AD0F6 /* FactoryFileDirectory.cpp */; };
                F56C7985131EC154000AD0F6 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73C3131EC151000AD0F6 /* File.cpp */; };
-               F56C7986131EC154000AD0F6 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73C5131EC151000AD0F6 /* FileCache.cpp */; };
-               F56C7987131EC154000AD0F6 /* FileCDDA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73C7131EC151000AD0F6 /* FileCDDA.cpp */; };
-               F56C7988131EC154000AD0F6 /* FileCurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73C9131EC151000AD0F6 /* FileCurl.cpp */; };
-               F56C7989131EC154000AD0F6 /* FileDAAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73CB131EC151000AD0F6 /* FileDAAP.cpp */; };
                F56C798A131EC154000AD0F6 /* FileFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73CD131EC151000AD0F6 /* FileFactory.cpp */; };
-               F56C798B131EC154000AD0F6 /* FileFileReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73CF131EC151000AD0F6 /* FileFileReader.cpp */; };
-               F56C798C131EC154000AD0F6 /* FileHD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73D1131EC151000AD0F6 /* FileHD.cpp */; };
-               F56C798D131EC154000AD0F6 /* FileISO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73D3131EC151000AD0F6 /* FileISO.cpp */; };
-               F56C798E131EC154000AD0F6 /* FileLastFM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73D5131EC151000AD0F6 /* FileLastFM.cpp */; };
-               F56C798F131EC154000AD0F6 /* FileMusicDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73D7131EC151000AD0F6 /* FileMusicDatabase.cpp */; };
-               F56C7990131EC154000AD0F6 /* FileRar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73D9131EC151000AD0F6 /* FileRar.cpp */; };
-               F56C7991131EC154000AD0F6 /* FileRTV.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73DB131EC151000AD0F6 /* FileRTV.cpp */; };
-               F56C7992131EC154000AD0F6 /* FileSFTP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73DD131EC151000AD0F6 /* FileSFTP.cpp */; };
-               F56C7993131EC154000AD0F6 /* FileSpecialProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73E0131EC151000AD0F6 /* FileSpecialProtocol.cpp */; };
-               F56C7994131EC154000AD0F6 /* FileTuxBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73E2131EC151000AD0F6 /* FileTuxBox.cpp */; };
-               F56C7995131EC154000AD0F6 /* FileUDF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73E4131EC151000AD0F6 /* FileUDF.cpp */; };
-               F56C7997131EC154000AD0F6 /* FileZip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73E8131EC151000AD0F6 /* FileZip.cpp */; };
                F56C7998131EC154000AD0F6 /* FTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73EA131EC151000AD0F6 /* FTPDirectory.cpp */; };
                F56C7999131EC154000AD0F6 /* FTPParse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73EC131EC151000AD0F6 /* FTPParse.cpp */; };
                F56C799A131EC154000AD0F6 /* HDDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73EE131EC151000AD0F6 /* HDDirectory.cpp */; };
-               F56C799B131EC154000AD0F6 /* HDHomeRun.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73F0131EC151000AD0F6 /* HDHomeRun.cpp */; };
                F56C799C131EC154000AD0F6 /* HTSPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73F3131EC151000AD0F6 /* HTSPDirectory.cpp */; };
                F56C799D131EC154000AD0F6 /* HTSPSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73F5131EC151000AD0F6 /* HTSPSession.cpp */; };
                F56C799E131EC154000AD0F6 /* HTTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C73F7131EC151000AD0F6 /* HTTPDirectory.cpp */; };
 
 /* Begin PBXFileReference section */
                1830215F13B8E35300770920 /* controledit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = controledit.cpp; sourceTree = "<group>"; };
-               18404DF91396C43B00863BBA /* Slingbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Slingbox.cpp; sourceTree = "<group>"; };
-               18404DFA1396C43B00863BBA /* Slingbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Slingbox.h; sourceTree = "<group>"; };
                18404DFC1396C44F00863BBA /* SlingboxLib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = SlingboxLib.a; path = lib/SlingboxLib/SlingboxLib.a; sourceTree = "<group>"; };
                1840B792139968DB007C848B /* JSONVariantParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSONVariantParser.cpp; sourceTree = "<group>"; };
                1840B793139968DB007C848B /* JSONVariantParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONVariantParser.h; sourceTree = "<group>"; };
                1840B794139968DB007C848B /* JSONVariantWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSONVariantWriter.cpp; sourceTree = "<group>"; };
                1840B795139968DB007C848B /* JSONVariantWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONVariantWriter.h; sourceTree = "<group>"; };
+               188F752615211773009870CE /* IJSONRPCAnnouncer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSONRPCAnnouncer.h; sourceTree = "<group>"; };
+               188F752715211780009870CE /* JSONRPCUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONRPCUtils.h; sourceTree = "<group>"; };
+               188F760E15221809009870CE /* GUIOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIOperations.cpp; sourceTree = "<group>"; };
+               188F760F15221809009870CE /* GUIOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIOperations.h; sourceTree = "<group>"; };
+               188F76271522186C009870CE /* Mime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mime.cpp; sourceTree = "<group>"; };
+               188F76281522186C009870CE /* Mime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mime.h; sourceTree = "<group>"; };
                18968DE614155E1D005BA742 /* ApplicationOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ApplicationOperations.cpp; sourceTree = "<group>"; };
                18968DE714155E1D005BA742 /* ApplicationOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplicationOperations.h; sourceTree = "<group>"; };
                18ACF8E113597B0000B67371 /* RecentlyAddedJob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecentlyAddedJob.cpp; sourceTree = "<group>"; };
                7C0A7FCB13A9E76E00AFC2BD /* GUIWindowDebugInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIWindowDebugInfo.h; sourceTree = "<group>"; };
                7C89626E13B702F3003631FE /* GUIWindowScreensaverDim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIWindowScreensaverDim.cpp; sourceTree = "<group>"; };
                7C89626F13B702F3003631FE /* GUIWindowScreensaverDim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIWindowScreensaverDim.h; sourceTree = "<group>"; };
-               7C99B73D133D372300FC2B16 /* CacheCircular.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheCircular.cpp; sourceTree = "<group>"; };
-               7C99B73E133D372300FC2B16 /* CacheCircular.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheCircular.h; sourceTree = "<group>"; };
                7C99B7A8134072CD00FC2B16 /* GUIDialogPlayEject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogPlayEject.cpp; sourceTree = "<group>"; };
                7C99B7A9134072CD00FC2B16 /* GUIDialogPlayEject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIDialogPlayEject.h; sourceTree = "<group>"; };
+               7CCFD9A81514952700211D82 /* PCMCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMCodec.cpp; sourceTree = "<group>"; };
+               7CCFD9A91514952700211D82 /* PCMCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMCodec.h; sourceTree = "<group>"; };
                7CEE2E6B13D6B7A8000ABF2A /* TimeSmoother.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeSmoother.cpp; sourceTree = "<group>"; };
                7CEE2E6C13D6B7A8000ABF2A /* TimeSmoother.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeSmoother.h; sourceTree = "<group>"; };
                8316267613B670FF004AED87 /* README.ios */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.ios; sourceTree = "<group>"; };
                A192FD47135E46C800D92E9B /* IOSAudioRingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IOSAudioRingBuffer.h; path = AudioRenderers/IOSAudioRingBuffer.h; sourceTree = "<group>"; };
                C807119D135DB842002F601B /* InputOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputOperations.cpp; sourceTree = "<group>"; };
                C807119E135DB842002F601B /* InputOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputOperations.h; sourceTree = "<group>"; };
-               C80711A0135DB848002F601B /* AnnouncementUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnnouncementUtils.h; sourceTree = "<group>"; };
                C8EC5D4F136954E400CCC10D /* XBMC_keytable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XBMC_keytable.cpp; sourceTree = "<group>"; };
                C8EC5D50136954E400CCC10D /* XBMC_keytable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMC_keytable.h; sourceTree = "<group>"; };
-               DF0DF16813A3AF82008ED511 /* FileNFS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileNFS.cpp; sourceTree = "<group>"; };
-               DF0DF16913A3AF82008ED511 /* FileNFS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileNFS.h; sourceTree = "<group>"; };
                DF0DF16A13A3AF82008ED511 /* NFSDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NFSDirectory.cpp; sourceTree = "<group>"; };
                DF0DF16B13A3AF82008ED511 /* NFSDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NFSDirectory.h; sourceTree = "<group>"; };
                DF34890713FD96390026A711 /* GUIAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIAction.cpp; sourceTree = "<group>"; };
                DF34890813FD96390026A711 /* GUIAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIAction.h; sourceTree = "<group>"; };
                DF44852D140064F40069344B /* BXAcodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BXAcodec.cpp; sourceTree = "<group>"; };
                DF44852E140064F40069344B /* BXAcodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BXAcodec.h; sourceTree = "<group>"; };
-               DF4485301400651B0069344B /* FilePipe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FilePipe.cpp; sourceTree = "<group>"; };
-               DF4485311400651B0069344B /* FilePipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilePipe.h; sourceTree = "<group>"; };
                DF4485321400651B0069344B /* PipesManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipesManager.cpp; sourceTree = "<group>"; };
                DF4485331400651B0069344B /* PipesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PipesManager.h; sourceTree = "<group>"; };
                DF4485361400654A0069344B /* AirTunesServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirTunesServer.cpp; sourceTree = "<group>"; };
                DF4485371400654A0069344B /* AirTunesServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirTunesServer.h; sourceTree = "<group>"; };
-               DF673A231443769300A5A509 /* FileUPnP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileUPnP.cpp; sourceTree = "<group>"; };
-               DF673A241443769300A5A509 /* FileUPnP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileUPnP.h; sourceTree = "<group>"; };
+               DF527777151BAFD600B5B63B /* WebSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocket.cpp; sourceTree = "<group>"; };
+               DF527778151BAFD600B5B63B /* WebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocket.h; sourceTree = "<group>"; };
+               DF527779151BAFD600B5B63B /* WebSocketManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketManager.cpp; sourceTree = "<group>"; };
+               DF52777A151BAFD600B5B63B /* WebSocketManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketManager.h; sourceTree = "<group>"; };
+               DF52777B151BAFD600B5B63B /* WebSocketV13.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketV13.cpp; sourceTree = "<group>"; };
+               DF52777C151BAFD600B5B63B /* WebSocketV13.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketV13.h; sourceTree = "<group>"; };
+               DF52777D151BAFD600B5B63B /* WebSocketV8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketV8.cpp; sourceTree = "<group>"; };
+               DF52777E151BAFD600B5B63B /* WebSocketV8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketV8.h; sourceTree = "<group>"; };
+               DF527784151BAFEE00B5B63B /* Base64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Base64.cpp; sourceTree = "<group>"; };
+               DF527785151BAFEE00B5B63B /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = "<group>"; };
+               DF527786151BAFEE00B5B63B /* HttpResponse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpResponse.cpp; sourceTree = "<group>"; };
+               DF527787151BAFEE00B5B63B /* HttpResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpResponse.h; sourceTree = "<group>"; };
+               DF93D7381444B09C007C6459 /* AFPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AFPFile.cpp; sourceTree = "<group>"; };
+               DF93D7391444B09C007C6459 /* AFPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFPFile.h; sourceTree = "<group>"; };
+               DF93D73E1444B09C007C6459 /* CDDAFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDDAFile.cpp; sourceTree = "<group>"; };
+               DF93D73F1444B09C007C6459 /* CDDAFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDDAFile.h; sourceTree = "<group>"; };
+               DF93D7401444B09C007C6459 /* CurlFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CurlFile.cpp; sourceTree = "<group>"; };
+               DF93D7411444B09C007C6459 /* CurlFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CurlFile.h; sourceTree = "<group>"; };
+               DF93D7421444B09C007C6459 /* DAAPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DAAPFile.cpp; sourceTree = "<group>"; };
+               DF93D7431444B09C007C6459 /* DAAPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DAAPFile.h; sourceTree = "<group>"; };
+               DF93D7441444B09C007C6459 /* DirectoryFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryFactory.cpp; sourceTree = "<group>"; };
+               DF93D7451444B09C007C6459 /* DirectoryFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryFactory.h; sourceTree = "<group>"; };
+               DF93D7461444B09C007C6459 /* FileDirectoryFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileDirectoryFactory.cpp; sourceTree = "<group>"; };
+               DF93D7471444B09C007C6459 /* FileDirectoryFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileDirectoryFactory.h; sourceTree = "<group>"; };
+               DF93D7481444B09C007C6459 /* FileReaderFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileReaderFile.cpp; sourceTree = "<group>"; };
+               DF93D7491444B09C007C6459 /* FileReaderFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileReaderFile.h; sourceTree = "<group>"; };
+               DF93D74A1444B09C007C6459 /* HDFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDFile.cpp; sourceTree = "<group>"; };
+               DF93D74B1444B09C007C6459 /* HDFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDFile.h; sourceTree = "<group>"; };
+               DF93D74C1444B09C007C6459 /* ISOFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ISOFile.cpp; sourceTree = "<group>"; };
+               DF93D74D1444B09C007C6459 /* ISOFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISOFile.h; sourceTree = "<group>"; };
+               DF93D74E1444B09C007C6459 /* LastFMFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LastFMFile.cpp; sourceTree = "<group>"; };
+               DF93D74F1444B09C007C6459 /* LastFMFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LastFMFile.h; sourceTree = "<group>"; };
+               DF93D7501444B09C007C6459 /* MusicDatabaseFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MusicDatabaseFile.cpp; sourceTree = "<group>"; };
+               DF93D7511444B09C007C6459 /* MusicDatabaseFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicDatabaseFile.h; sourceTree = "<group>"; };
+               DF93D7521444B09C007C6459 /* NFSFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NFSFile.cpp; sourceTree = "<group>"; };
+               DF93D7531444B09C007C6459 /* NFSFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NFSFile.h; sourceTree = "<group>"; };
+               DF93D7541444B09C007C6459 /* PipeFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipeFile.cpp; sourceTree = "<group>"; };
+               DF93D7551444B09C007C6459 /* PipeFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PipeFile.h; sourceTree = "<group>"; };
+               DF93D7561444B09C007C6459 /* RarFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RarFile.cpp; sourceTree = "<group>"; };
+               DF93D7571444B09C007C6459 /* RarFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RarFile.h; sourceTree = "<group>"; };
+               DF93D7581444B09C007C6459 /* RTVFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTVFile.cpp; sourceTree = "<group>"; };
+               DF93D7591444B09C007C6459 /* RTVFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTVFile.h; sourceTree = "<group>"; };
+               DF93D75A1444B09C007C6459 /* SFTPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SFTPFile.cpp; sourceTree = "<group>"; };
+               DF93D75B1444B09C007C6459 /* SFTPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SFTPFile.h; sourceTree = "<group>"; };
+               DF93D75C1444B09C007C6459 /* ShoutcastFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShoutcastFile.cpp; sourceTree = "<group>"; };
+               DF93D75D1444B09C007C6459 /* ShoutcastFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShoutcastFile.h; sourceTree = "<group>"; };
+               DF93D75E1444B09C007C6459 /* SlingboxDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlingboxDirectory.cpp; sourceTree = "<group>"; };
+               DF93D75F1444B09C007C6459 /* SlingboxDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlingboxDirectory.h; sourceTree = "<group>"; };
+               DF93D7601444B09C007C6459 /* SlingboxFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlingboxFile.cpp; sourceTree = "<group>"; };
+               DF93D7611444B09C007C6459 /* SlingboxFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlingboxFile.h; sourceTree = "<group>"; };
+               DF93D7621444B09C007C6459 /* SmbFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SmbFile.cpp; sourceTree = "<group>"; };
+               DF93D7631444B09C007C6459 /* SmbFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmbFile.h; sourceTree = "<group>"; };
+               DF93D7641444B09C007C6459 /* SpecialProtocolFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialProtocolFile.cpp; sourceTree = "<group>"; };
+               DF93D7651444B09C007C6459 /* SpecialProtocolFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialProtocolFile.h; sourceTree = "<group>"; };
+               DF93D7661444B09C007C6459 /* TuxBoxDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TuxBoxDirectory.cpp; sourceTree = "<group>"; };
+               DF93D7671444B09C007C6459 /* TuxBoxDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TuxBoxDirectory.h; sourceTree = "<group>"; };
+               DF93D7681444B09C007C6459 /* TuxBoxFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TuxBoxFile.cpp; sourceTree = "<group>"; };
+               DF93D7691444B09C007C6459 /* TuxBoxFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TuxBoxFile.h; sourceTree = "<group>"; };
+               DF93D76A1444B09C007C6459 /* UDFFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UDFFile.cpp; sourceTree = "<group>"; };
+               DF93D76B1444B09C007C6459 /* UDFFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UDFFile.h; sourceTree = "<group>"; };
+               DF93D76C1444B09C007C6459 /* UPnPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UPnPFile.cpp; sourceTree = "<group>"; };
+               DF93D76D1444B09C007C6459 /* UPnPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPnPFile.h; sourceTree = "<group>"; };
+               DF93D76E1444B09C007C6459 /* ZipFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZipFile.cpp; sourceTree = "<group>"; };
+               DF93D76F1444B09C007C6459 /* ZipFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZipFile.h; sourceTree = "<group>"; };
+               DF93D82F1444B88B007C6459 /* HDHomeRunDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDHomeRunDirectory.cpp; sourceTree = "<group>"; };
+               DF93D8301444B88B007C6459 /* HDHomeRunDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDHomeRunDirectory.h; sourceTree = "<group>"; };
+               DF93D8311444B88B007C6459 /* HDHomeRunFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDHomeRunFile.cpp; sourceTree = "<group>"; };
+               DF93D8321444B88B007C6459 /* HDHomeRunFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDHomeRunFile.h; sourceTree = "<group>"; };
                DF98D9A61434F4B400A6EBE1 /* SkinVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkinVariable.cpp; sourceTree = "<group>"; };
                DF98D9A71434F4B400A6EBE1 /* SkinVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkinVariable.h; sourceTree = "<group>"; };
                DFA6BE8513FED2A10048CC11 /* AirPlayServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirPlayServer.cpp; sourceTree = "<group>"; };
                DFA6BE8913FED2B40048CC11 /* HttpParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpParser.h; sourceTree = "<group>"; };
                DFAB04BF13F8385F00B70BFB /* InertialScrollingHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InertialScrollingHandler.cpp; sourceTree = "<group>"; };
                DFAB04C013F8385F00B70BFB /* InertialScrollingHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InertialScrollingHandler.h; sourceTree = "<group>"; };
+               DFCA6AFE15224684000BFAAE /* HTTPApiHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPApiHandler.cpp; sourceTree = "<group>"; };
+               DFCA6AFF15224684000BFAAE /* HTTPApiHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPApiHandler.h; sourceTree = "<group>"; };
+               DFCA6B0015224684000BFAAE /* HTTPJsonRpcHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPJsonRpcHandler.cpp; sourceTree = "<group>"; };
+               DFCA6B0115224684000BFAAE /* HTTPJsonRpcHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPJsonRpcHandler.h; sourceTree = "<group>"; };
+               DFCA6B0215224684000BFAAE /* HTTPVfsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPVfsHandler.cpp; sourceTree = "<group>"; };
+               DFCA6B0315224684000BFAAE /* HTTPVfsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPVfsHandler.h; sourceTree = "<group>"; };
+               DFCA6B0415224684000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPWebinterfaceAddonsHandler.cpp; sourceTree = "<group>"; };
+               DFCA6B0515224684000BFAAE /* HTTPWebinterfaceAddonsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPWebinterfaceAddonsHandler.h; sourceTree = "<group>"; };
+               DFCA6B0615224684000BFAAE /* HTTPWebinterfaceHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPWebinterfaceHandler.cpp; sourceTree = "<group>"; };
+               DFCA6B0715224684000BFAAE /* HTTPWebinterfaceHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPWebinterfaceHandler.h; sourceTree = "<group>"; };
+               DFCA6B0815224684000BFAAE /* IHTTPRequestHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IHTTPRequestHandler.cpp; sourceTree = "<group>"; };
+               DFCA6B0915224684000BFAAE /* IHTTPRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IHTTPRequestHandler.h; sourceTree = "<group>"; };
                DFCFC5391413F7F70004D0BF /* AFPDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AFPDirectory.cpp; sourceTree = "<group>"; };
                DFCFC53A1413F7F70004D0BF /* AFPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFPDirectory.h; sourceTree = "<group>"; };
-               DFCFC53B1413F7F70004D0BF /* FileAFP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileAFP.cpp; sourceTree = "<group>"; };
-               DFCFC53C1413F7F70004D0BF /* FileAFP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileAFP.h; sourceTree = "<group>"; };
                DFD4D20D13D7286E00A47C47 /* Condition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Condition.h; sourceTree = "<group>"; };
                DFD4D20E13D7286E00A47C47 /* CriticalSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CriticalSection.h; sourceTree = "<group>"; };
                DFD4D21213D7286E00A47C47 /* Condition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Condition.h; sourceTree = "<group>"; };
                DFD4D21713D7286E00A47C47 /* ThreadLocal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadLocal.h; sourceTree = "<group>"; };
                DFD4D21C13D7286E00A47C47 /* SystemClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SystemClock.cpp; sourceTree = "<group>"; };
                DFD4D21D13D7286E00A47C47 /* SystemClock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SystemClock.h; sourceTree = "<group>"; };
+               DFDB00411516408F005079A4 /* CircularCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CircularCache.cpp; sourceTree = "<group>"; };
+               DFDB00421516408F005079A4 /* CircularCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CircularCache.h; sourceTree = "<group>"; };
+               DFDB00431516408F005079A4 /* DirectoryCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryCache.cpp; sourceTree = "<group>"; };
+               DFDB00441516408F005079A4 /* DirectoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryCache.h; sourceTree = "<group>"; };
+               DFDB00451516408F005079A4 /* FileCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCache.cpp; sourceTree = "<group>"; };
+               DFDB00461516408F005079A4 /* FileCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCache.h; sourceTree = "<group>"; };
+               DFDB00471516408F005079A4 /* MemBufferCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemBufferCache.cpp; sourceTree = "<group>"; };
+               DFDB00481516408F005079A4 /* MemBufferCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemBufferCache.h; sourceTree = "<group>"; };
                F54D9E8D12B71457006870F9 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
                F558F66813AFE7F300631E12 /* Condition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Condition.h; sourceTree = "<group>"; };
                F558F66E13AFE81500631E12 /* ThreadLocal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadLocal.h; sourceTree = "<group>"; };
                F56C73A1131EC151000AD0F6 /* MusicFileDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MusicFileDirectory.cpp; sourceTree = "<group>"; };
                F56C73A2131EC151000AD0F6 /* MusicFileDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicFileDirectory.h; sourceTree = "<group>"; };
                F56C73A3131EC151000AD0F6 /* MythSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MythSession.cpp; sourceTree = "<group>"; };
-               F56C73A4131EC151000AD0F6 /* FileSmb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSmb.cpp; sourceTree = "<group>"; };
                F56C73A5131EC151000AD0F6 /* SMBDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SMBDirectory.cpp; sourceTree = "<group>"; };
                F56C73A6131EC151000AD0F6 /* MythDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MythDirectory.cpp; sourceTree = "<group>"; };
                F56C73A7131EC151000AD0F6 /* MythDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MythDirectory.h; sourceTree = "<group>"; };
                F56C73A8131EC151000AD0F6 /* MythFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MythFile.cpp; sourceTree = "<group>"; };
                F56C73A9131EC151000AD0F6 /* MythFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MythFile.h; sourceTree = "<group>"; };
-               F56C73AA131EC151000AD0F6 /* FileShoutcast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileShoutcast.cpp; sourceTree = "<group>"; };
-               F56C73AB131EC151000AD0F6 /* CacheMemBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheMemBuffer.cpp; sourceTree = "<group>"; };
-               F56C73AC131EC151000AD0F6 /* CacheMemBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheMemBuffer.h; sourceTree = "<group>"; };
                F56C73AD131EC151000AD0F6 /* CacheStrategy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStrategy.cpp; sourceTree = "<group>"; };
                F56C73AE131EC151000AD0F6 /* CacheStrategy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheStrategy.h; sourceTree = "<group>"; };
                F56C73AF131EC151000AD0F6 /* CDDADirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDDADirectory.cpp; sourceTree = "<group>"; };
                F56C73B4131EC151000AD0F6 /* DAVDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DAVDirectory.h; sourceTree = "<group>"; };
                F56C73B5131EC151000AD0F6 /* Directory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Directory.cpp; sourceTree = "<group>"; };
                F56C73B6131EC151000AD0F6 /* Directory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Directory.h; sourceTree = "<group>"; };
-               F56C73B7131EC151000AD0F6 /* DirectoryCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryCache.cpp; sourceTree = "<group>"; };
-               F56C73B8131EC151000AD0F6 /* DirectoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryCache.h; sourceTree = "<group>"; };
                F56C73B9131EC151000AD0F6 /* DirectoryHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryHistory.cpp; sourceTree = "<group>"; };
                F56C73BA131EC151000AD0F6 /* DirectoryHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryHistory.h; sourceTree = "<group>"; };
-               F56C73BB131EC151000AD0F6 /* DirectoryTuxBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryTuxBox.cpp; sourceTree = "<group>"; };
-               F56C73BC131EC151000AD0F6 /* DirectoryTuxBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryTuxBox.h; sourceTree = "<group>"; };
                F56C73BD131EC151000AD0F6 /* DllLibCurl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DllLibCurl.cpp; sourceTree = "<group>"; };
                F56C73BE131EC151000AD0F6 /* DllLibCurl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DllLibCurl.h; sourceTree = "<group>"; };
-               F56C73BF131EC151000AD0F6 /* FactoryDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FactoryDirectory.cpp; sourceTree = "<group>"; };
-               F56C73C0131EC151000AD0F6 /* FactoryDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FactoryDirectory.h; sourceTree = "<group>"; };
-               F56C73C1131EC151000AD0F6 /* FactoryFileDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FactoryFileDirectory.cpp; sourceTree = "<group>"; };
-               F56C73C2131EC151000AD0F6 /* FactoryFileDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FactoryFileDirectory.h; sourceTree = "<group>"; };
                F56C73C3131EC151000AD0F6 /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = File.cpp; sourceTree = "<group>"; };
                F56C73C4131EC151000AD0F6 /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = File.h; sourceTree = "<group>"; };
-               F56C73C5131EC151000AD0F6 /* FileCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCache.cpp; sourceTree = "<group>"; };
-               F56C73C6131EC151000AD0F6 /* FileCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCache.h; sourceTree = "<group>"; };
-               F56C73C7131EC151000AD0F6 /* FileCDDA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCDDA.cpp; sourceTree = "<group>"; };
-               F56C73C8131EC151000AD0F6 /* FileCDDA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCDDA.h; sourceTree = "<group>"; };
-               F56C73C9131EC151000AD0F6 /* FileCurl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCurl.cpp; sourceTree = "<group>"; };
-               F56C73CA131EC151000AD0F6 /* FileCurl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCurl.h; sourceTree = "<group>"; };
-               F56C73CB131EC151000AD0F6 /* FileDAAP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileDAAP.cpp; sourceTree = "<group>"; };
-               F56C73CC131EC151000AD0F6 /* FileDAAP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileDAAP.h; sourceTree = "<group>"; };
                F56C73CD131EC151000AD0F6 /* FileFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFactory.cpp; sourceTree = "<group>"; };
                F56C73CE131EC151000AD0F6 /* FileFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileFactory.h; sourceTree = "<group>"; };
-               F56C73CF131EC151000AD0F6 /* FileFileReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFileReader.cpp; sourceTree = "<group>"; };
-               F56C73D0131EC151000AD0F6 /* FileFileReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileFileReader.h; sourceTree = "<group>"; };
-               F56C73D1131EC151000AD0F6 /* FileHD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileHD.cpp; sourceTree = "<group>"; };
-               F56C73D2131EC151000AD0F6 /* FileHD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileHD.h; sourceTree = "<group>"; };
-               F56C73D3131EC151000AD0F6 /* FileISO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileISO.cpp; sourceTree = "<group>"; };
-               F56C73D4131EC151000AD0F6 /* FileISO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileISO.h; sourceTree = "<group>"; };
-               F56C73D5131EC151000AD0F6 /* FileLastFM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileLastFM.cpp; sourceTree = "<group>"; };
-               F56C73D6131EC151000AD0F6 /* FileLastFM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileLastFM.h; sourceTree = "<group>"; };
-               F56C73D7131EC151000AD0F6 /* FileMusicDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileMusicDatabase.cpp; sourceTree = "<group>"; };
-               F56C73D8131EC151000AD0F6 /* FileMusicDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileMusicDatabase.h; sourceTree = "<group>"; };
-               F56C73D9131EC151000AD0F6 /* FileRar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileRar.cpp; sourceTree = "<group>"; };
-               F56C73DA131EC151000AD0F6 /* FileRar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileRar.h; sourceTree = "<group>"; };
-               F56C73DB131EC151000AD0F6 /* FileRTV.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileRTV.cpp; sourceTree = "<group>"; };
-               F56C73DC131EC151000AD0F6 /* FileRTV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileRTV.h; sourceTree = "<group>"; };
-               F56C73DD131EC151000AD0F6 /* FileSFTP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSFTP.cpp; sourceTree = "<group>"; };
-               F56C73DE131EC151000AD0F6 /* FileSFTP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSFTP.h; sourceTree = "<group>"; };
-               F56C73DF131EC151000AD0F6 /* FileSmb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSmb.h; sourceTree = "<group>"; };
-               F56C73E0131EC151000AD0F6 /* FileSpecialProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSpecialProtocol.cpp; sourceTree = "<group>"; };
-               F56C73E1131EC151000AD0F6 /* FileSpecialProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSpecialProtocol.h; sourceTree = "<group>"; };
-               F56C73E2131EC151000AD0F6 /* FileTuxBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileTuxBox.cpp; sourceTree = "<group>"; };
-               F56C73E3131EC151000AD0F6 /* FileTuxBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileTuxBox.h; sourceTree = "<group>"; };
-               F56C73E4131EC151000AD0F6 /* FileUDF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileUDF.cpp; sourceTree = "<group>"; };
-               F56C73E5131EC151000AD0F6 /* FileUDF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileUDF.h; sourceTree = "<group>"; };
-               F56C73E8131EC151000AD0F6 /* FileZip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileZip.cpp; sourceTree = "<group>"; };
-               F56C73E9131EC151000AD0F6 /* FileZip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileZip.h; sourceTree = "<group>"; };
                F56C73EA131EC151000AD0F6 /* FTPDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FTPDirectory.cpp; sourceTree = "<group>"; };
                F56C73EB131EC151000AD0F6 /* FTPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FTPDirectory.h; sourceTree = "<group>"; };
                F56C73EC131EC151000AD0F6 /* FTPParse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FTPParse.cpp; sourceTree = "<group>"; };
                F56C73ED131EC151000AD0F6 /* FTPParse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FTPParse.h; sourceTree = "<group>"; };
                F56C73EE131EC151000AD0F6 /* HDDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDDirectory.cpp; sourceTree = "<group>"; };
                F56C73EF131EC151000AD0F6 /* HDDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDDirectory.h; sourceTree = "<group>"; };
-               F56C73F0131EC151000AD0F6 /* HDHomeRun.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDHomeRun.cpp; sourceTree = "<group>"; };
-               F56C73F1131EC151000AD0F6 /* HDHomeRun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDHomeRun.h; sourceTree = "<group>"; };
                F56C73F2131EC151000AD0F6 /* HTSPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTSPDirectory.h; sourceTree = "<group>"; };
                F56C73F3131EC151000AD0F6 /* HTSPDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTSPDirectory.cpp; sourceTree = "<group>"; };
                F56C73F4131EC151000AD0F6 /* HTSPSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTSPSession.h; sourceTree = "<group>"; };
                        name = Documentation;
                        sourceTree = "<group>";
                };
+               DF527775151BAFD600B5B63B /* websocket */ = {
+                       isa = PBXGroup;
+                       children = (
+                               DF527777151BAFD600B5B63B /* WebSocket.cpp */,
+                               DF527778151BAFD600B5B63B /* WebSocket.h */,
+                               DF527779151BAFD600B5B63B /* WebSocketManager.cpp */,
+                               DF52777A151BAFD600B5B63B /* WebSocketManager.h */,
+                               DF52777B151BAFD600B5B63B /* WebSocketV13.cpp */,
+                               DF52777C151BAFD600B5B63B /* WebSocketV13.h */,
+                               DF52777D151BAFD600B5B63B /* WebSocketV8.cpp */,
+                               DF52777E151BAFD600B5B63B /* WebSocketV8.h */,
+                       );
+                       path = websocket;
+                       sourceTree = "<group>";
+               };
+               DFCA6AFD15224684000BFAAE /* httprequesthandler */ = {
+                       isa = PBXGroup;
+                       children = (
+                               DFCA6AFE15224684000BFAAE /* HTTPApiHandler.cpp */,
+                               DFCA6AFF15224684000BFAAE /* HTTPApiHandler.h */,
+                               DFCA6B0015224684000BFAAE /* HTTPJsonRpcHandler.cpp */,
+                               DFCA6B0115224684000BFAAE /* HTTPJsonRpcHandler.h */,
+                               DFCA6B0215224684000BFAAE /* HTTPVfsHandler.cpp */,
+                               DFCA6B0315224684000BFAAE /* HTTPVfsHandler.h */,
+                               DFCA6B0415224684000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp */,
+                               DFCA6B0515224684000BFAAE /* HTTPWebinterfaceAddonsHandler.h */,
+                               DFCA6B0615224684000BFAAE /* HTTPWebinterfaceHandler.cpp */,
+                               DFCA6B0715224684000BFAAE /* HTTPWebinterfaceHandler.h */,
+                               DFCA6B0815224684000BFAAE /* IHTTPRequestHandler.cpp */,
+                               DFCA6B0915224684000BFAAE /* IHTTPRequestHandler.h */,
+                       );
+                       path = httprequesthandler;
+                       sourceTree = "<group>";
+               };
                DFD4D20C13D7286E00A47C47 /* platform */ = {
                        isa = PBXGroup;
                        children = (
                                F56C7322131EC151000AD0F6 /* OGGcodec.h */,
                                F56C7323131EC151000AD0F6 /* PAPlayer.cpp */,
                                F56C7324131EC151000AD0F6 /* PAPlayer.h */,
+                               7CCFD9A81514952700211D82 /* PCMCodec.cpp */,
+                               7CCFD9A91514952700211D82 /* PCMCodec.h */,
                                F56C7325131EC151000AD0F6 /* ReplayGain.cpp */,
                                F56C7326131EC151000AD0F6 /* ReplayGain.h */,
                                F56C7328131EC151000AD0F6 /* SIDCodec.cpp */,
                                F56C739D131EC151000AD0F6 /* AddonsDirectory.h */,
                                DFCFC5391413F7F70004D0BF /* AFPDirectory.cpp */,
                                DFCFC53A1413F7F70004D0BF /* AFPDirectory.h */,
+                               DF93D7381444B09C007C6459 /* AFPFile.cpp */,
+                               DF93D7391444B09C007C6459 /* AFPFile.h */,
                                F56C739F131EC151000AD0F6 /* ASAPFileDirectory.cpp */,
                                F56C73A0131EC151000AD0F6 /* ASAPFileDirectory.h */,
-                               7C99B73D133D372300FC2B16 /* CacheCircular.cpp */,
-                               7C99B73E133D372300FC2B16 /* CacheCircular.h */,
-                               F56C73AB131EC151000AD0F6 /* CacheMemBuffer.cpp */,
-                               F56C73AC131EC151000AD0F6 /* CacheMemBuffer.h */,
                                F56C73AD131EC151000AD0F6 /* CacheStrategy.cpp */,
                                F56C73AE131EC151000AD0F6 /* CacheStrategy.h */,
                                F56C73AF131EC151000AD0F6 /* CDDADirectory.cpp */,
                                F56C73B0131EC151000AD0F6 /* CDDADirectory.h */,
+                               DF93D73E1444B09C007C6459 /* CDDAFile.cpp */,
+                               DF93D73F1444B09C007C6459 /* CDDAFile.h */,
+                               DFDB00411516408F005079A4 /* CircularCache.cpp */,
+                               DFDB00421516408F005079A4 /* CircularCache.h */,
+                               DF93D7401444B09C007C6459 /* CurlFile.cpp */,
+                               DF93D7411444B09C007C6459 /* CurlFile.h */,
                                F56C73B1131EC151000AD0F6 /* DAAPDirectory.cpp */,
                                F56C73B2131EC151000AD0F6 /* DAAPDirectory.h */,
+                               DF93D7421444B09C007C6459 /* DAAPFile.cpp */,
+                               DF93D7431444B09C007C6459 /* DAAPFile.h */,
                                F56C73B3131EC151000AD0F6 /* DAVDirectory.cpp */,
                                F56C73B4131EC151000AD0F6 /* DAVDirectory.h */,
                                F56C73B5131EC151000AD0F6 /* Directory.cpp */,
                                F56C73B6131EC151000AD0F6 /* Directory.h */,
-                               F56C73B7131EC151000AD0F6 /* DirectoryCache.cpp */,
-                               F56C73B8131EC151000AD0F6 /* DirectoryCache.h */,
+                               DFDB00431516408F005079A4 /* DirectoryCache.cpp */,
+                               DFDB00441516408F005079A4 /* DirectoryCache.h */,
+                               DF93D7441444B09C007C6459 /* DirectoryFactory.cpp */,
+                               DF93D7451444B09C007C6459 /* DirectoryFactory.h */,
                                F56C73B9131EC151000AD0F6 /* DirectoryHistory.cpp */,
                                F56C73BA131EC151000AD0F6 /* DirectoryHistory.h */,
-                               F56C73BB131EC151000AD0F6 /* DirectoryTuxBox.cpp */,
-                               F56C73BC131EC151000AD0F6 /* DirectoryTuxBox.h */,
                                F56C73BD131EC151000AD0F6 /* DllLibCurl.cpp */,
                                F56C73BE131EC151000AD0F6 /* DllLibCurl.h */,
-                               F56C73BF131EC151000AD0F6 /* FactoryDirectory.cpp */,
-                               F56C73C0131EC151000AD0F6 /* FactoryDirectory.h */,
-                               F56C73C1131EC151000AD0F6 /* FactoryFileDirectory.cpp */,
-                               F56C73C2131EC151000AD0F6 /* FactoryFileDirectory.h */,
                                F56C73C3131EC151000AD0F6 /* File.cpp */,
                                F56C73C4131EC151000AD0F6 /* File.h */,
-                               DFCFC53B1413F7F70004D0BF /* FileAFP.cpp */,
-                               DFCFC53C1413F7F70004D0BF /* FileAFP.h */,
-                               F56C73C5131EC151000AD0F6 /* FileCache.cpp */,
-                               F56C73C6131EC151000AD0F6 /* FileCache.h */,
-                               F56C73C7131EC151000AD0F6 /* FileCDDA.cpp */,
-                               F56C73C8131EC151000AD0F6 /* FileCDDA.h */,
-                               F56C73C9131EC151000AD0F6 /* FileCurl.cpp */,
-                               F56C73CA131EC151000AD0F6 /* FileCurl.h */,
-                               F56C73CB131EC151000AD0F6 /* FileDAAP.cpp */,
-                               F56C73CC131EC151000AD0F6 /* FileDAAP.h */,
+                               DFDB00451516408F005079A4 /* FileCache.cpp */,
+                               DFDB00461516408F005079A4 /* FileCache.h */,
+                               DF93D7461444B09C007C6459 /* FileDirectoryFactory.cpp */,
+                               DF93D7471444B09C007C6459 /* FileDirectoryFactory.h */,
                                F56C73CD131EC151000AD0F6 /* FileFactory.cpp */,
                                F56C73CE131EC151000AD0F6 /* FileFactory.h */,
-                               F56C73CF131EC151000AD0F6 /* FileFileReader.cpp */,
-                               F56C73D0131EC151000AD0F6 /* FileFileReader.h */,
-                               F56C73D1131EC151000AD0F6 /* FileHD.cpp */,
-                               F56C73D2131EC151000AD0F6 /* FileHD.h */,
-                               F56C73D3131EC151000AD0F6 /* FileISO.cpp */,
-                               F56C73D4131EC151000AD0F6 /* FileISO.h */,
-                               F56C73D5131EC151000AD0F6 /* FileLastFM.cpp */,
-                               F56C73D6131EC151000AD0F6 /* FileLastFM.h */,
-                               F56C73D7131EC151000AD0F6 /* FileMusicDatabase.cpp */,
-                               F56C73D8131EC151000AD0F6 /* FileMusicDatabase.h */,
-                               DF0DF16813A3AF82008ED511 /* FileNFS.cpp */,
-                               DF0DF16913A3AF82008ED511 /* FileNFS.h */,
-                               DF4485301400651B0069344B /* FilePipe.cpp */,
-                               DF4485311400651B0069344B /* FilePipe.h */,
-                               F56C73D9131EC151000AD0F6 /* FileRar.cpp */,
-                               F56C73DA131EC151000AD0F6 /* FileRar.h */,
-                               F56C73DB131EC151000AD0F6 /* FileRTV.cpp */,
-                               F56C73DC131EC151000AD0F6 /* FileRTV.h */,
-                               F56C73DD131EC151000AD0F6 /* FileSFTP.cpp */,
-                               F56C73DE131EC151000AD0F6 /* FileSFTP.h */,
-                               F56C73AA131EC151000AD0F6 /* FileShoutcast.cpp */,
-                               F56C73A4131EC151000AD0F6 /* FileSmb.cpp */,
-                               F56C73DF131EC151000AD0F6 /* FileSmb.h */,
-                               F56C73E0131EC151000AD0F6 /* FileSpecialProtocol.cpp */,
-                               F56C73E1131EC151000AD0F6 /* FileSpecialProtocol.h */,
-                               F56C73E2131EC151000AD0F6 /* FileTuxBox.cpp */,
-                               F56C73E3131EC151000AD0F6 /* FileTuxBox.h */,
-                               F56C73E4131EC151000AD0F6 /* FileUDF.cpp */,
-                               F56C73E5131EC151000AD0F6 /* FileUDF.h */,
-                               DF673A231443769300A5A509 /* FileUPnP.cpp */,
-                               DF673A241443769300A5A509 /* FileUPnP.h */,
-                               F56C73E8131EC151000AD0F6 /* FileZip.cpp */,
-                               F56C73E9131EC151000AD0F6 /* FileZip.h */,
+                               DF93D7481444B09C007C6459 /* FileReaderFile.cpp */,
+                               DF93D7491444B09C007C6459 /* FileReaderFile.h */,
                                F56C73EA131EC151000AD0F6 /* FTPDirectory.cpp */,
                                F56C73EB131EC151000AD0F6 /* FTPDirectory.h */,
                                F56C73EC131EC151000AD0F6 /* FTPParse.cpp */,
                                F56C73ED131EC151000AD0F6 /* FTPParse.h */,
                                F56C73EE131EC151000AD0F6 /* HDDirectory.cpp */,
                                F56C73EF131EC151000AD0F6 /* HDDirectory.h */,
-                               F56C73F0131EC151000AD0F6 /* HDHomeRun.cpp */,
-                               F56C73F1131EC151000AD0F6 /* HDHomeRun.h */,
+                               DF93D74A1444B09C007C6459 /* HDFile.cpp */,
+                               DF93D74B1444B09C007C6459 /* HDFile.h */,
+                               DF93D82F1444B88B007C6459 /* HDHomeRunDirectory.cpp */,
+                               DF93D8301444B88B007C6459 /* HDHomeRunDirectory.h */,
+                               DF93D8311444B88B007C6459 /* HDHomeRunFile.cpp */,
+                               DF93D8321444B88B007C6459 /* HDHomeRunFile.h */,
                                F56C73F3131EC151000AD0F6 /* HTSPDirectory.cpp */,
                                F56C73F2131EC151000AD0F6 /* HTSPDirectory.h */,
                                F56C73F5131EC151000AD0F6 /* HTSPSession.cpp */,
                                F56C73FE131EC151000AD0F6 /* iso9660.h */,
                                F56C73FF131EC151000AD0F6 /* ISO9660Directory.cpp */,
                                F56C7400131EC151000AD0F6 /* ISO9660Directory.h */,
+                               DF93D74C1444B09C007C6459 /* ISOFile.cpp */,
+                               DF93D74D1444B09C007C6459 /* ISOFile.h */,
                                F56C7401131EC151000AD0F6 /* LastFMDirectory.cpp */,
                                F56C7402131EC151000AD0F6 /* LastFMDirectory.h */,
+                               DF93D74E1444B09C007C6459 /* LastFMFile.cpp */,
+                               DF93D74F1444B09C007C6459 /* LastFMFile.h */,
+                               DFDB00471516408F005079A4 /* MemBufferCache.cpp */,
+                               DFDB00481516408F005079A4 /* MemBufferCache.h */,
                                F56C7403131EC151000AD0F6 /* MultiPathDirectory.cpp */,
                                F56C7404131EC152000AD0F6 /* MultiPathDirectory.h */,
                                F56C7405131EC152000AD0F6 /* MultiPathFile.cpp */,
                                F56C7406131EC152000AD0F6 /* MultiPathFile.h */,
                                F56C7434131EC152000AD0F6 /* MusicDatabaseDirectory.cpp */,
                                F56C7435131EC152000AD0F6 /* MusicDatabaseDirectory.h */,
+                               DF93D7501444B09C007C6459 /* MusicDatabaseFile.cpp */,
+                               DF93D7511444B09C007C6459 /* MusicDatabaseFile.h */,
                                F56C73A1131EC151000AD0F6 /* MusicFileDirectory.cpp */,
                                F56C73A2131EC151000AD0F6 /* MusicFileDirectory.h */,
                                F56C7436131EC152000AD0F6 /* MusicSearchDirectory.cpp */,
                                F56C73A3131EC151000AD0F6 /* MythSession.cpp */,
                                DF0DF16A13A3AF82008ED511 /* NFSDirectory.cpp */,
                                DF0DF16B13A3AF82008ED511 /* NFSDirectory.h */,
+                               DF93D7521444B09C007C6459 /* NFSFile.cpp */,
+                               DF93D7531444B09C007C6459 /* NFSFile.h */,
                                F56C739A131EC151000AD0F6 /* NptXbmcFile.cpp */,
                                F56C7438131EC152000AD0F6 /* NSFFileDirectory.cpp */,
                                F56C7439131EC152000AD0F6 /* NSFFileDirectory.h */,
                                F56C743A131EC152000AD0F6 /* OGGFileDirectory.cpp */,
                                F56C743B131EC152000AD0F6 /* OGGFileDirectory.h */,
+                               DF93D7541444B09C007C6459 /* PipeFile.cpp */,
+                               DF93D7551444B09C007C6459 /* PipeFile.h */,
                                DF4485321400651B0069344B /* PipesManager.cpp */,
                                DF4485331400651B0069344B /* PipesManager.h */,
                                F56C743C131EC152000AD0F6 /* PlaylistDirectory.cpp */,
                                F56C7441131EC152000AD0F6 /* PluginDirectory.h */,
                                F56C7442131EC152000AD0F6 /* RarDirectory.cpp */,
                                F56C7443131EC152000AD0F6 /* RarDirectory.h */,
+                               DF93D7561444B09C007C6459 /* RarFile.cpp */,
+                               DF93D7571444B09C007C6459 /* RarFile.h */,
                                F56C7444131EC152000AD0F6 /* RarManager.cpp */,
                                F56C7445131EC152000AD0F6 /* RarManager.h */,
                                F56C739B131EC151000AD0F6 /* RSSDirectory.cpp */,
                                F56C739C131EC151000AD0F6 /* RSSDirectory.h */,
                                F56C7446131EC152000AD0F6 /* RTVDirectory.cpp */,
                                F56C7447131EC152000AD0F6 /* RTVDirectory.h */,
+                               DF93D7581444B09C007C6459 /* RTVFile.cpp */,
+                               DF93D7591444B09C007C6459 /* RTVFile.h */,
                                F56C7449131EC152000AD0F6 /* SAPDirectory.cpp */,
                                F56C7448131EC152000AD0F6 /* SAPDirectory.h */,
                                F56C744B131EC152000AD0F6 /* SAPFile.cpp */,
                                F56C744A131EC152000AD0F6 /* SAPFile.h */,
                                F56C744C131EC152000AD0F6 /* SFTPDirectory.cpp */,
                                F56C744D131EC152000AD0F6 /* SFTPDirectory.h */,
+                               DF93D75A1444B09C007C6459 /* SFTPFile.cpp */,
+                               DF93D75B1444B09C007C6459 /* SFTPFile.h */,
+                               DF93D75C1444B09C007C6459 /* ShoutcastFile.cpp */,
+                               DF93D75D1444B09C007C6459 /* ShoutcastFile.h */,
                                F56C744E131EC152000AD0F6 /* SIDFileDirectory.cpp */,
                                F56C744F131EC152000AD0F6 /* SIDFileDirectory.h */,
-                               18404DF91396C43B00863BBA /* Slingbox.cpp */,
-                               18404DFA1396C43B00863BBA /* Slingbox.h */,
+                               DF93D75E1444B09C007C6459 /* SlingboxDirectory.cpp */,
+                               DF93D75F1444B09C007C6459 /* SlingboxDirectory.h */,
+                               DF93D7601444B09C007C6459 /* SlingboxFile.cpp */,
+                               DF93D7611444B09C007C6459 /* SlingboxFile.h */,
                                F56C7450131EC152000AD0F6 /* SmartPlaylistDirectory.cpp */,
                                F56C7451131EC152000AD0F6 /* SmartPlaylistDirectory.h */,
                                F56C73A5131EC151000AD0F6 /* SMBDirectory.cpp */,
                                F56C7452131EC152000AD0F6 /* SMBDirectory.h */,
+                               DF93D7621444B09C007C6459 /* SmbFile.cpp */,
+                               DF93D7631444B09C007C6459 /* SmbFile.h */,
                                F57A1DBB1329FB0A00498CC7 /* SourcesDirectory.cpp */,
                                F57A1DBC1329FB0A00498CC7 /* SourcesDirectory.h */,
                                F56C7396131EC151000AD0F6 /* SpecialProtocol.cpp */,
                                F56C7397131EC151000AD0F6 /* SpecialProtocol.h */,
                                F56C7398131EC151000AD0F6 /* SpecialProtocolDirectory.cpp */,
                                F56C7399131EC151000AD0F6 /* SpecialProtocolDirectory.h */,
+                               DF93D7641444B09C007C6459 /* SpecialProtocolFile.cpp */,
+                               DF93D7651444B09C007C6459 /* SpecialProtocolFile.h */,
                                F56C7453131EC152000AD0F6 /* StackDirectory.cpp */,
                                F56C7454131EC152000AD0F6 /* StackDirectory.h */,
+                               DF93D7661444B09C007C6459 /* TuxBoxDirectory.cpp */,
+                               DF93D7671444B09C007C6459 /* TuxBoxDirectory.h */,
+                               DF93D7681444B09C007C6459 /* TuxBoxFile.cpp */,
+                               DF93D7691444B09C007C6459 /* TuxBoxFile.h */,
                                F56C7455131EC152000AD0F6 /* udf25.cpp */,
                                F56C7456131EC152000AD0F6 /* udf25.h */,
                                F56C7457131EC152000AD0F6 /* UDFDirectory.cpp */,
                                F56C7458131EC152000AD0F6 /* UDFDirectory.h */,
+                               DF93D76A1444B09C007C6459 /* UDFFile.cpp */,
+                               DF93D76B1444B09C007C6459 /* UDFFile.h */,
                                F56C7459131EC152000AD0F6 /* UPnPDirectory.cpp */,
                                F56C745A131EC152000AD0F6 /* UPnPDirectory.h */,
+                               DF93D76C1444B09C007C6459 /* UPnPFile.cpp */,
+                               DF93D76D1444B09C007C6459 /* UPnPFile.h */,
                                F56C7490131EC152000AD0F6 /* VideoDatabaseDirectory.cpp */,
                                F56C7491131EC152000AD0F6 /* VideoDatabaseDirectory.h */,
                                F56C7492131EC152000AD0F6 /* VirtualDirectory.cpp */,
                                F56C7498131EC152000AD0F6 /* ZeroconfDirectory.h */,
                                F56C749B131EC152000AD0F6 /* ZipDirectory.cpp */,
                                F56C749C131EC152000AD0F6 /* ZipDirectory.h */,
+                               DF93D76E1444B09C007C6459 /* ZipFile.cpp */,
+                               DF93D76F1444B09C007C6459 /* ZipFile.h */,
                                F56C749D131EC152000AD0F6 /* ZipManager.cpp */,
                                F56C749E131EC152000AD0F6 /* ZipManager.h */,
                        );
                                F56C7564131EC152000AD0F6 /* python */,
                                F56C75A3131EC152000AD0F6 /* AnnouncementManager.cpp */,
                                F56C75A4131EC152000AD0F6 /* AnnouncementManager.h */,
-                               C80711A0135DB848002F601B /* AnnouncementUtils.h */,
                                F56C75A5131EC153000AD0F6 /* Builtins.cpp */,
                                F56C75A6131EC153000AD0F6 /* Builtins.h */,
                                F56C75A7131EC153000AD0F6 /* IAnnouncer.h */,
                F56C7647131EC153000AD0F6 /* network */ = {
                        isa = PBXGroup;
                        children = (
+                               DFCA6AFD15224684000BFAAE /* httprequesthandler */,
                                F56C7648131EC153000AD0F6 /* libscrobbler */,
                                F56C7650131EC153000AD0F6 /* linux */,
                                F56C7653131EC153000AD0F6 /* osx */,
+                               DF527775151BAFD600B5B63B /* websocket */,
                                DFA6BE8513FED2A10048CC11 /* AirPlayServer.cpp */,
                                DFA6BE8613FED2A10048CC11 /* AirPlayServer.h */,
                                DF4485361400654A0069344B /* AirTunesServer.cpp */,
                                F56C7724131EC154000AD0F6 /* AsyncFileCopy.h */,
                                F56C7725131EC154000AD0F6 /* AutoPtrHandle.cpp */,
                                F56C7726131EC154000AD0F6 /* AutoPtrHandle.h */,
+                               DF527784151BAFEE00B5B63B /* Base64.cpp */,
+                               DF527785151BAFEE00B5B63B /* Base64.h */,
                                F56C7727131EC154000AD0F6 /* BitstreamStats.cpp */,
                                F56C7728131EC154000AD0F6 /* BitstreamStats.h */,
                                F56C7729131EC154000AD0F6 /* CharsetConverter.cpp */,
                                F56C7740131EC154000AD0F6 /* HttpHeader.h */,
                                DFA6BE8813FED2B40048CC11 /* HttpParser.cpp */,
                                DFA6BE8913FED2B40048CC11 /* HttpParser.h */,
+                               DF527786151BAFEE00B5B63B /* HttpResponse.cpp */,
+                               DF527787151BAFEE00B5B63B /* HttpResponse.h */,
                                F56C7741131EC154000AD0F6 /* InfoLoader.cpp */,
                                F56C7742131EC154000AD0F6 /* InfoLoader.h */,
                                F56C7747131EC154000AD0F6 /* Job.h */,
                                F56C770F131EC153000AD0F6 /* MathUtils.h */,
                                F56C774C131EC154000AD0F6 /* md5.cpp */,
                                F56C774D131EC154000AD0F6 /* md5.h */,
+                               188F76271522186C009870CE /* Mime.cpp */,
+                               188F76281522186C009870CE /* Mime.h */,
                                F56C774E131EC154000AD0F6 /* PCMAmplifier.cpp */,
                                F56C774F131EC154000AD0F6 /* PCMAmplifier.h */,
                                F56C7750131EC154000AD0F6 /* PCMRemap.cpp */,
                                F5AE40F41341751E0004BD79 /* FileItemHandler.h */,
                                F5AE40F51341751E0004BD79 /* FileOperations.cpp */,
                                F5AE40F61341751E0004BD79 /* FileOperations.h */,
+                               188F760E15221809009870CE /* GUIOperations.cpp */,
+                               188F760F15221809009870CE /* GUIOperations.h */,
                                F5AE40F71341751E0004BD79 /* IClient.h */,
+                               188F752615211773009870CE /* IJSONRPCAnnouncer.h */,
                                C807119D135DB842002F601B /* InputOperations.cpp */,
                                C807119E135DB842002F601B /* InputOperations.h */,
                                F5AE40F81341751E0004BD79 /* ITransportLayer.h */,
                                F5AE40F91341751E0004BD79 /* JSONRPC.cpp */,
                                F5AE40FA1341751E0004BD79 /* JSONRPC.h */,
+                               188F752715211780009870CE /* JSONRPCUtils.h */,
                                F5AE4539134D2E720004BD79 /* JSONServiceDescription.cpp */,
                                F5AE453A134D2E720004BD79 /* JSONServiceDescription.h */,
                                F5AE40FB1341751E0004BD79 /* JSONUtils.h */,
                                F56C7971131EC154000AD0F6 /* ASAPFileDirectory.cpp in Sources */,
                                F56C7972131EC154000AD0F6 /* MusicFileDirectory.cpp in Sources */,
                                F56C7973131EC154000AD0F6 /* MythSession.cpp in Sources */,
-                               F56C7974131EC154000AD0F6 /* FileSmb.cpp in Sources */,
                                F56C7975131EC154000AD0F6 /* SMBDirectory.cpp in Sources */,
                                F56C7976131EC154000AD0F6 /* MythDirectory.cpp in Sources */,
                                F56C7977131EC154000AD0F6 /* MythFile.cpp in Sources */,
-                               F56C7978131EC154000AD0F6 /* FileShoutcast.cpp in Sources */,
-                               F56C7979131EC154000AD0F6 /* CacheMemBuffer.cpp in Sources */,
                                F56C797A131EC154000AD0F6 /* CacheStrategy.cpp in Sources */,
                                F56C797B131EC154000AD0F6 /* CDDADirectory.cpp in Sources */,
                                F56C797C131EC154000AD0F6 /* DAAPDirectory.cpp in Sources */,
                                F56C797D131EC154000AD0F6 /* DAVDirectory.cpp in Sources */,
                                F56C797E131EC154000AD0F6 /* Directory.cpp in Sources */,
-                               F56C797F131EC154000AD0F6 /* DirectoryCache.cpp in Sources */,
                                F56C7980131EC154000AD0F6 /* DirectoryHistory.cpp in Sources */,
-                               F56C7981131EC154000AD0F6 /* DirectoryTuxBox.cpp in Sources */,
                                F56C7982131EC154000AD0F6 /* DllLibCurl.cpp in Sources */,
-                               F56C7983131EC154000AD0F6 /* FactoryDirectory.cpp in Sources */,
-                               F56C7984131EC154000AD0F6 /* FactoryFileDirectory.cpp in Sources */,
                                F56C7985131EC154000AD0F6 /* File.cpp in Sources */,
-                               F56C7986131EC154000AD0F6 /* FileCache.cpp in Sources */,
-                               F56C7987131EC154000AD0F6 /* FileCDDA.cpp in Sources */,
-                               F56C7988131EC154000AD0F6 /* FileCurl.cpp in Sources */,
-                               F56C7989131EC154000AD0F6 /* FileDAAP.cpp in Sources */,
                                F56C798A131EC154000AD0F6 /* FileFactory.cpp in Sources */,
-                               F56C798B131EC154000AD0F6 /* FileFileReader.cpp in Sources */,
-                               F56C798C131EC154000AD0F6 /* FileHD.cpp in Sources */,
-                               F56C798D131EC154000AD0F6 /* FileISO.cpp in Sources */,
-                               F56C798E131EC154000AD0F6 /* FileLastFM.cpp in Sources */,
-                               F56C798F131EC154000AD0F6 /* FileMusicDatabase.cpp in Sources */,
-                               F56C7990131EC154000AD0F6 /* FileRar.cpp in Sources */,
-                               F56C7991131EC154000AD0F6 /* FileRTV.cpp in Sources */,
-                               F56C7992131EC154000AD0F6 /* FileSFTP.cpp in Sources */,
-                               F56C7993131EC154000AD0F6 /* FileSpecialProtocol.cpp in Sources */,
-                               F56C7994131EC154000AD0F6 /* FileTuxBox.cpp in Sources */,
-                               F56C7995131EC154000AD0F6 /* FileUDF.cpp in Sources */,
-                               F56C7997131EC154000AD0F6 /* FileZip.cpp in Sources */,
                                F56C7998131EC154000AD0F6 /* FTPDirectory.cpp in Sources */,
                                F56C7999131EC154000AD0F6 /* FTPParse.cpp in Sources */,
                                F56C799A131EC154000AD0F6 /* HDDirectory.cpp in Sources */,
-                               F56C799B131EC154000AD0F6 /* HDHomeRun.cpp in Sources */,
                                F56C799C131EC154000AD0F6 /* HTSPDirectory.cpp in Sources */,
                                F56C799D131EC154000AD0F6 /* HTSPSession.cpp in Sources */,
                                F56C799E131EC154000AD0F6 /* HTTPDirectory.cpp in Sources */,
                                F56C7FB0131F36BF000AD0F6 /* DVDVideoCodecVideoToolBox.cpp in Sources */,
                                F57A1DBD1329FB0A00498CC7 /* SourcesDirectory.cpp in Sources */,
                                F5B13E0113344F310045076D /* DarwinUtils.mm in Sources */,
-                               7C99B73F133D372300FC2B16 /* CacheCircular.cpp in Sources */,
                                7C99B7AA134072CD00FC2B16 /* GUIDialogPlayEject.cpp in Sources */,
                                F5AE40EA134175160004BD79 /* HttpApi.cpp in Sources */,
                                F5AE40EB134175160004BD79 /* XBMChttp.cpp in Sources */,
                                18ACF8E313597B0000B67371 /* RecentlyAddedJob.cpp in Sources */,
                                C807119F135DB842002F601B /* InputOperations.cpp in Sources */,
                                C8EC5D51136954E400CCC10D /* XBMC_keytable.cpp in Sources */,
-                               18404DFB1396C43B00863BBA /* Slingbox.cpp in Sources */,
                                1840B796139968DB007C848B /* JSONVariantParser.cpp in Sources */,
                                1840B797139968DB007C848B /* JSONVariantWriter.cpp in Sources */,
                                7C0A7ECD13A5DBF900AFC2BD /* AppParamParser.cpp in Sources */,
                                7C0A7FC813A9E75400AFC2BD /* DirtyRegionSolvers.cpp in Sources */,
                                7C0A7FC913A9E75400AFC2BD /* DirtyRegionTracker.cpp in Sources */,
                                7C0A7FCC13A9E76E00AFC2BD /* GUIWindowDebugInfo.cpp in Sources */,
-                               DF0DF16C13A3AF82008ED511 /* FileNFS.cpp in Sources */,
                                DF0DF16D13A3AF82008ED511 /* NFSDirectory.cpp in Sources */,
                                7C89627013B702F3003631FE /* GUIWindowScreensaverDim.cpp in Sources */,
                                1830216013B8E35300770920 /* controledit.cpp in Sources */,
                                DFA6BE8A13FED2B40048CC11 /* HttpParser.cpp in Sources */,
                                18968DE814155E1D005BA742 /* ApplicationOperations.cpp in Sources */,
                                DFCFC53D1413F7F70004D0BF /* AFPDirectory.cpp in Sources */,
-                               DFCFC53E1413F7F70004D0BF /* FileAFP.cpp in Sources */,
                                32D6D47C1423A9D8003641AC /* JpegIO.cpp in Sources */,
                                DF44852F140064F40069344B /* BXAcodec.cpp in Sources */,
-                               DF4485341400651B0069344B /* FilePipe.cpp in Sources */,
                                DF4485351400651B0069344B /* PipesManager.cpp in Sources */,
                                DF4485381400654A0069344B /* AirTunesServer.cpp in Sources */,
                                DF98D9A81434F4B400A6EBE1 /* SkinVariable.cpp in Sources */,
                                F5E1132814357B6500175026 /* GUIDialogPeripheralSettings.cpp in Sources */,
                                F5E1132914357B6500175026 /* Peripherals.cpp in Sources */,
                                F5E113AD1435882400175026 /* pyrendercapture.cpp in Sources */,
-                               DF673A251443769300A5A509 /* FileUPnP.cpp in Sources */,
                                F5BD033A148D4923001B5583 /* CryptThreading.cpp in Sources */,
+                               7CCFD9AA1514952700211D82 /* PCMCodec.cpp in Sources */,
+                               DF527780151BAFD600B5B63B /* WebSocket.cpp in Sources */,
+                               DF527781151BAFD600B5B63B /* WebSocketManager.cpp in Sources */,
+                               DF527782151BAFD600B5B63B /* WebSocketV13.cpp in Sources */,
+                               DF527783151BAFD600B5B63B /* WebSocketV8.cpp in Sources */,
+                               DF527788151BAFEE00B5B63B /* Base64.cpp in Sources */,
+                               DF527789151BAFEE00B5B63B /* HttpResponse.cpp in Sources */,
+                               188F761015221809009870CE /* GUIOperations.cpp in Sources */,
+                               188F76291522186C009870CE /* Mime.cpp in Sources */,
+                               DFCA6B0B15224684000BFAAE /* HTTPApiHandler.cpp in Sources */,
+                               DFCA6B0C15224684000BFAAE /* HTTPJsonRpcHandler.cpp in Sources */,
+                               DFCA6B0D15224684000BFAAE /* HTTPVfsHandler.cpp in Sources */,
+                               DFCA6B0E15224684000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp in Sources */,
+                               DFCA6B0F15224684000BFAAE /* HTTPWebinterfaceHandler.cpp in Sources */,
+                               DFCA6B1015224684000BFAAE /* IHTTPRequestHandler.cpp in Sources */,
+                               DF93D7701444B09C007C6459 /* AFPFile.cpp in Sources */,
+                               DF93D7731444B09C007C6459 /* CDDAFile.cpp in Sources */,
+                               DF93D7741444B09C007C6459 /* CurlFile.cpp in Sources */,
+                               DF93D7751444B09C007C6459 /* DAAPFile.cpp in Sources */,
+                               DF93D7761444B09C007C6459 /* DirectoryFactory.cpp in Sources */,
+                               DF93D7771444B09C007C6459 /* FileDirectoryFactory.cpp in Sources */,
+                               DF93D7781444B09C007C6459 /* FileReaderFile.cpp in Sources */,
+                               DF93D7791444B09C007C6459 /* HDFile.cpp in Sources */,
+                               DF93D77A1444B09C007C6459 /* ISOFile.cpp in Sources */,
+                               DF93D77B1444B09C007C6459 /* LastFMFile.cpp in Sources */,
+                               DF93D77C1444B09C007C6459 /* MusicDatabaseFile.cpp in Sources */,
+                               DF93D77D1444B09C007C6459 /* NFSFile.cpp in Sources */,
+                               DF93D77E1444B09C007C6459 /* PipeFile.cpp in Sources */,
+                               DF93D77F1444B09C007C6459 /* RarFile.cpp in Sources */,
+                               DF93D7801444B09C007C6459 /* RTVFile.cpp in Sources */,
+                               DF93D7811444B09C007C6459 /* SFTPFile.cpp in Sources */,
+                               DF93D7821444B09C007C6459 /* ShoutcastFile.cpp in Sources */,
+                               DF93D7831444B09C007C6459 /* SlingboxDirectory.cpp in Sources */,
+                               DF93D7841444B09C007C6459 /* SlingboxFile.cpp in Sources */,
+                               DF93D7851444B09C007C6459 /* SmbFile.cpp in Sources */,
+                               DF93D7861444B09C007C6459 /* SpecialProtocolFile.cpp in Sources */,
+                               DF93D7871444B09C007C6459 /* TuxBoxDirectory.cpp in Sources */,
+                               DF93D7881444B09C007C6459 /* TuxBoxFile.cpp in Sources */,
+                               DF93D7891444B09C007C6459 /* UDFFile.cpp in Sources */,
+                               DF93D78A1444B09C007C6459 /* UPnPFile.cpp in Sources */,
+                               DF93D78B1444B09C007C6459 /* ZipFile.cpp in Sources */,
+                               DF93D8331444B88B007C6459 /* HDHomeRunDirectory.cpp in Sources */,
+                               DF93D8341444B88B007C6459 /* HDHomeRunFile.cpp in Sources */,
+                               DFDB00491516408F005079A4 /* CircularCache.cpp in Sources */,
+                               DFDB004A1516408F005079A4 /* DirectoryCache.cpp in Sources */,
+                               DFDB004B1516408F005079A4 /* FileCache.cpp in Sources */,
+                               DFDB004C1516408F005079A4 /* MemBufferCache.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index b2ce3c9..7dfb790 100644 (file)
@@ -9,9 +9,10 @@
 /* Begin PBXBuildFile section */
                1830219E13B8E37300770920 /* controledit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1830219D13B8E37300770920 /* controledit.cpp */; };
                18404DD31396C3D200863BBA /* SlingboxLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18404DD21396C3D200863BBA /* SlingboxLib.a */; };
-               18404DD61396C3F300863BBA /* Slingbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18404DD41396C3F300863BBA /* Slingbox.cpp */; };
                1840B77A1399616D007C848B /* JSONVariantParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1840B7761399616D007C848B /* JSONVariantParser.cpp */; };
                1840B77B1399616D007C848B /* JSONVariantWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1840B7781399616D007C848B /* JSONVariantWriter.cpp */; };
+               188F761E1522182F009870CE /* GUIOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 188F761C1522182F009870CE /* GUIOperations.cpp */; };
+               188F76211522184E009870CE /* Mime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 188F761F1522184E009870CE /* Mime.cpp */; };
                18968DDE14155E01005BA742 /* ApplicationOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18968DDC14155E01005BA742 /* ApplicationOperations.cpp */; };
                18ACF8FD13597B5700B67371 /* RecentlyAddedJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18ACF8FB13597B5700B67371 /* RecentlyAddedJob.cpp */; };
                18B700F613A6A7850009C1AF /* AddonVersion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B700F413A6A7850009C1AF /* AddonVersion.cpp */; };
                7C0A7FB213A9E72E00AFC2BD /* DirtyRegionSolvers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7FAE13A9E72E00AFC2BD /* DirtyRegionSolvers.cpp */; };
                7C0A7FB313A9E72E00AFC2BD /* DirtyRegionTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7FB013A9E72E00AFC2BD /* DirtyRegionTracker.cpp */; };
                7C89628013B7031E003631FE /* GUIWindowScreensaverDim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C89627E13B7031E003631FE /* GUIWindowScreensaverDim.cpp */; };
-               7C99B6E9133D36E200FC2B16 /* CacheCircular.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B6E7133D36E200FC2B16 /* CacheCircular.cpp */; };
                7C99B7BE1340730000FC2B16 /* GUIDialogPlayEject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B7BC1340730000FC2B16 /* GUIDialogPlayEject.cpp */; };
+               7CCFD9991514950700211D82 /* PCMCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCFD9971514950700211D82 /* PCMCodec.cpp */; };
                7CEE2E7F13D6B7D4000ABF2A /* TimeSmoother.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CEE2E7D13D6B7D4000ABF2A /* TimeSmoother.cpp */; };
                C80711AD135DB85F002F601B /* InputOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C80711AB135DB85F002F601B /* InputOperations.cpp */; };
                C8EC5D26136953E100CCC10D /* XBMC_keytable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C8EC5D24136953E100CCC10D /* XBMC_keytable.cpp */; };
-               DF0DF17F13A3AF9F008ED511 /* FileNFS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0DF17B13A3AF9F008ED511 /* FileNFS.cpp */; };
                DF0DF18013A3AF9F008ED511 /* NFSDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0DF17D13A3AF9F008ED511 /* NFSDirectory.cpp */; };
                DF3488F813FD961A0026A711 /* GUIAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF3488F613FD961A0026A711 /* GUIAction.cpp */; };
                DF44856C140065C60069344B /* BXAcodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF44856A140065C60069344B /* BXAcodec.cpp */; };
-               DF448571140065E10069344B /* FilePipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF44856D140065E10069344B /* FilePipe.cpp */; };
                DF448572140065E10069344B /* PipesManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF44856F140065E10069344B /* PipesManager.cpp */; };
                DF4485751400662D0069344B /* AirTunesServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4485731400662D0069344B /* AirTunesServer.cpp */; };
-               DF6739E21443765F00A5A509 /* FileUPnP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF6739E01443765F00A5A509 /* FileUPnP.cpp */; };
+               DF527757151BAF8200B5B63B /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52774E151BAF8200B5B63B /* WebSocket.cpp */; };
+               DF527758151BAF8200B5B63B /* WebSocketManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527750151BAF8200B5B63B /* WebSocketManager.cpp */; };
+               DF527759151BAF8200B5B63B /* WebSocketV13.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527752151BAF8200B5B63B /* WebSocketV13.cpp */; };
+               DF52775A151BAF8200B5B63B /* WebSocketV8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527754151BAF8200B5B63B /* WebSocketV8.cpp */; };
+               DF527760151BAFA000B5B63B /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52775C151BAFA000B5B63B /* Base64.cpp */; };
+               DF527761151BAFA000B5B63B /* HttpResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52775E151BAFA000B5B63B /* HttpResponse.cpp */; };
+               DF93D7CF1444B105007C6459 /* AFPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7971444B105007C6459 /* AFPFile.cpp */; };
+               DF93D7D21444B105007C6459 /* CDDAFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D79D1444B105007C6459 /* CDDAFile.cpp */; };
+               DF93D7D31444B105007C6459 /* CurlFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D79F1444B105007C6459 /* CurlFile.cpp */; };
+               DF93D7D41444B105007C6459 /* DAAPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7A11444B105007C6459 /* DAAPFile.cpp */; };
+               DF93D7D51444B105007C6459 /* DirectoryFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7A31444B105007C6459 /* DirectoryFactory.cpp */; };
+               DF93D7D61444B105007C6459 /* FileDirectoryFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7A51444B105007C6459 /* FileDirectoryFactory.cpp */; };
+               DF93D7D71444B105007C6459 /* FileReaderFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7A71444B105007C6459 /* FileReaderFile.cpp */; };
+               DF93D7D81444B105007C6459 /* HDFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7A91444B105007C6459 /* HDFile.cpp */; };
+               DF93D7D91444B105007C6459 /* ISOFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7AB1444B105007C6459 /* ISOFile.cpp */; };
+               DF93D7DA1444B105007C6459 /* LastFMFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7AD1444B105007C6459 /* LastFMFile.cpp */; };
+               DF93D7DB1444B105007C6459 /* MusicDatabaseFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7AF1444B105007C6459 /* MusicDatabaseFile.cpp */; };
+               DF93D7DC1444B105007C6459 /* NFSFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7B11444B105007C6459 /* NFSFile.cpp */; };
+               DF93D7DD1444B105007C6459 /* PipeFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7B31444B105007C6459 /* PipeFile.cpp */; };
+               DF93D7DE1444B105007C6459 /* RarFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7B51444B105007C6459 /* RarFile.cpp */; };
+               DF93D7DF1444B105007C6459 /* RTVFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7B71444B105007C6459 /* RTVFile.cpp */; };
+               DF93D7E01444B105007C6459 /* SFTPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7B91444B105007C6459 /* SFTPFile.cpp */; };
+               DF93D7E11444B105007C6459 /* ShoutcastFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7BB1444B105007C6459 /* ShoutcastFile.cpp */; };
+               DF93D7E21444B105007C6459 /* SlingboxDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7BD1444B105007C6459 /* SlingboxDirectory.cpp */; };
+               DF93D7E31444B105007C6459 /* SlingboxFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7BF1444B105007C6459 /* SlingboxFile.cpp */; };
+               DF93D7E41444B105007C6459 /* SmbFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7C11444B105007C6459 /* SmbFile.cpp */; };
+               DF93D7E51444B105007C6459 /* SpecialProtocolFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7C31444B105007C6459 /* SpecialProtocolFile.cpp */; };
+               DF93D7E61444B105007C6459 /* TuxBoxDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7C51444B105007C6459 /* TuxBoxDirectory.cpp */; };
+               DF93D7E71444B105007C6459 /* TuxBoxFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7C71444B105007C6459 /* TuxBoxFile.cpp */; };
+               DF93D7E81444B105007C6459 /* UDFFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7C91444B105007C6459 /* UDFFile.cpp */; };
+               DF93D7E91444B105007C6459 /* UPnPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7CB1444B105007C6459 /* UPnPFile.cpp */; };
+               DF93D7EA1444B105007C6459 /* ZipFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7CD1444B105007C6459 /* ZipFile.cpp */; };
+               DF93D81E1444B86B007C6459 /* HDHomeRunDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D81A1444B86B007C6459 /* HDHomeRunDirectory.cpp */; };
+               DF93D81F1444B86B007C6459 /* HDHomeRunFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D81C1444B86B007C6459 /* HDHomeRunFile.cpp */; };
                DF98D9991434F49500A6EBE1 /* SkinVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF98D9971434F49500A6EBE1 /* SkinVariable.cpp */; };
                DFA6BE4313FECA010048CC11 /* AirPlayServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA6BE4113FECA010048CC11 /* AirPlayServer.cpp */; };
                DFA6BE7713FED09C0048CC11 /* HttpParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA6BE7513FED09C0048CC11 /* HttpParser.cpp */; };
                DFAB04B013F8383300B70BFB /* InertialScrollingHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAB04AE13F8383300B70BFB /* InertialScrollingHandler.cpp */; };
+               DFCA6AEB15224671000BFAAE /* HTTPApiHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6ADE15224671000BFAAE /* HTTPApiHandler.cpp */; };
+               DFCA6AEC15224671000BFAAE /* HTTPJsonRpcHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AE015224671000BFAAE /* HTTPJsonRpcHandler.cpp */; };
+               DFCA6AED15224671000BFAAE /* HTTPVfsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AE215224671000BFAAE /* HTTPVfsHandler.cpp */; };
+               DFCA6AEE15224671000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AE415224671000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp */; };
+               DFCA6AEF15224671000BFAAE /* HTTPWebinterfaceHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AE615224671000BFAAE /* HTTPWebinterfaceHandler.cpp */; };
+               DFCA6AF015224671000BFAAE /* IHTTPRequestHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AE815224671000BFAAE /* IHTTPRequestHandler.cpp */; };
                DFCFC52A1413F7D60004D0BF /* AFPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCFC5261413F7D60004D0BF /* AFPDirectory.cpp */; };
-               DFCFC52B1413F7D60004D0BF /* FileAFP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCFC5281413F7D60004D0BF /* FileAFP.cpp */; };
                DFD4D1E213D725ED00A47C47 /* Implementation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD4D1D813D725ED00A47C47 /* Implementation.cpp */; };
                DFD4D1E713D7263000A47C47 /* README.platform in Resources */ = {isa = PBXBuildFile; fileRef = DFD4D1E613D7263000A47C47 /* README.platform */; };
                DFD4D1FE13D7283500A47C47 /* SystemClock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD4D1FC13D7283500A47C47 /* SystemClock.cpp */; };
+               DFDB00241516403A005079A4 /* CircularCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDB001C1516403A005079A4 /* CircularCache.cpp */; };
+               DFDB00251516403A005079A4 /* DirectoryCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDB001E1516403A005079A4 /* DirectoryCache.cpp */; };
+               DFDB00261516403A005079A4 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDB00201516403A005079A4 /* FileCache.cpp */; };
+               DFDB00271516403A005079A4 /* MemBufferCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDB00221516403A005079A4 /* MemBufferCache.cpp */; };
                F56B143412CAF279009B4C96 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F56B143312CAF279009B4C96 /* CoreVideo.framework */; };
                F56B14A512CAF523009B4C96 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F56B14A412CAF523009B4C96 /* AudioToolbox.framework */; };
                F56B15D512CD67A9009B4C96 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F56B15D412CD67A9009B4C96 /* CoreGraphics.framework */; };
                F56C895B131F42ED000AD0F6 /* ASAPFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8382131F42E8000AD0F6 /* ASAPFileDirectory.cpp */; };
                F56C895C131F42ED000AD0F6 /* MusicFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8384131F42E8000AD0F6 /* MusicFileDirectory.cpp */; };
                F56C895D131F42ED000AD0F6 /* MythSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8386131F42E8000AD0F6 /* MythSession.cpp */; };
-               F56C895E131F42ED000AD0F6 /* FileSmb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8387131F42E8000AD0F6 /* FileSmb.cpp */; };
                F56C895F131F42ED000AD0F6 /* SMBDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8388131F42E8000AD0F6 /* SMBDirectory.cpp */; };
                F56C8960131F42ED000AD0F6 /* MythDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8389131F42E8000AD0F6 /* MythDirectory.cpp */; };
                F56C8961131F42ED000AD0F6 /* MythFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C838B131F42E8000AD0F6 /* MythFile.cpp */; };
-               F56C8962131F42ED000AD0F6 /* FileShoutcast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C838D131F42E8000AD0F6 /* FileShoutcast.cpp */; };
-               F56C8963131F42ED000AD0F6 /* CacheMemBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C838E131F42E8000AD0F6 /* CacheMemBuffer.cpp */; };
                F56C8964131F42ED000AD0F6 /* CacheStrategy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8390131F42E8000AD0F6 /* CacheStrategy.cpp */; };
                F56C8965131F42ED000AD0F6 /* CDDADirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8392131F42E8000AD0F6 /* CDDADirectory.cpp */; };
                F56C8966131F42ED000AD0F6 /* DAAPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8394131F42E8000AD0F6 /* DAAPDirectory.cpp */; };
                F56C8967131F42ED000AD0F6 /* DAVDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8396131F42E8000AD0F6 /* DAVDirectory.cpp */; };
                F56C8968131F42ED000AD0F6 /* Directory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8398131F42E8000AD0F6 /* Directory.cpp */; };
-               F56C8969131F42ED000AD0F6 /* DirectoryCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C839A131F42E8000AD0F6 /* DirectoryCache.cpp */; };
                F56C896A131F42ED000AD0F6 /* DirectoryHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C839C131F42E8000AD0F6 /* DirectoryHistory.cpp */; };
-               F56C896B131F42ED000AD0F6 /* DirectoryTuxBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C839E131F42E8000AD0F6 /* DirectoryTuxBox.cpp */; };
                F56C896C131F42ED000AD0F6 /* DllLibCurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83A0131F42E8000AD0F6 /* DllLibCurl.cpp */; };
-               F56C896D131F42ED000AD0F6 /* FactoryDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83A2131F42E8000AD0F6 /* FactoryDirectory.cpp */; };
-               F56C896E131F42ED000AD0F6 /* FactoryFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83A4131F42E8000AD0F6 /* FactoryFileDirectory.cpp */; };
                F56C896F131F42ED000AD0F6 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83A6131F42E8000AD0F6 /* File.cpp */; };
-               F56C8970131F42ED000AD0F6 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83A8131F42E8000AD0F6 /* FileCache.cpp */; };
-               F56C8971131F42ED000AD0F6 /* FileCDDA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83AA131F42E8000AD0F6 /* FileCDDA.cpp */; };
-               F56C8972131F42ED000AD0F6 /* FileCurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83AC131F42E8000AD0F6 /* FileCurl.cpp */; };
-               F56C8973131F42ED000AD0F6 /* FileDAAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83AE131F42E8000AD0F6 /* FileDAAP.cpp */; };
                F56C8974131F42ED000AD0F6 /* FileFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83B0131F42E8000AD0F6 /* FileFactory.cpp */; };
-               F56C8975131F42ED000AD0F6 /* FileFileReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83B2131F42E8000AD0F6 /* FileFileReader.cpp */; };
-               F56C8976131F42ED000AD0F6 /* FileHD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83B4131F42E8000AD0F6 /* FileHD.cpp */; };
-               F56C8977131F42ED000AD0F6 /* FileISO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83B6131F42E8000AD0F6 /* FileISO.cpp */; };
-               F56C8978131F42ED000AD0F6 /* FileLastFM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83B8131F42E8000AD0F6 /* FileLastFM.cpp */; };
-               F56C8979131F42ED000AD0F6 /* FileMusicDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83BA131F42E8000AD0F6 /* FileMusicDatabase.cpp */; };
-               F56C897A131F42ED000AD0F6 /* FileRar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83BC131F42E8000AD0F6 /* FileRar.cpp */; };
-               F56C897B131F42ED000AD0F6 /* FileRTV.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83BE131F42E8000AD0F6 /* FileRTV.cpp */; };
-               F56C897C131F42ED000AD0F6 /* FileSFTP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83C0131F42E8000AD0F6 /* FileSFTP.cpp */; };
-               F56C897D131F42ED000AD0F6 /* FileSpecialProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83C3131F42E8000AD0F6 /* FileSpecialProtocol.cpp */; };
-               F56C897E131F42ED000AD0F6 /* FileTuxBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83C5131F42E8000AD0F6 /* FileTuxBox.cpp */; };
-               F56C897F131F42ED000AD0F6 /* FileUDF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83C7131F42E8000AD0F6 /* FileUDF.cpp */; };
-               F56C8981131F42ED000AD0F6 /* FileZip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83CB131F42E8000AD0F6 /* FileZip.cpp */; };
                F56C8982131F42ED000AD0F6 /* FTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83CD131F42E8000AD0F6 /* FTPDirectory.cpp */; };
                F56C8983131F42ED000AD0F6 /* FTPParse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83CF131F42E8000AD0F6 /* FTPParse.cpp */; };
                F56C8984131F42ED000AD0F6 /* HDDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83D1131F42E8000AD0F6 /* HDDirectory.cpp */; };
-               F56C8985131F42ED000AD0F6 /* HDHomeRun.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83D3131F42E8000AD0F6 /* HDHomeRun.cpp */; };
                F56C8986131F42ED000AD0F6 /* HTSPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83D6131F42E8000AD0F6 /* HTSPDirectory.cpp */; };
                F56C8987131F42ED000AD0F6 /* HTSPSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83D8131F42E8000AD0F6 /* HTSPSession.cpp */; };
                F56C8988131F42ED000AD0F6 /* HTTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C83DA131F42E8000AD0F6 /* HTTPDirectory.cpp */; };
 /* Begin PBXFileReference section */
                1830219D13B8E37300770920 /* controledit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = controledit.cpp; sourceTree = "<group>"; };
                18404DD21396C3D200863BBA /* SlingboxLib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = SlingboxLib.a; path = lib/SlingboxLib/SlingboxLib.a; sourceTree = "<group>"; };
-               18404DD41396C3F300863BBA /* Slingbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Slingbox.cpp; sourceTree = "<group>"; };
-               18404DD51396C3F300863BBA /* Slingbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Slingbox.h; sourceTree = "<group>"; };
                1840B7761399616D007C848B /* JSONVariantParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSONVariantParser.cpp; sourceTree = "<group>"; };
                1840B7771399616D007C848B /* JSONVariantParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONVariantParser.h; sourceTree = "<group>"; };
                1840B7781399616D007C848B /* JSONVariantWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSONVariantWriter.cpp; sourceTree = "<group>"; };
                1840B7791399616D007C848B /* JSONVariantWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONVariantWriter.h; sourceTree = "<group>"; };
+               188F7535152117AA009870CE /* IJSONRPCAnnouncer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSONRPCAnnouncer.h; sourceTree = "<group>"; };
+               188F7536152117B2009870CE /* JSONRPCUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONRPCUtils.h; sourceTree = "<group>"; };
+               188F761C1522182F009870CE /* GUIOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIOperations.cpp; sourceTree = "<group>"; };
+               188F761D1522182F009870CE /* GUIOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIOperations.h; sourceTree = "<group>"; };
+               188F761F1522184E009870CE /* Mime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mime.cpp; sourceTree = "<group>"; };
+               188F76201522184E009870CE /* Mime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mime.h; sourceTree = "<group>"; };
                18968DDC14155E01005BA742 /* ApplicationOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ApplicationOperations.cpp; sourceTree = "<group>"; };
                18968DDD14155E01005BA742 /* ApplicationOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplicationOperations.h; sourceTree = "<group>"; };
                18ACF8FB13597B5700B67371 /* RecentlyAddedJob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecentlyAddedJob.cpp; sourceTree = "<group>"; };
                7C0A7FB113A9E72E00AFC2BD /* DirtyRegionTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirtyRegionTracker.h; sourceTree = "<group>"; };
                7C89627E13B7031E003631FE /* GUIWindowScreensaverDim.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIWindowScreensaverDim.cpp; sourceTree = "<group>"; };
                7C89627F13B7031E003631FE /* GUIWindowScreensaverDim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIWindowScreensaverDim.h; sourceTree = "<group>"; };
-               7C99B6E7133D36E200FC2B16 /* CacheCircular.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheCircular.cpp; sourceTree = "<group>"; };
-               7C99B6E8133D36E200FC2B16 /* CacheCircular.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheCircular.h; sourceTree = "<group>"; };
                7C99B7BC1340730000FC2B16 /* GUIDialogPlayEject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogPlayEject.cpp; sourceTree = "<group>"; };
                7C99B7BD1340730000FC2B16 /* GUIDialogPlayEject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIDialogPlayEject.h; sourceTree = "<group>"; };
+               7CCFD9971514950700211D82 /* PCMCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMCodec.cpp; sourceTree = "<group>"; };
+               7CCFD9981514950700211D82 /* PCMCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMCodec.h; sourceTree = "<group>"; };
                7CEE2E7D13D6B7D4000ABF2A /* TimeSmoother.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeSmoother.cpp; sourceTree = "<group>"; };
                7CEE2E7E13D6B7D4000ABF2A /* TimeSmoother.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeSmoother.h; sourceTree = "<group>"; };
                83D619BB13C0D25300418A0F /* README.ios */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.ios; sourceTree = "<group>"; };
                8D576316048677EA00EA77CD /* XBMC.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XBMC.app; sourceTree = BUILT_PRODUCTS_DIR; };
                C80711AB135DB85F002F601B /* InputOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputOperations.cpp; sourceTree = "<group>"; };
                C80711AC135DB85F002F601B /* InputOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputOperations.h; sourceTree = "<group>"; };
-               C80711AE135DB865002F601B /* AnnouncementUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnnouncementUtils.h; sourceTree = "<group>"; };
                C8EC5D24136953E100CCC10D /* XBMC_keytable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XBMC_keytable.cpp; sourceTree = "<group>"; };
                C8EC5D25136953E100CCC10D /* XBMC_keytable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMC_keytable.h; sourceTree = "<group>"; };
-               DF0DF17B13A3AF9F008ED511 /* FileNFS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileNFS.cpp; sourceTree = "<group>"; };
-               DF0DF17C13A3AF9F008ED511 /* FileNFS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileNFS.h; sourceTree = "<group>"; };
                DF0DF17D13A3AF9F008ED511 /* NFSDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NFSDirectory.cpp; sourceTree = "<group>"; };
                DF0DF17E13A3AF9F008ED511 /* NFSDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NFSDirectory.h; sourceTree = "<group>"; };
                DF3488F613FD961A0026A711 /* GUIAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIAction.cpp; sourceTree = "<group>"; };
                DF3488F713FD961A0026A711 /* GUIAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIAction.h; sourceTree = "<group>"; };
                DF44856A140065C60069344B /* BXAcodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BXAcodec.cpp; sourceTree = "<group>"; };
                DF44856B140065C60069344B /* BXAcodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BXAcodec.h; sourceTree = "<group>"; };
-               DF44856D140065E10069344B /* FilePipe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FilePipe.cpp; sourceTree = "<group>"; };
-               DF44856E140065E10069344B /* FilePipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilePipe.h; sourceTree = "<group>"; };
                DF44856F140065E10069344B /* PipesManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipesManager.cpp; sourceTree = "<group>"; };
                DF448570140065E10069344B /* PipesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PipesManager.h; sourceTree = "<group>"; };
                DF4485731400662D0069344B /* AirTunesServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirTunesServer.cpp; sourceTree = "<group>"; };
                DF4485741400662D0069344B /* AirTunesServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirTunesServer.h; sourceTree = "<group>"; };
-               DF6739E01443765F00A5A509 /* FileUPnP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileUPnP.cpp; sourceTree = "<group>"; };
-               DF6739E11443765F00A5A509 /* FileUPnP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileUPnP.h; sourceTree = "<group>"; };
+               DF52774E151BAF8200B5B63B /* WebSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocket.cpp; sourceTree = "<group>"; };
+               DF52774F151BAF8200B5B63B /* WebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocket.h; sourceTree = "<group>"; };
+               DF527750151BAF8200B5B63B /* WebSocketManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketManager.cpp; sourceTree = "<group>"; };
+               DF527751151BAF8200B5B63B /* WebSocketManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketManager.h; sourceTree = "<group>"; };
+               DF527752151BAF8200B5B63B /* WebSocketV13.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketV13.cpp; sourceTree = "<group>"; };
+               DF527753151BAF8200B5B63B /* WebSocketV13.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketV13.h; sourceTree = "<group>"; };
+               DF527754151BAF8200B5B63B /* WebSocketV8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketV8.cpp; sourceTree = "<group>"; };
+               DF527755151BAF8200B5B63B /* WebSocketV8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketV8.h; sourceTree = "<group>"; };
+               DF52775C151BAFA000B5B63B /* Base64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Base64.cpp; sourceTree = "<group>"; };
+               DF52775D151BAFA000B5B63B /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = "<group>"; };
+               DF52775E151BAFA000B5B63B /* HttpResponse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpResponse.cpp; sourceTree = "<group>"; };
+               DF52775F151BAFA000B5B63B /* HttpResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpResponse.h; sourceTree = "<group>"; };
+               DF93D7971444B105007C6459 /* AFPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AFPFile.cpp; sourceTree = "<group>"; };
+               DF93D7981444B105007C6459 /* AFPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFPFile.h; sourceTree = "<group>"; };
+               DF93D79D1444B105007C6459 /* CDDAFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDDAFile.cpp; sourceTree = "<group>"; };
+               DF93D79E1444B105007C6459 /* CDDAFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDDAFile.h; sourceTree = "<group>"; };
+               DF93D79F1444B105007C6459 /* CurlFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CurlFile.cpp; sourceTree = "<group>"; };
+               DF93D7A01444B105007C6459 /* CurlFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CurlFile.h; sourceTree = "<group>"; };
+               DF93D7A11444B105007C6459 /* DAAPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DAAPFile.cpp; sourceTree = "<group>"; };
+               DF93D7A21444B105007C6459 /* DAAPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DAAPFile.h; sourceTree = "<group>"; };
+               DF93D7A31444B105007C6459 /* DirectoryFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryFactory.cpp; sourceTree = "<group>"; };
+               DF93D7A41444B105007C6459 /* DirectoryFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryFactory.h; sourceTree = "<group>"; };
+               DF93D7A51444B105007C6459 /* FileDirectoryFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileDirectoryFactory.cpp; sourceTree = "<group>"; };
+               DF93D7A61444B105007C6459 /* FileDirectoryFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileDirectoryFactory.h; sourceTree = "<group>"; };
+               DF93D7A71444B105007C6459 /* FileReaderFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileReaderFile.cpp; sourceTree = "<group>"; };
+               DF93D7A81444B105007C6459 /* FileReaderFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileReaderFile.h; sourceTree = "<group>"; };
+               DF93D7A91444B105007C6459 /* HDFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDFile.cpp; sourceTree = "<group>"; };
+               DF93D7AA1444B105007C6459 /* HDFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDFile.h; sourceTree = "<group>"; };
+               DF93D7AB1444B105007C6459 /* ISOFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ISOFile.cpp; sourceTree = "<group>"; };
+               DF93D7AC1444B105007C6459 /* ISOFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISOFile.h; sourceTree = "<group>"; };
+               DF93D7AD1444B105007C6459 /* LastFMFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LastFMFile.cpp; sourceTree = "<group>"; };
+               DF93D7AE1444B105007C6459 /* LastFMFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LastFMFile.h; sourceTree = "<group>"; };
+               DF93D7AF1444B105007C6459 /* MusicDatabaseFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MusicDatabaseFile.cpp; sourceTree = "<group>"; };
+               DF93D7B01444B105007C6459 /* MusicDatabaseFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicDatabaseFile.h; sourceTree = "<group>"; };
+               DF93D7B11444B105007C6459 /* NFSFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NFSFile.cpp; sourceTree = "<group>"; };
+               DF93D7B21444B105007C6459 /* NFSFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NFSFile.h; sourceTree = "<group>"; };
+               DF93D7B31444B105007C6459 /* PipeFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipeFile.cpp; sourceTree = "<group>"; };
+               DF93D7B41444B105007C6459 /* PipeFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PipeFile.h; sourceTree = "<group>"; };
+               DF93D7B51444B105007C6459 /* RarFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RarFile.cpp; sourceTree = "<group>"; };
+               DF93D7B61444B105007C6459 /* RarFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RarFile.h; sourceTree = "<group>"; };
+               DF93D7B71444B105007C6459 /* RTVFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTVFile.cpp; sourceTree = "<group>"; };
+               DF93D7B81444B105007C6459 /* RTVFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTVFile.h; sourceTree = "<group>"; };
+               DF93D7B91444B105007C6459 /* SFTPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SFTPFile.cpp; sourceTree = "<group>"; };
+               DF93D7BA1444B105007C6459 /* SFTPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SFTPFile.h; sourceTree = "<group>"; };
+               DF93D7BB1444B105007C6459 /* ShoutcastFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShoutcastFile.cpp; sourceTree = "<group>"; };
+               DF93D7BC1444B105007C6459 /* ShoutcastFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShoutcastFile.h; sourceTree = "<group>"; };
+               DF93D7BD1444B105007C6459 /* SlingboxDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlingboxDirectory.cpp; sourceTree = "<group>"; };
+               DF93D7BE1444B105007C6459 /* SlingboxDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlingboxDirectory.h; sourceTree = "<group>"; };
+               DF93D7BF1444B105007C6459 /* SlingboxFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlingboxFile.cpp; sourceTree = "<group>"; };
+               DF93D7C01444B105007C6459 /* SlingboxFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlingboxFile.h; sourceTree = "<group>"; };
+               DF93D7C11444B105007C6459 /* SmbFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SmbFile.cpp; sourceTree = "<group>"; };
+               DF93D7C21444B105007C6459 /* SmbFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmbFile.h; sourceTree = "<group>"; };
+               DF93D7C31444B105007C6459 /* SpecialProtocolFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialProtocolFile.cpp; sourceTree = "<group>"; };
+               DF93D7C41444B105007C6459 /* SpecialProtocolFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialProtocolFile.h; sourceTree = "<group>"; };
+               DF93D7C51444B105007C6459 /* TuxBoxDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TuxBoxDirectory.cpp; sourceTree = "<group>"; };
+               DF93D7C61444B105007C6459 /* TuxBoxDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TuxBoxDirectory.h; sourceTree = "<group>"; };
+               DF93D7C71444B105007C6459 /* TuxBoxFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TuxBoxFile.cpp; sourceTree = "<group>"; };
+               DF93D7C81444B105007C6459 /* TuxBoxFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TuxBoxFile.h; sourceTree = "<group>"; };
+               DF93D7C91444B105007C6459 /* UDFFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UDFFile.cpp; sourceTree = "<group>"; };
+               DF93D7CA1444B105007C6459 /* UDFFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UDFFile.h; sourceTree = "<group>"; };
+               DF93D7CB1444B105007C6459 /* UPnPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UPnPFile.cpp; sourceTree = "<group>"; };
+               DF93D7CC1444B105007C6459 /* UPnPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPnPFile.h; sourceTree = "<group>"; };
+               DF93D7CD1444B105007C6459 /* ZipFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZipFile.cpp; sourceTree = "<group>"; };
+               DF93D7CE1444B105007C6459 /* ZipFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZipFile.h; sourceTree = "<group>"; };
+               DF93D81A1444B86B007C6459 /* HDHomeRunDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDHomeRunDirectory.cpp; sourceTree = "<group>"; };
+               DF93D81B1444B86B007C6459 /* HDHomeRunDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDHomeRunDirectory.h; sourceTree = "<group>"; };
+               DF93D81C1444B86B007C6459 /* HDHomeRunFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDHomeRunFile.cpp; sourceTree = "<group>"; };
+               DF93D81D1444B86B007C6459 /* HDHomeRunFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDHomeRunFile.h; sourceTree = "<group>"; };
                DF98D9971434F49500A6EBE1 /* SkinVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkinVariable.cpp; sourceTree = "<group>"; };
                DF98D9981434F49500A6EBE1 /* SkinVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkinVariable.h; sourceTree = "<group>"; };
                DFA6BE4113FECA010048CC11 /* AirPlayServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirPlayServer.cpp; sourceTree = "<group>"; };
                DFA6BE7613FED09C0048CC11 /* HttpParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpParser.h; sourceTree = "<group>"; };
                DFAB04AE13F8383300B70BFB /* InertialScrollingHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InertialScrollingHandler.cpp; sourceTree = "<group>"; };
                DFAB04AF13F8383300B70BFB /* InertialScrollingHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InertialScrollingHandler.h; sourceTree = "<group>"; };
+               DFCA6ADE15224671000BFAAE /* HTTPApiHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPApiHandler.cpp; sourceTree = "<group>"; };
+               DFCA6ADF15224671000BFAAE /* HTTPApiHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPApiHandler.h; sourceTree = "<group>"; };
+               DFCA6AE015224671000BFAAE /* HTTPJsonRpcHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPJsonRpcHandler.cpp; sourceTree = "<group>"; };
+               DFCA6AE115224671000BFAAE /* HTTPJsonRpcHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPJsonRpcHandler.h; sourceTree = "<group>"; };
+               DFCA6AE215224671000BFAAE /* HTTPVfsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPVfsHandler.cpp; sourceTree = "<group>"; };
+               DFCA6AE315224671000BFAAE /* HTTPVfsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPVfsHandler.h; sourceTree = "<group>"; };
+               DFCA6AE415224671000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPWebinterfaceAddonsHandler.cpp; sourceTree = "<group>"; };
+               DFCA6AE515224671000BFAAE /* HTTPWebinterfaceAddonsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPWebinterfaceAddonsHandler.h; sourceTree = "<group>"; };
+               DFCA6AE615224671000BFAAE /* HTTPWebinterfaceHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPWebinterfaceHandler.cpp; sourceTree = "<group>"; };
+               DFCA6AE715224671000BFAAE /* HTTPWebinterfaceHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPWebinterfaceHandler.h; sourceTree = "<group>"; };
+               DFCA6AE815224671000BFAAE /* IHTTPRequestHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IHTTPRequestHandler.cpp; sourceTree = "<group>"; };
+               DFCA6AE915224671000BFAAE /* IHTTPRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IHTTPRequestHandler.h; sourceTree = "<group>"; };
                DFCFC5261413F7D60004D0BF /* AFPDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AFPDirectory.cpp; sourceTree = "<group>"; };
                DFCFC5271413F7D60004D0BF /* AFPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFPDirectory.h; sourceTree = "<group>"; };
-               DFCFC5281413F7D60004D0BF /* FileAFP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileAFP.cpp; sourceTree = "<group>"; };
-               DFCFC5291413F7D60004D0BF /* FileAFP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileAFP.h; sourceTree = "<group>"; };
                DFD4D1D113D725ED00A47C47 /* Condition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Condition.h; sourceTree = "<group>"; };
                DFD4D1D213D725ED00A47C47 /* CriticalSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CriticalSection.h; sourceTree = "<group>"; };
                DFD4D1D613D725ED00A47C47 /* Condition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Condition.h; sourceTree = "<group>"; };
                DFD4D1E613D7263000A47C47 /* README.platform */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.platform; sourceTree = "<group>"; };
                DFD4D1FC13D7283500A47C47 /* SystemClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SystemClock.cpp; sourceTree = "<group>"; };
                DFD4D1FD13D7283500A47C47 /* SystemClock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SystemClock.h; sourceTree = "<group>"; };
+               DFDB001C1516403A005079A4 /* CircularCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CircularCache.cpp; sourceTree = "<group>"; };
+               DFDB001D1516403A005079A4 /* CircularCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CircularCache.h; sourceTree = "<group>"; };
+               DFDB001E1516403A005079A4 /* DirectoryCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryCache.cpp; sourceTree = "<group>"; };
+               DFDB001F1516403A005079A4 /* DirectoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryCache.h; sourceTree = "<group>"; };
+               DFDB00201516403A005079A4 /* FileCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCache.cpp; sourceTree = "<group>"; };
+               DFDB00211516403A005079A4 /* FileCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCache.h; sourceTree = "<group>"; };
+               DFDB00221516403A005079A4 /* MemBufferCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemBufferCache.cpp; sourceTree = "<group>"; };
+               DFDB00231516403A005079A4 /* MemBufferCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemBufferCache.h; sourceTree = "<group>"; };
                F558F60613AFDC1700631E12 /* Condition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Condition.h; sourceTree = "<group>"; };
                F558F61013AFDC3000631E12 /* ThreadLocal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadLocal.h; sourceTree = "<group>"; };
                F56B143312CAF279009B4C96 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
                F56C8384131F42E8000AD0F6 /* MusicFileDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MusicFileDirectory.cpp; sourceTree = "<group>"; };
                F56C8385131F42E8000AD0F6 /* MusicFileDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicFileDirectory.h; sourceTree = "<group>"; };
                F56C8386131F42E8000AD0F6 /* MythSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MythSession.cpp; sourceTree = "<group>"; };
-               F56C8387131F42E8000AD0F6 /* FileSmb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSmb.cpp; sourceTree = "<group>"; };
                F56C8388131F42E8000AD0F6 /* SMBDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SMBDirectory.cpp; sourceTree = "<group>"; };
                F56C8389131F42E8000AD0F6 /* MythDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MythDirectory.cpp; sourceTree = "<group>"; };
                F56C838A131F42E8000AD0F6 /* MythDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MythDirectory.h; sourceTree = "<group>"; };
                F56C838B131F42E8000AD0F6 /* MythFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MythFile.cpp; sourceTree = "<group>"; };
                F56C838C131F42E8000AD0F6 /* MythFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MythFile.h; sourceTree = "<group>"; };
-               F56C838D131F42E8000AD0F6 /* FileShoutcast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileShoutcast.cpp; sourceTree = "<group>"; };
-               F56C838E131F42E8000AD0F6 /* CacheMemBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheMemBuffer.cpp; sourceTree = "<group>"; };
-               F56C838F131F42E8000AD0F6 /* CacheMemBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheMemBuffer.h; sourceTree = "<group>"; };
                F56C8390131F42E8000AD0F6 /* CacheStrategy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStrategy.cpp; sourceTree = "<group>"; };
                F56C8391131F42E8000AD0F6 /* CacheStrategy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheStrategy.h; sourceTree = "<group>"; };
                F56C8392131F42E8000AD0F6 /* CDDADirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDDADirectory.cpp; sourceTree = "<group>"; };
                F56C8397131F42E8000AD0F6 /* DAVDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DAVDirectory.h; sourceTree = "<group>"; };
                F56C8398131F42E8000AD0F6 /* Directory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Directory.cpp; sourceTree = "<group>"; };
                F56C8399131F42E8000AD0F6 /* Directory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Directory.h; sourceTree = "<group>"; };
-               F56C839A131F42E8000AD0F6 /* DirectoryCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryCache.cpp; sourceTree = "<group>"; };
-               F56C839B131F42E8000AD0F6 /* DirectoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryCache.h; sourceTree = "<group>"; };
                F56C839C131F42E8000AD0F6 /* DirectoryHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryHistory.cpp; sourceTree = "<group>"; };
                F56C839D131F42E8000AD0F6 /* DirectoryHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryHistory.h; sourceTree = "<group>"; };
-               F56C839E131F42E8000AD0F6 /* DirectoryTuxBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryTuxBox.cpp; sourceTree = "<group>"; };
-               F56C839F131F42E8000AD0F6 /* DirectoryTuxBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryTuxBox.h; sourceTree = "<group>"; };
                F56C83A0131F42E8000AD0F6 /* DllLibCurl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DllLibCurl.cpp; sourceTree = "<group>"; };
                F56C83A1131F42E8000AD0F6 /* DllLibCurl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DllLibCurl.h; sourceTree = "<group>"; };
-               F56C83A2131F42E8000AD0F6 /* FactoryDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FactoryDirectory.cpp; sourceTree = "<group>"; };
-               F56C83A3131F42E8000AD0F6 /* FactoryDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FactoryDirectory.h; sourceTree = "<group>"; };
-               F56C83A4131F42E8000AD0F6 /* FactoryFileDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FactoryFileDirectory.cpp; sourceTree = "<group>"; };
-               F56C83A5131F42E8000AD0F6 /* FactoryFileDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FactoryFileDirectory.h; sourceTree = "<group>"; };
                F56C83A6131F42E8000AD0F6 /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = File.cpp; sourceTree = "<group>"; };
                F56C83A7131F42E8000AD0F6 /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = File.h; sourceTree = "<group>"; };
-               F56C83A8131F42E8000AD0F6 /* FileCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCache.cpp; sourceTree = "<group>"; };
-               F56C83A9131F42E8000AD0F6 /* FileCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCache.h; sourceTree = "<group>"; };
-               F56C83AA131F42E8000AD0F6 /* FileCDDA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCDDA.cpp; sourceTree = "<group>"; };
-               F56C83AB131F42E8000AD0F6 /* FileCDDA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCDDA.h; sourceTree = "<group>"; };
-               F56C83AC131F42E8000AD0F6 /* FileCurl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCurl.cpp; sourceTree = "<group>"; };
-               F56C83AD131F42E8000AD0F6 /* FileCurl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCurl.h; sourceTree = "<group>"; };
-               F56C83AE131F42E8000AD0F6 /* FileDAAP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileDAAP.cpp; sourceTree = "<group>"; };
-               F56C83AF131F42E8000AD0F6 /* FileDAAP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileDAAP.h; sourceTree = "<group>"; };
                F56C83B0131F42E8000AD0F6 /* FileFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFactory.cpp; sourceTree = "<group>"; };
                F56C83B1131F42E8000AD0F6 /* FileFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileFactory.h; sourceTree = "<group>"; };
-               F56C83B2131F42E8000AD0F6 /* FileFileReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFileReader.cpp; sourceTree = "<group>"; };
-               F56C83B3131F42E8000AD0F6 /* FileFileReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileFileReader.h; sourceTree = "<group>"; };
-               F56C83B4131F42E8000AD0F6 /* FileHD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileHD.cpp; sourceTree = "<group>"; };
-               F56C83B5131F42E8000AD0F6 /* FileHD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileHD.h; sourceTree = "<group>"; };
-               F56C83B6131F42E8000AD0F6 /* FileISO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileISO.cpp; sourceTree = "<group>"; };
-               F56C83B7131F42E8000AD0F6 /* FileISO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileISO.h; sourceTree = "<group>"; };
-               F56C83B8131F42E8000AD0F6 /* FileLastFM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileLastFM.cpp; sourceTree = "<group>"; };
-               F56C83B9131F42E8000AD0F6 /* FileLastFM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileLastFM.h; sourceTree = "<group>"; };
-               F56C83BA131F42E8000AD0F6 /* FileMusicDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileMusicDatabase.cpp; sourceTree = "<group>"; };
-               F56C83BB131F42E8000AD0F6 /* FileMusicDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileMusicDatabase.h; sourceTree = "<group>"; };
-               F56C83BC131F42E8000AD0F6 /* FileRar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileRar.cpp; sourceTree = "<group>"; };
-               F56C83BD131F42E8000AD0F6 /* FileRar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileRar.h; sourceTree = "<group>"; };
-               F56C83BE131F42E8000AD0F6 /* FileRTV.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileRTV.cpp; sourceTree = "<group>"; };
-               F56C83BF131F42E8000AD0F6 /* FileRTV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileRTV.h; sourceTree = "<group>"; };
-               F56C83C0131F42E8000AD0F6 /* FileSFTP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSFTP.cpp; sourceTree = "<group>"; };
-               F56C83C1131F42E8000AD0F6 /* FileSFTP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSFTP.h; sourceTree = "<group>"; };
-               F56C83C2131F42E8000AD0F6 /* FileSmb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSmb.h; sourceTree = "<group>"; };
-               F56C83C3131F42E8000AD0F6 /* FileSpecialProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSpecialProtocol.cpp; sourceTree = "<group>"; };
-               F56C83C4131F42E8000AD0F6 /* FileSpecialProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSpecialProtocol.h; sourceTree = "<group>"; };
-               F56C83C5131F42E8000AD0F6 /* FileTuxBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileTuxBox.cpp; sourceTree = "<group>"; };
-               F56C83C6131F42E8000AD0F6 /* FileTuxBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileTuxBox.h; sourceTree = "<group>"; };
-               F56C83C7131F42E8000AD0F6 /* FileUDF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileUDF.cpp; sourceTree = "<group>"; };
-               F56C83C8131F42E8000AD0F6 /* FileUDF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileUDF.h; sourceTree = "<group>"; };
-               F56C83CB131F42E8000AD0F6 /* FileZip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileZip.cpp; sourceTree = "<group>"; };
-               F56C83CC131F42E8000AD0F6 /* FileZip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileZip.h; sourceTree = "<group>"; };
                F56C83CD131F42E8000AD0F6 /* FTPDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FTPDirectory.cpp; sourceTree = "<group>"; };
                F56C83CE131F42E8000AD0F6 /* FTPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FTPDirectory.h; sourceTree = "<group>"; };
                F56C83CF131F42E8000AD0F6 /* FTPParse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FTPParse.cpp; sourceTree = "<group>"; };
                F56C83D0131F42E8000AD0F6 /* FTPParse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FTPParse.h; sourceTree = "<group>"; };
                F56C83D1131F42E8000AD0F6 /* HDDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDDirectory.cpp; sourceTree = "<group>"; };
                F56C83D2131F42E8000AD0F6 /* HDDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDDirectory.h; sourceTree = "<group>"; };
-               F56C83D3131F42E8000AD0F6 /* HDHomeRun.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDHomeRun.cpp; sourceTree = "<group>"; };
-               F56C83D4131F42E8000AD0F6 /* HDHomeRun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDHomeRun.h; sourceTree = "<group>"; };
                F56C83D5131F42E8000AD0F6 /* HTSPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTSPDirectory.h; sourceTree = "<group>"; };
                F56C83D6131F42E8000AD0F6 /* HTSPDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTSPDirectory.cpp; sourceTree = "<group>"; };
                F56C83D7131F42E8000AD0F6 /* HTSPSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTSPSession.h; sourceTree = "<group>"; };
                        name = Documentation;
                        sourceTree = "<group>";
                };
+               DF52774C151BAF8200B5B63B /* websocket */ = {
+                       isa = PBXGroup;
+                       children = (
+                               DF52774E151BAF8200B5B63B /* WebSocket.cpp */,
+                               DF52774F151BAF8200B5B63B /* WebSocket.h */,
+                               DF527750151BAF8200B5B63B /* WebSocketManager.cpp */,
+                               DF527751151BAF8200B5B63B /* WebSocketManager.h */,
+                               DF527752151BAF8200B5B63B /* WebSocketV13.cpp */,
+                               DF527753151BAF8200B5B63B /* WebSocketV13.h */,
+                               DF527754151BAF8200B5B63B /* WebSocketV8.cpp */,
+                               DF527755151BAF8200B5B63B /* WebSocketV8.h */,
+                       );
+                       path = websocket;
+                       sourceTree = "<group>";
+               };
+               DFCA6ADD15224671000BFAAE /* httprequesthandler */ = {
+                       isa = PBXGroup;
+                       children = (
+                               DFCA6ADE15224671000BFAAE /* HTTPApiHandler.cpp */,
+                               DFCA6ADF15224671000BFAAE /* HTTPApiHandler.h */,
+                               DFCA6AE015224671000BFAAE /* HTTPJsonRpcHandler.cpp */,
+                               DFCA6AE115224671000BFAAE /* HTTPJsonRpcHandler.h */,
+                               DFCA6AE215224671000BFAAE /* HTTPVfsHandler.cpp */,
+                               DFCA6AE315224671000BFAAE /* HTTPVfsHandler.h */,
+                               DFCA6AE415224671000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp */,
+                               DFCA6AE515224671000BFAAE /* HTTPWebinterfaceAddonsHandler.h */,
+                               DFCA6AE615224671000BFAAE /* HTTPWebinterfaceHandler.cpp */,
+                               DFCA6AE715224671000BFAAE /* HTTPWebinterfaceHandler.h */,
+                               DFCA6AE815224671000BFAAE /* IHTTPRequestHandler.cpp */,
+                               DFCA6AE915224671000BFAAE /* IHTTPRequestHandler.h */,
+                       );
+                       path = httprequesthandler;
+                       sourceTree = "<group>";
+               };
                DFD4D1D013D725ED00A47C47 /* platform */ = {
                        isa = PBXGroup;
                        children = (
                                F56C8323131F42E7000AD0F6 /* OGGcodec.h */,
                                F56C8324131F42E7000AD0F6 /* PAPlayer.cpp */,
                                F56C8325131F42E7000AD0F6 /* PAPlayer.h */,
+                               7CCFD9971514950700211D82 /* PCMCodec.cpp */,
+                               7CCFD9981514950700211D82 /* PCMCodec.h */,
                                F56C8326131F42E7000AD0F6 /* ReplayGain.cpp */,
                                F56C8327131F42E7000AD0F6 /* ReplayGain.h */,
                                F56C8328131F42E7000AD0F6 /* SIDCodec.cpp */,
                                F56C8380131F42E8000AD0F6 /* AddonsDirectory.h */,
                                DFCFC5261413F7D60004D0BF /* AFPDirectory.cpp */,
                                DFCFC5271413F7D60004D0BF /* AFPDirectory.h */,
+                               DF93D7971444B105007C6459 /* AFPFile.cpp */,
+                               DF93D7981444B105007C6459 /* AFPFile.h */,
                                F56C8382131F42E8000AD0F6 /* ASAPFileDirectory.cpp */,
                                F56C8383131F42E8000AD0F6 /* ASAPFileDirectory.h */,
-                               7C99B6E7133D36E200FC2B16 /* CacheCircular.cpp */,
-                               7C99B6E8133D36E200FC2B16 /* CacheCircular.h */,
-                               F56C838E131F42E8000AD0F6 /* CacheMemBuffer.cpp */,
-                               F56C838F131F42E8000AD0F6 /* CacheMemBuffer.h */,
                                F56C8390131F42E8000AD0F6 /* CacheStrategy.cpp */,
                                F56C8391131F42E8000AD0F6 /* CacheStrategy.h */,
                                F56C8392131F42E8000AD0F6 /* CDDADirectory.cpp */,
                                F56C8393131F42E8000AD0F6 /* CDDADirectory.h */,
+                               DF93D79D1444B105007C6459 /* CDDAFile.cpp */,
+                               DF93D79E1444B105007C6459 /* CDDAFile.h */,
+                               DFDB001C1516403A005079A4 /* CircularCache.cpp */,
+                               DFDB001D1516403A005079A4 /* CircularCache.h */,
+                               DF93D79F1444B105007C6459 /* CurlFile.cpp */,
+                               DF93D7A01444B105007C6459 /* CurlFile.h */,
                                F56C8394131F42E8000AD0F6 /* DAAPDirectory.cpp */,
                                F56C8395131F42E8000AD0F6 /* DAAPDirectory.h */,
+                               DF93D7A11444B105007C6459 /* DAAPFile.cpp */,
+                               DF93D7A21444B105007C6459 /* DAAPFile.h */,
                                F56C8396131F42E8000AD0F6 /* DAVDirectory.cpp */,
                                F56C8397131F42E8000AD0F6 /* DAVDirectory.h */,
                                F56C8398131F42E8000AD0F6 /* Directory.cpp */,
                                F56C8399131F42E8000AD0F6 /* Directory.h */,
-                               F56C839A131F42E8000AD0F6 /* DirectoryCache.cpp */,
-                               F56C839B131F42E8000AD0F6 /* DirectoryCache.h */,
+                               DFDB001E1516403A005079A4 /* DirectoryCache.cpp */,
+                               DFDB001F1516403A005079A4 /* DirectoryCache.h */,
+                               DF93D7A31444B105007C6459 /* DirectoryFactory.cpp */,
+                               DF93D7A41444B105007C6459 /* DirectoryFactory.h */,
                                F56C839C131F42E8000AD0F6 /* DirectoryHistory.cpp */,
                                F56C839D131F42E8000AD0F6 /* DirectoryHistory.h */,
-                               F56C839E131F42E8000AD0F6 /* DirectoryTuxBox.cpp */,
-                               F56C839F131F42E8000AD0F6 /* DirectoryTuxBox.h */,
                                F56C83A0131F42E8000AD0F6 /* DllLibCurl.cpp */,
                                F56C83A1131F42E8000AD0F6 /* DllLibCurl.h */,
-                               F56C83A2131F42E8000AD0F6 /* FactoryDirectory.cpp */,
-                               F56C83A3131F42E8000AD0F6 /* FactoryDirectory.h */,
-                               F56C83A4131F42E8000AD0F6 /* FactoryFileDirectory.cpp */,
-                               F56C83A5131F42E8000AD0F6 /* FactoryFileDirectory.h */,
                                F56C83A6131F42E8000AD0F6 /* File.cpp */,
                                F56C83A7131F42E8000AD0F6 /* File.h */,
-                               DFCFC5281413F7D60004D0BF /* FileAFP.cpp */,
-                               DFCFC5291413F7D60004D0BF /* FileAFP.h */,
-                               F56C83A8131F42E8000AD0F6 /* FileCache.cpp */,
-                               F56C83A9131F42E8000AD0F6 /* FileCache.h */,
-                               F56C83AA131F42E8000AD0F6 /* FileCDDA.cpp */,
-                               F56C83AB131F42E8000AD0F6 /* FileCDDA.h */,
-                               F56C83AC131F42E8000AD0F6 /* FileCurl.cpp */,
-                               F56C83AD131F42E8000AD0F6 /* FileCurl.h */,
-                               F56C83AE131F42E8000AD0F6 /* FileDAAP.cpp */,
-                               F56C83AF131F42E8000AD0F6 /* FileDAAP.h */,
+                               DFDB00201516403A005079A4 /* FileCache.cpp */,
+                               DFDB00211516403A005079A4 /* FileCache.h */,
+                               DF93D7A51444B105007C6459 /* FileDirectoryFactory.cpp */,
+                               DF93D7A61444B105007C6459 /* FileDirectoryFactory.h */,
                                F56C83B0131F42E8000AD0F6 /* FileFactory.cpp */,
                                F56C83B1131F42E8000AD0F6 /* FileFactory.h */,
-                               F56C83B2131F42E8000AD0F6 /* FileFileReader.cpp */,
-                               F56C83B3131F42E8000AD0F6 /* FileFileReader.h */,
-                               F56C83B4131F42E8000AD0F6 /* FileHD.cpp */,
-                               F56C83B5131F42E8000AD0F6 /* FileHD.h */,
-                               F56C83B6131F42E8000AD0F6 /* FileISO.cpp */,
-                               F56C83B7131F42E8000AD0F6 /* FileISO.h */,
-                               F56C83B8131F42E8000AD0F6 /* FileLastFM.cpp */,
-                               F56C83B9131F42E8000AD0F6 /* FileLastFM.h */,
-                               F56C83BA131F42E8000AD0F6 /* FileMusicDatabase.cpp */,
-                               F56C83BB131F42E8000AD0F6 /* FileMusicDatabase.h */,
-                               DF0DF17B13A3AF9F008ED511 /* FileNFS.cpp */,
-                               DF0DF17C13A3AF9F008ED511 /* FileNFS.h */,
-                               DF44856D140065E10069344B /* FilePipe.cpp */,
-                               DF44856E140065E10069344B /* FilePipe.h */,
-                               F56C83BC131F42E8000AD0F6 /* FileRar.cpp */,
-                               F56C83BD131F42E8000AD0F6 /* FileRar.h */,
-                               F56C83BE131F42E8000AD0F6 /* FileRTV.cpp */,
-                               F56C83BF131F42E8000AD0F6 /* FileRTV.h */,
-                               F56C83C0131F42E8000AD0F6 /* FileSFTP.cpp */,
-                               F56C83C1131F42E8000AD0F6 /* FileSFTP.h */,
-                               F56C838D131F42E8000AD0F6 /* FileShoutcast.cpp */,
-                               F56C8387131F42E8000AD0F6 /* FileSmb.cpp */,
-                               F56C83C2131F42E8000AD0F6 /* FileSmb.h */,
-                               F56C83C3131F42E8000AD0F6 /* FileSpecialProtocol.cpp */,
-                               F56C83C4131F42E8000AD0F6 /* FileSpecialProtocol.h */,
-                               F56C83C5131F42E8000AD0F6 /* FileTuxBox.cpp */,
-                               F56C83C6131F42E8000AD0F6 /* FileTuxBox.h */,
-                               F56C83C7131F42E8000AD0F6 /* FileUDF.cpp */,
-                               F56C83C8131F42E8000AD0F6 /* FileUDF.h */,
-                               DF6739E01443765F00A5A509 /* FileUPnP.cpp */,
-                               DF6739E11443765F00A5A509 /* FileUPnP.h */,
-                               F56C83CB131F42E8000AD0F6 /* FileZip.cpp */,
-                               F56C83CC131F42E8000AD0F6 /* FileZip.h */,
+                               DF93D7A71444B105007C6459 /* FileReaderFile.cpp */,
+                               DF93D7A81444B105007C6459 /* FileReaderFile.h */,
                                F56C83CD131F42E8000AD0F6 /* FTPDirectory.cpp */,
                                F56C83CE131F42E8000AD0F6 /* FTPDirectory.h */,
                                F56C83CF131F42E8000AD0F6 /* FTPParse.cpp */,
                                F56C83D0131F42E8000AD0F6 /* FTPParse.h */,
                                F56C83D1131F42E8000AD0F6 /* HDDirectory.cpp */,
                                F56C83D2131F42E8000AD0F6 /* HDDirectory.h */,
-                               F56C83D3131F42E8000AD0F6 /* HDHomeRun.cpp */,
-                               F56C83D4131F42E8000AD0F6 /* HDHomeRun.h */,
+                               DF93D7A91444B105007C6459 /* HDFile.cpp */,
+                               DF93D7AA1444B105007C6459 /* HDFile.h */,
+                               DF93D81A1444B86B007C6459 /* HDHomeRunDirectory.cpp */,
+                               DF93D81B1444B86B007C6459 /* HDHomeRunDirectory.h */,
+                               DF93D81C1444B86B007C6459 /* HDHomeRunFile.cpp */,
+                               DF93D81D1444B86B007C6459 /* HDHomeRunFile.h */,
                                F56C83D6131F42E8000AD0F6 /* HTSPDirectory.cpp */,
                                F56C83D5131F42E8000AD0F6 /* HTSPDirectory.h */,
                                F56C83D8131F42E8000AD0F6 /* HTSPSession.cpp */,
                                F56C83E1131F42E8000AD0F6 /* iso9660.h */,
                                F56C83E2131F42E8000AD0F6 /* ISO9660Directory.cpp */,
                                F56C83E3131F42E8000AD0F6 /* ISO9660Directory.h */,
+                               DF93D7AB1444B105007C6459 /* ISOFile.cpp */,
+                               DF93D7AC1444B105007C6459 /* ISOFile.h */,
                                F56C83E4131F42E8000AD0F6 /* LastFMDirectory.cpp */,
                                F56C83E5131F42E8000AD0F6 /* LastFMDirectory.h */,
+                               DF93D7AD1444B105007C6459 /* LastFMFile.cpp */,
+                               DF93D7AE1444B105007C6459 /* LastFMFile.h */,
+                               DFDB00221516403A005079A4 /* MemBufferCache.cpp */,
+                               DFDB00231516403A005079A4 /* MemBufferCache.h */,
                                F56C83E6131F42E8000AD0F6 /* MultiPathDirectory.cpp */,
                                F56C83E7131F42E8000AD0F6 /* MultiPathDirectory.h */,
                                F56C83E8131F42E8000AD0F6 /* MultiPathFile.cpp */,
                                F56C83E9131F42E8000AD0F6 /* MultiPathFile.h */,
                                F56C8417131F42E8000AD0F6 /* MusicDatabaseDirectory.cpp */,
                                F56C8418131F42E8000AD0F6 /* MusicDatabaseDirectory.h */,
+                               DF93D7AF1444B105007C6459 /* MusicDatabaseFile.cpp */,
+                               DF93D7B01444B105007C6459 /* MusicDatabaseFile.h */,
                                F56C8384131F42E8000AD0F6 /* MusicFileDirectory.cpp */,
                                F56C8385131F42E8000AD0F6 /* MusicFileDirectory.h */,
                                F56C8419131F42E8000AD0F6 /* MusicSearchDirectory.cpp */,
                                F56C8386131F42E8000AD0F6 /* MythSession.cpp */,
                                DF0DF17D13A3AF9F008ED511 /* NFSDirectory.cpp */,
                                DF0DF17E13A3AF9F008ED511 /* NFSDirectory.h */,
+                               DF93D7B11444B105007C6459 /* NFSFile.cpp */,
+                               DF93D7B21444B105007C6459 /* NFSFile.h */,
                                F56C837D131F42E8000AD0F6 /* NptXbmcFile.cpp */,
                                F56C841B131F42E8000AD0F6 /* NSFFileDirectory.cpp */,
                                F56C841C131F42E8000AD0F6 /* NSFFileDirectory.h */,
                                F56C841D131F42E8000AD0F6 /* OGGFileDirectory.cpp */,
                                F56C841E131F42E8000AD0F6 /* OGGFileDirectory.h */,
+                               DF93D7B31444B105007C6459 /* PipeFile.cpp */,
+                               DF93D7B41444B105007C6459 /* PipeFile.h */,
                                DF44856F140065E10069344B /* PipesManager.cpp */,
                                DF448570140065E10069344B /* PipesManager.h */,
                                F56C841F131F42E8000AD0F6 /* PlaylistDirectory.cpp */,
                                F56C8424131F42E8000AD0F6 /* PluginDirectory.h */,
                                F56C8425131F42E8000AD0F6 /* RarDirectory.cpp */,
                                F56C8426131F42E8000AD0F6 /* RarDirectory.h */,
+                               DF93D7B51444B105007C6459 /* RarFile.cpp */,
+                               DF93D7B61444B105007C6459 /* RarFile.h */,
                                F56C8427131F42E8000AD0F6 /* RarManager.cpp */,
                                F56C8428131F42E8000AD0F6 /* RarManager.h */,
                                F56C837E131F42E8000AD0F6 /* RSSDirectory.cpp */,
                                F56C837F131F42E8000AD0F6 /* RSSDirectory.h */,
                                F56C8429131F42E8000AD0F6 /* RTVDirectory.cpp */,
                                F56C842A131F42E8000AD0F6 /* RTVDirectory.h */,
+                               DF93D7B71444B105007C6459 /* RTVFile.cpp */,
+                               DF93D7B81444B105007C6459 /* RTVFile.h */,
                                F56C842C131F42E8000AD0F6 /* SAPDirectory.cpp */,
                                F56C842B131F42E8000AD0F6 /* SAPDirectory.h */,
                                F56C842E131F42E8000AD0F6 /* SAPFile.cpp */,
                                F56C842D131F42E8000AD0F6 /* SAPFile.h */,
                                F56C842F131F42E8000AD0F6 /* SFTPDirectory.cpp */,
                                F56C8430131F42E8000AD0F6 /* SFTPDirectory.h */,
+                               DF93D7B91444B105007C6459 /* SFTPFile.cpp */,
+                               DF93D7BA1444B105007C6459 /* SFTPFile.h */,
+                               DF93D7BB1444B105007C6459 /* ShoutcastFile.cpp */,
+                               DF93D7BC1444B105007C6459 /* ShoutcastFile.h */,
                                F56C8431131F42E8000AD0F6 /* SIDFileDirectory.cpp */,
                                F56C8432131F42E8000AD0F6 /* SIDFileDirectory.h */,
-                               18404DD41396C3F300863BBA /* Slingbox.cpp */,
-                               18404DD51396C3F300863BBA /* Slingbox.h */,
+                               DF93D7BD1444B105007C6459 /* SlingboxDirectory.cpp */,
+                               DF93D7BE1444B105007C6459 /* SlingboxDirectory.h */,
+                               DF93D7BF1444B105007C6459 /* SlingboxFile.cpp */,
+                               DF93D7C01444B105007C6459 /* SlingboxFile.h */,
                                F56C8433131F42E8000AD0F6 /* SmartPlaylistDirectory.cpp */,
                                F56C8434131F42E8000AD0F6 /* SmartPlaylistDirectory.h */,
                                F56C8388131F42E8000AD0F6 /* SMBDirectory.cpp */,
                                F56C8435131F42E8000AD0F6 /* SMBDirectory.h */,
+                               DF93D7C11444B105007C6459 /* SmbFile.cpp */,
+                               DF93D7C21444B105007C6459 /* SmbFile.h */,
                                F57A1DB61329FAF700498CC7 /* SourcesDirectory.cpp */,
                                F57A1DB71329FAF700498CC7 /* SourcesDirectory.h */,
                                F56C8379131F42E8000AD0F6 /* SpecialProtocol.cpp */,
                                F56C837A131F42E8000AD0F6 /* SpecialProtocol.h */,
                                F56C837B131F42E8000AD0F6 /* SpecialProtocolDirectory.cpp */,
                                F56C837C131F42E8000AD0F6 /* SpecialProtocolDirectory.h */,
+                               DF93D7C31444B105007C6459 /* SpecialProtocolFile.cpp */,
+                               DF93D7C41444B105007C6459 /* SpecialProtocolFile.h */,
                                F56C8436131F42E8000AD0F6 /* StackDirectory.cpp */,
                                F56C8437131F42E8000AD0F6 /* StackDirectory.h */,
+                               DF93D7C51444B105007C6459 /* TuxBoxDirectory.cpp */,
+                               DF93D7C61444B105007C6459 /* TuxBoxDirectory.h */,
+                               DF93D7C71444B105007C6459 /* TuxBoxFile.cpp */,
+                               DF93D7C81444B105007C6459 /* TuxBoxFile.h */,
                                F56C8438131F42E8000AD0F6 /* udf25.cpp */,
                                F56C8439131F42E8000AD0F6 /* udf25.h */,
                                F56C843A131F42E8000AD0F6 /* UDFDirectory.cpp */,
                                F56C843B131F42E8000AD0F6 /* UDFDirectory.h */,
+                               DF93D7C91444B105007C6459 /* UDFFile.cpp */,
+                               DF93D7CA1444B105007C6459 /* UDFFile.h */,
                                F56C843C131F42E8000AD0F6 /* UPnPDirectory.cpp */,
                                F56C843D131F42E8000AD0F6 /* UPnPDirectory.h */,
+                               DF93D7CB1444B105007C6459 /* UPnPFile.cpp */,
+                               DF93D7CC1444B105007C6459 /* UPnPFile.h */,
                                F56C8473131F42E8000AD0F6 /* VideoDatabaseDirectory.cpp */,
                                F56C8474131F42E8000AD0F6 /* VideoDatabaseDirectory.h */,
                                F56C8475131F42E8000AD0F6 /* VirtualDirectory.cpp */,
                                F56C847B131F42E9000AD0F6 /* ZeroconfDirectory.h */,
                                F56C847E131F42E9000AD0F6 /* ZipDirectory.cpp */,
                                F56C847F131F42E9000AD0F6 /* ZipDirectory.h */,
+                               DF93D7CD1444B105007C6459 /* ZipFile.cpp */,
+                               DF93D7CE1444B105007C6459 /* ZipFile.h */,
                                F56C8480131F42E9000AD0F6 /* ZipManager.cpp */,
                                F56C8481131F42E9000AD0F6 /* ZipManager.h */,
                        );
                                F56C8547131F42E9000AD0F6 /* python */,
                                F56C8586131F42EA000AD0F6 /* AnnouncementManager.cpp */,
                                F56C8587131F42EA000AD0F6 /* AnnouncementManager.h */,
-                               C80711AE135DB865002F601B /* AnnouncementUtils.h */,
                                F56C8588131F42EA000AD0F6 /* Builtins.cpp */,
                                F56C8589131F42EA000AD0F6 /* Builtins.h */,
                                F56C858A131F42EA000AD0F6 /* IAnnouncer.h */,
                F56C862A131F42EA000AD0F6 /* network */ = {
                        isa = PBXGroup;
                        children = (
+                               DFCA6ADD15224671000BFAAE /* httprequesthandler */,
                                F56C862B131F42EA000AD0F6 /* libscrobbler */,
                                F56C8633131F42EA000AD0F6 /* linux */,
                                F56C8636131F42EA000AD0F6 /* osx */,
+                               DF52774C151BAF8200B5B63B /* websocket */,
                                DFA6BE4113FECA010048CC11 /* AirPlayServer.cpp */,
                                DFA6BE4213FECA010048CC11 /* AirPlayServer.h */,
                                DF4485731400662D0069344B /* AirTunesServer.cpp */,
                                F56C8713131F42EC000AD0F6 /* AsyncFileCopy.h */,
                                F56C8714131F42EC000AD0F6 /* AutoPtrHandle.cpp */,
                                F56C8715131F42EC000AD0F6 /* AutoPtrHandle.h */,
+                               DF52775C151BAFA000B5B63B /* Base64.cpp */,
+                               DF52775D151BAFA000B5B63B /* Base64.h */,
                                F56C8716131F42EC000AD0F6 /* BitstreamStats.cpp */,
                                F56C8717131F42EC000AD0F6 /* BitstreamStats.h */,
                                F56C8718131F42EC000AD0F6 /* CharsetConverter.cpp */,
                                F56C872F131F42EC000AD0F6 /* HttpHeader.h */,
                                DFA6BE7513FED09C0048CC11 /* HttpParser.cpp */,
                                DFA6BE7613FED09C0048CC11 /* HttpParser.h */,
+                               DF52775E151BAFA000B5B63B /* HttpResponse.cpp */,
+                               DF52775F151BAFA000B5B63B /* HttpResponse.h */,
                                F56C8730131F42EC000AD0F6 /* InfoLoader.cpp */,
                                F56C8731131F42EC000AD0F6 /* InfoLoader.h */,
                                F56C8736131F42EC000AD0F6 /* Job.h */,
                                F56C86FE131F42EB000AD0F6 /* MathUtils.h */,
                                F56C873B131F42EC000AD0F6 /* md5.cpp */,
                                F56C873C131F42EC000AD0F6 /* md5.h */,
+                               188F761F1522184E009870CE /* Mime.cpp */,
+                               188F76201522184E009870CE /* Mime.h */,
                                F56C873D131F42EC000AD0F6 /* PCMAmplifier.cpp */,
                                F56C873E131F42EC000AD0F6 /* PCMAmplifier.h */,
                                F56C873F131F42EC000AD0F6 /* PCMRemap.cpp */,
                                F5AE4147134175520004BD79 /* FileItemHandler.h */,
                                F5AE4148134175520004BD79 /* FileOperations.cpp */,
                                F5AE4149134175520004BD79 /* FileOperations.h */,
+                               188F761C1522182F009870CE /* GUIOperations.cpp */,
+                               188F761D1522182F009870CE /* GUIOperations.h */,
                                F5AE414A134175520004BD79 /* IClient.h */,
+                               188F7535152117AA009870CE /* IJSONRPCAnnouncer.h */,
                                C80711AB135DB85F002F601B /* InputOperations.cpp */,
                                C80711AC135DB85F002F601B /* InputOperations.h */,
                                F5AE414B134175520004BD79 /* ITransportLayer.h */,
                                F5AE414C134175520004BD79 /* JSONRPC.cpp */,
                                F5AE414D134175520004BD79 /* JSONRPC.h */,
+                               188F7536152117B2009870CE /* JSONRPCUtils.h */,
                                F5AE452E134D2E3E0004BD79 /* JSONServiceDescription.cpp */,
                                F5AE452F134D2E3E0004BD79 /* JSONServiceDescription.h */,
                                F5AE414E134175520004BD79 /* JSONUtils.h */,
                                F56C895B131F42ED000AD0F6 /* ASAPFileDirectory.cpp in Sources */,
                                F56C895C131F42ED000AD0F6 /* MusicFileDirectory.cpp in Sources */,
                                F56C895D131F42ED000AD0F6 /* MythSession.cpp in Sources */,
-                               F56C895E131F42ED000AD0F6 /* FileSmb.cpp in Sources */,
                                F56C895F131F42ED000AD0F6 /* SMBDirectory.cpp in Sources */,
                                F56C8960131F42ED000AD0F6 /* MythDirectory.cpp in Sources */,
                                F56C8961131F42ED000AD0F6 /* MythFile.cpp in Sources */,
-                               F56C8962131F42ED000AD0F6 /* FileShoutcast.cpp in Sources */,
-                               F56C8963131F42ED000AD0F6 /* CacheMemBuffer.cpp in Sources */,
                                F56C8964131F42ED000AD0F6 /* CacheStrategy.cpp in Sources */,
                                F56C8965131F42ED000AD0F6 /* CDDADirectory.cpp in Sources */,
                                F56C8966131F42ED000AD0F6 /* DAAPDirectory.cpp in Sources */,
                                F56C8967131F42ED000AD0F6 /* DAVDirectory.cpp in Sources */,
                                F56C8968131F42ED000AD0F6 /* Directory.cpp in Sources */,
-                               F56C8969131F42ED000AD0F6 /* DirectoryCache.cpp in Sources */,
                                F56C896A131F42ED000AD0F6 /* DirectoryHistory.cpp in Sources */,
-                               F56C896B131F42ED000AD0F6 /* DirectoryTuxBox.cpp in Sources */,
                                F56C896C131F42ED000AD0F6 /* DllLibCurl.cpp in Sources */,
-                               F56C896D131F42ED000AD0F6 /* FactoryDirectory.cpp in Sources */,
-                               F56C896E131F42ED000AD0F6 /* FactoryFileDirectory.cpp in Sources */,
                                F56C896F131F42ED000AD0F6 /* File.cpp in Sources */,
-                               F56C8970131F42ED000AD0F6 /* FileCache.cpp in Sources */,
-                               F56C8971131F42ED000AD0F6 /* FileCDDA.cpp in Sources */,
-                               F56C8972131F42ED000AD0F6 /* FileCurl.cpp in Sources */,
-                               F56C8973131F42ED000AD0F6 /* FileDAAP.cpp in Sources */,
                                F56C8974131F42ED000AD0F6 /* FileFactory.cpp in Sources */,
-                               F56C8975131F42ED000AD0F6 /* FileFileReader.cpp in Sources */,
-                               F56C8976131F42ED000AD0F6 /* FileHD.cpp in Sources */,
-                               F56C8977131F42ED000AD0F6 /* FileISO.cpp in Sources */,
-                               F56C8978131F42ED000AD0F6 /* FileLastFM.cpp in Sources */,
-                               F56C8979131F42ED000AD0F6 /* FileMusicDatabase.cpp in Sources */,
-                               F56C897A131F42ED000AD0F6 /* FileRar.cpp in Sources */,
-                               F56C897B131F42ED000AD0F6 /* FileRTV.cpp in Sources */,
-                               F56C897C131F42ED000AD0F6 /* FileSFTP.cpp in Sources */,
-                               F56C897D131F42ED000AD0F6 /* FileSpecialProtocol.cpp in Sources */,
-                               F56C897E131F42ED000AD0F6 /* FileTuxBox.cpp in Sources */,
-                               F56C897F131F42ED000AD0F6 /* FileUDF.cpp in Sources */,
-                               F56C8981131F42ED000AD0F6 /* FileZip.cpp in Sources */,
                                F56C8982131F42ED000AD0F6 /* FTPDirectory.cpp in Sources */,
                                F56C8983131F42ED000AD0F6 /* FTPParse.cpp in Sources */,
                                F56C8984131F42ED000AD0F6 /* HDDirectory.cpp in Sources */,
-                               F56C8985131F42ED000AD0F6 /* HDHomeRun.cpp in Sources */,
                                F56C8986131F42ED000AD0F6 /* HTSPDirectory.cpp in Sources */,
                                F56C8987131F42ED000AD0F6 /* HTSPSession.cpp in Sources */,
                                F56C8988131F42ED000AD0F6 /* HTTPDirectory.cpp in Sources */,
                                F56C8BAB131F4466000AD0F6 /* XBMCEAGLView.mm in Sources */,
                                F57A1DB81329FAF700498CC7 /* SourcesDirectory.cpp in Sources */,
                                F5B13DCF1334490D0045076D /* DarwinUtils.mm in Sources */,
-                               7C99B6E9133D36E200FC2B16 /* CacheCircular.cpp in Sources */,
                                7C99B7BE1340730000FC2B16 /* GUIDialogPlayEject.cpp in Sources */,
                                F5AE413D1341754C0004BD79 /* HttpApi.cpp in Sources */,
                                F5AE413E1341754C0004BD79 /* XBMChttp.cpp in Sources */,
                                18ACF8FD13597B5700B67371 /* RecentlyAddedJob.cpp in Sources */,
                                C80711AD135DB85F002F601B /* InputOperations.cpp in Sources */,
                                C8EC5D26136953E100CCC10D /* XBMC_keytable.cpp in Sources */,
-                               18404DD61396C3F300863BBA /* Slingbox.cpp in Sources */,
                                1840B77A1399616D007C848B /* JSONVariantParser.cpp in Sources */,
                                1840B77B1399616D007C848B /* JSONVariantWriter.cpp in Sources */,
                                7C0A7EDE13A5DC2800AFC2BD /* AppParamParser.cpp in Sources */,
                                7C0A7F9D13A9E70800AFC2BD /* GUIWindowDebugInfo.cpp in Sources */,
                                7C0A7FB213A9E72E00AFC2BD /* DirtyRegionSolvers.cpp in Sources */,
                                7C0A7FB313A9E72E00AFC2BD /* DirtyRegionTracker.cpp in Sources */,
-                               DF0DF17F13A3AF9F008ED511 /* FileNFS.cpp in Sources */,
                                DF0DF18013A3AF9F008ED511 /* NFSDirectory.cpp in Sources */,
                                7C89628013B7031E003631FE /* GUIWindowScreensaverDim.cpp in Sources */,
                                1830219E13B8E37300770920 /* controledit.cpp in Sources */,
                                DFA6BE7713FED09C0048CC11 /* HttpParser.cpp in Sources */,
                                18968DDE14155E01005BA742 /* ApplicationOperations.cpp in Sources */,
                                DFCFC52A1413F7D60004D0BF /* AFPDirectory.cpp in Sources */,
-                               DFCFC52B1413F7D60004D0BF /* FileAFP.cpp in Sources */,
                                3291892B1423A9B700E878CD /* JpegIO.cpp in Sources */,
                                DF44856C140065C60069344B /* BXAcodec.cpp in Sources */,
-                               DF448571140065E10069344B /* FilePipe.cpp in Sources */,
                                DF448572140065E10069344B /* PipesManager.cpp in Sources */,
                                DF4485751400662D0069344B /* AirTunesServer.cpp in Sources */,
                                DF98D9991434F49500A6EBE1 /* SkinVariable.cpp in Sources */,
                                F5E112E8143577A000175026 /* GUIDialogPeripheralManager.cpp in Sources */,
                                F5E112E9143577A000175026 /* GUIDialogPeripheralSettings.cpp in Sources */,
                                F5E112EC143577A000175026 /* Peripherals.cpp in Sources */,
-                               DF6739E21443765F00A5A509 /* FileUPnP.cpp in Sources */,
                                F5BD034F148D496A001B5583 /* CryptThreading.cpp in Sources */,
+                               7CCFD9991514950700211D82 /* PCMCodec.cpp in Sources */,
+                               DF527757151BAF8200B5B63B /* WebSocket.cpp in Sources */,
+                               DF527758151BAF8200B5B63B /* WebSocketManager.cpp in Sources */,
+                               DF527759151BAF8200B5B63B /* WebSocketV13.cpp in Sources */,
+                               DF52775A151BAF8200B5B63B /* WebSocketV8.cpp in Sources */,
+                               DF527760151BAFA000B5B63B /* Base64.cpp in Sources */,
+                               DF527761151BAFA000B5B63B /* HttpResponse.cpp in Sources */,
+                               188F761E1522182F009870CE /* GUIOperations.cpp in Sources */,
+                               188F76211522184E009870CE /* Mime.cpp in Sources */,
+                               DFCA6AEB15224671000BFAAE /* HTTPApiHandler.cpp in Sources */,
+                               DFCA6AEC15224671000BFAAE /* HTTPJsonRpcHandler.cpp in Sources */,
+                               DFCA6AED15224671000BFAAE /* HTTPVfsHandler.cpp in Sources */,
+                               DFCA6AEE15224671000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp in Sources */,
+                               DFCA6AEF15224671000BFAAE /* HTTPWebinterfaceHandler.cpp in Sources */,
+                               DFCA6AF015224671000BFAAE /* IHTTPRequestHandler.cpp in Sources */,
+                               DF93D7CF1444B105007C6459 /* AFPFile.cpp in Sources */,
+                               DF93D7D21444B105007C6459 /* CDDAFile.cpp in Sources */,
+                               DF93D7D31444B105007C6459 /* CurlFile.cpp in Sources */,
+                               DF93D7D41444B105007C6459 /* DAAPFile.cpp in Sources */,
+                               DF93D7D51444B105007C6459 /* DirectoryFactory.cpp in Sources */,
+                               DF93D7D61444B105007C6459 /* FileDirectoryFactory.cpp in Sources */,
+                               DF93D7D71444B105007C6459 /* FileReaderFile.cpp in Sources */,
+                               DF93D7D81444B105007C6459 /* HDFile.cpp in Sources */,
+                               DF93D7D91444B105007C6459 /* ISOFile.cpp in Sources */,
+                               DF93D7DA1444B105007C6459 /* LastFMFile.cpp in Sources */,
+                               DF93D7DB1444B105007C6459 /* MusicDatabaseFile.cpp in Sources */,
+                               DF93D7DC1444B105007C6459 /* NFSFile.cpp in Sources */,
+                               DF93D7DD1444B105007C6459 /* PipeFile.cpp in Sources */,
+                               DF93D7DE1444B105007C6459 /* RarFile.cpp in Sources */,
+                               DF93D7DF1444B105007C6459 /* RTVFile.cpp in Sources */,
+                               DF93D7E01444B105007C6459 /* SFTPFile.cpp in Sources */,
+                               DF93D7E11444B105007C6459 /* ShoutcastFile.cpp in Sources */,
+                               DF93D7E21444B105007C6459 /* SlingboxDirectory.cpp in Sources */,
+                               DF93D7E31444B105007C6459 /* SlingboxFile.cpp in Sources */,
+                               DF93D7E41444B105007C6459 /* SmbFile.cpp in Sources */,
+                               DF93D7E51444B105007C6459 /* SpecialProtocolFile.cpp in Sources */,
+                               DF93D7E61444B105007C6459 /* TuxBoxDirectory.cpp in Sources */,
+                               DF93D7E71444B105007C6459 /* TuxBoxFile.cpp in Sources */,
+                               DF93D7E81444B105007C6459 /* UDFFile.cpp in Sources */,
+                               DF93D7E91444B105007C6459 /* UPnPFile.cpp in Sources */,
+                               DF93D7EA1444B105007C6459 /* ZipFile.cpp in Sources */,
+                               DF93D81E1444B86B007C6459 /* HDHomeRunDirectory.cpp in Sources */,
+                               DF93D81F1444B86B007C6459 /* HDHomeRunFile.cpp in Sources */,
+                               DFDB00241516403A005079A4 /* CircularCache.cpp in Sources */,
+                               DFDB00251516403A005079A4 /* DirectoryCache.cpp in Sources */,
+                               DFDB00261516403A005079A4 /* FileCache.cpp in Sources */,
+                               DFDB00271516403A005079A4 /* MemBufferCache.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 9347c97..7a76d99 100644 (file)
@@ -43,9 +43,7 @@
                183C454D130C4D55006AA317 /* xbmcvfsmodule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 189047D11301DEAB00C11012 /* xbmcvfsmodule.cpp */; settings = {COMPILER_FLAGS = "-I$XBMC_DEPENDS/include/python2.6"; }; };
                183FDF8A11AF0B0500B81E9C /* PluginSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 183FDF8811AF0B0500B81E9C /* PluginSource.cpp */; };
                183FDF8B11AF0B0500B81E9C /* PluginSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 183FDF8811AF0B0500B81E9C /* PluginSource.cpp */; };
-               18404D9E1396C13500863BBA /* Slingbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18404D9C1396C13500863BBA /* Slingbox.cpp */; };
                18404DA61396C31B00863BBA /* SlingboxLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18404DA51396C31B00863BBA /* SlingboxLib.a */; };
-               18404E701396E05D00863BBA /* Slingbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18404D9C1396C13500863BBA /* Slingbox.cpp */; };
                18404E711396E06C00863BBA /* SlingboxLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18404DA51396C31B00863BBA /* SlingboxLib.a */; };
                1840B74D13993D8A007C848B /* JSONVariantParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1840B74B13993D8A007C848B /* JSONVariantParser.cpp */; };
                1840B74E13993D8A007C848B /* JSONVariantParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1840B74B13993D8A007C848B /* JSONVariantParser.cpp */; };
                1840B75413993DA0007C848B /* JSONVariantWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1840B75113993DA0007C848B /* JSONVariantWriter.cpp */; };
                184C472F1296BC6E0006DB3E /* Service.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 184C472D1296BC6E0006DB3E /* Service.cpp */; };
                184C47301296BC6E0006DB3E /* Service.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 184C472D1296BC6E0006DB3E /* Service.cpp */; };
+               188F75FE152217BC009870CE /* Mime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 188F75FC152217BC009870CE /* Mime.cpp */; };
+               188F75FF152217BC009870CE /* Mime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 188F75FC152217BC009870CE /* Mime.cpp */; };
+               188F7602152217DF009870CE /* GUIOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 188F7600152217DF009870CE /* GUIOperations.cpp */; };
+               188F7603152217DF009870CE /* GUIOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 188F7600152217DF009870CE /* GUIOperations.cpp */; };
                18968DC814155D7C005BA742 /* ApplicationOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18968DC614155D7C005BA742 /* ApplicationOperations.cpp */; };
                18968DC914155D7C005BA742 /* ApplicationOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18968DC614155D7C005BA742 /* ApplicationOperations.cpp */; };
                18ACF84313596C9B00B67371 /* RecentlyAddedJob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18ACF84113596C9B00B67371 /* RecentlyAddedJob.cpp */; };
                432D7CE512D86DA500CE4C49 /* NetworkLinux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 432D7CE312D86DA500CE4C49 /* NetworkLinux.cpp */; };
                432D7CF712D870E800CE4C49 /* TCPServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 432D7CF612D870E800CE4C49 /* TCPServer.cpp */; };
                432D7CF812D870E800CE4C49 /* TCPServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 432D7CF612D870E800CE4C49 /* TCPServer.cpp */; };
-               433219D712E4C6A500CD7486 /* FileUDF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 433219D112E4C6A500CD7486 /* FileUDF.cpp */; };
                433219D812E4C6A500CD7486 /* udf25.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 433219D312E4C6A500CD7486 /* udf25.cpp */; };
                433219D912E4C6A500CD7486 /* UDFDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 433219D512E4C6A500CD7486 /* UDFDirectory.cpp */; };
-               433219DA12E4C6A500CD7486 /* FileUDF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 433219D112E4C6A500CD7486 /* FileUDF.cpp */; };
                433219DB12E4C6A500CD7486 /* udf25.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 433219D312E4C6A500CD7486 /* udf25.cpp */; };
                433219DC12E4C6A500CD7486 /* UDFDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 433219D512E4C6A500CD7486 /* UDFDirectory.cpp */; };
                43348AA3107747CD00F859CF /* Edl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43348AA1107747CD00F859CF /* Edl.cpp */; };
                7C8A14571154CB2600E5FCFA /* TextureCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8A14541154CB2600E5FCFA /* TextureCache.cpp */; };
                7C8A187C115B2A8200E5FCFA /* TextureDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8A187A115B2A8200E5FCFA /* TextureDatabase.cpp */; };
                7C8A187D115B2A8200E5FCFA /* TextureDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8A187A115B2A8200E5FCFA /* TextureDatabase.cpp */; };
-               7C99B6A4133D342100FC2B16 /* CacheCircular.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B6A2133D342100FC2B16 /* CacheCircular.cpp */; };
-               7C99B6A5133D342100FC2B16 /* CacheCircular.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B6A2133D342100FC2B16 /* CacheCircular.cpp */; };
+               7C99B6A4133D342100FC2B16 /* CircularCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B6A2133D342100FC2B16 /* CircularCache.cpp */; };
+               7C99B6A5133D342100FC2B16 /* CircularCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B6A2133D342100FC2B16 /* CircularCache.cpp */; };
                7C99B7951340723F00FC2B16 /* GUIDialogPlayEject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B7931340723F00FC2B16 /* GUIDialogPlayEject.cpp */; };
                7C99B7961340723F00FC2B16 /* GUIDialogPlayEject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C99B7931340723F00FC2B16 /* GUIDialogPlayEject.cpp */; };
                7CAA20511079C8160096DE39 /* BaseRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CAA204F1079C8160096DE39 /* BaseRenderer.cpp */; };
                7CCF7F1E1069F3AE00992676 /* Builtins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCF7F1B1069F3AE00992676 /* Builtins.cpp */; };
                7CCF7FC9106A0DF500992676 /* TimeUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCF7FC7106A0DF500992676 /* TimeUtils.cpp */; };
                7CCF7FCA106A0DF500992676 /* TimeUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCF7FC7106A0DF500992676 /* TimeUtils.cpp */; };
+               7CCFD98C151494E100211D82 /* PCMCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCFD98A151494E100211D82 /* PCMCodec.cpp */; };
+               7CCFD98D151494E100211D82 /* PCMCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CCFD98A151494E100211D82 /* PCMCodec.cpp */; };
                7CD2C3AA11940B270009EFC1 /* DirectoryNodeCountry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CD2C3A811940B270009EFC1 /* DirectoryNodeCountry.cpp */; };
                7CD2C3AB11940B270009EFC1 /* DirectoryNodeCountry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CD2C3A811940B270009EFC1 /* DirectoryNodeCountry.cpp */; };
                7CD2CD0111B38B000009EFC1 /* PythonAddon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CD2CCFE11B38B000009EFC1 /* PythonAddon.cpp */; };
                C8D0B2AF1265A9A800F0C0AC /* SystemGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C8D0B2AE1265A9A800F0C0AC /* SystemGlobals.cpp */; };
                C8D0B2B01265A9A800F0C0AC /* SystemGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C8D0B2AE1265A9A800F0C0AC /* SystemGlobals.cpp */; };
                C8EC5D0E1369519D00CCC10D /* XBMC_keytable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C8EC5D0C1369519D00CCC10D /* XBMC_keytable.cpp */; };
-               DF0DF15B13A3ADA7008ED511 /* FileNFS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0DF15713A3ADA7008ED511 /* FileNFS.cpp */; };
                DF0DF15C13A3ADA7008ED511 /* NFSDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0DF15913A3ADA7008ED511 /* NFSDirectory.cpp */; };
                DF24A6B41406C7C500C7721E /* AFPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF24A6B01406C7C500C7721E /* AFPDirectory.cpp */; };
-               DF24A6B51406C7C500C7721E /* FileAFP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF24A6B21406C7C500C7721E /* FileAFP.cpp */; };
                DF24A6B61406C7C500C7721E /* AFPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF24A6B01406C7C500C7721E /* AFPDirectory.cpp */; };
-               DF24A6B71406C7C500C7721E /* FileAFP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF24A6B21406C7C500C7721E /* FileAFP.cpp */; };
                DF3488E713FD958F0026A711 /* GUIAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF3488E513FD958F0026A711 /* GUIAction.cpp */; };
                DF3488E813FD958F0026A711 /* GUIAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF3488E513FD958F0026A711 /* GUIAction.cpp */; };
                DF34892A13FD9C780026A711 /* AirPlayServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF34892813FD9C780026A711 /* AirPlayServer.cpp */; };
                DF34898313FDAAF60026A711 /* HttpParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF34898113FDAAF60026A711 /* HttpParser.cpp */; };
                DF448457140048A60069344B /* AirTunesServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF448455140048A60069344B /* AirTunesServer.cpp */; };
                DF448458140048A60069344B /* AirTunesServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF448455140048A60069344B /* AirTunesServer.cpp */; };
-               DF44845D140048C80069344B /* FilePipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF448459140048C80069344B /* FilePipe.cpp */; };
                DF44845E140048C80069344B /* PipesManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF44845B140048C80069344B /* PipesManager.cpp */; };
-               DF44845F140048C80069344B /* FilePipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF448459140048C80069344B /* FilePipe.cpp */; };
                DF448460140048C80069344B /* PipesManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF44845B140048C80069344B /* PipesManager.cpp */; };
                DF4484EE140054530069344B /* BXAcodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4484EC140054530069344B /* BXAcodec.cpp */; };
                DF4484EF140054530069344B /* BXAcodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4484EC140054530069344B /* BXAcodec.cpp */; };
+               DF5276E1151BAEDA00B5B63B /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52769A151BAEDA00B5B63B /* Base64.cpp */; };
+               DF5276E2151BAEDA00B5B63B /* HttpResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52769C151BAEDA00B5B63B /* HttpResponse.cpp */; };
+               DF527726151BAEDA00B5B63B /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52769A151BAEDA00B5B63B /* Base64.cpp */; };
+               DF527727151BAEDA00B5B63B /* HttpResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52769C151BAEDA00B5B63B /* HttpResponse.cpp */; };
+               DF527734151BAF4C00B5B63B /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52772B151BAF4C00B5B63B /* WebSocket.cpp */; };
+               DF527735151BAF4C00B5B63B /* WebSocketManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52772D151BAF4C00B5B63B /* WebSocketManager.cpp */; };
+               DF527736151BAF4C00B5B63B /* WebSocketV13.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52772F151BAF4C00B5B63B /* WebSocketV13.cpp */; };
+               DF527737151BAF4C00B5B63B /* WebSocketV8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527731151BAF4C00B5B63B /* WebSocketV8.cpp */; };
+               DF527739151BAF4C00B5B63B /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52772B151BAF4C00B5B63B /* WebSocket.cpp */; };
+               DF52773A151BAF4C00B5B63B /* WebSocketManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52772D151BAF4C00B5B63B /* WebSocketManager.cpp */; };
+               DF52773B151BAF4C00B5B63B /* WebSocketV13.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52772F151BAF4C00B5B63B /* WebSocketV13.cpp */; };
+               DF52773C151BAF4C00B5B63B /* WebSocketV8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527731151BAF4C00B5B63B /* WebSocketV8.cpp */; };
                DF673AA51443819600A5A509 /* AddonManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B49FF41152BFA5001AF8A6 /* AddonManager.cpp */; };
-               DF85BAB51443669A000686BE /* FileUPnP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF85BAB41443669A000686BE /* FileUPnP.cpp */; };
-               DF85BAB61443669A000686BE /* FileUPnP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF85BAB41443669A000686BE /* FileUPnP.cpp */; };
+               DF93D65D1444A7A3007C6459 /* SlingboxDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D65C1444A7A3007C6459 /* SlingboxDirectory.cpp */; };
+               DF93D65E1444A7A3007C6459 /* SlingboxDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D65C1444A7A3007C6459 /* SlingboxDirectory.cpp */; };
+               DF93D6991444A8B1007C6459 /* AFPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6631444A8B0007C6459 /* AFPFile.cpp */; };
+               DF93D69A1444A8B1007C6459 /* DirectoryCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6651444A8B0007C6459 /* DirectoryCache.cpp */; };
+               DF93D69B1444A8B1007C6459 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6671444A8B0007C6459 /* FileCache.cpp */; };
+               DF93D69C1444A8B1007C6459 /* CDDAFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6691444A8B0007C6459 /* CDDAFile.cpp */; };
+               DF93D69D1444A8B1007C6459 /* CurlFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D66B1444A8B0007C6459 /* CurlFile.cpp */; };
+               DF93D69E1444A8B1007C6459 /* DAAPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D66D1444A8B0007C6459 /* DAAPFile.cpp */; };
+               DF93D69F1444A8B1007C6459 /* DirectoryFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D66F1444A8B0007C6459 /* DirectoryFactory.cpp */; };
+               DF93D6A01444A8B1007C6459 /* FileDirectoryFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6711444A8B0007C6459 /* FileDirectoryFactory.cpp */; };
+               DF93D6A11444A8B1007C6459 /* FileReaderFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6731444A8B0007C6459 /* FileReaderFile.cpp */; };
+               DF93D6A21444A8B1007C6459 /* HDFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6751444A8B0007C6459 /* HDFile.cpp */; };
+               DF93D6A31444A8B1007C6459 /* ISOFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6771444A8B0007C6459 /* ISOFile.cpp */; };
+               DF93D6A41444A8B1007C6459 /* LastFMFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6791444A8B0007C6459 /* LastFMFile.cpp */; };
+               DF93D6A51444A8B1007C6459 /* MusicDatabaseFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D67B1444A8B0007C6459 /* MusicDatabaseFile.cpp */; };
+               DF93D6A61444A8B1007C6459 /* NFSFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D67D1444A8B0007C6459 /* NFSFile.cpp */; };
+               DF93D6A71444A8B1007C6459 /* PipeFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D67F1444A8B0007C6459 /* PipeFile.cpp */; };
+               DF93D6A81444A8B1007C6459 /* RarFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6811444A8B0007C6459 /* RarFile.cpp */; };
+               DF93D6A91444A8B1007C6459 /* RTVFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6831444A8B0007C6459 /* RTVFile.cpp */; };
+               DF93D6AA1444A8B1007C6459 /* SFTPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6851444A8B0007C6459 /* SFTPFile.cpp */; };
+               DF93D6AB1444A8B1007C6459 /* ShoutcastFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6871444A8B0007C6459 /* ShoutcastFile.cpp */; };
+               DF93D6AC1444A8B1007C6459 /* SlingboxFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6891444A8B0007C6459 /* SlingboxFile.cpp */; };
+               DF93D6AD1444A8B1007C6459 /* SmbFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D68B1444A8B0007C6459 /* SmbFile.cpp */; };
+               DF93D6AE1444A8B1007C6459 /* SpecialProtocolFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D68D1444A8B0007C6459 /* SpecialProtocolFile.cpp */; };
+               DF93D6AF1444A8B1007C6459 /* TuxBoxDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D68F1444A8B0007C6459 /* TuxBoxDirectory.cpp */; };
+               DF93D6B01444A8B1007C6459 /* TuxBoxFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6911444A8B0007C6459 /* TuxBoxFile.cpp */; };
+               DF93D6B11444A8B1007C6459 /* UDFFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6931444A8B0007C6459 /* UDFFile.cpp */; };
+               DF93D6B21444A8B1007C6459 /* UPnPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6951444A8B0007C6459 /* UPnPFile.cpp */; };
+               DF93D6B31444A8B1007C6459 /* ZipFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6971444A8B0007C6459 /* ZipFile.cpp */; };
+               DF93D6B41444A8B1007C6459 /* AFPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6631444A8B0007C6459 /* AFPFile.cpp */; };
+               DF93D6B51444A8B1007C6459 /* DirectoryCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6651444A8B0007C6459 /* DirectoryCache.cpp */; };
+               DF93D6B61444A8B1007C6459 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6671444A8B0007C6459 /* FileCache.cpp */; };
+               DF93D6B71444A8B1007C6459 /* CDDAFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6691444A8B0007C6459 /* CDDAFile.cpp */; };
+               DF93D6B81444A8B1007C6459 /* CurlFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D66B1444A8B0007C6459 /* CurlFile.cpp */; };
+               DF93D6B91444A8B1007C6459 /* DAAPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D66D1444A8B0007C6459 /* DAAPFile.cpp */; };
+               DF93D6BA1444A8B1007C6459 /* DirectoryFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D66F1444A8B0007C6459 /* DirectoryFactory.cpp */; };
+               DF93D6BB1444A8B1007C6459 /* FileDirectoryFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6711444A8B0007C6459 /* FileDirectoryFactory.cpp */; };
+               DF93D6BC1444A8B1007C6459 /* FileReaderFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6731444A8B0007C6459 /* FileReaderFile.cpp */; };
+               DF93D6BD1444A8B1007C6459 /* HDFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6751444A8B0007C6459 /* HDFile.cpp */; };
+               DF93D6BE1444A8B1007C6459 /* ISOFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6771444A8B0007C6459 /* ISOFile.cpp */; };
+               DF93D6BF1444A8B1007C6459 /* LastFMFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6791444A8B0007C6459 /* LastFMFile.cpp */; };
+               DF93D6C01444A8B1007C6459 /* MusicDatabaseFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D67B1444A8B0007C6459 /* MusicDatabaseFile.cpp */; };
+               DF93D6C11444A8B1007C6459 /* NFSFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D67D1444A8B0007C6459 /* NFSFile.cpp */; };
+               DF93D6C21444A8B1007C6459 /* PipeFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D67F1444A8B0007C6459 /* PipeFile.cpp */; };
+               DF93D6C31444A8B1007C6459 /* RarFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6811444A8B0007C6459 /* RarFile.cpp */; };
+               DF93D6C41444A8B1007C6459 /* RTVFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6831444A8B0007C6459 /* RTVFile.cpp */; };
+               DF93D6C51444A8B1007C6459 /* SFTPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6851444A8B0007C6459 /* SFTPFile.cpp */; };
+               DF93D6C61444A8B1007C6459 /* ShoutcastFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6871444A8B0007C6459 /* ShoutcastFile.cpp */; };
+               DF93D6C71444A8B1007C6459 /* SlingboxFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6891444A8B0007C6459 /* SlingboxFile.cpp */; };
+               DF93D6C81444A8B1007C6459 /* SmbFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D68B1444A8B0007C6459 /* SmbFile.cpp */; };
+               DF93D6C91444A8B1007C6459 /* SpecialProtocolFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D68D1444A8B0007C6459 /* SpecialProtocolFile.cpp */; };
+               DF93D6CA1444A8B1007C6459 /* TuxBoxDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D68F1444A8B0007C6459 /* TuxBoxDirectory.cpp */; };
+               DF93D6CB1444A8B1007C6459 /* TuxBoxFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6911444A8B0007C6459 /* TuxBoxFile.cpp */; };
+               DF93D6CC1444A8B1007C6459 /* UDFFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6931444A8B0007C6459 /* UDFFile.cpp */; };
+               DF93D6CD1444A8B1007C6459 /* UPnPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6951444A8B0007C6459 /* UPnPFile.cpp */; };
+               DF93D6CE1444A8B1007C6459 /* ZipFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D6971444A8B0007C6459 /* ZipFile.cpp */; };
+               DF93D7F21444B54A007C6459 /* HDHomeRunFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7F01444B54A007C6459 /* HDHomeRunFile.cpp */; };
+               DF93D7F31444B54A007C6459 /* HDHomeRunFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7F01444B54A007C6459 /* HDHomeRunFile.cpp */; };
+               DF93D7F61444B568007C6459 /* HDHomeRunDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7F51444B568007C6459 /* HDHomeRunDirectory.cpp */; };
+               DF93D7F71444B568007C6459 /* HDHomeRunDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D7F51444B568007C6459 /* HDHomeRunDirectory.cpp */; };
                DF98D98C1434F47D00A6EBE1 /* SkinVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF98D98A1434F47D00A6EBE1 /* SkinVariable.cpp */; };
                DF98D98D1434F47D00A6EBE1 /* SkinVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF98D98A1434F47D00A6EBE1 /* SkinVariable.cpp */; };
                DFAB049813F8376700B70BFB /* InertialScrollingHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAB049613F8376700B70BFB /* InertialScrollingHandler.cpp */; };
                DFAB049913F8376700B70BFB /* InertialScrollingHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAB049613F8376700B70BFB /* InertialScrollingHandler.cpp */; };
+               DFC1B8F01464840E00B1BE79 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DFC1B8EF1464840E00B1BE79 /* SystemConfiguration.framework */; };
+               DFC1BA3414648D6500B1BE79 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DFC1B8EF1464840E00B1BE79 /* SystemConfiguration.framework */; };
+               DFCA6AC6152245CD000BFAAE /* HTTPApiHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AB9152245CD000BFAAE /* HTTPApiHandler.cpp */; };
+               DFCA6AC7152245CD000BFAAE /* HTTPJsonRpcHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6ABB152245CD000BFAAE /* HTTPJsonRpcHandler.cpp */; };
+               DFCA6AC8152245CD000BFAAE /* HTTPVfsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6ABD152245CD000BFAAE /* HTTPVfsHandler.cpp */; };
+               DFCA6AC9152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6ABF152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp */; };
+               DFCA6ACA152245CD000BFAAE /* HTTPWebinterfaceHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AC1152245CD000BFAAE /* HTTPWebinterfaceHandler.cpp */; };
+               DFCA6ACB152245CD000BFAAE /* IHTTPRequestHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AC3152245CD000BFAAE /* IHTTPRequestHandler.cpp */; };
+               DFCA6ACD152245CD000BFAAE /* HTTPApiHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AB9152245CD000BFAAE /* HTTPApiHandler.cpp */; };
+               DFCA6ACE152245CD000BFAAE /* HTTPJsonRpcHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6ABB152245CD000BFAAE /* HTTPJsonRpcHandler.cpp */; };
+               DFCA6ACF152245CD000BFAAE /* HTTPVfsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6ABD152245CD000BFAAE /* HTTPVfsHandler.cpp */; };
+               DFCA6AD0152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6ABF152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp */; };
+               DFCA6AD1152245CD000BFAAE /* HTTPWebinterfaceHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AC1152245CD000BFAAE /* HTTPWebinterfaceHandler.cpp */; };
+               DFCA6AD2152245CD000BFAAE /* IHTTPRequestHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AC3152245CD000BFAAE /* IHTTPRequestHandler.cpp */; };
                E306D12E0DDF7B590052C2AD /* XBMCHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E306D12C0DDF7B590052C2AD /* XBMCHelper.cpp */; };
                E33206380D5070AA00435CE3 /* DVDDemuxVobsub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E33206370D5070AA00435CE3 /* DVDDemuxVobsub.cpp */; };
                E33466A60D2E5103005A65EC /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E33466A50D2E5103005A65EC /* IOKit.framework */; };
                E38E1FFC0D25F9FD00618676 /* DynamicDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E168C0D25F9FA00618676 /* DynamicDll.cpp */; };
                E38E1FFE0D25F9FD00618676 /* Favourites.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16900D25F9FA00618676 /* Favourites.cpp */; };
                E38E1FFF0D25F9FD00618676 /* FileItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16920D25F9FA00618676 /* FileItem.cpp */; };
-               E38E20010D25F9FD00618676 /* CacheMemBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16970D25F9FA00618676 /* CacheMemBuffer.cpp */; };
+               E38E20010D25F9FD00618676 /* MemBufferCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16970D25F9FA00618676 /* MemBufferCache.cpp */; };
                E38E20020D25F9FD00618676 /* CacheStrategy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16990D25F9FA00618676 /* CacheStrategy.cpp */; };
                E38E20030D25F9FD00618676 /* CDDADirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E169B0D25F9FA00618676 /* CDDADirectory.cpp */; };
                E38E20040D25F9FD00618676 /* cddb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E169D0D25F9FA00618676 /* cddb.cpp */; };
                E38E20050D25F9FD00618676 /* cdioSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E169F0D25F9FA00618676 /* cdioSupport.cpp */; };
                E38E20060D25F9FD00618676 /* DAAPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16AA0D25F9FA00618676 /* DAAPDirectory.cpp */; };
                E38E20070D25F9FD00618676 /* Directory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16AC0D25F9FA00618676 /* Directory.cpp */; };
-               E38E20080D25F9FD00618676 /* DirectoryCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16AE0D25F9FA00618676 /* DirectoryCache.cpp */; };
                E38E20090D25F9FD00618676 /* DirectoryHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16B00D25F9FA00618676 /* DirectoryHistory.cpp */; };
-               E38E200A0D25F9FD00618676 /* DirectoryTuxBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16B20D25F9FA00618676 /* DirectoryTuxBox.cpp */; };
                E38E200B0D25F9FD00618676 /* DllLibCurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16B40D25F9FA00618676 /* DllLibCurl.cpp */; };
-               E38E200C0D25F9FD00618676 /* FactoryDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16B60D25F9FA00618676 /* FactoryDirectory.cpp */; };
-               E38E200D0D25F9FD00618676 /* FactoryFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16B80D25F9FA00618676 /* FactoryFileDirectory.cpp */; };
                E38E200E0D25F9FD00618676 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16BA0D25F9FA00618676 /* File.cpp */; };
-               E38E200F0D25F9FD00618676 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16BC0D25F9FA00618676 /* FileCache.cpp */; };
-               E38E20100D25F9FD00618676 /* FileCDDA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16BE0D25F9FA00618676 /* FileCDDA.cpp */; };
-               E38E20110D25F9FD00618676 /* FileCurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16C00D25F9FA00618676 /* FileCurl.cpp */; };
-               E38E20120D25F9FD00618676 /* FileDAAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16C20D25F9FA00618676 /* FileDAAP.cpp */; };
                E38E20130D25F9FD00618676 /* FileFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16C40D25F9FA00618676 /* FileFactory.cpp */; };
-               E38E20140D25F9FD00618676 /* FileFileReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16C60D25F9FA00618676 /* FileFileReader.cpp */; };
-               E38E20160D25F9FD00618676 /* FileHD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16CA0D25F9FA00618676 /* FileHD.cpp */; };
-               E38E20170D25F9FD00618676 /* FileISO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16CC0D25F9FA00618676 /* FileISO.cpp */; };
-               E38E20180D25F9FD00618676 /* FileLastFM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16CE0D25F9FA00618676 /* FileLastFM.cpp */; };
-               E38E201A0D25F9FD00618676 /* FileMusicDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16D20D25F9FA00618676 /* FileMusicDatabase.cpp */; };
-               E38E201B0D25F9FD00618676 /* FileRar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16D40D25F9FA00618676 /* FileRar.cpp */; };
-               E38E201C0D25F9FD00618676 /* FileRTV.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16D60D25F9FA00618676 /* FileRTV.cpp */; };
-               E38E20200D25F9FD00618676 /* FileTuxBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16DE0D25F9FA00618676 /* FileTuxBox.cpp */; };
-               E38E20220D25F9FD00618676 /* FileZip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16E20D25F9FA00618676 /* FileZip.cpp */; };
                E38E20230D25F9FD00618676 /* FTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16E40D25F9FA00618676 /* FTPDirectory.cpp */; };
                E38E20240D25F9FD00618676 /* FTPParse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16E60D25F9FA00618676 /* FTPParse.cpp */; };
                E38E20250D25F9FD00618676 /* HDDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16E80D25F9FA00618676 /* HDDirectory.cpp */; };
-               E38E20260D25F9FD00618676 /* HDHomeRun.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16EA0D25F9FA00618676 /* HDHomeRun.cpp */; };
                E38E20270D25F9FD00618676 /* IDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16EC0D25F9FA00618676 /* IDirectory.cpp */; };
                E38E20280D25F9FD00618676 /* IFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16EE0D25F9FA00618676 /* IFile.cpp */; };
                E38E20290D25F9FD00618676 /* iso9660.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16F10D25F9FA00618676 /* iso9660.cpp */; };
                E38E25BB0D263CE000618676 /* xbmcplugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E259C0D263CE000618676 /* xbmcplugin.cpp */; settings = {COMPILER_FLAGS = "-I$XBMC_DEPENDS/include/python2.6"; }; };
                E38E25C00D263DC100618676 /* DVDFactoryDemuxer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E25BF0D263DC100618676 /* DVDFactoryDemuxer.cpp */; };
                E38E25C30D263DE200618676 /* DVDDemuxFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E25C20D263DE200618676 /* DVDDemuxFFmpeg.cpp */; };
-               E38F12C20D29FF200035C331 /* FileShoutcast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38F12C10D29FF200035C331 /* FileShoutcast.cpp */; };
                E3A4780A0D29029A00F3C3A6 /* GUIDialogCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3A478090D29029A00F3C3A6 /* GUIDialogCache.cpp */; };
                E3A4781A0D29032C00F3C3A6 /* GUIDialogAccessPoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3A478190D29032C00F3C3A6 /* GUIDialogAccessPoints.cpp */; };
                E3B53E7C0D97B08100021A96 /* DVDSubtitleParserMicroDVD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3B53E7A0D97B08100021A96 /* DVDSubtitleParserMicroDVD.cpp */; };
                E3BBB7990D7EA78A00CAAFD3 /* MythSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3BBB7980D7EA78A00CAAFD3 /* MythSession.cpp */; };
-               E3DAAF8C0D6E1B0500F17647 /* FileSmb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3DAAF8A0D6E1B0500F17647 /* FileSmb.cpp */; };
                E3DAAF8D0D6E1B0500F17647 /* SMBDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3DAAF8B0D6E1B0500F17647 /* SMBDirectory.cpp */; };
                E3E91FFD0D8C61DF002BF43D /* EventPacket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3E91FFA0D8C61DF002BF43D /* EventPacket.cpp */; };
                E3E91FFE0D8C61DF002BF43D /* EventServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3E91FFB0D8C61DF002BF43D /* EventServer.cpp */; };
                F558F28013ABD57400631E12 /* DirtyRegionTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F558F27D13ABD57400631E12 /* DirtyRegionTracker.cpp */; };
                F558F29613ABD7DF00631E12 /* GUIWindowDebugInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F558F29413ABD7DF00631E12 /* GUIWindowDebugInfo.cpp */; };
                F558F29713ABD7DF00631E12 /* GUIWindowDebugInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F558F29413ABD7DF00631E12 /* GUIWindowDebugInfo.cpp */; };
-               F558F3D013AE663300631E12 /* FileNFS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0DF15713A3ADA7008ED511 /* FileNFS.cpp */; };
                F558F3D113AE663A00631E12 /* NFSDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF0DF15913A3ADA7008ED511 /* NFSDirectory.cpp */; };
                F56579AF13060D1E0085ED7F /* RenderCapture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56579AD13060D1E0085ED7F /* RenderCapture.cpp */; };
                F56A084B0F4A18FB003F9F87 /* karaokewindowbackground.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56A084A0F4A18FB003F9F87 /* karaokewindowbackground.cpp */; };
                F57A1D1F1329B15300498CC7 /* AutoPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = F57A1D1D1329B15300498CC7 /* AutoPool.mm */; };
                F57B6F801071B8B500079ACB /* JobManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F57B6F7E1071B8B500079ACB /* JobManager.cpp */; };
                F57B6F811071B8B500079ACB /* JobManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F57B6F7E1071B8B500079ACB /* JobManager.cpp */; };
-               F584E1290F257BD800DB26A5 /* FileSpecialProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F584E1270F257BD800DB26A5 /* FileSpecialProtocol.cpp */; };
                F584E12E0F257C5100DB26A5 /* HTTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F584E12D0F257C5100DB26A5 /* HTTPDirectory.cpp */; };
                F58E293911FFC103006F4D46 /* DVDInputStreamBluray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F58E293711FFC103006F4D46 /* DVDInputStreamBluray.cpp */; };
                F58E293A11FFC103006F4D46 /* DVDInputStreamBluray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F58E293711FFC103006F4D46 /* DVDInputStreamBluray.cpp */; };
                F5A1C93E0F6B06CF00A96ABD /* DynamicDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E168C0D25F9FA00618676 /* DynamicDll.cpp */; };
                F5A1C9400F6B06CF00A96ABD /* Favourites.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16900D25F9FA00618676 /* Favourites.cpp */; };
                F5A1C9410F6B06CF00A96ABD /* FileItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16920D25F9FA00618676 /* FileItem.cpp */; };
-               F5A1C9420F6B06CF00A96ABD /* CacheMemBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16970D25F9FA00618676 /* CacheMemBuffer.cpp */; };
+               F5A1C9420F6B06CF00A96ABD /* MemBufferCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16970D25F9FA00618676 /* MemBufferCache.cpp */; };
                F5A1C9430F6B06CF00A96ABD /* CacheStrategy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16990D25F9FA00618676 /* CacheStrategy.cpp */; };
                F5A1C9440F6B06CF00A96ABD /* CDDADirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E169B0D25F9FA00618676 /* CDDADirectory.cpp */; };
                F5A1C9450F6B06CF00A96ABD /* cddb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E169D0D25F9FA00618676 /* cddb.cpp */; };
                F5A1C9460F6B06CF00A96ABD /* cdioSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E169F0D25F9FA00618676 /* cdioSupport.cpp */; };
                F5A1C9470F6B06CF00A96ABD /* DAAPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16AA0D25F9FA00618676 /* DAAPDirectory.cpp */; };
                F5A1C9480F6B06CF00A96ABD /* Directory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16AC0D25F9FA00618676 /* Directory.cpp */; };
-               F5A1C9490F6B06CF00A96ABD /* DirectoryCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16AE0D25F9FA00618676 /* DirectoryCache.cpp */; };
                F5A1C94A0F6B06CF00A96ABD /* DirectoryHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16B00D25F9FA00618676 /* DirectoryHistory.cpp */; };
-               F5A1C94B0F6B06CF00A96ABD /* DirectoryTuxBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16B20D25F9FA00618676 /* DirectoryTuxBox.cpp */; };
                F5A1C94C0F6B06CF00A96ABD /* DllLibCurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16B40D25F9FA00618676 /* DllLibCurl.cpp */; };
-               F5A1C94D0F6B06CF00A96ABD /* FactoryDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16B60D25F9FA00618676 /* FactoryDirectory.cpp */; };
-               F5A1C94E0F6B06CF00A96ABD /* FactoryFileDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16B80D25F9FA00618676 /* FactoryFileDirectory.cpp */; };
                F5A1C94F0F6B06CF00A96ABD /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16BA0D25F9FA00618676 /* File.cpp */; };
-               F5A1C9500F6B06CF00A96ABD /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16BC0D25F9FA00618676 /* FileCache.cpp */; };
-               F5A1C9510F6B06CF00A96ABD /* FileCDDA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16BE0D25F9FA00618676 /* FileCDDA.cpp */; };
-               F5A1C9520F6B06CF00A96ABD /* FileCurl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16C00D25F9FA00618676 /* FileCurl.cpp */; };
-               F5A1C9530F6B06CF00A96ABD /* FileDAAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16C20D25F9FA00618676 /* FileDAAP.cpp */; };
                F5A1C9540F6B06CF00A96ABD /* FileFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16C40D25F9FA00618676 /* FileFactory.cpp */; };
-               F5A1C9550F6B06CF00A96ABD /* FileFileReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16C60D25F9FA00618676 /* FileFileReader.cpp */; };
-               F5A1C9560F6B06CF00A96ABD /* FileHD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16CA0D25F9FA00618676 /* FileHD.cpp */; };
-               F5A1C9570F6B06CF00A96ABD /* FileISO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16CC0D25F9FA00618676 /* FileISO.cpp */; };
-               F5A1C9580F6B06CF00A96ABD /* FileLastFM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16CE0D25F9FA00618676 /* FileLastFM.cpp */; };
-               F5A1C9590F6B06CF00A96ABD /* FileMusicDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16D20D25F9FA00618676 /* FileMusicDatabase.cpp */; };
-               F5A1C95A0F6B06CF00A96ABD /* FileRar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16D40D25F9FA00618676 /* FileRar.cpp */; };
-               F5A1C95B0F6B06CF00A96ABD /* FileRTV.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16D60D25F9FA00618676 /* FileRTV.cpp */; };
-               F5A1C95C0F6B06CF00A96ABD /* FileTuxBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16DE0D25F9FA00618676 /* FileTuxBox.cpp */; };
-               F5A1C95D0F6B06CF00A96ABD /* FileZip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16E20D25F9FA00618676 /* FileZip.cpp */; };
                F5A1C95E0F6B06CF00A96ABD /* FTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16E40D25F9FA00618676 /* FTPDirectory.cpp */; };
                F5A1C95F0F6B06CF00A96ABD /* FTPParse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16E60D25F9FA00618676 /* FTPParse.cpp */; };
                F5A1C9600F6B06CF00A96ABD /* HDDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16E80D25F9FA00618676 /* HDDirectory.cpp */; };
-               F5A1C9610F6B06CF00A96ABD /* HDHomeRun.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16EA0D25F9FA00618676 /* HDHomeRun.cpp */; };
                F5A1C9620F6B06CF00A96ABD /* IDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16EC0D25F9FA00618676 /* IDirectory.cpp */; };
                F5A1C9630F6B06CF00A96ABD /* IFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16EE0D25F9FA00618676 /* IFile.cpp */; };
                F5A1C9640F6B06CF00A96ABD /* iso9660.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E16F10D25F9FA00618676 /* iso9660.cpp */; };
                F5A1CB1A0F6B06CF00A96ABD /* DVDDemuxFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E25C20D263DE200618676 /* DVDDemuxFFmpeg.cpp */; };
                F5A1CB1B0F6B06CF00A96ABD /* GUIDialogCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3A478090D29029A00F3C3A6 /* GUIDialogCache.cpp */; };
                F5A1CB1D0F6B06CF00A96ABD /* GUIDialogAccessPoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3A478190D29032C00F3C3A6 /* GUIDialogAccessPoints.cpp */; };
-               F5A1CB1F0F6B06CF00A96ABD /* FileShoutcast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38F12C10D29FF200035C331 /* FileShoutcast.cpp */; };
                F5A1CB220F6B06CF00A96ABD /* DVDPlayerCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E36578860D3AA7B40033CC1C /* DVDPlayerCodec.cpp */; };
                F5A1CB230F6B06CF00A96ABD /* DVDDemuxVobsub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E33206370D5070AA00435CE3 /* DVDDemuxVobsub.cpp */; };
                F5A1CB240F6B06CF00A96ABD /* DVDInputStreamTV.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E33979940D62FD47004ECDDA /* DVDInputStreamTV.cpp */; };
                F5A1CB250F6B06CF00A96ABD /* PltMediaConnect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9F600D67BD2F0095F5DD /* PltMediaConnect.cpp */; };
                F5A1CB3C0F6B06CF00A96ABD /* MythDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9FA50D67D1FB0095F5DD /* MythDirectory.cpp */; };
                F5A1CB3D0F6B06CF00A96ABD /* MythFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9FA70D67D1FB0095F5DD /* MythFile.cpp */; };
-               F5A1CB3E0F6B06CF00A96ABD /* FileSmb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3DAAF8A0D6E1B0500F17647 /* FileSmb.cpp */; };
                F5A1CB3F0F6B06CF00A96ABD /* SMBDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3DAAF8B0D6E1B0500F17647 /* SMBDirectory.cpp */; };
                F5A1CB410F6B06CF00A96ABD /* MythSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3BBB7980D7EA78A00CAAFD3 /* MythSession.cpp */; };
                F5A1CB420F6B06CF00A96ABD /* EventPacket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3E91FFA0D8C61DF002BF43D /* EventPacket.cpp */; };
                F5A1CB7F0F6B06CF00A96ABD /* AudioRendererFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A00B070EFDDDFC00CD59F3 /* AudioRendererFactory.cpp */; };
                F5A1CB800F6B06CF00A96ABD /* NullDirectSound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A00B240EFDE44100CD59F3 /* NullDirectSound.cpp */; };
                F5A1CB810F6B06CF00A96ABD /* ExternalPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C5608C40F1754930056433A /* ExternalPlayer.cpp */; };
-               F5A1CB820F6B06CF00A96ABD /* FileSpecialProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F584E1270F257BD800DB26A5 /* FileSpecialProtocol.cpp */; };
                F5A1CB830F6B06CF00A96ABD /* HTTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F584E12D0F257C5100DB26A5 /* HTTPDirectory.cpp */; };
                F5A1CB840F6B06CF00A96ABD /* GUIDialogKaraokeSongSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F54C51D00F1E783200D46E3C /* GUIDialogKaraokeSongSelector.cpp */; };
                F5A1CB850F6B06CF00A96ABD /* karaokelyricscdg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F54C51D40F1E784800D46E3C /* karaokelyricscdg.cpp */; };
                F5A7A703112893E50059D6AA /* AnnouncementManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A7A700112893E50059D6AA /* AnnouncementManager.cpp */; };
                F5A7A85B112908F00059D6AA /* WebServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A7A859112908F00059D6AA /* WebServer.cpp */; };
                F5A7A85C112908F00059D6AA /* WebServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A7A859112908F00059D6AA /* WebServer.cpp */; };
-               F5A7B376113AFB5F0059D6AA /* FileSFTP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A7B374113AFB5F0059D6AA /* FileSFTP.cpp */; };
-               F5A7B377113AFB5F0059D6AA /* FileSFTP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A7B374113AFB5F0059D6AA /* FileSFTP.cpp */; };
                F5A7B37E113AFB900059D6AA /* SFTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A7B37C113AFB900059D6AA /* SFTPDirectory.cpp */; };
                F5A7B37F113AFB900059D6AA /* SFTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A7B37C113AFB900059D6AA /* SFTPDirectory.cpp */; };
                F5A7B42C113CBB950059D6AA /* AddonsDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A7B42B113CBB950059D6AA /* AddonsDirectory.cpp */; };
                18308CB51303370800AA309E /* stdio_utf8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdio_utf8.h; sourceTree = "<group>"; };
                183FDF8811AF0B0500B81E9C /* PluginSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginSource.cpp; sourceTree = "<group>"; };
                183FDF8911AF0B0500B81E9C /* PluginSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginSource.h; sourceTree = "<group>"; };
-               18404D9C1396C13500863BBA /* Slingbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Slingbox.cpp; sourceTree = "<group>"; };
-               18404D9D1396C13500863BBA /* Slingbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Slingbox.h; sourceTree = "<group>"; };
                18404DA51396C31B00863BBA /* SlingboxLib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = SlingboxLib.a; path = lib/SlingboxLib/SlingboxLib.a; sourceTree = "<group>"; };
                1840B74B13993D8A007C848B /* JSONVariantParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSONVariantParser.cpp; sourceTree = "<group>"; };
                1840B74C13993D8A007C848B /* JSONVariantParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONVariantParser.h; sourceTree = "<group>"; };
                1840B75213993DA0007C848B /* JSONVariantWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONVariantWriter.h; sourceTree = "<group>"; };
                184C472D1296BC6E0006DB3E /* Service.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Service.cpp; sourceTree = "<group>"; };
                184C472E1296BC6E0006DB3E /* Service.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Service.h; sourceTree = "<group>"; };
+               188F751815211733009870CE /* IJSONRPCAnnouncer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJSONRPCAnnouncer.h; sourceTree = "<group>"; };
+               188F751915211743009870CE /* JSONRPCUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONRPCUtils.h; sourceTree = "<group>"; };
+               188F75FC152217BC009870CE /* Mime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mime.cpp; sourceTree = "<group>"; };
+               188F75FD152217BC009870CE /* Mime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mime.h; sourceTree = "<group>"; };
+               188F7600152217DF009870CE /* GUIOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIOperations.cpp; sourceTree = "<group>"; };
+               188F7601152217DF009870CE /* GUIOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIOperations.h; sourceTree = "<group>"; };
                189047D11301DEAB00C11012 /* xbmcvfsmodule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xbmcvfsmodule.cpp; sourceTree = "<group>"; };
                18968DC614155D7C005BA742 /* ApplicationOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ApplicationOperations.cpp; sourceTree = "<group>"; };
                18968DC714155D7C005BA742 /* ApplicationOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplicationOperations.h; sourceTree = "<group>"; };
                432D7CE312D86DA500CE4C49 /* NetworkLinux.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkLinux.cpp; sourceTree = "<group>"; };
                432D7CF512D870D600CE4C49 /* TCPServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCPServer.h; sourceTree = "<group>"; };
                432D7CF612D870E800CE4C49 /* TCPServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TCPServer.cpp; sourceTree = "<group>"; };
-               433219D112E4C6A500CD7486 /* FileUDF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileUDF.cpp; sourceTree = "<group>"; };
-               433219D212E4C6A500CD7486 /* FileUDF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileUDF.h; sourceTree = "<group>"; };
                433219D312E4C6A500CD7486 /* udf25.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = udf25.cpp; sourceTree = "<group>"; };
                433219D412E4C6A500CD7486 /* udf25.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udf25.h; sourceTree = "<group>"; };
                433219D512E4C6A500CD7486 /* UDFDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UDFDirectory.cpp; sourceTree = "<group>"; };
                7C8A14551154CB2600E5FCFA /* TextureCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextureCache.h; sourceTree = "<group>"; };
                7C8A187A115B2A8200E5FCFA /* TextureDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureDatabase.cpp; sourceTree = "<group>"; };
                7C8A187B115B2A8200E5FCFA /* TextureDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextureDatabase.h; sourceTree = "<group>"; };
-               7C99B6A2133D342100FC2B16 /* CacheCircular.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheCircular.cpp; sourceTree = "<group>"; };
-               7C99B6A3133D342100FC2B16 /* CacheCircular.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheCircular.h; sourceTree = "<group>"; };
+               7C99B6A2133D342100FC2B16 /* CircularCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CircularCache.cpp; sourceTree = "<group>"; };
+               7C99B6A3133D342100FC2B16 /* CircularCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CircularCache.h; sourceTree = "<group>"; };
                7C99B7931340723F00FC2B16 /* GUIDialogPlayEject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogPlayEject.cpp; sourceTree = "<group>"; };
                7C99B7941340723F00FC2B16 /* GUIDialogPlayEject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIDialogPlayEject.h; sourceTree = "<group>"; };
                7CAA204F1079C8160096DE39 /* BaseRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BaseRenderer.cpp; sourceTree = "<group>"; };
                7CCF7F1C1069F3AE00992676 /* Builtins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Builtins.h; sourceTree = "<group>"; };
                7CCF7FC7106A0DF500992676 /* TimeUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeUtils.cpp; sourceTree = "<group>"; };
                7CCF7FC8106A0DF500992676 /* TimeUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeUtils.h; sourceTree = "<group>"; };
+               7CCFD98A151494E100211D82 /* PCMCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMCodec.cpp; sourceTree = "<group>"; };
+               7CCFD98B151494E100211D82 /* PCMCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMCodec.h; sourceTree = "<group>"; };
                7CD2C3A811940B270009EFC1 /* DirectoryNodeCountry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryNodeCountry.cpp; sourceTree = "<group>"; };
                7CD2C3A911940B270009EFC1 /* DirectoryNodeCountry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryNodeCountry.h; sourceTree = "<group>"; };
                7CD2CCFE11B38B000009EFC1 /* PythonAddon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PythonAddon.cpp; sourceTree = "<group>"; };
                88ECB6580DE013C4003396A7 /* DiskArbitration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiskArbitration.framework; path = /System/Library/Frameworks/DiskArbitration.framework; sourceTree = "<absolute>"; };
                8DD76F7E0486A8DE00D96B5E /* XBMC */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = XBMC; sourceTree = BUILT_PRODUCTS_DIR; };
                C80425701158A0DE00D158A6 /* controlslider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = controlslider.cpp; sourceTree = "<group>"; };
-               C807114A135DB5BF002F601B /* AnnouncementUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnnouncementUtils.h; sourceTree = "<group>"; };
                C807114B135DB5CC002F601B /* InputOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputOperations.cpp; sourceTree = "<group>"; };
                C807114C135DB5CC002F601B /* InputOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputOperations.h; sourceTree = "<group>"; };
                C84BF7321349BB74006D6FC9 /* JSONServiceDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSONServiceDescription.cpp; sourceTree = "<group>"; };
                C8D0B2AE1265A9A800F0C0AC /* SystemGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SystemGlobals.cpp; sourceTree = "<group>"; };
                C8EC5D0C1369519D00CCC10D /* XBMC_keytable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XBMC_keytable.cpp; sourceTree = "<group>"; };
                C8EC5D0D1369519D00CCC10D /* XBMC_keytable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMC_keytable.h; sourceTree = "<group>"; };
-               DF0DF15713A3ADA7008ED511 /* FileNFS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileNFS.cpp; sourceTree = "<group>"; };
-               DF0DF15813A3ADA7008ED511 /* FileNFS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileNFS.h; sourceTree = "<group>"; };
                DF0DF15913A3ADA7008ED511 /* NFSDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NFSDirectory.cpp; sourceTree = "<group>"; };
                DF0DF15A13A3ADA7008ED511 /* NFSDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NFSDirectory.h; sourceTree = "<group>"; };
                DF24A6B01406C7C500C7721E /* AFPDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AFPDirectory.cpp; sourceTree = "<group>"; };
                DF24A6B11406C7C500C7721E /* AFPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFPDirectory.h; sourceTree = "<group>"; };
-               DF24A6B21406C7C500C7721E /* FileAFP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileAFP.cpp; sourceTree = "<group>"; };
-               DF24A6B31406C7C500C7721E /* FileAFP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileAFP.h; sourceTree = "<group>"; };
                DF3488E513FD958F0026A711 /* GUIAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIAction.cpp; sourceTree = "<group>"; };
                DF3488E613FD958F0026A711 /* GUIAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIAction.h; sourceTree = "<group>"; };
                DF34892813FD9C780026A711 /* AirPlayServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirPlayServer.cpp; sourceTree = "<group>"; };
                DF34898113FDAAF60026A711 /* HttpParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpParser.cpp; sourceTree = "<group>"; };
                DF448455140048A60069344B /* AirTunesServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirTunesServer.cpp; sourceTree = "<group>"; };
                DF448456140048A60069344B /* AirTunesServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirTunesServer.h; sourceTree = "<group>"; };
-               DF448459140048C80069344B /* FilePipe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FilePipe.cpp; sourceTree = "<group>"; };
-               DF44845A140048C80069344B /* FilePipe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilePipe.h; sourceTree = "<group>"; };
                DF44845B140048C80069344B /* PipesManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipesManager.cpp; sourceTree = "<group>"; };
                DF44845C140048C80069344B /* PipesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PipesManager.h; sourceTree = "<group>"; };
                DF4484EC140054530069344B /* BXAcodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BXAcodec.cpp; sourceTree = "<group>"; };
                DF4484ED140054530069344B /* BXAcodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BXAcodec.h; sourceTree = "<group>"; };
-               DF85BAB31443669A000686BE /* FileUPnP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileUPnP.h; sourceTree = "<group>"; };
-               DF85BAB41443669A000686BE /* FileUPnP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileUPnP.cpp; sourceTree = "<group>"; };
+               DF52769A151BAEDA00B5B63B /* Base64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Base64.cpp; sourceTree = "<group>"; };
+               DF52769B151BAEDA00B5B63B /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = "<group>"; };
+               DF52769C151BAEDA00B5B63B /* HttpResponse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpResponse.cpp; sourceTree = "<group>"; };
+               DF52769D151BAEDA00B5B63B /* HttpResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpResponse.h; sourceTree = "<group>"; };
+               DF52772B151BAF4C00B5B63B /* WebSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocket.cpp; sourceTree = "<group>"; };
+               DF52772C151BAF4C00B5B63B /* WebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocket.h; sourceTree = "<group>"; };
+               DF52772D151BAF4C00B5B63B /* WebSocketManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketManager.cpp; sourceTree = "<group>"; };
+               DF52772E151BAF4C00B5B63B /* WebSocketManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketManager.h; sourceTree = "<group>"; };
+               DF52772F151BAF4C00B5B63B /* WebSocketV13.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketV13.cpp; sourceTree = "<group>"; };
+               DF527730151BAF4C00B5B63B /* WebSocketV13.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketV13.h; sourceTree = "<group>"; };
+               DF527731151BAF4C00B5B63B /* WebSocketV8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketV8.cpp; sourceTree = "<group>"; };
+               DF527732151BAF4C00B5B63B /* WebSocketV8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketV8.h; sourceTree = "<group>"; };
+               DF93D65B1444A7A3007C6459 /* SlingboxDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlingboxDirectory.h; sourceTree = "<group>"; };
+               DF93D65C1444A7A3007C6459 /* SlingboxDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlingboxDirectory.cpp; sourceTree = "<group>"; };
+               DF93D6631444A8B0007C6459 /* AFPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AFPFile.cpp; sourceTree = "<group>"; };
+               DF93D6641444A8B0007C6459 /* AFPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFPFile.h; sourceTree = "<group>"; };
+               DF93D6651444A8B0007C6459 /* DirectoryCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryCache.cpp; sourceTree = "<group>"; };
+               DF93D6661444A8B0007C6459 /* DirectoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryCache.h; sourceTree = "<group>"; };
+               DF93D6671444A8B0007C6459 /* FileCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCache.cpp; sourceTree = "<group>"; };
+               DF93D6681444A8B0007C6459 /* FileCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCache.h; sourceTree = "<group>"; };
+               DF93D6691444A8B0007C6459 /* CDDAFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDDAFile.cpp; sourceTree = "<group>"; };
+               DF93D66A1444A8B0007C6459 /* CDDAFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDDAFile.h; sourceTree = "<group>"; };
+               DF93D66B1444A8B0007C6459 /* CurlFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CurlFile.cpp; sourceTree = "<group>"; };
+               DF93D66C1444A8B0007C6459 /* CurlFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CurlFile.h; sourceTree = "<group>"; };
+               DF93D66D1444A8B0007C6459 /* DAAPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DAAPFile.cpp; sourceTree = "<group>"; };
+               DF93D66E1444A8B0007C6459 /* DAAPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DAAPFile.h; sourceTree = "<group>"; };
+               DF93D66F1444A8B0007C6459 /* DirectoryFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryFactory.cpp; sourceTree = "<group>"; };
+               DF93D6701444A8B0007C6459 /* DirectoryFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryFactory.h; sourceTree = "<group>"; };
+               DF93D6711444A8B0007C6459 /* FileDirectoryFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileDirectoryFactory.cpp; sourceTree = "<group>"; };
+               DF93D6721444A8B0007C6459 /* FileDirectoryFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileDirectoryFactory.h; sourceTree = "<group>"; };
+               DF93D6731444A8B0007C6459 /* FileReaderFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileReaderFile.cpp; sourceTree = "<group>"; };
+               DF93D6741444A8B0007C6459 /* FileReaderFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileReaderFile.h; sourceTree = "<group>"; };
+               DF93D6751444A8B0007C6459 /* HDFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDFile.cpp; sourceTree = "<group>"; };
+               DF93D6761444A8B0007C6459 /* HDFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDFile.h; sourceTree = "<group>"; };
+               DF93D6771444A8B0007C6459 /* ISOFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ISOFile.cpp; sourceTree = "<group>"; };
+               DF93D6781444A8B0007C6459 /* ISOFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISOFile.h; sourceTree = "<group>"; };
+               DF93D6791444A8B0007C6459 /* LastFMFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LastFMFile.cpp; sourceTree = "<group>"; };
+               DF93D67A1444A8B0007C6459 /* LastFMFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LastFMFile.h; sourceTree = "<group>"; };
+               DF93D67B1444A8B0007C6459 /* MusicDatabaseFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MusicDatabaseFile.cpp; sourceTree = "<group>"; };
+               DF93D67C1444A8B0007C6459 /* MusicDatabaseFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicDatabaseFile.h; sourceTree = "<group>"; };
+               DF93D67D1444A8B0007C6459 /* NFSFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NFSFile.cpp; sourceTree = "<group>"; };
+               DF93D67E1444A8B0007C6459 /* NFSFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NFSFile.h; sourceTree = "<group>"; };
+               DF93D67F1444A8B0007C6459 /* PipeFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipeFile.cpp; sourceTree = "<group>"; };
+               DF93D6801444A8B0007C6459 /* PipeFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PipeFile.h; sourceTree = "<group>"; };
+               DF93D6811444A8B0007C6459 /* RarFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RarFile.cpp; sourceTree = "<group>"; };
+               DF93D6821444A8B0007C6459 /* RarFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RarFile.h; sourceTree = "<group>"; };
+               DF93D6831444A8B0007C6459 /* RTVFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTVFile.cpp; sourceTree = "<group>"; };
+               DF93D6841444A8B0007C6459 /* RTVFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTVFile.h; sourceTree = "<group>"; };
+               DF93D6851444A8B0007C6459 /* SFTPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SFTPFile.cpp; sourceTree = "<group>"; };
+               DF93D6861444A8B0007C6459 /* SFTPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SFTPFile.h; sourceTree = "<group>"; };
+               DF93D6871444A8B0007C6459 /* ShoutcastFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShoutcastFile.cpp; sourceTree = "<group>"; };
+               DF93D6881444A8B0007C6459 /* ShoutcastFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShoutcastFile.h; sourceTree = "<group>"; };
+               DF93D6891444A8B0007C6459 /* SlingboxFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlingboxFile.cpp; sourceTree = "<group>"; };
+               DF93D68A1444A8B0007C6459 /* SlingboxFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlingboxFile.h; sourceTree = "<group>"; };
+               DF93D68B1444A8B0007C6459 /* SmbFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SmbFile.cpp; sourceTree = "<group>"; };
+               DF93D68C1444A8B0007C6459 /* SmbFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmbFile.h; sourceTree = "<group>"; };
+               DF93D68D1444A8B0007C6459 /* SpecialProtocolFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialProtocolFile.cpp; sourceTree = "<group>"; };
+               DF93D68E1444A8B0007C6459 /* SpecialProtocolFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialProtocolFile.h; sourceTree = "<group>"; };
+               DF93D68F1444A8B0007C6459 /* TuxBoxDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TuxBoxDirectory.cpp; sourceTree = "<group>"; };
+               DF93D6901444A8B0007C6459 /* TuxBoxDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TuxBoxDirectory.h; sourceTree = "<group>"; };
+               DF93D6911444A8B0007C6459 /* TuxBoxFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TuxBoxFile.cpp; sourceTree = "<group>"; };
+               DF93D6921444A8B0007C6459 /* TuxBoxFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TuxBoxFile.h; sourceTree = "<group>"; };
+               DF93D6931444A8B0007C6459 /* UDFFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UDFFile.cpp; sourceTree = "<group>"; };
+               DF93D6941444A8B0007C6459 /* UDFFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UDFFile.h; sourceTree = "<group>"; };
+               DF93D6951444A8B0007C6459 /* UPnPFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UPnPFile.cpp; sourceTree = "<group>"; };
+               DF93D6961444A8B0007C6459 /* UPnPFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPnPFile.h; sourceTree = "<group>"; };
+               DF93D6971444A8B0007C6459 /* ZipFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZipFile.cpp; sourceTree = "<group>"; };
+               DF93D6981444A8B0007C6459 /* ZipFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZipFile.h; sourceTree = "<group>"; };
+               DF93D7F01444B54A007C6459 /* HDHomeRunFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDHomeRunFile.cpp; sourceTree = "<group>"; };
+               DF93D7F11444B54A007C6459 /* HDHomeRunFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDHomeRunFile.h; sourceTree = "<group>"; };
+               DF93D7F41444B568007C6459 /* HDHomeRunDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDHomeRunDirectory.h; sourceTree = "<group>"; };
+               DF93D7F51444B568007C6459 /* HDHomeRunDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDHomeRunDirectory.cpp; sourceTree = "<group>"; };
                DF98D98A1434F47D00A6EBE1 /* SkinVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkinVariable.cpp; sourceTree = "<group>"; };
                DF98D98B1434F47D00A6EBE1 /* SkinVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkinVariable.h; sourceTree = "<group>"; };
                DFAB049613F8376700B70BFB /* InertialScrollingHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InertialScrollingHandler.cpp; sourceTree = "<group>"; };
                DFAB049713F8376700B70BFB /* InertialScrollingHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InertialScrollingHandler.h; sourceTree = "<group>"; };
+               DFC1B8EF1464840E00B1BE79 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
+               DFCA6AB9152245CD000BFAAE /* HTTPApiHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPApiHandler.cpp; sourceTree = "<group>"; };
+               DFCA6ABA152245CD000BFAAE /* HTTPApiHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPApiHandler.h; sourceTree = "<group>"; };
+               DFCA6ABB152245CD000BFAAE /* HTTPJsonRpcHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPJsonRpcHandler.cpp; sourceTree = "<group>"; };
+               DFCA6ABC152245CD000BFAAE /* HTTPJsonRpcHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPJsonRpcHandler.h; sourceTree = "<group>"; };
+               DFCA6ABD152245CD000BFAAE /* HTTPVfsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPVfsHandler.cpp; sourceTree = "<group>"; };
+               DFCA6ABE152245CD000BFAAE /* HTTPVfsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPVfsHandler.h; sourceTree = "<group>"; };
+               DFCA6ABF152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPWebinterfaceAddonsHandler.cpp; sourceTree = "<group>"; };
+               DFCA6AC0152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPWebinterfaceAddonsHandler.h; sourceTree = "<group>"; };
+               DFCA6AC1152245CD000BFAAE /* HTTPWebinterfaceHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPWebinterfaceHandler.cpp; sourceTree = "<group>"; };
+               DFCA6AC2152245CD000BFAAE /* HTTPWebinterfaceHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPWebinterfaceHandler.h; sourceTree = "<group>"; };
+               DFCA6AC3152245CD000BFAAE /* IHTTPRequestHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IHTTPRequestHandler.cpp; sourceTree = "<group>"; };
+               DFCA6AC4152245CD000BFAAE /* IHTTPRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IHTTPRequestHandler.h; sourceTree = "<group>"; };
                E306D12C0DDF7B590052C2AD /* XBMCHelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XBMCHelper.cpp; sourceTree = "<group>"; };
                E306D12D0DDF7B590052C2AD /* XBMCHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMCHelper.h; sourceTree = "<group>"; };
                E33206370D5070AA00435CE3 /* DVDDemuxVobsub.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDDemuxVobsub.cpp; sourceTree = "<group>"; };
                E38E16910D25F9FA00618676 /* Favourites.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Favourites.h; sourceTree = "<group>"; };
                E38E16920D25F9FA00618676 /* FileItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileItem.cpp; sourceTree = "<group>"; };
                E38E16930D25F9FA00618676 /* FileItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileItem.h; sourceTree = "<group>"; };
-               E38E16970D25F9FA00618676 /* CacheMemBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheMemBuffer.cpp; sourceTree = "<group>"; };
-               E38E16980D25F9FA00618676 /* CacheMemBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheMemBuffer.h; sourceTree = "<group>"; };
+               E38E16970D25F9FA00618676 /* MemBufferCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemBufferCache.cpp; sourceTree = "<group>"; };
+               E38E16980D25F9FA00618676 /* MemBufferCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemBufferCache.h; sourceTree = "<group>"; };
                E38E16990D25F9FA00618676 /* CacheStrategy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheStrategy.cpp; sourceTree = "<group>"; };
                E38E169A0D25F9FA00618676 /* CacheStrategy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheStrategy.h; sourceTree = "<group>"; };
                E38E169B0D25F9FA00618676 /* CDDADirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDDADirectory.cpp; sourceTree = "<group>"; };
                E38E16AB0D25F9FA00618676 /* DAAPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DAAPDirectory.h; sourceTree = "<group>"; };
                E38E16AC0D25F9FA00618676 /* Directory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Directory.cpp; sourceTree = "<group>"; };
                E38E16AD0D25F9FA00618676 /* Directory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Directory.h; sourceTree = "<group>"; };
-               E38E16AE0D25F9FA00618676 /* DirectoryCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryCache.cpp; sourceTree = "<group>"; };
-               E38E16AF0D25F9FA00618676 /* DirectoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryCache.h; sourceTree = "<group>"; };
                E38E16B00D25F9FA00618676 /* DirectoryHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryHistory.cpp; sourceTree = "<group>"; };
                E38E16B10D25F9FA00618676 /* DirectoryHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryHistory.h; sourceTree = "<group>"; };
-               E38E16B20D25F9FA00618676 /* DirectoryTuxBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectoryTuxBox.cpp; sourceTree = "<group>"; };
-               E38E16B30D25F9FA00618676 /* DirectoryTuxBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryTuxBox.h; sourceTree = "<group>"; };
                E38E16B40D25F9FA00618676 /* DllLibCurl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DllLibCurl.cpp; sourceTree = "<group>"; };
                E38E16B50D25F9FA00618676 /* DllLibCurl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DllLibCurl.h; sourceTree = "<group>"; };
-               E38E16B60D25F9FA00618676 /* FactoryDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FactoryDirectory.cpp; sourceTree = "<group>"; };
-               E38E16B70D25F9FA00618676 /* FactoryDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FactoryDirectory.h; sourceTree = "<group>"; };
-               E38E16B80D25F9FA00618676 /* FactoryFileDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FactoryFileDirectory.cpp; sourceTree = "<group>"; };
-               E38E16B90D25F9FA00618676 /* FactoryFileDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FactoryFileDirectory.h; sourceTree = "<group>"; };
                E38E16BA0D25F9FA00618676 /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = File.cpp; sourceTree = "<group>"; };
                E38E16BB0D25F9FA00618676 /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = File.h; sourceTree = "<group>"; };
-               E38E16BC0D25F9FA00618676 /* FileCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCache.cpp; sourceTree = "<group>"; };
-               E38E16BD0D25F9FA00618676 /* FileCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCache.h; sourceTree = "<group>"; };
-               E38E16BE0D25F9FA00618676 /* FileCDDA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCDDA.cpp; sourceTree = "<group>"; };
-               E38E16BF0D25F9FA00618676 /* FileCDDA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCDDA.h; sourceTree = "<group>"; };
-               E38E16C00D25F9FA00618676 /* FileCurl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileCurl.cpp; sourceTree = "<group>"; };
-               E38E16C10D25F9FA00618676 /* FileCurl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileCurl.h; sourceTree = "<group>"; };
-               E38E16C20D25F9FA00618676 /* FileDAAP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileDAAP.cpp; sourceTree = "<group>"; };
-               E38E16C30D25F9FA00618676 /* FileDAAP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileDAAP.h; sourceTree = "<group>"; };
                E38E16C40D25F9FA00618676 /* FileFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFactory.cpp; sourceTree = "<group>"; };
                E38E16C50D25F9FA00618676 /* FileFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileFactory.h; sourceTree = "<group>"; };
-               E38E16C60D25F9FA00618676 /* FileFileReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFileReader.cpp; sourceTree = "<group>"; };
-               E38E16C70D25F9FA00618676 /* FileFileReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileFileReader.h; sourceTree = "<group>"; };
-               E38E16CA0D25F9FA00618676 /* FileHD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileHD.cpp; sourceTree = "<group>"; };
-               E38E16CB0D25F9FA00618676 /* FileHD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileHD.h; sourceTree = "<group>"; };
-               E38E16CC0D25F9FA00618676 /* FileISO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileISO.cpp; sourceTree = "<group>"; };
-               E38E16CD0D25F9FA00618676 /* FileISO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileISO.h; sourceTree = "<group>"; };
-               E38E16CE0D25F9FA00618676 /* FileLastFM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileLastFM.cpp; sourceTree = "<group>"; };
-               E38E16CF0D25F9FA00618676 /* FileLastFM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileLastFM.h; sourceTree = "<group>"; };
-               E38E16D20D25F9FA00618676 /* FileMusicDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileMusicDatabase.cpp; sourceTree = "<group>"; };
-               E38E16D30D25F9FA00618676 /* FileMusicDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileMusicDatabase.h; sourceTree = "<group>"; };
-               E38E16D40D25F9FA00618676 /* FileRar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileRar.cpp; sourceTree = "<group>"; };
-               E38E16D50D25F9FA00618676 /* FileRar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileRar.h; sourceTree = "<group>"; };
-               E38E16D60D25F9FA00618676 /* FileRTV.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileRTV.cpp; sourceTree = "<group>"; };
-               E38E16D70D25F9FA00618676 /* FileRTV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileRTV.h; sourceTree = "<group>"; };
-               E38E16DB0D25F9FA00618676 /* FileSmb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSmb.h; sourceTree = "<group>"; };
-               E38E16DE0D25F9FA00618676 /* FileTuxBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileTuxBox.cpp; sourceTree = "<group>"; };
-               E38E16DF0D25F9FA00618676 /* FileTuxBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileTuxBox.h; sourceTree = "<group>"; };
-               E38E16E20D25F9FA00618676 /* FileZip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileZip.cpp; sourceTree = "<group>"; };
-               E38E16E30D25F9FA00618676 /* FileZip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileZip.h; sourceTree = "<group>"; };
                E38E16E40D25F9FA00618676 /* FTPDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FTPDirectory.cpp; sourceTree = "<group>"; };
                E38E16E50D25F9FA00618676 /* FTPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FTPDirectory.h; sourceTree = "<group>"; };
                E38E16E60D25F9FA00618676 /* FTPParse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FTPParse.cpp; sourceTree = "<group>"; };
                E38E16E70D25F9FA00618676 /* FTPParse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FTPParse.h; sourceTree = "<group>"; };
                E38E16E80D25F9FA00618676 /* HDDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDDirectory.cpp; sourceTree = "<group>"; };
                E38E16E90D25F9FA00618676 /* HDDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDDirectory.h; sourceTree = "<group>"; };
-               E38E16EA0D25F9FA00618676 /* HDHomeRun.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDHomeRun.cpp; sourceTree = "<group>"; };
-               E38E16EB0D25F9FA00618676 /* HDHomeRun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDHomeRun.h; sourceTree = "<group>"; };
                E38E16EC0D25F9FA00618676 /* IDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDirectory.cpp; sourceTree = "<group>"; };
                E38E16ED0D25F9FA00618676 /* IDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDirectory.h; sourceTree = "<group>"; };
                E38E16EE0D25F9FA00618676 /* IFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IFile.cpp; sourceTree = "<group>"; };
                E38E259C0D263CE000618676 /* xbmcplugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xbmcplugin.cpp; sourceTree = "<group>"; };
                E38E25BF0D263DC100618676 /* DVDFactoryDemuxer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDFactoryDemuxer.cpp; sourceTree = "<group>"; };
                E38E25C20D263DE200618676 /* DVDDemuxFFmpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDDemuxFFmpeg.cpp; sourceTree = "<group>"; };
-               E38F12C10D29FF200035C331 /* FileShoutcast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileShoutcast.cpp; sourceTree = "<group>"; };
                E3A478090D29029A00F3C3A6 /* GUIDialogCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogCache.cpp; sourceTree = "<group>"; };
                E3A478190D29032C00F3C3A6 /* GUIDialogAccessPoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogAccessPoints.cpp; sourceTree = "<group>"; };
                E3B53E7A0D97B08100021A96 /* DVDSubtitleParserMicroDVD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDSubtitleParserMicroDVD.cpp; sourceTree = "<group>"; };
                E3B53E7B0D97B08100021A96 /* DVDSubtitleParserMicroDVD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDSubtitleParserMicroDVD.h; sourceTree = "<group>"; };
                E3BBB7980D7EA78A00CAAFD3 /* MythSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MythSession.cpp; sourceTree = "<group>"; };
-               E3DAAF8A0D6E1B0500F17647 /* FileSmb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSmb.cpp; sourceTree = "<group>"; };
                E3DAAF8B0D6E1B0500F17647 /* SMBDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SMBDirectory.cpp; sourceTree = "<group>"; };
                E3E91FFA0D8C61DF002BF43D /* EventPacket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventPacket.cpp; sourceTree = "<group>"; };
                E3E91FFB0D8C61DF002BF43D /* EventServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventServer.cpp; sourceTree = "<group>"; };
                F57A1D1D1329B15300498CC7 /* AutoPool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AutoPool.mm; sourceTree = "<group>"; };
                F57B6F7E1071B8B500079ACB /* JobManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JobManager.cpp; sourceTree = "<group>"; };
                F57B6F7F1071B8B500079ACB /* JobManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JobManager.h; sourceTree = "<group>"; };
-               F584E1270F257BD800DB26A5 /* FileSpecialProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSpecialProtocol.cpp; sourceTree = "<group>"; };
-               F584E1280F257BD800DB26A5 /* FileSpecialProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSpecialProtocol.h; sourceTree = "<group>"; };
                F584E12C0F257C5100DB26A5 /* HTTPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPDirectory.h; sourceTree = "<group>"; };
                F584E12D0F257C5100DB26A5 /* HTTPDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPDirectory.cpp; sourceTree = "<group>"; };
                F58E293711FFC103006F4D46 /* DVDInputStreamBluray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDInputStreamBluray.cpp; sourceTree = "<group>"; };
                F5A7A701112893E50059D6AA /* AnnouncementManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnnouncementManager.h; sourceTree = "<group>"; };
                F5A7A859112908F00059D6AA /* WebServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebServer.cpp; sourceTree = "<group>"; };
                F5A7A85A112908F00059D6AA /* WebServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebServer.h; sourceTree = "<group>"; };
-               F5A7B374113AFB5F0059D6AA /* FileSFTP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSFTP.cpp; sourceTree = "<group>"; };
-               F5A7B375113AFB5F0059D6AA /* FileSFTP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSFTP.h; sourceTree = "<group>"; };
                F5A7B37C113AFB900059D6AA /* SFTPDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SFTPDirectory.cpp; sourceTree = "<group>"; };
                F5A7B37D113AFB900059D6AA /* SFTPDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SFTPDirectory.h; sourceTree = "<group>"; };
                F5A7B42A113CBB950059D6AA /* AddonsDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddonsDirectory.h; sourceTree = "<group>"; };
                                F56C8CF3131F5DFD000AD0F6 /* libiconv.dylib in Frameworks */,
                                F56C8CF6131F5E0B000AD0F6 /* libncurses.dylib in Frameworks */,
                                18404DA61396C31B00863BBA /* SlingboxLib.a in Frameworks */,
+                               DFC1B8F01464840E00B1BE79 /* SystemConfiguration.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                F5B5D64E133FC2E7007A4B4C /* librtv.a in Frameworks */,
                                F5B5D650133FC312007A4B4C /* libxdaap.a in Frameworks */,
                                18404E711396E06C00863BBA /* SlingboxLib.a in Frameworks */,
+                               DFC1BA3414648D6500B1BE79 /* SystemConfiguration.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                F56C8CF5131F5E0B000AD0F6 /* libncurses.dylib */,
                                F56C8CEF131F5DED000AD0F6 /* libxml2.dylib */,
                                F56C8CE6131F5DC6000AD0F6 /* libz.dylib */,
+                               DFC1B8EF1464840E00B1BE79 /* SystemConfiguration.framework */,
                                E38E23910D2626E600618676 /* OpenGL.framework */,
                                F59879070FBAA0C3008EF4FB /* QuartzCore.framework */,
                                E35EF2540D380C3D00DB5CD5 /* QuickTime.framework */,
                431376F212D6449100680C15 /* network */ = {
                        isa = PBXGroup;
                        children = (
+                               DFCA6AB8152245CD000BFAAE /* httprequesthandler */,
                                4313772B12D6474F00680C15 /* libscrobbler */,
                                432D7CE112D86D4900CE4C49 /* linux */,
                                4313772312D646E300680C15 /* osx */,
+                               DF527729151BAF4C00B5B63B /* websocket */,
                                DF34892813FD9C780026A711 /* AirPlayServer.cpp */,
                                DF34892913FD9C780026A711 /* AirPlayServer.h */,
                                DF448455140048A60069344B /* AirTunesServer.cpp */,
                                E38E19820D25F9FB00618676 /* python */,
                                F5A7A700112893E50059D6AA /* AnnouncementManager.cpp */,
                                F5A7A701112893E50059D6AA /* AnnouncementManager.h */,
-                               C807114A135DB5BF002F601B /* AnnouncementUtils.h */,
                                7CCF7F1B1069F3AE00992676 /* Builtins.cpp */,
                                7CCF7F1C1069F3AE00992676 /* Builtins.h */,
                                436721A612D66A09002508E6 /* IAnnouncer.h */,
                        name = Documentation;
                        sourceTree = "<group>";
                };
+               DF527729151BAF4C00B5B63B /* websocket */ = {
+                       isa = PBXGroup;
+                       children = (
+                               DF52772B151BAF4C00B5B63B /* WebSocket.cpp */,
+                               DF52772C151BAF4C00B5B63B /* WebSocket.h */,
+                               DF52772D151BAF4C00B5B63B /* WebSocketManager.cpp */,
+                               DF52772E151BAF4C00B5B63B /* WebSocketManager.h */,
+                               DF52772F151BAF4C00B5B63B /* WebSocketV13.cpp */,
+                               DF527730151BAF4C00B5B63B /* WebSocketV13.h */,
+                               DF527731151BAF4C00B5B63B /* WebSocketV8.cpp */,
+                               DF527732151BAF4C00B5B63B /* WebSocketV8.h */,
+                       );
+                       path = websocket;
+                       sourceTree = "<group>";
+               };
+               DFCA6AB8152245CD000BFAAE /* httprequesthandler */ = {
+                       isa = PBXGroup;
+                       children = (
+                               DFCA6AB9152245CD000BFAAE /* HTTPApiHandler.cpp */,
+                               DFCA6ABA152245CD000BFAAE /* HTTPApiHandler.h */,
+                               DFCA6ABB152245CD000BFAAE /* HTTPJsonRpcHandler.cpp */,
+                               DFCA6ABC152245CD000BFAAE /* HTTPJsonRpcHandler.h */,
+                               DFCA6ABD152245CD000BFAAE /* HTTPVfsHandler.cpp */,
+                               DFCA6ABE152245CD000BFAAE /* HTTPVfsHandler.h */,
+                               DFCA6ABF152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp */,
+                               DFCA6AC0152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.h */,
+                               DFCA6AC1152245CD000BFAAE /* HTTPWebinterfaceHandler.cpp */,
+                               DFCA6AC2152245CD000BFAAE /* HTTPWebinterfaceHandler.h */,
+                               DFCA6AC3152245CD000BFAAE /* IHTTPRequestHandler.cpp */,
+                               DFCA6AC4152245CD000BFAAE /* IHTTPRequestHandler.h */,
+                       );
+                       path = httprequesthandler;
+                       sourceTree = "<group>";
+               };
                E37D5CB40D3023BB0081D327 /* osx */ = {
                        isa = PBXGroup;
                        children = (
                                E38E16240D25F9FA00618676 /* OGGcodec.h */,
                                F5987FDA0FBE2DFD008EF4FB /* PAPlayer.cpp */,
                                F5987FD90FBE2DFD008EF4FB /* PAPlayer.h */,
+                               7CCFD98A151494E100211D82 /* PCMCodec.cpp */,
+                               7CCFD98B151494E100211D82 /* PCMCodec.h */,
                                E38E162A0D25F9FA00618676 /* ReplayGain.cpp */,
                                E38E162B0D25F9FA00618676 /* ReplayGain.h */,
                                E38E16310D25F9FA00618676 /* SIDCodec.cpp */,
                                F5A7B42A113CBB950059D6AA /* AddonsDirectory.h */,
                                DF24A6B01406C7C500C7721E /* AFPDirectory.cpp */,
                                DF24A6B11406C7C500C7721E /* AFPDirectory.h */,
+                               DF93D6631444A8B0007C6459 /* AFPFile.cpp */,
+                               DF93D6641444A8B0007C6459 /* AFPFile.h */,
                                88ACB0190DCF40800083CFDF /* ASAPFileDirectory.cpp */,
                                88ACB01A0DCF40800083CFDF /* ASAPFileDirectory.h */,
-                               7C99B6A2133D342100FC2B16 /* CacheCircular.cpp */,
-                               7C99B6A3133D342100FC2B16 /* CacheCircular.h */,
-                               E38E16970D25F9FA00618676 /* CacheMemBuffer.cpp */,
-                               E38E16980D25F9FA00618676 /* CacheMemBuffer.h */,
                                E38E16990D25F9FA00618676 /* CacheStrategy.cpp */,
                                E38E169A0D25F9FA00618676 /* CacheStrategy.h */,
                                E38E169B0D25F9FA00618676 /* CDDADirectory.cpp */,
                                E38E169C0D25F9FA00618676 /* CDDADirectory.h */,
+                               DF93D6691444A8B0007C6459 /* CDDAFile.cpp */,
+                               DF93D66A1444A8B0007C6459 /* CDDAFile.h */,
+                               7C99B6A2133D342100FC2B16 /* CircularCache.cpp */,
+                               7C99B6A3133D342100FC2B16 /* CircularCache.h */,
+                               DF93D66B1444A8B0007C6459 /* CurlFile.cpp */,
+                               DF93D66C1444A8B0007C6459 /* CurlFile.h */,
                                E38E16AA0D25F9FA00618676 /* DAAPDirectory.cpp */,
                                E38E16AB0D25F9FA00618676 /* DAAPDirectory.h */,
+                               DF93D66D1444A8B0007C6459 /* DAAPFile.cpp */,
+                               DF93D66E1444A8B0007C6459 /* DAAPFile.h */,
                                7C45DBE710F325C400D4BBF3 /* DAVDirectory.cpp */,
                                7C45DBE810F325C400D4BBF3 /* DAVDirectory.h */,
                                E38E16AC0D25F9FA00618676 /* Directory.cpp */,
                                E38E16AD0D25F9FA00618676 /* Directory.h */,
-                               E38E16AE0D25F9FA00618676 /* DirectoryCache.cpp */,
-                               E38E16AF0D25F9FA00618676 /* DirectoryCache.h */,
+                               DF93D6651444A8B0007C6459 /* DirectoryCache.cpp */,
+                               DF93D6661444A8B0007C6459 /* DirectoryCache.h */,
+                               DF93D66F1444A8B0007C6459 /* DirectoryFactory.cpp */,
+                               DF93D6701444A8B0007C6459 /* DirectoryFactory.h */,
                                E38E16B00D25F9FA00618676 /* DirectoryHistory.cpp */,
                                E38E16B10D25F9FA00618676 /* DirectoryHistory.h */,
-                               E38E16B20D25F9FA00618676 /* DirectoryTuxBox.cpp */,
-                               E38E16B30D25F9FA00618676 /* DirectoryTuxBox.h */,
                                E38E16B40D25F9FA00618676 /* DllLibCurl.cpp */,
                                E38E16B50D25F9FA00618676 /* DllLibCurl.h */,
-                               E38E16B60D25F9FA00618676 /* FactoryDirectory.cpp */,
-                               E38E16B70D25F9FA00618676 /* FactoryDirectory.h */,
-                               E38E16B80D25F9FA00618676 /* FactoryFileDirectory.cpp */,
-                               E38E16B90D25F9FA00618676 /* FactoryFileDirectory.h */,
                                E38E16BA0D25F9FA00618676 /* File.cpp */,
                                E38E16BB0D25F9FA00618676 /* File.h */,
-                               DF24A6B21406C7C500C7721E /* FileAFP.cpp */,
-                               DF24A6B31406C7C500C7721E /* FileAFP.h */,
-                               E38E16BC0D25F9FA00618676 /* FileCache.cpp */,
-                               E38E16BD0D25F9FA00618676 /* FileCache.h */,
-                               E38E16BE0D25F9FA00618676 /* FileCDDA.cpp */,
-                               E38E16BF0D25F9FA00618676 /* FileCDDA.h */,
-                               E38E16C00D25F9FA00618676 /* FileCurl.cpp */,
-                               E38E16C10D25F9FA00618676 /* FileCurl.h */,
-                               E38E16C20D25F9FA00618676 /* FileDAAP.cpp */,
-                               E38E16C30D25F9FA00618676 /* FileDAAP.h */,
+                               DF93D6671444A8B0007C6459 /* FileCache.cpp */,
+                               DF93D6681444A8B0007C6459 /* FileCache.h */,
+                               DF93D6711444A8B0007C6459 /* FileDirectoryFactory.cpp */,
+                               DF93D6721444A8B0007C6459 /* FileDirectoryFactory.h */,
                                E38E16C40D25F9FA00618676 /* FileFactory.cpp */,
                                E38E16C50D25F9FA00618676 /* FileFactory.h */,
-                               E38E16C60D25F9FA00618676 /* FileFileReader.cpp */,
-                               E38E16C70D25F9FA00618676 /* FileFileReader.h */,
-                               E38E16CA0D25F9FA00618676 /* FileHD.cpp */,
-                               E38E16CB0D25F9FA00618676 /* FileHD.h */,
-                               E38E16CC0D25F9FA00618676 /* FileISO.cpp */,
-                               E38E16CD0D25F9FA00618676 /* FileISO.h */,
-                               E38E16CE0D25F9FA00618676 /* FileLastFM.cpp */,
-                               E38E16CF0D25F9FA00618676 /* FileLastFM.h */,
-                               E38E16D20D25F9FA00618676 /* FileMusicDatabase.cpp */,
-                               E38E16D30D25F9FA00618676 /* FileMusicDatabase.h */,
-                               DF0DF15713A3ADA7008ED511 /* FileNFS.cpp */,
-                               DF0DF15813A3ADA7008ED511 /* FileNFS.h */,
-                               DF448459140048C80069344B /* FilePipe.cpp */,
-                               DF44845A140048C80069344B /* FilePipe.h */,
-                               E38E16D40D25F9FA00618676 /* FileRar.cpp */,
-                               E38E16D50D25F9FA00618676 /* FileRar.h */,
-                               E38E16D60D25F9FA00618676 /* FileRTV.cpp */,
-                               E38E16D70D25F9FA00618676 /* FileRTV.h */,
-                               F5A7B374113AFB5F0059D6AA /* FileSFTP.cpp */,
-                               F5A7B375113AFB5F0059D6AA /* FileSFTP.h */,
-                               E38F12C10D29FF200035C331 /* FileShoutcast.cpp */,
-                               E3DAAF8A0D6E1B0500F17647 /* FileSmb.cpp */,
-                               E38E16DB0D25F9FA00618676 /* FileSmb.h */,
-                               F584E1270F257BD800DB26A5 /* FileSpecialProtocol.cpp */,
-                               F584E1280F257BD800DB26A5 /* FileSpecialProtocol.h */,
-                               E38E16DE0D25F9FA00618676 /* FileTuxBox.cpp */,
-                               E38E16DF0D25F9FA00618676 /* FileTuxBox.h */,
-                               433219D112E4C6A500CD7486 /* FileUDF.cpp */,
-                               433219D212E4C6A500CD7486 /* FileUDF.h */,
-                               DF85BAB41443669A000686BE /* FileUPnP.cpp */,
-                               DF85BAB31443669A000686BE /* FileUPnP.h */,
-                               E38E16E20D25F9FA00618676 /* FileZip.cpp */,
-                               E38E16E30D25F9FA00618676 /* FileZip.h */,
+                               DF93D6731444A8B0007C6459 /* FileReaderFile.cpp */,
+                               DF93D6741444A8B0007C6459 /* FileReaderFile.h */,
                                E38E16E40D25F9FA00618676 /* FTPDirectory.cpp */,
                                E38E16E50D25F9FA00618676 /* FTPDirectory.h */,
                                E38E16E60D25F9FA00618676 /* FTPParse.cpp */,
                                E38E16E70D25F9FA00618676 /* FTPParse.h */,
                                E38E16E80D25F9FA00618676 /* HDDirectory.cpp */,
                                E38E16E90D25F9FA00618676 /* HDDirectory.h */,
-                               E38E16EA0D25F9FA00618676 /* HDHomeRun.cpp */,
-                               E38E16EB0D25F9FA00618676 /* HDHomeRun.h */,
+                               DF93D6751444A8B0007C6459 /* HDFile.cpp */,
+                               DF93D6761444A8B0007C6459 /* HDFile.h */,
+                               DF93D7F51444B568007C6459 /* HDHomeRunDirectory.cpp */,
+                               DF93D7F41444B568007C6459 /* HDHomeRunDirectory.h */,
+                               DF93D7F01444B54A007C6459 /* HDHomeRunFile.cpp */,
+                               DF93D7F11444B54A007C6459 /* HDHomeRunFile.h */,
                                E43196140FB2382E0030E150 /* HTSPDirectory.cpp */,
                                E43196130FB2382D0030E150 /* HTSPDirectory.h */,
                                E43196160FB2382E0030E150 /* HTSPSession.cpp */,
                                E38E16F20D25F9FA00618676 /* iso9660.h */,
                                E38E16F30D25F9FA00618676 /* ISO9660Directory.cpp */,
                                E38E16F40D25F9FA00618676 /* ISO9660Directory.h */,
+                               DF93D6771444A8B0007C6459 /* ISOFile.cpp */,
+                               DF93D6781444A8B0007C6459 /* ISOFile.h */,
                                E38E16F50D25F9FA00618676 /* LastFMDirectory.cpp */,
                                E38E16F60D25F9FA00618676 /* LastFMDirectory.h */,
+                               DF93D6791444A8B0007C6459 /* LastFMFile.cpp */,
+                               DF93D67A1444A8B0007C6459 /* LastFMFile.h */,
+                               E38E16970D25F9FA00618676 /* MemBufferCache.cpp */,
+                               E38E16980D25F9FA00618676 /* MemBufferCache.h */,
                                E38E17080D25F9FA00618676 /* MultiPathDirectory.cpp */,
                                E38E17090D25F9FA00618676 /* MultiPathDirectory.h */,
                                F50629780E57B9680066625A /* MultiPathFile.cpp */,
                                F50629790E57B9680066625A /* MultiPathFile.h */,
                                E38E17370D25F9FA00618676 /* MusicDatabaseDirectory.cpp */,
                                E38E17380D25F9FA00618676 /* MusicDatabaseDirectory.h */,
+                               DF93D67B1444A8B0007C6459 /* MusicDatabaseFile.cpp */,
+                               DF93D67C1444A8B0007C6459 /* MusicDatabaseFile.h */,
                                880DBE530DC224A100E26B71 /* MusicFileDirectory.cpp */,
                                880DBE540DC224A100E26B71 /* MusicFileDirectory.h */,
                                E38E17390D25F9FA00618676 /* MusicSearchDirectory.cpp */,
                                E3BBB7980D7EA78A00CAAFD3 /* MythSession.cpp */,
                                DF0DF15913A3ADA7008ED511 /* NFSDirectory.cpp */,
                                DF0DF15A13A3ADA7008ED511 /* NFSDirectory.h */,
+                               DF93D67D1444A8B0007C6459 /* NFSFile.cpp */,
+                               DF93D67E1444A8B0007C6459 /* NFSFile.h */,
                                E4E91BB70E7F7338001F0546 /* NptXbmcFile.cpp */,
                                E38E173C0D25F9FA00618676 /* NSFFileDirectory.cpp */,
                                E38E173D0D25F9FA00618676 /* NSFFileDirectory.h */,
                                E38E173E0D25F9FA00618676 /* OGGFileDirectory.cpp */,
                                E38E173F0D25F9FA00618676 /* OGGFileDirectory.h */,
+                               DF93D67F1444A8B0007C6459 /* PipeFile.cpp */,
+                               DF93D6801444A8B0007C6459 /* PipeFile.h */,
                                DF44845B140048C80069344B /* PipesManager.cpp */,
                                DF44845C140048C80069344B /* PipesManager.h */,
                                E38E17400D25F9FA00618676 /* PlaylistDirectory.cpp */,
                                E38E17450D25F9FA00618676 /* PluginDirectory.h */,
                                E38E17460D25F9FA00618676 /* RarDirectory.cpp */,
                                E38E17470D25F9FA00618676 /* RarDirectory.h */,
+                               DF93D6811444A8B0007C6459 /* RarFile.cpp */,
+                               DF93D6821444A8B0007C6459 /* RarFile.h */,
                                E38E17480D25F9FA00618676 /* RarManager.cpp */,
                                E38E17490D25F9FA00618676 /* RarManager.h */,
                                889B4D8C0E0EF86C00FAD25E /* RSSDirectory.cpp */,
                                889B4D8D0E0EF86C00FAD25E /* RSSDirectory.h */,
                                E38E174B0D25F9FA00618676 /* RTVDirectory.cpp */,
                                E38E174C0D25F9FA00618676 /* RTVDirectory.h */,
+                               DF93D6831444A8B0007C6459 /* RTVFile.cpp */,
+                               DF93D6841444A8B0007C6459 /* RTVFile.h */,
                                E4DC97500FFE5BA8008E0C07 /* SAPDirectory.cpp */,
                                E4DC97510FFE5BA8008E0C07 /* SAPDirectory.h */,
                                E4DC97520FFE5BA8008E0C07 /* SAPFile.cpp */,
                                E4DC97530FFE5BA8008E0C07 /* SAPFile.h */,
                                F5A7B37C113AFB900059D6AA /* SFTPDirectory.cpp */,
                                F5A7B37D113AFB900059D6AA /* SFTPDirectory.h */,
+                               DF93D6851444A8B0007C6459 /* SFTPFile.cpp */,
+                               DF93D6861444A8B0007C6459 /* SFTPFile.h */,
+                               DF93D6871444A8B0007C6459 /* ShoutcastFile.cpp */,
+                               DF93D6881444A8B0007C6459 /* ShoutcastFile.h */,
                                E38E17510D25F9FA00618676 /* SIDFileDirectory.cpp */,
                                E38E17520D25F9FA00618676 /* SIDFileDirectory.h */,
-                               18404D9C1396C13500863BBA /* Slingbox.cpp */,
-                               18404D9D1396C13500863BBA /* Slingbox.h */,
+                               DF93D65C1444A7A3007C6459 /* SlingboxDirectory.cpp */,
+                               DF93D65B1444A7A3007C6459 /* SlingboxDirectory.h */,
+                               DF93D6891444A8B0007C6459 /* SlingboxFile.cpp */,
+                               DF93D68A1444A8B0007C6459 /* SlingboxFile.h */,
                                E38E17530D25F9FA00618676 /* SmartPlaylistDirectory.cpp */,
                                E38E17540D25F9FA00618676 /* SmartPlaylistDirectory.h */,
                                E3DAAF8B0D6E1B0500F17647 /* SMBDirectory.cpp */,
                                E38E17560D25F9FA00618676 /* SMBDirectory.h */,
+                               DF93D68B1444A8B0007C6459 /* SmbFile.cpp */,
+                               DF93D68C1444A8B0007C6459 /* SmbFile.h */,
                                7C84A59C12FA3C1600CD1714 /* SourcesDirectory.cpp */,
                                7C84A59D12FA3C1600CD1714 /* SourcesDirectory.h */,
                                7C2D6AE20F35453E00DD2E85 /* SpecialProtocol.cpp */,
                                7C2D6AE30F35453E00DD2E85 /* SpecialProtocol.h */,
                                7CEBD8A60F33A0D800CAF6AD /* SpecialProtocolDirectory.cpp */,
                                7CEBD8A70F33A0D800CAF6AD /* SpecialProtocolDirectory.h */,
+                               DF93D68D1444A8B0007C6459 /* SpecialProtocolFile.cpp */,
+                               DF93D68E1444A8B0007C6459 /* SpecialProtocolFile.h */,
                                E38E17590D25F9FA00618676 /* StackDirectory.cpp */,
                                E38E175A0D25F9FA00618676 /* StackDirectory.h */,
+                               DF93D68F1444A8B0007C6459 /* TuxBoxDirectory.cpp */,
+                               DF93D6901444A8B0007C6459 /* TuxBoxDirectory.h */,
+                               DF93D6911444A8B0007C6459 /* TuxBoxFile.cpp */,
+                               DF93D6921444A8B0007C6459 /* TuxBoxFile.h */,
                                433219D312E4C6A500CD7486 /* udf25.cpp */,
                                433219D412E4C6A500CD7486 /* udf25.h */,
                                433219D512E4C6A500CD7486 /* UDFDirectory.cpp */,
                                433219D612E4C6A500CD7486 /* UDFDirectory.h */,
+                               DF93D6931444A8B0007C6459 /* UDFFile.cpp */,
+                               DF93D6941444A8B0007C6459 /* UDFFile.h */,
                                E38E175B0D25F9FA00618676 /* UPnPDirectory.cpp */,
                                E38E175C0D25F9FA00618676 /* UPnPDirectory.h */,
+                               DF93D6951444A8B0007C6459 /* UPnPFile.cpp */,
+                               DF93D6961444A8B0007C6459 /* UPnPFile.h */,
                                E38E178A0D25F9FA00618676 /* VideoDatabaseDirectory.cpp */,
                                E38E178B0D25F9FA00618676 /* VideoDatabaseDirectory.h */,
                                E38E178C0D25F9FA00618676 /* VirtualDirectory.cpp */,
                                E49ACD8A100745C400A86ECD /* ZeroconfDirectory.h */,
                                E38E17930D25F9FA00618676 /* ZipDirectory.cpp */,
                                E38E17940D25F9FA00618676 /* ZipDirectory.h */,
+                               DF93D6971444A8B0007C6459 /* ZipFile.cpp */,
+                               DF93D6981444A8B0007C6459 /* ZipFile.h */,
                                E38E17950D25F9FA00618676 /* ZipManager.cpp */,
                                E38E17960D25F9FA00618676 /* ZipManager.h */,
                        );
                                F5FDF51B0E7218950005B0A6 /* AsyncFileCopy.h */,
                                F5BDB81F120203C200F0B710 /* AutoPtrHandle.cpp */,
                                F5BDB81E120203C200F0B710 /* AutoPtrHandle.h */,
+                               DF52769A151BAEDA00B5B63B /* Base64.cpp */,
+                               DF52769B151BAEDA00B5B63B /* Base64.h */,
                                E38E1E270D25F9FD00618676 /* BitstreamStats.cpp */,
                                E38E1E280D25F9FD00618676 /* BitstreamStats.h */,
                                E38E1E290D25F9FD00618676 /* CharsetConverter.cpp */,
                                E38E1E470D25F9FD00618676 /* HttpHeader.h */,
                                DF34898113FDAAF60026A711 /* HttpParser.cpp */,
                                DF34897A13FDAA270026A711 /* HttpParser.h */,
+                               DF52769C151BAEDA00B5B63B /* HttpResponse.cpp */,
+                               DF52769D151BAEDA00B5B63B /* HttpResponse.h */,
                                E38E1E4C0D25F9FD00618676 /* InfoLoader.cpp */,
                                E38E1E4D0D25F9FD00618676 /* InfoLoader.h */,
                                7CAA205B107AFC280096DE39 /* Job.h */,
                                18B7C9E7129447B9009E7A26 /* MathUtils.h */,
                                F5F8E1E60E427F6700A8E96F /* md5.cpp */,
                                F5F8E1E70E427F6700A8E96F /* md5.h */,
+                               188F75FC152217BC009870CE /* Mime.cpp */,
+                               188F75FD152217BC009870CE /* Mime.h */,
                                E38E1E6D0D25F9FD00618676 /* PCMAmplifier.cpp */,
                                E38E1E6E0D25F9FD00618676 /* PCMAmplifier.h */,
                                18CCEAEC1112F5B800615FC6 /* PCMRemap.cpp */,
                                F5AE408713415D9E0004BD79 /* FileItemHandler.h */,
                                F5AE408813415D9E0004BD79 /* FileOperations.cpp */,
                                F5AE408913415D9E0004BD79 /* FileOperations.h */,
+                               188F7600152217DF009870CE /* GUIOperations.cpp */,
+                               188F7601152217DF009870CE /* GUIOperations.h */,
                                F5AE408A13415D9E0004BD79 /* IClient.h */,
+                               188F751815211733009870CE /* IJSONRPCAnnouncer.h */,
                                C807114B135DB5CC002F601B /* InputOperations.cpp */,
                                C807114C135DB5CC002F601B /* InputOperations.h */,
                                F5AE408B13415D9E0004BD79 /* ITransportLayer.h */,
                                F5AE408C13415D9E0004BD79 /* JSONRPC.cpp */,
                                F5AE408D13415D9E0004BD79 /* JSONRPC.h */,
+                               188F751915211743009870CE /* JSONRPCUtils.h */,
                                C84BF7321349BB74006D6FC9 /* JSONServiceDescription.cpp */,
                                C84BF7331349BB74006D6FC9 /* JSONServiceDescription.h */,
                                F5AE408E13415D9E0004BD79 /* JSONUtils.h */,
                                E38E1FFC0D25F9FD00618676 /* DynamicDll.cpp in Sources */,
                                E38E1FFE0D25F9FD00618676 /* Favourites.cpp in Sources */,
                                E38E1FFF0D25F9FD00618676 /* FileItem.cpp in Sources */,
-                               E38E20010D25F9FD00618676 /* CacheMemBuffer.cpp in Sources */,
+                               E38E20010D25F9FD00618676 /* MemBufferCache.cpp in Sources */,
                                E38E20020D25F9FD00618676 /* CacheStrategy.cpp in Sources */,
                                E38E20030D25F9FD00618676 /* CDDADirectory.cpp in Sources */,
                                E38E20040D25F9FD00618676 /* cddb.cpp in Sources */,
                                E38E20050D25F9FD00618676 /* cdioSupport.cpp in Sources */,
                                E38E20060D25F9FD00618676 /* DAAPDirectory.cpp in Sources */,
                                E38E20070D25F9FD00618676 /* Directory.cpp in Sources */,
-                               E38E20080D25F9FD00618676 /* DirectoryCache.cpp in Sources */,
                                E38E20090D25F9FD00618676 /* DirectoryHistory.cpp in Sources */,
-                               E38E200A0D25F9FD00618676 /* DirectoryTuxBox.cpp in Sources */,
                                E38E200B0D25F9FD00618676 /* DllLibCurl.cpp in Sources */,
-                               E38E200C0D25F9FD00618676 /* FactoryDirectory.cpp in Sources */,
-                               E38E200D0D25F9FD00618676 /* FactoryFileDirectory.cpp in Sources */,
                                E38E200E0D25F9FD00618676 /* File.cpp in Sources */,
-                               E38E200F0D25F9FD00618676 /* FileCache.cpp in Sources */,
-                               E38E20100D25F9FD00618676 /* FileCDDA.cpp in Sources */,
-                               E38E20110D25F9FD00618676 /* FileCurl.cpp in Sources */,
-                               E38E20120D25F9FD00618676 /* FileDAAP.cpp in Sources */,
                                E38E20130D25F9FD00618676 /* FileFactory.cpp in Sources */,
-                               E38E20140D25F9FD00618676 /* FileFileReader.cpp in Sources */,
-                               E38E20160D25F9FD00618676 /* FileHD.cpp in Sources */,
-                               E38E20170D25F9FD00618676 /* FileISO.cpp in Sources */,
-                               E38E20180D25F9FD00618676 /* FileLastFM.cpp in Sources */,
-                               E38E201A0D25F9FD00618676 /* FileMusicDatabase.cpp in Sources */,
-                               E38E201B0D25F9FD00618676 /* FileRar.cpp in Sources */,
-                               E38E201C0D25F9FD00618676 /* FileRTV.cpp in Sources */,
-                               E38E20200D25F9FD00618676 /* FileTuxBox.cpp in Sources */,
-                               E38E20220D25F9FD00618676 /* FileZip.cpp in Sources */,
                                E38E20230D25F9FD00618676 /* FTPDirectory.cpp in Sources */,
                                E38E20240D25F9FD00618676 /* FTPParse.cpp in Sources */,
                                E38E20250D25F9FD00618676 /* HDDirectory.cpp in Sources */,
-                               E38E20260D25F9FD00618676 /* HDHomeRun.cpp in Sources */,
                                E38E20270D25F9FD00618676 /* IDirectory.cpp in Sources */,
                                E38E20280D25F9FD00618676 /* IFile.cpp in Sources */,
                                E38E20290D25F9FD00618676 /* iso9660.cpp in Sources */,
                                E38E25C30D263DE200618676 /* DVDDemuxFFmpeg.cpp in Sources */,
                                E3A4780A0D29029A00F3C3A6 /* GUIDialogCache.cpp in Sources */,
                                E3A4781A0D29032C00F3C3A6 /* GUIDialogAccessPoints.cpp in Sources */,
-                               E38F12C20D29FF200035C331 /* FileShoutcast.cpp in Sources */,
                                E36578880D3AA7B40033CC1C /* DVDPlayerCodec.cpp in Sources */,
                                E33206380D5070AA00435CE3 /* DVDDemuxVobsub.cpp in Sources */,
                                E33979960D62FD48004ECDDA /* DVDInputStreamTV.cpp in Sources */,
                                810C9F630D67BD2F0095F5DD /* PltMediaConnect.cpp in Sources */,
                                810C9FA90D67D1FB0095F5DD /* MythDirectory.cpp in Sources */,
                                810C9FAA0D67D1FB0095F5DD /* MythFile.cpp in Sources */,
-                               E3DAAF8C0D6E1B0500F17647 /* FileSmb.cpp in Sources */,
                                E3DAAF8D0D6E1B0500F17647 /* SMBDirectory.cpp in Sources */,
                                E3BBB7990D7EA78A00CAAFD3 /* MythSession.cpp in Sources */,
                                E3E91FFD0D8C61DF002BF43D /* EventPacket.cpp in Sources */,
                                F5A00B080EFDDDFC00CD59F3 /* AudioRendererFactory.cpp in Sources */,
                                F5A00B260EFDE44100CD59F3 /* NullDirectSound.cpp in Sources */,
                                7C5608C70F1754930056433A /* ExternalPlayer.cpp in Sources */,
-                               F584E1290F257BD800DB26A5 /* FileSpecialProtocol.cpp in Sources */,
                                F584E12E0F257C5100DB26A5 /* HTTPDirectory.cpp in Sources */,
                                F54C51D20F1E783200D46E3C /* GUIDialogKaraokeSongSelector.cpp in Sources */,
                                F54C51D50F1E784800D46E3C /* karaokelyricscdg.cpp in Sources */,
                                F5A7A702112893E50059D6AA /* AnnouncementManager.cpp in Sources */,
                                F5A7A85B112908F00059D6AA /* WebServer.cpp in Sources */,
                                7C7B2B301134F36400713D6D /* mysqldataset.cpp in Sources */,
-                               F5A7B376113AFB5F0059D6AA /* FileSFTP.cpp in Sources */,
                                F5A7B37E113AFB900059D6AA /* SFTPDirectory.cpp in Sources */,
                                F5A7B42C113CBB950059D6AA /* AddonsDirectory.cpp in Sources */,
                                18B4A0021152BFA5001AF8A6 /* Addon.cpp in Sources */,
                                18B7CA1E12944A8E009E7A26 /* tinyxmlparser.cpp in Sources */,
                                432D7CE412D86DA500CE4C49 /* NetworkLinux.cpp in Sources */,
                                432D7CF712D870E800CE4C49 /* TCPServer.cpp in Sources */,
-                               433219D712E4C6A500CD7486 /* FileUDF.cpp in Sources */,
                                433219D812E4C6A500CD7486 /* udf25.cpp in Sources */,
                                433219D912E4C6A500CD7486 /* UDFDirectory.cpp in Sources */,
                                7C4705AE12EF584C00369E51 /* AddonInstaller.cpp in Sources */,
                                7C84A59E12FA3C1600CD1714 /* SourcesDirectory.cpp in Sources */,
                                F57A1D1E1329B15300498CC7 /* AutoPool.mm in Sources */,
                                F5B13C8D1334056B0045076D /* DarwinUtils.mm in Sources */,
-                               7C99B6A4133D342100FC2B16 /* CacheCircular.cpp in Sources */,
+                               7C99B6A4133D342100FC2B16 /* CircularCache.cpp in Sources */,
                                7C99B7951340723F00FC2B16 /* GUIDialogPlayEject.cpp in Sources */,
                                F5AE407613415D8D0004BD79 /* HttpApi.cpp in Sources */,
                                F5AE407913415D8D0004BD79 /* XBMChttp.cpp in Sources */,
                                18ACF84313596C9B00B67371 /* RecentlyAddedJob.cpp in Sources */,
                                C807114D135DB5CC002F601B /* InputOperations.cpp in Sources */,
                                C8EC5D0E1369519D00CCC10D /* XBMC_keytable.cpp in Sources */,
-                               18404D9E1396C13500863BBA /* Slingbox.cpp in Sources */,
                                1840B74D13993D8A007C848B /* JSONVariantParser.cpp in Sources */,
                                1840B75313993DA0007C848B /* JSONVariantWriter.cpp in Sources */,
                                7C0A7EC013A5DBCE00AFC2BD /* AppParamParser.cpp in Sources */,
                                F558F27B13ABD56600631E12 /* DirtyRegionSolvers.cpp in Sources */,
                                F558F27F13ABD57400631E12 /* DirtyRegionTracker.cpp in Sources */,
                                F558F29613ABD7DF00631E12 /* GUIWindowDebugInfo.cpp in Sources */,
-                               DF0DF15B13A3ADA7008ED511 /* FileNFS.cpp in Sources */,
                                DF0DF15C13A3ADA7008ED511 /* NFSDirectory.cpp in Sources */,
                                7C89619213B6A16F003631FE /* GUIWindowScreensaverDim.cpp in Sources */,
                                1830212813B8E2DC00770920 /* controledit.cpp in Sources */,
                                DF34898213FDAAF60026A711 /* HttpParser.cpp in Sources */,
                                18968DC814155D7C005BA742 /* ApplicationOperations.cpp in Sources */,
                                DF24A6B41406C7C500C7721E /* AFPDirectory.cpp in Sources */,
-                               DF24A6B51406C7C500C7721E /* FileAFP.cpp in Sources */,
                                32C631281423A90F00F18420 /* JpegIO.cpp in Sources */,
                                DF448457140048A60069344B /* AirTunesServer.cpp in Sources */,
-                               DF44845D140048C80069344B /* FilePipe.cpp in Sources */,
                                DF44845E140048C80069344B /* PipesManager.cpp in Sources */,
                                DF4484EE140054530069344B /* BXAcodec.cpp in Sources */,
                                DF98D98C1434F47D00A6EBE1 /* SkinVariable.cpp in Sources */,
                                F5E1125E14356B2400175026 /* pyrendercapture.cpp in Sources */,
                                F5E1138014357F3800175026 /* PeripheralCecAdapter.cpp in Sources */,
                                F54BCC5F1439345300F86B0F /* HotKeyController.m in Sources */,
-                               DF85BAB51443669A000686BE /* FileUPnP.cpp in Sources */,
                                DF673AA51443819600A5A509 /* AddonManager.cpp in Sources */,
                                F5BD02F6148D3A7E001B5583 /* CryptThreading.cpp in Sources */,
+                               7CCFD98D151494E100211D82 /* PCMCodec.cpp in Sources */,
+                               DF5276E1151BAEDA00B5B63B /* Base64.cpp in Sources */,
+                               DF5276E2151BAEDA00B5B63B /* HttpResponse.cpp in Sources */,
+                               DF527734151BAF4C00B5B63B /* WebSocket.cpp in Sources */,
+                               DF527735151BAF4C00B5B63B /* WebSocketManager.cpp in Sources */,
+                               DF527736151BAF4C00B5B63B /* WebSocketV13.cpp in Sources */,
+                               DF527737151BAF4C00B5B63B /* WebSocketV8.cpp in Sources */,
+                               188F75FE152217BC009870CE /* Mime.cpp in Sources */,
+                               188F7602152217DF009870CE /* GUIOperations.cpp in Sources */,
+                               DFCA6AC6152245CD000BFAAE /* HTTPApiHandler.cpp in Sources */,
+                               DFCA6AC7152245CD000BFAAE /* HTTPJsonRpcHandler.cpp in Sources */,
+                               DFCA6AC8152245CD000BFAAE /* HTTPVfsHandler.cpp in Sources */,
+                               DFCA6AC9152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp in Sources */,
+                               DFCA6ACA152245CD000BFAAE /* HTTPWebinterfaceHandler.cpp in Sources */,
+                               DFCA6ACB152245CD000BFAAE /* IHTTPRequestHandler.cpp in Sources */,
+                               DF93D65D1444A7A3007C6459 /* SlingboxDirectory.cpp in Sources */,
+                               DF93D6991444A8B1007C6459 /* AFPFile.cpp in Sources */,
+                               DF93D69A1444A8B1007C6459 /* DirectoryCache.cpp in Sources */,
+                               DF93D69B1444A8B1007C6459 /* FileCache.cpp in Sources */,
+                               DF93D69C1444A8B1007C6459 /* CDDAFile.cpp in Sources */,
+                               DF93D69D1444A8B1007C6459 /* CurlFile.cpp in Sources */,
+                               DF93D69E1444A8B1007C6459 /* DAAPFile.cpp in Sources */,
+                               DF93D69F1444A8B1007C6459 /* DirectoryFactory.cpp in Sources */,
+                               DF93D6A01444A8B1007C6459 /* FileDirectoryFactory.cpp in Sources */,
+                               DF93D6A11444A8B1007C6459 /* FileReaderFile.cpp in Sources */,
+                               DF93D6A21444A8B1007C6459 /* HDFile.cpp in Sources */,
+                               DF93D6A31444A8B1007C6459 /* ISOFile.cpp in Sources */,
+                               DF93D6A41444A8B1007C6459 /* LastFMFile.cpp in Sources */,
+                               DF93D6A51444A8B1007C6459 /* MusicDatabaseFile.cpp in Sources */,
+                               DF93D6A61444A8B1007C6459 /* NFSFile.cpp in Sources */,
+                               DF93D6A71444A8B1007C6459 /* PipeFile.cpp in Sources */,
+                               DF93D6A81444A8B1007C6459 /* RarFile.cpp in Sources */,
+                               DF93D6A91444A8B1007C6459 /* RTVFile.cpp in Sources */,
+                               DF93D6AA1444A8B1007C6459 /* SFTPFile.cpp in Sources */,
+                               DF93D6AB1444A8B1007C6459 /* ShoutcastFile.cpp in Sources */,
+                               DF93D6AC1444A8B1007C6459 /* SlingboxFile.cpp in Sources */,
+                               DF93D6AD1444A8B1007C6459 /* SmbFile.cpp in Sources */,
+                               DF93D6AE1444A8B1007C6459 /* SpecialProtocolFile.cpp in Sources */,
+                               DF93D6AF1444A8B1007C6459 /* TuxBoxDirectory.cpp in Sources */,
+                               DF93D6B01444A8B1007C6459 /* TuxBoxFile.cpp in Sources */,
+                               DF93D6B11444A8B1007C6459 /* UDFFile.cpp in Sources */,
+                               DF93D6B21444A8B1007C6459 /* UPnPFile.cpp in Sources */,
+                               DF93D6B31444A8B1007C6459 /* ZipFile.cpp in Sources */,
+                               DF93D7F21444B54A007C6459 /* HDHomeRunFile.cpp in Sources */,
+                               DF93D7F61444B568007C6459 /* HDHomeRunDirectory.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                F5A1C93E0F6B06CF00A96ABD /* DynamicDll.cpp in Sources */,
                                F5A1C9400F6B06CF00A96ABD /* Favourites.cpp in Sources */,
                                F5A1C9410F6B06CF00A96ABD /* FileItem.cpp in Sources */,
-                               F5A1C9420F6B06CF00A96ABD /* CacheMemBuffer.cpp in Sources */,
+                               F5A1C9420F6B06CF00A96ABD /* MemBufferCache.cpp in Sources */,
                                F5A1C9430F6B06CF00A96ABD /* CacheStrategy.cpp in Sources */,
                                F5A1C9440F6B06CF00A96ABD /* CDDADirectory.cpp in Sources */,
                                F5A1C9450F6B06CF00A96ABD /* cddb.cpp in Sources */,
                                F5A1C9460F6B06CF00A96ABD /* cdioSupport.cpp in Sources */,
                                F5A1C9470F6B06CF00A96ABD /* DAAPDirectory.cpp in Sources */,
                                F5A1C9480F6B06CF00A96ABD /* Directory.cpp in Sources */,
-                               F5A1C9490F6B06CF00A96ABD /* DirectoryCache.cpp in Sources */,
                                F5A1C94A0F6B06CF00A96ABD /* DirectoryHistory.cpp in Sources */,
-                               F5A1C94B0F6B06CF00A96ABD /* DirectoryTuxBox.cpp in Sources */,
                                F5A1C94C0F6B06CF00A96ABD /* DllLibCurl.cpp in Sources */,
-                               F5A1C94D0F6B06CF00A96ABD /* FactoryDirectory.cpp in Sources */,
-                               F5A1C94E0F6B06CF00A96ABD /* FactoryFileDirectory.cpp in Sources */,
                                F5A1C94F0F6B06CF00A96ABD /* File.cpp in Sources */,
-                               F5A1C9500F6B06CF00A96ABD /* FileCache.cpp in Sources */,
-                               F5A1C9510F6B06CF00A96ABD /* FileCDDA.cpp in Sources */,
-                               F5A1C9520F6B06CF00A96ABD /* FileCurl.cpp in Sources */,
-                               F5A1C9530F6B06CF00A96ABD /* FileDAAP.cpp in Sources */,
                                F5A1C9540F6B06CF00A96ABD /* FileFactory.cpp in Sources */,
-                               F5A1C9550F6B06CF00A96ABD /* FileFileReader.cpp in Sources */,
-                               F5A1C9560F6B06CF00A96ABD /* FileHD.cpp in Sources */,
-                               F5A1C9570F6B06CF00A96ABD /* FileISO.cpp in Sources */,
-                               F5A1C9580F6B06CF00A96ABD /* FileLastFM.cpp in Sources */,
-                               F5A1C9590F6B06CF00A96ABD /* FileMusicDatabase.cpp in Sources */,
-                               F5A1C95A0F6B06CF00A96ABD /* FileRar.cpp in Sources */,
-                               F5A1C95B0F6B06CF00A96ABD /* FileRTV.cpp in Sources */,
-                               F5A1C95C0F6B06CF00A96ABD /* FileTuxBox.cpp in Sources */,
-                               F5A1C95D0F6B06CF00A96ABD /* FileZip.cpp in Sources */,
                                F5A1C95E0F6B06CF00A96ABD /* FTPDirectory.cpp in Sources */,
                                F5A1C95F0F6B06CF00A96ABD /* FTPParse.cpp in Sources */,
                                F5A1C9600F6B06CF00A96ABD /* HDDirectory.cpp in Sources */,
-                               F5A1C9610F6B06CF00A96ABD /* HDHomeRun.cpp in Sources */,
                                F5A1C9620F6B06CF00A96ABD /* IDirectory.cpp in Sources */,
                                F5A1C9630F6B06CF00A96ABD /* IFile.cpp in Sources */,
                                F5A1C9640F6B06CF00A96ABD /* iso9660.cpp in Sources */,
                                F5A1CB1A0F6B06CF00A96ABD /* DVDDemuxFFmpeg.cpp in Sources */,
                                F5A1CB1B0F6B06CF00A96ABD /* GUIDialogCache.cpp in Sources */,
                                F5A1CB1D0F6B06CF00A96ABD /* GUIDialogAccessPoints.cpp in Sources */,
-                               F5A1CB1F0F6B06CF00A96ABD /* FileShoutcast.cpp in Sources */,
                                F5A1CB220F6B06CF00A96ABD /* DVDPlayerCodec.cpp in Sources */,
                                F5A1CB230F6B06CF00A96ABD /* DVDDemuxVobsub.cpp in Sources */,
                                F5A1CB240F6B06CF00A96ABD /* DVDInputStreamTV.cpp in Sources */,
                                F5A1CB250F6B06CF00A96ABD /* PltMediaConnect.cpp in Sources */,
                                F5A1CB3C0F6B06CF00A96ABD /* MythDirectory.cpp in Sources */,
                                F5A1CB3D0F6B06CF00A96ABD /* MythFile.cpp in Sources */,
-                               F5A1CB3E0F6B06CF00A96ABD /* FileSmb.cpp in Sources */,
                                F5A1CB3F0F6B06CF00A96ABD /* SMBDirectory.cpp in Sources */,
                                F5A1CB410F6B06CF00A96ABD /* MythSession.cpp in Sources */,
                                F5A1CB420F6B06CF00A96ABD /* EventPacket.cpp in Sources */,
                                F5A1CB7F0F6B06CF00A96ABD /* AudioRendererFactory.cpp in Sources */,
                                F5A1CB800F6B06CF00A96ABD /* NullDirectSound.cpp in Sources */,
                                F5A1CB810F6B06CF00A96ABD /* ExternalPlayer.cpp in Sources */,
-                               F5A1CB820F6B06CF00A96ABD /* FileSpecialProtocol.cpp in Sources */,
                                F5A1CB830F6B06CF00A96ABD /* HTTPDirectory.cpp in Sources */,
                                F5A1CB840F6B06CF00A96ABD /* GUIDialogKaraokeSongSelector.cpp in Sources */,
                                F5A1CB850F6B06CF00A96ABD /* karaokelyricscdg.cpp in Sources */,
                                F5A7A703112893E50059D6AA /* AnnouncementManager.cpp in Sources */,
                                F5A7A85C112908F00059D6AA /* WebServer.cpp in Sources */,
                                7C7B2B311134F36400713D6D /* mysqldataset.cpp in Sources */,
-                               F5A7B377113AFB5F0059D6AA /* FileSFTP.cpp in Sources */,
                                F5A7B37F113AFB900059D6AA /* SFTPDirectory.cpp in Sources */,
                                F5A7B42D113CBB950059D6AA /* AddonsDirectory.cpp in Sources */,
                                18B4A0081152BFA5001AF8A6 /* Addon.cpp in Sources */,
                                18B7CA2C12944A8E009E7A26 /* tinyxmlparser.cpp in Sources */,
                                432D7CE512D86DA500CE4C49 /* NetworkLinux.cpp in Sources */,
                                432D7CF812D870E800CE4C49 /* TCPServer.cpp in Sources */,
-                               433219DA12E4C6A500CD7486 /* FileUDF.cpp in Sources */,
                                433219DB12E4C6A500CD7486 /* udf25.cpp in Sources */,
                                433219DC12E4C6A500CD7486 /* UDFDirectory.cpp in Sources */,
                                7C4705AF12EF584C00369E51 /* AddonInstaller.cpp in Sources */,
                                7C84A59F12FA3C1600CD1714 /* SourcesDirectory.cpp in Sources */,
                                F57A1D1F1329B15300498CC7 /* AutoPool.mm in Sources */,
                                F5B13C8E1334056B0045076D /* DarwinUtils.mm in Sources */,
-                               7C99B6A5133D342100FC2B16 /* CacheCircular.cpp in Sources */,
+                               7C99B6A5133D342100FC2B16 /* CircularCache.cpp in Sources */,
                                7C99B7961340723F00FC2B16 /* GUIDialogPlayEject.cpp in Sources */,
                                F5AE407A13415D8D0004BD79 /* HttpApi.cpp in Sources */,
                                F5AE407D13415D8D0004BD79 /* XBMChttp.cpp in Sources */,
                                43EA4297136C1D9E002C82A5 /* RenderCapture.cpp in Sources */,
                                43EA429B136C1E2F002C82A5 /* xbmcvfsmodule.cpp in Sources */,
                                43EA42B0136C2274002C82A5 /* InputOperations.cpp in Sources */,
-                               18404E701396E05D00863BBA /* Slingbox.cpp in Sources */,
                                1840B74E13993D8A007C848B /* JSONVariantParser.cpp in Sources */,
                                1840B75413993DA0007C848B /* JSONVariantWriter.cpp in Sources */,
                                7C0A7EC113A5DBCE00AFC2BD /* AppParamParser.cpp in Sources */,
                                F558F27C13ABD56600631E12 /* DirtyRegionSolvers.cpp in Sources */,
                                F558F28013ABD57400631E12 /* DirtyRegionTracker.cpp in Sources */,
                                F558F29713ABD7DF00631E12 /* GUIWindowDebugInfo.cpp in Sources */,
-                               F558F3D013AE663300631E12 /* FileNFS.cpp in Sources */,
                                F558F3D113AE663A00631E12 /* NFSDirectory.cpp in Sources */,
                                7C89619313B6A16F003631FE /* GUIWindowScreensaverDim.cpp in Sources */,
                                1830212913B8E2DC00770920 /* controledit.cpp in Sources */,
                                DF34898313FDAAF60026A711 /* HttpParser.cpp in Sources */,
                                18968DC914155D7C005BA742 /* ApplicationOperations.cpp in Sources */,
                                DF24A6B61406C7C500C7721E /* AFPDirectory.cpp in Sources */,
-                               DF24A6B71406C7C500C7721E /* FileAFP.cpp in Sources */,
                                F5E10D381428426B00175026 /* JpegIO.cpp in Sources */,
                                DF448458140048A60069344B /* AirTunesServer.cpp in Sources */,
-                               DF44845F140048C80069344B /* FilePipe.cpp in Sources */,
                                DF448460140048C80069344B /* PipesManager.cpp in Sources */,
                                DF4484EF140054530069344B /* BXAcodec.cpp in Sources */,
                                DF98D98D1434F47D00A6EBE1 /* SkinVariable.cpp in Sources */,
                                F5E1125F14356B2400175026 /* pyrendercapture.cpp in Sources */,
                                F5E1138114357F3900175026 /* PeripheralCecAdapter.cpp in Sources */,
                                F54BCC601439345300F86B0F /* HotKeyController.m in Sources */,
-                               DF85BAB61443669A000686BE /* FileUPnP.cpp in Sources */,
                                F5BD02F7148D3A7E001B5583 /* CryptThreading.cpp in Sources */,
+                               7CCFD98C151494E100211D82 /* PCMCodec.cpp in Sources */,
+                               DF527726151BAEDA00B5B63B /* Base64.cpp in Sources */,
+                               DF527727151BAEDA00B5B63B /* HttpResponse.cpp in Sources */,
+                               DF527739151BAF4C00B5B63B /* WebSocket.cpp in Sources */,
+                               DF52773A151BAF4C00B5B63B /* WebSocketManager.cpp in Sources */,
+                               DF52773B151BAF4C00B5B63B /* WebSocketV13.cpp in Sources */,
+                               DF52773C151BAF4C00B5B63B /* WebSocketV8.cpp in Sources */,
+                               188F75FF152217BC009870CE /* Mime.cpp in Sources */,
+                               188F7603152217DF009870CE /* GUIOperations.cpp in Sources */,
+                               DFCA6ACD152245CD000BFAAE /* HTTPApiHandler.cpp in Sources */,
+                               DFCA6ACE152245CD000BFAAE /* HTTPJsonRpcHandler.cpp in Sources */,
+                               DFCA6ACF152245CD000BFAAE /* HTTPVfsHandler.cpp in Sources */,
+                               DFCA6AD0152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp in Sources */,
+                               DFCA6AD1152245CD000BFAAE /* HTTPWebinterfaceHandler.cpp in Sources */,
+                               DFCA6AD2152245CD000BFAAE /* IHTTPRequestHandler.cpp in Sources */,
+                               DF93D65E1444A7A3007C6459 /* SlingboxDirectory.cpp in Sources */,
+                               DF93D6B41444A8B1007C6459 /* AFPFile.cpp in Sources */,
+                               DF93D6B51444A8B1007C6459 /* DirectoryCache.cpp in Sources */,
+                               DF93D6B61444A8B1007C6459 /* FileCache.cpp in Sources */,
+                               DF93D6B71444A8B1007C6459 /* CDDAFile.cpp in Sources */,
+                               DF93D6B81444A8B1007C6459 /* CurlFile.cpp in Sources */,
+                               DF93D6B91444A8B1007C6459 /* DAAPFile.cpp in Sources */,
+                               DF93D6BA1444A8B1007C6459 /* DirectoryFactory.cpp in Sources */,
+                               DF93D6BB1444A8B1007C6459 /* FileDirectoryFactory.cpp in Sources */,
+                               DF93D6BC1444A8B1007C6459 /* FileReaderFile.cpp in Sources */,
+                               DF93D6BD1444A8B1007C6459 /* HDFile.cpp in Sources */,
+                               DF93D6BE1444A8B1007C6459 /* ISOFile.cpp in Sources */,
+                               DF93D6BF1444A8B1007C6459 /* LastFMFile.cpp in Sources */,
+                               DF93D6C01444A8B1007C6459 /* MusicDatabaseFile.cpp in Sources */,
+                               DF93D6C11444A8B1007C6459 /* NFSFile.cpp in Sources */,
+                               DF93D6C21444A8B1007C6459 /* PipeFile.cpp in Sources */,
+                               DF93D6C31444A8B1007C6459 /* RarFile.cpp in Sources */,
+                               DF93D6C41444A8B1007C6459 /* RTVFile.cpp in Sources */,
+                               DF93D6C51444A8B1007C6459 /* SFTPFile.cpp in Sources */,
+                               DF93D6C61444A8B1007C6459 /* ShoutcastFile.cpp in Sources */,
+                               DF93D6C71444A8B1007C6459 /* SlingboxFile.cpp in Sources */,
+                               DF93D6C81444A8B1007C6459 /* SmbFile.cpp in Sources */,
+                               DF93D6C91444A8B1007C6459 /* SpecialProtocolFile.cpp in Sources */,
+                               DF93D6CA1444A8B1007C6459 /* TuxBoxDirectory.cpp in Sources */,
+                               DF93D6CB1444A8B1007C6459 /* TuxBoxFile.cpp in Sources */,
+                               DF93D6CC1444A8B1007C6459 /* UDFFile.cpp in Sources */,
+                               DF93D6CD1444A8B1007C6459 /* UPnPFile.cpp in Sources */,
+                               DF93D6CE1444A8B1007C6459 /* ZipFile.cpp in Sources */,
+                               DF93D7F31444B54A007C6459 /* HDHomeRunFile.cpp in Sources */,
+                               DF93D7F71444B568007C6459 /* HDHomeRunDirectory.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 252d868..be0684d 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="metadata.common.themoviedb.org"
        name="The MovieDB common scraper functions"
-       version="2.1.2"
+       version="2.1.4"
        provider-name="Team XBMC">
   <requires>
     <import addon="xbmc.metadata" version="1.0"/>
@@ -17,7 +17,7 @@
     <summary lang="fi">TMDb elokuvatietojen lataajan kirjasto</summary>
     <summary lang="fr">Scraper TMDb</summary>
     <summary lang="hu">TMDb leolvasó-könyvtár</summary>
-    <summary lang="nl">TMDb-scraperfuncties</summary>                  <!--Dit gaat over de functies, niet over de mediabibliotheek!-->
+    <summary lang="nl">TMDb-scraperfuncties</summary>
     <summary lang="pl">Scraper biblioteki TMDb</summary>
     <summary lang="pt">Scraper de filmes TMDb</summary>
     <summary lang="ro">Bibliotecă catalog TMDb</summary>
index 8390acf..a270f4c 100644 (file)
@@ -31,7 +31,7 @@
        <ParseTMDBPlot dest="5">
                <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
                        <RegExp input="$$1" output="\1" dest="9">
-                               <expression clear="yes" fixchars="1">&quot;overview&quot;:&quot;(.*?)&quot;,</expression>
+                               <expression clear="yes" fixchars="1">&quot;overview&quot;:&quot;(.*?)&quot;,&quot;</expression>
                        </RegExp>
                        <RegExp input="$$9" output="&lt;url function=&quot;ParseFallbackTMDBPlot&quot; cache=&quot;tmdb-en-$$8.json&quot;&gt;http://api.themoviedb.org/3/movie/$$8?api_key=57983e31fb435df4df77afb854740ea9&amp;language=en&lt;/url&gt;" dest="2">
                                <expression>^$</expression>
@@ -45,7 +45,7 @@
        <ParseFallbackTMDBPlot dest="5">
                <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
                        <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="2">
-                               <expression clear="yes" fixchars="1">&quot;overview&quot;:&quot;(.*?)&quot;,</expression>
+                               <expression clear="yes" fixchars="1">&quot;overview&quot;:&quot;(.*?)&quot;,&quot;</expression>
                        </RegExp>
                        <expression noclean="1" />
                </RegExp>
        <GetTMDBTrailerByIdChain dest="4">
                <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
                        <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBTrailer&quot; cache=&quot;tmdb-trailer-$INFO[language]-\1.json&quot;&gt;http://api.themoviedb.org/3/movie/\1/trailers?api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5">
-                               <expression>^([0-9]+)$</expression>
+                               <expression />
                        </RegExp>
                        <expression noclean="1" />
                </RegExp>
index 247c657..e7151af 100644 (file)
@@ -1,5 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <strings>
     <string id="30000">启用同人画</string>
-    <string id="30001">启用HD-Trailers.net预告片</string>
+    <string id="30001">首选HD-Trailers.net预告片</string>
+    <string id="30002">首选语言</string>
+    <string id="30003">获取评价信息于</string>
+    <string id="30004">启用预告片(YouTube)</string>
+    <string id="30005">保留原片名</string>
 </strings>
index 78c7685..7711a7f 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <strings>
     <string id="30000">Fanart inschakelen</string>
-    <string id="30001">Trailer inschakelen (HD-Trailers.net)</string>
+    <string id="30001">Trailers van HD-Trailers.net inschakelen</string>
     <string id="30002">Voorkeurstaal</string>
     <string id="30003">Verkrijg waardering van IMDb</string>
     <string id="30004">Trailer inschakelen (YouTube)</string>
index 7efd3a3..d61eda0 100644 (file)
@@ -2,8 +2,8 @@
 <strings>
     <string id="30000">Enable Fanart</string>
     <string id="30004">Enable Trailer (YouTube)</string>
-    <string id="30001">Enable Trailer (HD-Trailers.net)</string>
+    <string id="30001">Prefer Trailer from HD-Trailers.net</string>
     <string id="30002">Preferred language</string>
-    <string id="30003">Get rating from IMDb</string>
+    <string id="30003">Get rating from</string>
     <string id="30005">Keep Original Title</string>
 </strings>
index 2e71222..ab425a5 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <strings>
     <string id="30000">Fanitaide käytössä</string>
-    <string id="30004">Trailerit käytössä (YouTube)</string>
-    <string id="30001">Trailerit käytössä (HD-Trailers.net)</string>
+    <string id="30004">Trailerit käytössä</string>
+    <string id="30001">Valitse ensisijaisesti trailerit HD-Trailers.net -sivustolta</string>
     <string id="30002">Ensisijainen kieli</string>
     <string id="30003">Hae arvosana IMDb:stä</string>
     <string id="30005">Näytä alkuperäinen nimi</string>
index c09cbb4..a3ae511 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <strings>
     <string id="30000">Aktiviere Fanart</string>
-    <string id="30001">Aktiviere Trailer (HD-Trailers.net)</string>
+    <string id="30001">Aktiviere Trailer von HD-Trailers.net</string>
     <string id="30002">Bevorzugte Sprache</string>
     <string id="30003">Bewertung von IMDb nutzen</string>
     <string id="30004">Aktiviere Trailer (YouTube)</string>
index aac4afc..d5e3f07 100644 (file)
@@ -2,8 +2,8 @@
 <strings>
     <string id="30000">Fanartképek engedélyezése</string>
     <string id="30004">Filmelőzetesek engedélyezése (YouTube)</string>
-    <string id="30001">Filmelőzetesek engedélyezése (HD-Trailers.net)</string>
+    <string id="30001">Filmelőzetesek inkább a HD-Trailers.net-ről</string>
     <string id="30002">Preferált nyelv</string>
-    <string id="30003">Értékelés az IMDb-ről</string>
+    <string id="30003">Értékelés letöltése innen</string>
     <string id="30005">Eredeti filmcím megtartása</string>
 </strings>
index 4beab0f..59406fd 100644 (file)
@@ -6,7 +6,7 @@
 <!--$Revision$-->
 <strings>
   <string id="30000">Aktivera fanart</string>
-  <string id="30001">Aktivera trailers (HD-Trailers.net)</string>
+  <string id="30001">Aktivera trailers från HD-Trailers.net</string>
   <string id="30002">Föredraget språk</string>
   <string id="30003">Hämta betyg från IMDb</string>
   <string id="30004">Aktivera trailers (YouTube)</string>
index 1b66350..cf047d3 100644 (file)
@@ -1,13 +1,16 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="repository.xbmc.org"
                name="XBMC.org Add-ons"
-               version="2.0.1"
+               version="2.0.3"
                provider-name="Team XBMC">
+  <requires>
+    <import addon="xbmc.addon" version="11.0"/>
+  </requires>
        <extension point="xbmc.addon.repository"
                name="Official XBMC.org Add-on Repository">
-               <info compressed="true">http://mirrors.xbmc.org/addons/eden-pre/addons.xml</info>
-               <checksum>http://mirrors.xbmc.org/addons/eden-pre/addons.xml.md5</checksum>
-               <datadir zip="true">http://mirrors.xbmc.org/addons/eden-pre</datadir>
+               <info compressed="true">http://mirrors.xbmc.org/addons/eden/addons.xml</info>
+               <checksum>http://mirrors.xbmc.org/addons/eden/addons.xml.md5</checksum>
+               <datadir zip="true">http://mirrors.xbmc.org/addons/eden</datadir>
                <hashes>true</hashes>
        </extension>
        <extension point="xbmc.addon.metadata">
index c1cae0f..ccf175e 100644 (file)
@@ -22,6 +22,7 @@
     <summary lang="nl">Een meer psychedelische schermbeveiliging vindt u niet</summary>
     <summary lang="pl">Tak psychodeliczny jak tylko się da</summary>
     <summary lang="pt">A mais psicadélica protecção de ecrã.</summary>
+    <summary lang="ro">Un protector ecran cât se poate de psihedelic</summary>
     <summary lang="ru">Настолько психаделично, насколько такой может быть заставка</summary>
     <summary lang="se">Ungefär så psykedelisk som en skärmsläckare kan bli</summary>
     <summary lang="zh">最具迷幻效果的屏幕保护程序</summary>
@@ -35,6 +36,7 @@
     <description lang="nl">Ongetwijfeld de meest psychedelische screensaver. mogumbo dacht dat zijn Plasmascreensaver al bovenaan deze lijst stond, maar deze is nóg meer misselijkmakend. Houd uw braakzakje bij de hand, mocht u hier te lang naar staren.</description>
     <description lang="pl">Tak psychodeliczny wygaszacz jak tylko się da. Lepiej zaopatrz się w worki na chorobę lokomocyjną.</description>
     <description lang="pt">Esta é provavelmente a protecção de ecrã mais psicadélica de sempre. O mogumbo (autor) pensou que a sua protecção de ecrã 'Plasma' estava no topo da escala de protecções nauseantes mas esta parece ainda pior. Procure um saco de enjoo e sente-se, se vai ficar muito tempo a olhar para o ecrã.</description>
+    <description lang="ro">Acesta este un protector ecran cât se poate de psihedelic. mogumbo s-a gândit că protectorul Plasma era pe primul loc, dar acesta este și mai amețitor. Ar trebui să căutați o pungă de gunoi înainte de a vă uita la acesta prea mult.</description>
     <description lang="ru">Это настолько психаделично, насколько такой может быть заставка. mogumbo думал, что его хранитель экрана Plasma был недосягаем, но этот ещё более тошнотворный. Лучше найдите себе гигиенический пакет, перед тем как вы будете слишком долго смотреть на этот хранитель экрана.</description>
     <description lang="se">Det här är ungefär så psykedelisk skärmsläckare kan bli. mogumbo trodde hans plasma-skärmsläckare var toppen på skalan, men denna är till och med ännu mer kväljande. Du gör bäst i att leta upp en åksjukepåse innan du stirrar på denna för länge.</description>
     <description lang="zh">这大概是最具迷幻效果的屏幕保护程序了。mogumbo以为他的Plasma屏保已经是数一数二了,但这个更令人作犯晕。如果你要长时间盯视它最好先准备一个晕机袋。</description>
index 815522a..d4070f0 100644 (file)
@@ -22,6 +22,7 @@
     <summary lang="nl">Waarschijnlijk de op één na meest psychedelische schermbeveiliging ooit</summary>
     <summary lang="pl">Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie</summary>
     <summary lang="pt">Provavelmente a segunda mais psicadélica protecção de ecrã</summary>
+    <summary lang="ro">Probabil al doilea cel mai psihedelic protector ecran dintotdeauna</summary>
     <summary lang="se">Förmodligen den näst psykedeliska skärmsläckaren</summary>
     <summary lang="zh">也许是排名第二的迷幻效果屏幕保护程序</summary>
     <description lang="bg">Вероятно вторият по сила халюциногенен скрийнсейвър създаван някога. Просто се опитайте да съзрете всички тези цветове.</description>
@@ -34,6 +35,7 @@
     <description lang="nl">Waarschlijnlijk de op één na meest psychedelische schermbeveliging ooit. Probeer u het voor te stellen: al die kleuren die door mekaar lopen.</description>
     <description lang="pl">Prawdopodobnie drugi, najbardziej psychodeliczny wygaszacz na świecie. Spróbuj i zobacz ferię poruszających się barw.</description>
     <description lang="pt">Provavelmente a segunda mais psicadélica protecção de ecrã de sempre. Experimente-a para ver todas as cores moverem-se livremente.</description>
+    <description lang="ro">Probabil al doilea cel mai psihedelic protector ecran în existență. Doar încercați să vă imaginați toate acele culori mișcându-se.</description>
     <description lang="se">Förmodligen den näst psykedeliska skärmsläckaren som finns. Försök bara att uppfatta alla färger som rör sig runt och runt.</description>
     <description lang="zh">也许是排名第二的迷幻效果屏幕保护程序。你将看到所有颜色满处乱飞。</description>
     <platform>linux osx</platform>
index 88b6ab5..8119f4e 100644 (file)
@@ -22,6 +22,7 @@
     <summary lang="nl">Een hypnotiserende schermbeveiliging met partikeleffecten</summary>
     <summary lang="pl">Wygaszacz hipnotyzujący efektami cząsteczek</summary>
     <summary lang="pt">Protecção de ecrã com um efeito de partículas</summary>
+    <summary lang="ro">Un protector ecran cu efecte de particule fascinant</summary>
     <summary lang="ru">Завораживающий скринсейвер с эффектами частиц</summary>
     <summary lang="se">En fascinerande skärmsläckare av partikeleffekter</summary>
     <summary lang="zh">一个迷人的粒子效果屏幕保护程序</summary>
@@ -35,6 +36,7 @@
     <description lang="nl">Dit is een erg hypnotiserende screensaver. Je kunt ongelooflijk veel verschillende patronen bekomen.</description>
     <description lang="pl">Bardzo hipnotyzujący wygaszacz. Przekonaj się, ile niespotykanch wzorów da się osiągnąć.</description>
     <description lang="pt">Protecção de ecrã fantástica com um efeito de partículas. Vai reparar que consegue um número quase infinito de padrões.</description>
+    <description lang="ro">Acesta este un protector ecran cu efecte de particule foarte fascinant. O să vedeți că veți putea obține un număr uimitor de modele diferite.</description>
     <description lang="ru">Это - очень завораживающий хранитель экрана. Доступно огромное количество вариаций эффектов.</description>
     <description lang="se">Detta är en mycket fascinerande partikeleffektsskärmsläckare. Du kommer att upptäcka att du kan uppnå ett otroligt antal olika mönster.</description>
     <description lang="zh">这是一个非常迷人的粒子效果屏幕保护程序。你会发现你能看到惊人数量的不同图案。</description>
diff --git a/addons/screensaver.xbmc.builtin.dim/resources/language/Romanian/strings.xml b/addons/screensaver.xbmc.builtin.dim/resources/language/Romanian/strings.xml
new file mode 100644 (file)
index 0000000..10d414c
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<strings>
+    <string id="30000">Nivel întunecare</string>
+</strings>
diff --git a/addons/screensaver.xbmc.builtin.slideshow/resources/language/Romanian/strings.xml b/addons/screensaver.xbmc.builtin.slideshow/resources/language/Romanian/strings.xml
new file mode 100644 (file)
index 0000000..a67b685
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<strings>
+    <string id="30000">Sursă imagini</string>
+    <string id="30001">Dosar</string>
+    <string id="30002">Fundale (Fanart) video</string>
+    <string id="30003">Fundale (Fanart) muzică</string>
+    <string id="30004">Dosar imagini</string>
+    <string id="30005">Nivel întunecare</string>
+</strings>
index 4f11b25..ee9f44e 100644 (file)
                        </control>
                        <control type="image">
                                <description>Weather image</description>
-                               <posx>30</posx>
-                               <posy>1</posy>
-                               <width>25</width>
-                               <height>25</height>
+                               <posx>25</posx>
+                               <posy>0</posy>
+                               <width>30</width>
+                               <height>30</height>
                                <aspectratio>keep</aspectratio>
                                <texture>$INFO[Window(Weather).Property(Current.ConditionIcon)]</texture>
                        </control>
index a7e7e18..a5151b0 100644 (file)
@@ -1,23 +1,22 @@
 <includes>
-  <variable name="typehackflagging">
-    <value condition="[substring(ListItem.FilenameAndPath,bluray) | substring(ListItem.FilenameAndPath,bdrip)]">bluray</value>
-    <value condition="substring(ListItem.FilenameAndPath,hddvd)">hddvd</value>
-    <value condition="substring(ListItem.FilenameAndPath,dvd)">dvd</value>
-    <value condition="[substring(ListItem.FilenameAndPath,pdtv) | substring(ListItem.FilenameAndPath,hdtv) | substring(ListItem.FilenameAndPath,dsr)]">TV</value>
-    <value condition="substring(ListItem.FilenameAndPath,vhs)">vhs</value>
-  </variable>
-  <variable name="rating">
-    <value condition="substring(listitem.mpaa,Rated G)">mpaa_general</value>
-    <value condition="substring(listitem.mpaa,Rated PG) + !substring(listitem.mpaa,Rated PG-13)">mpaa_pg</value>
-    <value condition="substring(listitem.mpaa,Rated PG-13)">mpaa_pg13</value>
-    <value condition="substring(Listitem.mpaa,Rated R)">mpaa_restricted</value>
-    <value condition="substring(Listitem.mpaa,Rated NC)">mpaa_nc17</value>
-  </variable>
-  <variable name="videocodec">
-    <value condition="[substring(ListItem.VideoCodec,div,left) | stringcompare(ListItem.VideoCodec,dx50)]">divx</value>
-    <value>$INFO[ListItem.VideoCodec]</value>
-  </variable>
-
+       <variable name="typehackflagging">
+               <value condition="[substring(ListItem.FilenameAndPath,bluray) | substring(ListItem.FilenameAndPath,bdrip) | substring(ListItem.FilenameAndPath,bd25) | substring(ListItem.FilenameAndPath,bd50)]">bluray</value>
+               <value condition="substring(ListItem.FilenameAndPath,hddvd)">hddvd</value>
+               <value condition="substring(ListItem.FilenameAndPath,dvd)">dvd</value>
+               <value condition="[substring(ListItem.FilenameAndPath,pdtv) | substring(ListItem.FilenameAndPath,hdtv) | substring(ListItem.FilenameAndPath,dsr)]">TV</value>
+               <value condition="substring(ListItem.FilenameAndPath,vhs)">vhs</value>
+       </variable>
+       <variable name="rating">
+               <value condition="substring(listitem.mpaa,Rated G)">mpaa_general</value>
+               <value condition="substring(listitem.mpaa,Rated PG) + !substring(listitem.mpaa,Rated PG-13)">mpaa_pg</value>
+               <value condition="substring(listitem.mpaa,Rated PG-13)">mpaa_pg13</value>
+               <value condition="substring(Listitem.mpaa,Rated R)">mpaa_restricted</value>
+               <value condition="substring(Listitem.mpaa,Rated NC)">mpaa_nc17</value>
+       </variable>
+               <variable name="videocodec">
+               <value condition="[substring(ListItem.VideoCodec,div,left) | stringcompare(ListItem.VideoCodec,dx50)]">divx</value>
+               <value>$INFO[ListItem.VideoCodec]</value>
+       </variable>
        <include name="VideoCodecFlaggingConditions">
                <control type="image">
                        <description>Video rez Image</description>
index 1012367..d9e4c29 100644 (file)
                </control>
                <control type="button" id="90163">
                        <include>ButtonHomeSubCommonValues</include>
+                       <label>20434</label>
+                       <onclick>ActivateWindow(Videos,MovieSets,return)</onclick>
+                       <visible>Library.HasContent(Sets)</visible>
+               </control>
+               <control type="button" id="90164">
+                       <include>ButtonHomeSubCommonValues</include>
                        <label>369</label>
                        <onclick>ActivateWindow(Videos,MovieTitles,return)</onclick>
                </control>
-               <control type="button" id="90164">
+               <control type="button" id="90165">
                        <include>ButtonHomeSubCommonValues</include>
                        <label>135</label>
                        <onclick>ActivateWindow(Videos,MovieGenres,return)</onclick>
                </control>
-               <control type="button" id="90165">
+               <control type="button" id="90166">
                        <include>ButtonHomeSubCommonValues</include>
                        <label>652</label>
                        <onclick>ActivateWindow(Videos,MovieYears,return)</onclick>
                </control>
-               <control type="button" id="90166">
+               <control type="button" id="90167">
                        <include>ButtonHomeSubCommonValues</include>
                        <label>344</label>
                        <onclick>ActivateWindow(Videos,MovieActors,return)</onclick>
                </control>
-               <control type="image" id="90167">
+               <control type="image" id="90168">
                        <width>35</width>
                        <height>35</height>
                        <texture border="0,0,0,3">HomeSubEnd.png</texture>
index 5378079..f9b51c8 100644 (file)
                        <item id="1">
                                <label>$INFO[Window.Property(LatestMovie.1.Title)]</label>
                                <label2></label2>
-                               <onclick>PlayMedia($INFO[Window.Property(LatestMovie.1.Path)])</onclick>
+                               <onclick>PlayMedia($ESCINFO[Window.Property(LatestMovie.1.Path)])</onclick>
                                <icon>$INFO[Window.Property(LatestMovie.1.Thumb)]</icon>
                                <thumb>-</thumb>
                        </item>
                        <item id="2">
                                <label>$INFO[Window.Property(LatestMovie.2.Title)]</label>
                                <label2></label2>
-                               <onclick>PlayMedia($INFO[Window.Property(LatestMovie.2.Path)])</onclick>
+                               <onclick>PlayMedia($ESCINFO[Window.Property(LatestMovie.2.Path)])</onclick>
                                <icon>$INFO[Window.Property(LatestMovie.2.Thumb)]</icon>
                                <thumb>-</thumb>
                        </item>
                        <item id="3">
                                <label>$INFO[Window.Property(LatestMovie.3.Title)]</label>
                                <label2></label2>
-                               <onclick>PlayMedia($INFO[Window.Property(LatestMovie.3.Path)])</onclick>
+                               <onclick>PlayMedia($ESCINFO[Window.Property(LatestMovie.3.Path)])</onclick>
                                <icon>$INFO[Window.Property(LatestMovie.3.Thumb)]</icon>
                                <thumb>-</thumb>
                        </item>
                        <item id="4">
                                <label>$INFO[Window.Property(LatestMovie.4.Title)]</label>
                                <label2></label2>
-                               <onclick>PlayMedia($INFO[Window.Property(LatestMovie.4.Path)])</onclick>
+                               <onclick>PlayMedia($ESCINFO[Window.Property(LatestMovie.4.Path)])</onclick>
                                <icon>$INFO[Window.Property(LatestMovie.4.Thumb)]</icon>
                                <thumb>-</thumb>
                        </item>
                        <item id="5">
                                <label>$INFO[Window.Property(LatestMovie.5.Title)]</label>
                                <label2></label2>
-                               <onclick>PlayMedia($INFO[Window.Property(LatestMovie.5.Path)])</onclick>
+                               <onclick>PlayMedia($ESCINFO[Window.Property(LatestMovie.5.Path)])</onclick>
                                <icon>$INFO[Window.Property(LatestMovie.5.Thumb)]</icon>
                                <thumb>-</thumb>
                        </item>
                        <item id="4">
                                <label>$INFO[Window.Property(LatestEpisode.4.EpisodeTitle)]</label>
                                <label2>$INFO[Window.Property(LatestEpisode.4.ShowTitle)] - $INFO[Window.Property(LatestEpisode.4.EpisodeNo)]</label2>
-                               <onclick>PlayMedia($INFO[Window.Property(LatestEpisode.4.Path)])</onclick>
+                               <onclick>PlayMedia($ESCINFO[Window.Property(LatestEpisode.4.Path)])</onclick>
                                <icon>-</icon>
                                <thumb>$INFO[Window.Property(LatestEpisode.4.Thumb)]</thumb>
                        </item>
                        <item id="3">
                                <label>$INFO[Window.Property(LatestEpisode.3.EpisodeTitle)]</label>
                                <label2>$INFO[Window.Property(LatestEpisode.3.ShowTitle)] - $INFO[Window.Property(LatestEpisode.3.EpisodeNo)]</label2>
-                               <onclick>PlayMedia($INFO[Window.Property(LatestEpisode.3.Path)])</onclick>
+                               <onclick>PlayMedia($ESCINFO[Window.Property(LatestEpisode.3.Path)])</onclick>
                                <icon>-</icon>
                                <thumb>$INFO[Window.Property(LatestEpisode.3.Thumb)]</thumb>
                        </item>
                        <item id="2">
                                <label>$INFO[Window.Property(LatestEpisode.2.EpisodeTitle)]</label>
                                <label2>$INFO[Window.Property(LatestEpisode.2.ShowTitle)] - $INFO[Window.Property(LatestEpisode.2.EpisodeNo)]</label2>
-                               <onclick>PlayMedia($INFO[Window.Property(LatestEpisode.2.Path)])</onclick>
+                               <onclick>PlayMedia($ESCINFO[Window.Property(LatestEpisode.2.Path)])</onclick>
                                <icon>-</icon>
                                <thumb>$INFO[Window.Property(LatestEpisode.2.Thumb)]</thumb>
                        </item>
                        <item id="1">
                                <label>$INFO[Window.Property(LatestEpisode.1.EpisodeTitle)]</label>
                                <label2>$INFO[Window.Property(LatestEpisode.1.ShowTitle)] - $INFO[Window.Property(LatestEpisode.1.EpisodeNo)]</label2>
-                               <onclick>PlayMedia($INFO[Window.Property(LatestEpisode.1.Path)])</onclick>
+                               <onclick>PlayMedia($ESCINFO[Window.Property(LatestEpisode.1.Path)])</onclick>
                                <icon>-</icon>
                                <thumb>$INFO[Window.Property(LatestEpisode.1.Thumb)]</thumb>
                        </item>
index e55cf06..6c716ce 100644 (file)
                                                <icon>special://skin/backgrounds/addons.jpg</icon>
                                        </item>
                                        <item id="7">
-                                               <label>705</label>
-                                               <label2>31405</label2>
-                                               <onclick>ActivateWindow(NetworkSettings)</onclick>
-                                               <icon>special://skin/backgrounds/network.jpg</icon>
+                                               <label>14036</label>
+                                               <label2>31409</label2>
+                                               <onclick>ActivateWindow(ServiceSettings)</onclick>
+                                               <icon>special://skin/backgrounds/services.jpg</icon>
                                        </item>
                                        <item id="8">
                                                <label>13000</label>
index bdb3882..e5d699d 100644 (file)
                                                                <icon>special://skin/backgrounds/Addons.jpg</icon>
                                                                <thumb>$INFO[Skin.String(Home_Custom_Back_Addons_Folder)]</thumb>
                                                        </item>
+                                                       <item id="9">
+                                                               <label>341</label>
+                                                               <label2>Home_Custom_Back_PlayDisc_Folder</label2>
+                                                               <onclick>-</onclick>
+                                                               <icon>special://skin/backgrounds/playdisc.jpg</icon>
+                                                               <thumb>$INFO[Skin.String(Home_Custom_Back_PlayDisc_Folder)]</thumb>
+                                                       </item>                                                 
                                                </content>
                                        </control>
                                        <control type="image">
diff --git a/addons/skin.confluence/backgrounds/network.jpg b/addons/skin.confluence/backgrounds/network.jpg
deleted file mode 100644 (file)
index 32d59f7..0000000
Binary files a/addons/skin.confluence/backgrounds/network.jpg and /dev/null differ
diff --git a/addons/skin.confluence/backgrounds/services.jpg b/addons/skin.confluence/backgrounds/services.jpg
new file mode 100644 (file)
index 0000000..32d59f7
Binary files /dev/null and b/addons/skin.confluence/backgrounds/services.jpg differ
index a0a341a..2d5551d 100644 (file)
@@ -1,7 +1,8 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <!--Translator: ezechiel1917-->
-<!--Date of translation: 26/09/2010-->
-<!--updated 22/10/2011 by mirek-->
+<!--Date of translation: 26.09.2010-->
+<!--Updated 22.11.2011 by mirek-->
+<!--Updated 06.01.2012 by babča-->
 <strings>
   <!-- Misc labels -->
   <string id="31000">Změnit</string>
@@ -22,7 +23,7 @@
   <string id="31025">Položek</string>
   <string id="31026">Další možnosti</string>
   <string id="31027">Umístění</string>
+
   <!-- View Type labels -->
   <string id="31028">Obaly</string>
   <string id="31029">Fanart</string>
@@ -39,7 +40,7 @@
   <string id="31044">PŘETÁČÍ SE VPŘED</string>
   <string id="31045">PŘETÁČÍ SE ZPĚT</string>
   <string id="31046">Vlastnosti zvuku</string>
-  <string id="31047">Akutální předvolba</string>
+  <string id="31047">Aktuální předvolba</string>
   <string id="31048">Předvolby vizualizace</string>
   <string id="31049">Čas ukončení</string>
   <string id="31050">Seřadit: vzestupně</string>
@@ -54,7 +55,7 @@
   <string id="31059">Aktuální seznam stop</string>
   <string id="31060">Tento soubor se skládá z více částí. Vyberte tu, od které chcete spustit přehrávání.</string>
   <string id="31061">Aktuálně vybraný</string>
-  
+
   <!-- Skin Settings labels -->
   <string id="31100"></string>
   <string id="31101">Informace na Úvodní obrazovce</string>
@@ -88,7 +89,7 @@
   <string id="31128">Texty skladeb</string>
   <string id="31129"></string>
   <string id="31130"></string>
-  
+
   <string id="31131"></string>
   <string id="31132">Doplněk Texty skladeb</string>
   <string id="31133">Doplněk Titulky</string>
   <string id="31318">Malý Fanart</string>
   <string id="31319">Vybraný profil</string>
   <string id="31320">Naposledy přihlášen</string>
-  <string id="31321">Vyběr Karaoke skladby</string>
+  <string id="31321">Výběr karaoke skladby</string>
   <string id="31322">Odvysíláno</string>
   <string id="31323">Nejnovější filmy</string>
   <string id="31324">Nejnovější epizody</string>
   <string id="31403">[B]MOŽNOSTI OBRÁZKŮ[/B][CR][CR]Možnosti zobrazení obrázků · Konfigurace prezentace</string>
   <string id="31404">[B]MOŽNOSTI POČASÍ[/B][CR][CR]Nastavení oblastí pro předpověď počasí</string>
   <string id="31405">[B]MOŽNOSTI SÍTĚ[/B][CR][CR]Možnosti ovládání XBMC přes UPnP a HTTP · Nastavení sdílení médií[CR]Nastavení přístupu na internet</string>
-  <string id="31406">[B]MOŽNOSTI SYSTÉMU[/B][CR][CR]Nastavení a kalibrace obrazovky · Konfigurace výstupu zvuku · Nastavení dálkového ovládání[CR]Možnosti úsporného režimu · Ukládání informací o ladění · Konfigurace rodičovského zámku</string>
+  <string id="31406">[B]MOŽNOSTI SYSTÉMU[/B][CR][CR]Nastavení obrazovky · Konfigurace výstupu zvuku · Nastavení dálkového ovládání[CR]Možnosti úsporného režimu · Ukládání informací o ladění · Rodičovský zámek</string>
   <string id="31407">[B]MOŽNOSTI VZHLEDU[/B][CR][CR]Přizpůsobení vzhledu Confluence · Správa sekcí na úvodní obrazovce[CR]Nastavení pozadí vzhledu</string>
   <string id="31408">[B]MOŽNOSTI DOPLŇKŮ[/B][CR][CR]Správa nainstalovaných doplňků · Vyhledávání a instalace doplňků z xbmc.org[CR]Nastavení doplňků</string>
 
   <string id="31421">Přihlášení uživatele[CR]Pokračujte výběrem profilu</string>
-  
+
   <!-- Weather plugin -->
   <string id="31900">Mapy počasí</string>
   <string id="31901">Předpověď na 36 hodin</string>
index d32977a..7f7410d 100644 (file)
   <string id="31402">[B]CONFIGURE MUSIC SETTINGS[/B][CR][CR]Manage your music library · Set music playback options · Change music listing options[CR]Setup song submission · Set karaoke options</string>
   <string id="31403">[B]CONFIGURE PICTURE SETTINGS[/B][CR][CR]Set picture listing options · Configure slideshows</string>
   <string id="31404">[B]CONFIGURE WEATHER SETTINGS[/B][CR][CR]Set three cities to collect weather information</string>
-  <string id="31405">[B]CONFIGURE NETWORK SETTINGS[/B][CR][CR]Setup control of XBMC via UPnP and HTTP · Configure file sharing[CR]Set internet access options</string>
+
   <string id="31406">[B]CONFIGURE SYSTEM SETTINGS[/B][CR][CR]Setup and calibrate displays · Configure audio output · Setup remote controls[CR]Set power saving options · Enable debugging · Setup master lock</string>
   <string id="31407">[B]CONFIGURE SKIN SETTINGS[/B][CR][CR]Setup the Confluence skin · Add and remove home menu items[CR]Change skin backgrounds</string>
   <string id="31408">[B]CONFIGURE ADD-ONS[/B][CR][CR]Manage your installed Add-ons · Browse for and install Add-ons from xbmc.org[CR]Modify Add-on settings</string>
+  <string id="31409">[B]CONFIGURE SERVICE SETTINGS[/B][CR][CR]Setup control of XBMC via UPnP and HTTP · Configure file sharing[CR]Enable Zeroconf · Configure AirPlay</string>
 
   <string id="31421">Select your XBMC user Profile[CR]to login and continue</string>
   
index e698959..0760ab1 100644 (file)
   <string id="31402">[B]KONFIGURIERE MUSIK EINSTELLUNGEN[/B][CR][CR]Organisiere die Musik DB · Setze die Musik Abspiel Optionen · Wechsel die Musik Auflistungs Optionen · Einrichten der Lied Vorlage · Setze Karaoke Optionen</string>
   <string id="31403">[B]KONFIGURIERE BILDER EINSTELLUNGEN[/B][CR][CR]Setze Bild Auflistungs Optionen · Konfiguriere Diaschau</string>
   <string id="31404">[B]KONFIGURIERE WETTER EINSTELLUNGEN[/B][CR][CR]Wähle drei Städte zum sammeln der Wetter Informationen</string>
-  <string id="31405">[B]KONFIGURIERE NETZWERK EINSTELLUNGEN[/B][CR][CR]Einrichten der Steuerung von XBMC via UPnP und HTTP · Konfiguriere Datei Zugriff[CR]Setze Internet Zugriffs Optionen</string>
   <string id="31406">[B]KONFIGURIERE SYSTEM EINSTELLUNGEN[/B][CR][CR]Setze und kalibriere Displays · Konfiguriere Audioausgabe · Setze Fernbedienungs Einstellungen · Setze Energiespar Optionen · Aktiviere Debugging · Einrichten Master Sperre</string>
   <string id="31407">[B]KONFIGURIERE SKIN EINSTELLUNGEN[/B][CR][CR]Einrichten des Confluence Skin · Hinzufügen und entfernen der Home Menü Einträge[CR]Wechseln der Skin Hintergründe</string>
   <string id="31408">[B]KONFIGURIERE ADD-ONS[/B][CR][CR]Organisiere die installierten Add-ons · Installiere Add-ons von xbmc.org[CR]Add-on Einstellungen anpassen</string>
+  <string id="31409">[B]KONFIGURIERE DIENSTE[/B][CR][CR]Richte Zugriff auf XBMC via UPnP und HTTP ein · Konfiguriere die Dateifreigabe[CR]Aktiviere Zeroconf · Konfiguriere AirPlay</string>
   <string id="31421">Wähle Dein XBMC Benutzer Profil[CR]Zum Anmelden und Weitermachen</string>
 
   <string id="31900">Wetterkarten</string>
index cba0444..f3f7754 100644 (file)
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<strings>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<strings> <!-- Last update (by CutSickAss): 23/03/2012 -->
   <!-- Misc labels -->
   <string id="31000">Αλλαγή</string>
   <string id="31001">Αγαπητό</string>
@@ -7,16 +7,17 @@
   <string id="31003">Επιλογές λειτουργίας</string>
   <string id="31004">Απασχολημένο...</string>
   <string id="31005">Απόκρυψη Πληροφοριών</string>
+  <string id="31006">Προβολή Επιλογών</string>
+  <string id="31007">Plugin</string>
+  <string id="31008">Πλήρης Οθόνη</string>
 
-  <string id="31007">Επεκτάσεις</string>
-
-  <string id="31020">Πρόσφατα αναρτημένα</string>
-  <string id="31021">Αρχεία βίντεο</string>
-  <string id="31022">Αρχεία μουσικής</string>
+  <string id="31020">Προστέθηκαν πρόσφατα</string>
+  <string id="31021">Βίντεο - Αρχεία</string>
+  <string id="31022">Μουσική - Αρχεία</string>
   <string id="31023">Αναπαραγωγή</string>
   <string id="31024">Σελίδα</string>
   <string id="31025">Αντικείμενα</string>
-  <string id="31026">ΠÏ\81Ï\8cÏ\83θεÏ\84ες επιλογές</string>
+  <string id="31026">Î\94ιάÏ\86οÏ\81ες επιλογές</string>
   <string id="31027">Τοποθεσία</string>
  
   <!-- View Type labels -->
   <string id="31033">Πληροφορίες</string>
   
   <!-- Extra labels -->
-  <string id="31040">ΤÏ\8eÏ\81α Î±Î½Î±Ï\80αÏ\81άγεται</string>
+  <string id="31040">ΤÏ\8eÏ\81α Î\95κÏ\84ελείται</string>
 
-  <string id="31042">Î\91ναÏ\80αÏ\81άγεÏ\84αι</string>
+  <string id="31042">Î\91Î\9dÎ\91ΠÎ\91ΡÎ\91Î\93ΩÎ\93Î\97</string>
   <string id="31043">ΠΑΥΣΗ</string>
-  <string id="31044">ΠΡÎ\9fΩÎ\98Î\97ΣÎ\97 Î\9cΠΡÎ\9fΣΤÎ\91</string>
-  <string id="31045">ΠΡÎ\9fΩÎ\98Î\97ΣÎ\97 Î Î\99ΣΩ</string>
-  <string id="31046">Î\99διÏ\8cÏ\84ηÏ\84εÏ\82 Î®χου</string>
-  <string id="31047">Τρέχουσα απεικονίση</string>
-  <string id="31048">Î\91Ï\80εικονίσεις</string>
+  <string id="31044">ΜΠΡΟΣΤΑ</string>
+  <string id="31045">ΠΙΣΩ</string>
+  <string id="31046">Î\99διÏ\8cÏ\84ηÏ\84εÏ\82 Î\89χου</string>
+  <string id="31047">Τρέχον Προκαθορισμένο</string>
+  <string id="31048">ΠÏ\81οκαθοÏ\81ιÏ\83μένεÏ\82 Î\9fÏ\80Ï\84ικοÏ\80οιήσεις</string>
   <string id="31049">Χρόνος λήξης</string>
+  <string id="31050">Ταξ.: Αύξουσα</string>
+  <string id="31051">Ταξ.: Φθίνουσα</string>
 
 
   <!-- Playlist Editor labels -->
   <string id="31055">Άνοιγμα λίστας αναπαραγωγής</string>
   <string id="31056">Αποθήκευση λίστας αναπαραγωγής</string>
   <string id="31057">Κλείσιμο λίστας αναπαραγωγής</string>
-  <string id="31058">ΣÏ\8dÏ\83Ï\84ημα Î±Ï\81Ï\87είÏ\89ν Î¼Î¿Ï\85Ï\83ικής</string>
+  <string id="31058">Î\9cοÏ\85Ï\83ικά Î±Ï\81Ï\87εία Ï\83Ï\85Ï\83Ï\84ήμαÏ\84ος</string>
   <string id="31059">Τρέχουσα λίστα αναπαραγωγής</string>
-  <string id="31060">Αυτό το αρχείο είναι στοιβαγμένο, επιλέξτε το κομμάτι που επιθυμείτε για αναπαραγωγή.</string>
-  <string id="31061">Î\95Ï\80ιλέÏ\87θηκε Î· Ï\84Ï\81έÏ\87οÏ\85Ï\83α</string>
-
+  <string id="31060">Αυτό το αρχείο είναι στοιβαγμένο, επιλέξτε από που να γίνει αναπαραγωγή.</string>
+  <string id="31061">ΤÏ\81έÏ\87οÏ\85Ï\83α Î\95Ï\80ιλογή</string>
+  
   <!-- Skin Settings labels -->
   <string id="31100"></string>
   <string id="31101">Επιλογές αρχικής οθόνης</string>
   <string id="31102">Υπόβαθρο</string>
-  <string id="31103">Εμφάνιση "Παύση" κατά την παρουσίαση φωτογραφιών</string>
-  <string id="31104">Î\91ναÏ\80αÏ\81αγÏ\89γή Î\94ιαÏ\86ημιÏ\83Ï\84ικÏ\8eν Ï\84αινιÏ\8eν Ï\83ε Ï\80αÏ\81άθÏ\85Ï\81ο[COLOR=grey3](Μόνο οι πληροφορίες βίντεο)[/COLOR]</string>
-  <string id="31105"></string>
-  <string id="31106">ΠÏ\81Ï\8cÏ\83θεÏ\84ες επιλογές</string>
+  <string id="31103">Εμφάνιση 'Παύσης' σε παρουσίαση διαφανειών</string>
+  <string id="31104">Î\91ναÏ\80αÏ\81αγÏ\89γή Î\94ιαÏ\86ημιÏ\83Ï\84ικÏ\8eν Ï\83ε Ï\80αÏ\81άθÏ\85Ï\81ο [COLOR=grey3](Μόνο οι πληροφορίες βίντεο)[/COLOR]</string>
+  <string id="31105">Το πλήκτρο "Βίντεο" πάντα οδηγεί στα "Αρχεία" βίντεο</string>
+  <string id="31106">Î\94ιάÏ\86οÏ\81ες επιλογές</string>
   <string id="31107">Απόκρυψη των αναγνώσιμων σημαιών από τα ονόματα αρχείων βίντεο [COLOR=grey3](Blu-ray, HD-DVD)[/COLOR]</string>
-  <string id="31108">Απόκρυψη πλήκτρων από το κεντρικό μενού επιλογών</string>
+  <string id="31108">Απόκρυψη πλήκτρων του Κεντρικού Μενού</string>
   <string id="31109">Υπόβαθρα αρχικής οθόνης</string>
-  <string id="31110">Επεξεργασία υπόβαθρου για το αρχικό πλήκτρο</string>
+  <string id="31110">Επεξεργασία υποβάθρου για το αρχικό πλήκτρο</string>
   <string id="31111">Απόκρυψη</string>
   <string id="31112">Επιλογές</string>
-  <string id="31113">Εικόνα</string>
-  <string id="31114">Φάκελος</string>
+  <string id="31113">Î\9cία Î\95ικÏ\8cνα</string>
+  <string id="31114">ΠολλαÏ\80λέÏ\82 ÎµÎ¹ÎºÏ\8cνες</string>
   <string id="31115">Προσαρμογή</string>
   <string id="31116"></string>
   <string id="31117">Εμφάνιση των πρόσφατα προστιθέμενων βίντεο</string>
-  <string id="31118">Υπομενού αρχικής οθόνης</string>
-  <string id="31119"></string>
+  <string id="31118">Î¥Ï\80ομενοÏ\8d Î\95Ï\86αÏ\81μογÏ\8eν Î±Ï\81Ï\87ικήÏ\82 Î¿Î¸Ï\8cνηÏ\82</string>
+  <string id="31119">Απόκρυψη Fanart υποβάθρου</string>
   <string id="31120">ΕΤΙΚΕΤΑ ΠΛΗΚΤΡΟΥ</string>
-  <string id="31121"></string>
-  <string id="31122">Î\9fθÏ\8cνη Îºαιρού</string>
-  <string id="31123">Χρήση του "Αφίσα" αντί του "Πανό" για τις τηλεοπτικές σειρές</string>
-  <string id="31124">Î\95μÏ\86άνιÏ\83η Ï\89Ï\82 Ï\85Ï\80Ï\8cβαθÏ\81ο Ï\84ο Î²Î¯Î½Ï\84εο Ï\80οÏ\85 "ΤÏ\8eÏ\81α Î±Î½Î±Ï\80αÏ\81άγεται"</string>
-  <string id="31125">Î\95μÏ\86άνιÏ\83η Ï\89Ï\82 Ï\85Ï\80Ï\8cβαθÏ\81ο Î· Î±Ï\80εικÏ\8cνιÏ\83η Ï\80οÏ\85 "ΤÏ\8eÏ\81α Î±Î½Î±Ï\80αÏ\81άγεται"</string>
+  <string id="31121"></string>  <!-- blanked 2010-11-12 -->
+  <string id="31122">Σελίδα Î\9aαιρού</string>
+  <string id="31123">Χρήση "Αφισών" αντί για "Πανό" για τις τηλεοπτικές σειρές</string>
+  <string id="31124">Î\95μÏ\86άνιÏ\83η Ï\89Ï\82 Ï\85Ï\80Ï\8cβαθÏ\81ο Ï\84ο Î²Î¯Î½Ï\84εο Ï\80οÏ\85 "ΤÏ\8eÏ\81α Î\95κÏ\84ελείται"</string>
+  <string id="31125">Î\95μÏ\86άνιÏ\83η Ï\89Ï\82 Ï\85Ï\80Ï\8cβαθÏ\81ο Î· Î¿Ï\80Ï\84ικοÏ\80οίηÏ\83η Ï\80οÏ\85 "ΤÏ\8eÏ\81α Î\95κÏ\84ελείται"</string>
 
-  <string id="31126"></string>
-  <string id="31127"></string>
-  <string id="31128">Στίχοι XBMC</string>
-  <string id="31129"></string>
-  <string id="31130"></string>
+  <string id="31126">Αναπαραγωγή τραγουδιών σειρών (πρόσθετο TvTunes)</string>
+  <string id="31127">TvTunes</string>
+  <string id="31128">Στίχοι</string>
+  <string id="31129"></string>  <!-- blanked 2010-11-12 -->
+  <string id="31130"></string>  <!-- blanked 2010-11-12 -->
+  <string id="31131"></string> <!-- blanked 2010-12-23 -->
+  <string id="31132">Πρόσθετο στίχων</string>
+  <string id="31133">Πρόσθετο υποτίτλων</string>
+  <string id="31134">Υπομενού Βίντεο αρχικής οθόνης</string>
+  <string id="31135">Υπομενού Μουσικής αρχικής οθόνης</string>
+  <string id="31136">Υπομενού Εικόνων αρχικής οθόνης</string>
 
-  <string id="31140">Aπεικόνισεις οθόνης (OSD) Μουσική</string>
-  <string id="31141">Aπεικόνισεις οθόνης (OSD) Βίντεο</string>
+  <string id="31140">Aπεικονίσεις οθόνης (OSD) Μουσικής</string>
+  <string id="31141">Aπεικονίσεις οθόνης (OSD) Βίντεο</string>
 
   <!-- Script labels -->
   <string id="31200">Συντομεύσεις</string>
   <string id="31201">Κατηγορίες</string>
-  <string id="31202">Εμφάνιση συντελεστών</string>
+  <string id="31202">Εμφάνιση διανομής</string>
   <string id="31203">Επιλογή τραγουδιού</string>
   <string id="31204">Επιλογή Συνδέσμων</string>
-  <string id="31205">Προέλευση στίχων τραγουδιού</string>
+  <string id="31205">Προέλευση στίχων</string>
 
   <!-- Extra labels -->
-  <string id="31300">ΤÏ\81έÏ\87οÏ\85Ï\83εÏ\82 Ï\83Ï\85νθήκεÏ\82</string>
+  <string id="31300">ΤÏ\81έÏ\87οÏ\85Ï\83α Î¸ÎµÏ\81μοκÏ\81αÏ\83ία</string>
   <string id="31301">Τελευταία ενημέρωση</string>
   <string id="31302">Μενού</string>
-  <string id="31303"></string>
-  <string id="31304">ΦÏ\89Ï\84ογÏ\81αÏ\86ίεÏ\82</string>
-  <string id="31305">Δεν εντοπίσθηκε δίσκος πολυμέσων</string>
+  <string id="31303">Πηγή δεδομένων</string>
+  <string id="31304">Î\95ικÏ\8cνα</string>
+  <string id="31305">Δεν εντοπίστηκε οπτικός δίσκος</string>
   <string id="31306">Εξαγωγή</string>
   <string id="31307">Απόκρυψη Fanart</string>
   <string id="31308">Λεπτομέρειες ταινίας</string>
-  <string id="31309">Î\94εÏ\83μεÏ\85μένη Î¼Î½Î®Î¼Î·:</string>
+  <string id="31309">ΧÏ\81ήÏ\83η Î¼Î½Î®Î¼Î·Ï\82:</string>
   <string id="31310">Αριθμός κομματιού</string>
-  <string id="31311">Î\9cη Î´Î¹Î±Î¸Î­Ï\83ιμη[CR][CR]εικÏ\8cνα Fanart[CR][CR]Î\93ια Î½Î± Î¿Ï\81ίÏ\83εÏ\84ε Ï\80ιέÏ\83Ï\84ε Ï\84ο Ï\80λήκÏ\84Ï\81ο</string>
-  <string id="31312">Î\95νεÏ\81γÏ\8cÏ\82 ÎºÎ±Ï\84αγÏ\81αÏ\86έαÏ\82</string>
-  <string id="31313">Επιλογή καταγραφέα</string>
-  <string id="31314">Επιλόγες αναζήτησης περιεχομένου</string>
+  <string id="31311">Î\95ικÏ\8cνα Fanart[CR][CR]Î\9cη Î´Î¹Î±Î¸Î­Ï\83ιμη[CR][CR] Î Î¹Î­Ï\83Ï\84ε Ï\84ο Ï\80λήκÏ\84Ï\81ο Î³Î¹Î± Î½Î± Î¸Î­Ï\83εÏ\84ε</string>
+  <string id="31312">ΤÏ\81έÏ\87ον Scraper</string>
+  <string id="31313">Επιλογή Scraper</string>
+  <string id="31314">Επιλογές Σάρωσης Περιεχομένου</string>
   <string id="31315">Βασικό</string>
   <string id="31316"></string>
   <string id="31317">Ορισμός διαδρομής Fanart</string>
   <string id="31318">Μικρό Fanart</string>
   <string id="31319">Επιλεγμένο προφίλ</string>
-  <string id="31320">Τελευταία είσοδος στο</string>
-  <string id="31321">Επιλογέας τραγουδιών Karaoke</string>
-  <string id="31322">Î\91ιθέÏ\81ιο</string>
-  <string id="31323">ΠÏ\81Ï\8cÏ\83Ï\86αÏ\84εÏ\82 Ï\84αινίες</string>
-  <string id="31324">ΠÏ\81Ï\8cÏ\83Ï\86αÏ\84α Îµπεισόδια</string>
+  <string id="31320">Τελευταία είσοδος</string>
+  <string id="31321">Επιλογέας τραγουδιού Karaoke</string>
+  <string id="31322">ΠÏ\81Ï\8eÏ\84η Î Ï\81οβολή</string>
+  <string id="31323">Î\9dεÏ\8eÏ\84εÏ\81εÏ\82 Î¤αινίες</string>
+  <string id="31324">Î\9dεÏ\8eÏ\84εÏ\81α Î\95πεισόδια</string>
   <string id="31325">Επιλογές λίστας αναπαραγωγής</string>
   <string id="31326">Δημιουργήθηκε</string>
   <string id="31327">Ανάλυση</string>
-  <string id="31328">Προστέθηκε πρόσφατα</string>
-  <string id="31329">[B]Εφαρμογή χρονοδιακόπτη![/B] [COLOR=grey2] - Αυτόματος τερματισμός λειτουργίας σε[/COLOR]</string>
-  <string id="31330">Πιέστε το πλήκτρο για να αναπαραχθεί[CR][CR]το διαφημιστικό ταινίας</string>
+  <string id="31328">Προστέθηκαν Πρόσφατα</string>
+  <string id="31329">[B]Εφαρμογή χρονοδιακόπτη![/B] [COLOR=grey2] - Αυτόματος τερματισμός συστήματος σε[/COLOR]</string>
+  <string id="31330">Πιέστε το πλήκτρο για αναπαραγωγή[CR][CR]του Διαφημιστικού Ταινίας</string>
+  <string id="31331">Λεπτομέρειες Άλμπουμ</string>
 
   <!-- Video and Music OSD Labels  -->
   <string id="31351">Παύση</string>
   <string id="31352">Διακοπή</string>
-  <string id="31353">ΠÏ\81οÏ\8eθηÏ\83η Î¼προστά</string>
-  <string id="31354">Προώθηση πίσω</string>
+  <string id="31353">Î\9cπροστά</string>
+  <string id="31354">Πίσω</string>
   <string id="31355">Μενού ταινίας</string>
   <string id="31356">Λήψη υποτίτλων</string>
   <string id="31357"></string>
 
+  <!-- Skin Fontsets -->
+  <string id="31390">Προεπιλογή</string>
+  <string id="31391">Προεπιλογή χωρίς Κεφαλαία</string>
+  <string id="31392">Βασισμένη σε Arial</string>
+
   <!-- Description Labels  -->
-  <string id="31400">[B]ΠΡΟΣΑΡΜΟΓΗ ΡΥΘΜΙΣΕΩΝ ΕΞΑΤΟΜΙΚΕΥΣΗΣ[/B][CR][CR]Αλλαγή κελύφους · Αλλαγή χώρας και γλώσσας συστήματος · Ορισμός των γενικών επιλόγων εμφάνισης[CR]Προσαρμογή της προφύλαξης οθόνης</string>
-  <string id="31401">[B]ΠΡΟΣΑΡΜΟΓΗ ΡΥΘΜΙΣΕΩΝ ΒΙΝΤΕΟ[/B][CR][CR]Διαχείριση της συλλογής βίντεο · Διαμόρφωση γραμματοσειράς υποτίτλων[CR]Προσαρμογή της ποιότητας ανάλυσης των βίντεο και ρύθμιση του αναπαραγωγέα</string>
-  <string id="31402">[B]ΠΡΟΣΑΡΜΟΓΗ ΡΥΘΜΙΣΕΩΝ ΜΟΥΣΙΚΗΣ[/B][CR][CR]Διαχείριση της συλλογής τραγουδιών · Eπιλογές εμφάνισης της λίστας μουσικής[CR]Προσαρμογή ρυθμίσεων και αλλαγή γραμματοσειράς για Karaoke</string>
-  <string id="31403">[B]ΠΡΟΣΑΡΜΟΓΗ ΡΥΘΜΙΣΕΩΝ ΦΩΤΟΓΡΑΦΙΩΝ[/B][CR][CR]Ρύθμιση επιλογών προβολής φωτογραφιών · Ρύθμιση παρουσίασης διαφανειών</string>
-  <string id="31404">[B]ΠΡΟΣΑΡΜΟΓΗ ΡΥΘΜΙΣΕΩΝ ΚΑΙΡΟΥ[/B][CR][CR]Ορισμός τριών πόλεων για τις οποίες θα γίνει πρόγνωση καιρού</string>
-  <string id="31405">[B]ΠΡΟΣΑΡΜΟΓΗ ΡΥΘΜΙΣΕΩΝ ΔΙΚΤΥΟΥ[/B][CR][CR]Προσαρμογή πρωτοκόλλων επικοινωνίας και μεταφοράς κοινόχρηστων αρχείων[CR]Ρύθμιση κοινόχρηστων αρχείων πολυμέσων · Ορισμός ρυθμίσεων δικτύου</string>
-  <string id="31406">[B]ΠΡΟΣΑΡΜΟΓΗ ΡΥΘΜΙΣΕΩΝ ΣΥΣΤΗΜΑΤΟΣ[/B][CR][CR]Βαθμονόμιση γραφικού περιβάλλοντος · Ρύθμιση υλικού ήχου · Εγκατάσταση τηλεχειριστηρίων[CR]Αλλαγή και τροποποίηση του τρόπου τερματισμού του προγράμματος · Ρύθμιση κεντρικού κλειδώματος</string>
-  <string id="31407">[B]ΠΡΟΣΑΡΜΟΓΗ ΡΥΘΜΙΣΕΩΝ ΚΕΛΥΦΟΥΣ[/B][CR][CR]Αλλαγή και τροποποίηση υπόβαθρων · Προσθήκη ή απομάκρυνση πλήκτρων από την αρχική οθόνη[CR]Δημιουργία συντομεύσεων προς τα scripts προκειμένου να ενσωματωθούν στο κέλυφος</string>
-  <string id="31408">[B]ΠΡΟΣΑΡΜΟΓΗ ΡΥΘΜΙΣΕΩΝ ΠΡΟΣΘΕΤΩΝ[/B][CR][CR]Διαχείριση των Πρόσθετων σας · Αναζήτηση και εγκατάσταση Πρόσθετων από το XBMC.org[CR]Τροποποίηση ρυθμίσεων των Πρόσθετων</string>
+  <string id="31400">[B]ΡΥΘΜΙΣΕΙΣ ΕΞΑΤΟΜΙΚΕΥΣΗΣ[/B][CR][CR]Αλλαγή κελύφους · Αλλαγή χώρας και γλώσσας συστήματος · Επιλογές καταλόγου αρχείων[CR]Προσαρμογή της προφύλαξης οθόνης</string>
+  <string id="31401">[B]ΡΥΘΜΙΣΕΙΣ ΒΙΝΤΕΟ[/B][CR][CR]Διαχείριση της συλλογής βίντεο · Ρύθμιση αναπαραγωγής βίντεο · Επιλογές καταλόγου ταινιών[CR]Ρύθμιση γραμματοσειράς υποτίτλων</string>
+  <string id="31402">[B]ΡΥΘΜΙΣΕΙΣ ΜΟΥΣΙΚΗΣ[/B][CR][CR]Διαχείριση της συλλογής τραγουδιών · Ρύθμιση αναπαραγωγής μουσικής · Επιλογές καταλόγου μουσικής[CR]Ρύθμιση υποβολής τραγουδιού · Επιλογές karaoke</string>
+  <string id="31403">[B]ΡΥΘΜΙΣΕΙΣ ΕΙΚΟΝΩΝ[/B][CR][CR]Επιλογές καταλόγου εικόνων · Ρύθμιση παρουσίασης διαφανειών</string>
+  <string id="31404">[B]ΡΥΘΜΙΣΕΙΣ ΚΑΙΡΟΥ[/B][CR][CR]Ορισμός τριών πόλεων για τις οποίες θα γίνεται πρόγνωση καιρού</string>
+  <string id="31405">[B]ΡΥΘΜΙΣΕΙΣ ΔΙΚΤΥΟΥ[/B][CR][CR]Ρύθμιση χειρισμού του XBMC μέσω UPnP και HTTP · Ρύθμιση κοινής χρήσης αρχείων[CR]Ορισμός ρυθμίσεων διαδικτύου</string>
+  <string id="31406">[B]ΡΥΘΜΙΣΕΙΣ ΣΥΣΤΗΜΑΤΟΣ[/B][CR][CR]Διαμόρφωση και βαθμονόμηση οθονών · Ρύθμιση εξόδου ήχου · Εγκατάσταση τηλεχειριστηρίων · Ρύθμιση εξοικονόμησης ενέργειας · Ενεργοποίηση καταγραφής σφαλμάτων (debug) · Ρύθμιση κεντρικού κλειδώματος</string>
+  <string id="31407">[B]ΡΥΘΜΙΣΕΙΣ ΚΕΛΥΦΟΥΣ[/B][CR][CR]Ρύθμιση του κελύφους Confluence · Προσθήκη και απομάκρυνση αντικειμένων από την αρχική οθόνη[CR]Αλλαγή υποβάθρου κελύφους</string>
+  <string id="31408">[B]ΡΥΘΜΙΣΕΙΣ ΠΡΟΣΘΕΤΩΝ[/B][CR][CR]Διαχείριση εγκατεστημένων Πρόσθετων · Αναζήτηση και εγκατάσταση Πρόσθετων από το xbmc.org[CR]Τροποποίηση ρυθμίσεων των Πρόσθετων</string>
+
+  <string id="31421">Επιλέξτε προφίλ χρήστη για το XBMC[CR]για να συνδεθείτε και να συνεχίσετε</string>
   
-  <string id="31421">Επιλέξτε προφίλ χρήστη για το XBMC[CR]για να συνδεθείτε και συνεχίστε</string>
-</strings>
+  <!-- Weather plugin -->
+  <string id="31900">Χάρτες Καιρού</string>
+  <string id="31901">36ωρη Πρόβλεψη</string>
+  <string id="31902">Ωριαία Πρόβλεψη</string>
+  <string id="31903">Πρόβλεψη Σαββατοκύριακου</string>
+  <string id="31904">Πρόβλεψη 10 ημερών</string>
+  <string id="31905">Πρόβλεψη</string>
+  <string id="31906">Χάρτες &amp; Βίντεο</string>
+  <string id="31907">Βίντεο Πρόβλεψης [COLOR=grey2](Πλήρης Οθόνη)[/COLOR]</string>
+  <string id="31908">Πιθανότητα Υετού</string>
+  <string id="31909">Ανάκτηση πρόβλεψης καιρού...</string>
+
+  </strings>
index 2595bd0..b0c3f43 100644 (file)
   <string id="31300">현재 온도</string>
   <string id="31301">마지막 업데이트</string>
   <string id="31302">메뉴</string>
-  <string id="31303"></string>
+  <string id="31303">날씨 정보 제공</string>
   <string id="31304">사진</string>
   <string id="31305">디스크 미디어 감지되지 않음</string>
   <string id="31306">꺼내기</string>
index 07b59e3..2920d19 100644 (file)
@@ -33,7 +33,7 @@
   <string id="31033">Informacija</string>
 
   <!-- Extra labels -->
-  <string id="31040">Dabar grojami</string>
+  <string id="31040">Aktualus failas</string>
 
   <string id="31042">RODOMA</string>
   <string id="31043">PAUZĖ</string>
@@ -53,7 +53,7 @@
   <string id="31057">Uždaryti grojaraštį</string>
   <string id="31058">Sisteminiai audio failai</string>
   <string id="31059">Aktualus grojaraštis</string>
-  <string id="31060">Šis failas yra sugrupuotas, pasirinkite dalį katrą norite atkurti.</string>
+  <string id="31060">Šie failai yra sugrupuoti, pasirinkite dalį katrą norite atkurti.</string>
   <string id="31061">Dabartinis Pasirinkimas</string>
 
   <!-- Skin Settings labels -->
   <string id="31323">Nauji Filmai</string>
   <string id="31324">Nauji Epizodai</string>
   <string id="31325">Sąrašo Opcijos</string>
-  <string id="31326">Sukūrta</string>
+  <string id="31326">Sukurta</string>
   <string id="31327">Leidimas</string>
   <string id="31328">Neseniai Dadėta</string>
   <string id="31329">[B]NUSTATYTAS LAIKRODIS![/B] [COLOR=red] - AUTOMATIŠKAI ATSIJUNGS PO[/COLOR]</string>
   <string id="31392">Arial Pagrindu</string>
 
   <!-- Description Labels  -->
-  <string id="31400">[B][COLOR=blue]IŠVAIZDOS PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=red]Pakeisti išvaizdą · Nustatyti kalbą ir regioną · Pakeisti failų sarašą.[CR]Nustatyti ekrano vaizdą.[/COLOR]</string>
+  <string id="31400">[B][COLOR=blue]IŠVAIZDOS PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=red]Pakeisti išvaizdą · Nustatyti kalbą ir regioną[CR]Pakeisti failų sarašą · Nustatyti ekrano vaizdą.[/COLOR]</string>
   <string id="31401">[B][COLOR=blue]VIDEO PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=red]Tvarkyti video biblioteką · Nustatyti video atkūrimo opcijas.[CR]Nustatyti video sarašą · Nustatyti subtitrų šriftą.[/COLOR]</string>
   <string id="31402">[B][COLOR=blue]MUZIKOS PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=red]Tvarkyti audio biblioteką· Nustatyti audio atkūrimo opcijas.[CR]Nustatyti audio sarašą · Nustatyti audio pridėjimą · Nustatyti karaoke.[/COLOR]</string>
   <string id="31403">[B][COLOR=blue]PAVEIKSLŲ PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=red]Tvarkyti nuotraukų biblioteką · Nustatyti pristatymą · Nustatyti prezentaciją.[/COLOR]</string>
   <string id="31404">[B][COLOR=blue]ORŲ PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=red]Nustatyti trys Miestus gauti informacijai apie orus.[/COLOR]</string>
   <string id="31405">[B][COLOR=blue]TINKLO PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=red]Nustatyti XBMC valdymą  per UPnP ir HTTP · Nustatyti failų apsikeitimą.[CR]Nustatyi prieigą prie interneto.[/COLOR]</string>
-  <string id="31406">[B][COLOR=blue]SISTEMOS PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=red] Nustatyti ekrano kalibravimą · Nustatyti audio išėjimą · Nustatyti distancinį pultą.[CR]Nustatyti energijos sąnaudas · Nustatyti derinimą · Nustatyti blokavimą.[/COLOR]</string>
-  <string id="31407">[B][COLOR=red]ŠABLONŲ PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=blue]www.xbmc.lt . www.xbmc.org . info@xbmc.lt[/COLOR][CR][COLOR=red]Nustatyti pasirinktą šabloną. Pakeisti šablono foną.[CR]Pridėti ir (arba) pašalinti pagrindinius menių punktus.[/COLOR]</string>
+  <string id="31406">[B][COLOR=blue]SISTEMOS PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=red]Nustatyti ekrano kalibravimą · Nustatyti audio išėjimą · Nustatyti distancinį pultą.[CR]Nustatyti energijos sąnaudas · Nustatyti derinimą · Nustatyti blokavimą.[/COLOR]</string>
+  <string id="31407">[B][COLOR=blue]ŠABLONŲ PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=red]Nustatyti pasirinktą šabloną. Pakeisti šablono foną.[CR]Pridėti ir (arba) pašalinti pagrindinius menių punktus.[/COLOR]</string>
   <string id="31408">[B][COLOR=blue]PRIEDŲ PARAMETRŲ NUSTATYMAI[/COLOR][/B][CR][CR][COLOR=red]Nustatyti parametrų valdymą · Nustatymų diegimą iš xbmc.org[CR]Nustatyti priedų pakeitimą.[/COLOR]</string>
 
   <string id="31421">Pasirinkite XBMC vartotojo profilį[CR]įeiti į sistemą ir tęsti.</string>
 
-
   <!-- Weather plugin -->
   <string id="31900">Orų Žemėlapiai</string>
   <string id="31901">36 Valandų Prognozė</string>
   <string id="31903">Savaitgalio Prognozė</string>
   <string id="31904">10 Dienų Prognozė</string>
   <string id="31905">Prognozė</string>
-  <string id="31906">Žemėlapiai &amp; Video</string>
+  <string id="31906">Žemėlapiai ir Video</string>
   <string id="31907">Video Prognozė [COLOR=grey2](Pilnaekranis Atkūrimas)[/COLOR]</string>
   <string id="31908">Kritulių Tikimybė</string>
   <string id="31909">Parsiunčiama Prognozės Informacija...</string>
index 74b2cfa..baf62a5 100644 (file)
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <!--Language file translated with Team XBMC Translator[wm]-->
 <!--File for addons/skin.confluence/language/Portuguese (Brazil)/ -->
-<!--Translator: bugre (wm), Fabiano Santiago (fabianosan) -->
+<!--Translator: bugre (wm), Fabiano Santiago (fabianosan), wcampos -->
 <!--Email: wxxx333-nospam-at-gmail.com, fabianosan@hotmail.com -->
-<!--Date of translation: 11/23/2009-->
-<!--Updated on 15/11/2010 bugre -->
+<!--Date of translation: 03/03/2012-->
+<!--Updated on 03/03/2012 wcampos -->
 <!--$Revision$-->
 <!--Based on english strings version 35254 -->
 <strings>
@@ -15,6 +15,8 @@
   <string id="31004">Executando...</string>
   <string id="31005">Esconder INFO</string>
   <string id="31007">Plugins</string>
+  <string id="31008">Tela Cheia</string>
+  
   <string id="31020">Adicionado recentemente</string>
   <string id="31021">Video - Arquivos</string>
   <string id="31022">Música - Arquivos</string>
   <string id="31025">Itens</string>
   <string id="31026">Opções diversas</string>
   <string id="31027">Localização</string>
+  
   <string id="31028">Vitrine</string>
   <string id="31029">Fanart</string>
   <string id="31030">Lista Completa</string>
   <string id="31031">Ícones de imagens</string>
   <string id="31032">Vitrine de Imagens</string>
   <string id="31033">Info</string>
+  
   <string id="31040">Tocando agora</string>
+  
   <string id="31042">TOCANDO</string>
   <string id="31043">PAUSADO</string>
   <string id="31044">AVANÇO RÁPIDO</string>
   <string id="31045">RETROCEDER</string>
   <string id="31046">Propriedades de áudio</string>
-  <string id="31047">Preconfiguração atual</string>
-  <string id="31048">Visualizar pre-configurações</string>
+  <string id="31047">Pré configuração atual</string>
+  <string id="31048">Visualizar pré-configurações</string>
   <string id="31049">Tempo de término</string>
+  <string id="31050">Ordem: Ascendente</string>
+  <string id="31051">Ordem: Descendente</string>
+  
   <string id="31055">Abrir playlist</string>
   <string id="31056">Salvar playlist</string>
   <string id="31057">Fechar playlist</string>
@@ -45,6 +53,7 @@
   <string id="31059">Playlist atual</string>
   <string id="31060">Este arquivo está empilhado, selecione a parte de onde executar.</string>
   <string id="31061">Selecionado</string>
+  
   <string id="31100"></string>
   <string id="31101">Opções da tela principal (home)</string>
   <string id="31102">Fundo</string>
   <string id="31123">Usar "Pôsters" ao invés de "Faixas" para Seriados</string>
   <string id="31124">Exibir fundo Vídeo "Tocando Agora"</string>
   <string id="31125">Exibir fundo Visualização "Tocando Agora"</string>
+  <string id="31126">Reproduzir música tema do seriado na biblioteca de vídeo(TvTunes add-on)</string>
+  <string id="31127">TvTunes</string>
+   
   <string id="31128">Letras</string>
   <string id="31131"></string>
   <string id="31132">Add-on de Letras</string>
   <string id="31133">Add-on de legendas</string>
+  <string id="31134">Home Page Submenu de Videos</string>
+  <string id="31135">Home Page Submenu de Música</string>
+  <string id="31136">Home Page Submenu de Imagens</string>
+  
   <string id="31140">OSD de Música</string>
   <string id="31141">OSD de Video</string>
+  
   <string id="31200">Atalhos</string>
   <string id="31201">Categorias</string>
   <string id="31202">Elenco do Seriado</string>
   <string id="31203">Escolha sua música</string>
   <string id="31204">Seção de Links</string>
   <string id="31205">Origem das Letras</string>
+  
   <string id="31300">Temp. Atual</string>
   <string id="31301">Última atualização</string>
   <string id="31302">Menu</string>
   <string id="31328">Adicionado Recentemente</string>
   <string id="31329">[B]Timer definido![/B] [COLOR=grey2] - Sistema se desligará em[/COLOR]</string>
   <string id="31330">Clique no botão para tocar o[CR][CR]trailer</string>
+  <string id="31331">Detalhes do Álbum</string>
+  
   <string id="31351">Pausar</string>
   <string id="31352">Parar</string>
   <string id="31353">Avançar</string>
   <string id="31355">Menu do Filme</string>
   <string id="31356">Download de Legendas</string>
   <string id="31357"></string>
+  
   <string id="31390">Padrão da skin</string>
   <string id="31391">Padrão da skin sem capslock</string>
   <string id="31392">Baseado em Arial</string>
+  
   <string id="31400">[B]CONFIGURAR AJUSTES DE APARÊNCIA[/B][CR][CR]Mudar o skin · Definir idioma e região · Definir opções de listagem de arquivos · Definir um descanso de tela</string>
   <string id="31401">[B]CONFIGURAR AJUSTES DE VÍDEO[/B][CR][CR]Gerenciar sua coleção de vídeos · Definir opções de execução de vídeo · Alterar opções de listagem de vídeo · Definir fonte para legendas</string>
   <string id="31402">[B]CONFIGURAR AJUSTES DE MÚSICAS[/B][CR][CR]Gerenciar sua coleção de músicas · Definir opções de execução de música · Alterar opções de listagem de música · Configurar submissão de música · Definir opções de karaoke</string>
   <string id="31407">[B]CONFIGURAR AJUSTES DE SKIN[/B][CR][CR]Configurar o skin Confluence · Adicionar e remover itens no menu principal(home) · Alterar fundos do skin</string>
   <string id="31408">[B]CONFIGURAR AJUSTES DE ADD-ONS[/B][CR][CR]Configurar Add-ons existentes · Procurar e instalar novos Add-ons de xbmc.org[CR]Alterar configurações do Add-on</string>
   <string id="31421">Selecione seu Perfil de usuário XBMC[CR]para conectar e continue</string>
+  !-- Weather plugin -->
+  <string id="31900">Mapas - Clima</string>
+  <string id="31901">Previsão 36 Horas</string>
+  <string id="31902">Previsão por hora</string>
+  <string id="31903">Previsão fim de semana</string>
+  <string id="31904">Previsão 10 Dias</string>
+  <string id="31905">Previsão</string>
+  <string id="31906">Mapas &amp; Video</string>
+  <string id="31907">Vídeo da Previsão [COLOR=grey2](Playback em tela cheia)[/COLOR]</string>
+  <string id="31908">Chance de precipitação</string>
+  <string id="31909">Buscando informações da previsão...</string>
+  
 </strings>
\ No newline at end of file
index 1eff937..f126cd5 100644 (file)
@@ -8,8 +8,9 @@
   <string id="31003">Opțiuni de alimentare</string>
   <string id="31004">Procesare...</string>
   <string id="31005">Ascunde detalii</string>
-
+  <string id="31006">Opțiuni vizualizare</string>
   <string id="31007">Module</string>
+  <string id="31008">Pe tot ecranul</string>
 
   <string id="31020">Adăugate recent</string>
   <string id="31021">Fișiere video</string>
@@ -39,6 +40,8 @@
   <string id="31047">Viz. predefinită curentă</string>
   <string id="31048">Vizualizări predefinite</string>
   <string id="31049">Se termină la</string>
+  <string id="31050">Sort.: Ascendent</string>
+  <string id="31051">Sort.: Descendent</string>
 
 
   <!-- Playlist Editor labels -->
   <string id="31101">Opțiuni ecran principal</string>
   <string id="31102">Fundal</string>
   <string id="31103">Arată „În pauză” la prezentare diapozitive</string>
-  <string id="31104">Redă trailere intr-o fereastră [COLOR=grey3](doar în dialogul de informații video)[/COLOR]</string>
-  <string id="31105"></string>
+  <string id="31104">Redă secvențele intr-o fereastră [COLOR=grey3](doar în dialogul de informații video)[/COLOR]</string>
+  <string id="31105">Butonul „Video” duce întotdeauna către „Fișiere” video</string>
   <string id="31106">Opțiuni diverse</string>
-  <string id="31107">Ascunde marcare citit în nume de fișiere video [COLOR=grey3](Blu-ray, HD-DVD)[/COLOR]</string>
+  <string id="31107">Ascunde marcare citită din numele fișierelor video [COLOR=grey3](Blu-ray, HD-DVD)[/COLOR]</string>
   <string id="31108">Ascundere butoane meniu principal</string>
   <string id="31109">Fundale media</string>
   <string id="31110">Modificare fundal pentru</string>
   <string id="31115">Personalizator</string>
   <string id="31116"></string>
   <string id="31117">Arată filme și episoade adăugate recent</string>
-  <string id="31118">Submeniu programe pagină inițială</string>
-  <string id="31119"></string>
+  <string id="31118">Submeniu Programe în pagină inițială</string>
+  <string id="31119">Ascunde fundal (Fanart)</string>
   <string id="31120">ETICHETĂ BUTON</string>
   <string id="31121"></string>
   <string id="31122">Pagină meteo</string>
   <string id="31123">Folosește „Afișe” în loc de „Bannere” pentru seriale</string>
   <string id="31124">Arată video „Acum în redare” pe fundal</string>
   <string id="31125">Arată vizualizare „Acum în redare” pe fundal</string>
-  <string id="31126"></string>
-  <string id="31127"></string>
+  <string id="31126">Redă cântece temă TV în mediateca video (supliment TvTunes)</string>
+  <string id="31127">TvTunes</string>
   <string id="31128">Versuri</string>
   <string id="31129"></string>
   <string id="31130"></string>
   <string id="31131"></string>
+  <string id="31132">Supliment versuri</string>
+  <string id="31133">Supliment subtitrări</string>
+  <string id="31134">Submeniu Video în pagina inițială</string>
+  <string id="31135">Submeniu Muzică în pagina inițială</string>
+  <string id="31136">Submeniu Imagini în pagina inițială</string>
 
   <string id="31140">Meniu audio</string>
   <string id="31141">Meniu video</string>
   <string id="31300">Temperatură curentă</string>
   <string id="31301">Ultima actualizare</string>
   <string id="31302">Meniu</string>
-  <string id="31303"></string>
+  <string id="31303">Furnizor informații</string>
   <string id="31304">Imagine</string>
   <string id="31305">Niciun disc media detectat</string>
   <string id="31306">Scoate</string>
   <string id="31326">Creat</string>
   <string id="31327">Rezoluție</string>
   <string id="31328">Adăugate recent</string>
-  <string id="31329">[B]Cronometrul este setat![/B] [COLOR=grey2] - Închidere automată sistem în[/COLOR]</string>
-  <string id="31330">Clic pe buton pentru redare[CR][CR]Trailer film</string>
+  <string id="31329">[B]Planificare închidere activată![/B] [COLOR=grey2] Închidere sistem în[/COLOR]</string>
+  <string id="31330">Clic pe buton pentru redare[CR][CR]secvențe din film (trailer)</string>
+  <string id="31331">Detalii album</string>
 
   <!-- Video and Music OSD Labels  -->
   <string id="31351">Pauză</string>
   <string id="31408">[B]CONFIGURAȚI SUPLIMENTE[/B][CR][CR]Administrați suplimentele instalate · Căutați și instalați suplimente de la xbmc.org[CR]Modificați setări suplimente</string>
 
   <string id="31421">Selectați profilul dumneavoastră de utilizator XBMC[CR]pentru a vă autentifica și a continua</string>
+  
+  <!-- Weather plugin -->
+  <string id="31900">Hărți meteo</string>
+  <string id="31901">Previziune pe 36 de ore</string>
+  <string id="31902">Previziune la o oră</string>
+  <string id="31903">Previziune weekend</string>
+  <string id="31904">Previziune pe 10 zile</string>
+  <string id="31905">Previziune</string>
+  <string id="31906">Hărți și video</string>
+  <string id="31907">Previziune video [COLOR=grey2](Redare pe tot ecranul)[/COLOR]</string>
+  <string id="31908">Șansă de precipitații</string>
+  <string id="31909">Preluare informații previziune...</string>
+
 </strings>
diff --git a/addons/skin.confluence/media/flagging/audio/vorbis.png b/addons/skin.confluence/media/flagging/audio/vorbis.png
new file mode 100644 (file)
index 0000000..8b047cd
Binary files /dev/null and b/addons/skin.confluence/media/flagging/audio/vorbis.png differ
index 9b6fcdb..1d03746 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 9b6fcdbb095bc84cdf84c1fd01ff719e972cbaaa
+Subproject commit 1d03746646111f97e28b807a290bd762c7db547c
diff --git a/addons/visualization.glspectrum/resources/language/Romanian/strings.xml b/addons/visualization.glspectrum/resources/language/Romanian/strings.xml
new file mode 100644 (file)
index 0000000..a9f8a99
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<strings>
+    <!-- settings labels -->
+    <string id="30000">Mod</string>
+    <string id="30001">umplere</string>
+    <string id="30002">contur</string>
+    <string id="30003">puncte</string>
+    <string id="30004">Înălțime bară</string>
+    <string id="30005">mică</string>
+    <string id="30006">standard</string>
+    <string id="30007">mare</string>
+    <string id="30008">foarte mare</string>
+    <string id="30009">Viteză</string>
+    <string id="30010">foarte încet</string>
+    <string id="30011">încet</string>
+    <string id="30012">standard</string>
+    <string id="30013">repede</string>
+    <string id="30014">foarte repede</string>
+</strings>
index 44f02da..8963ffb 100644 (file)
@@ -19,6 +19,7 @@
     <summary lang="nl">iTunes-visualisaties</summary>
     <summary lang="pl">Wrapper wizualizacji iTunes</summary>
     <summary lang="pt">Visualização iTunes</summary>
+    <summary lang="ro">Wrapper vizualizare iTunes</summary>
     <summary lang="se">iTunes visualiseringsomslag</summary>
     <summary lang="zh">iTunes可视化效果包</summary>
     <description lang="bg">iTunes Visualization Wrapper ви позволява да използвате визуализациите от локалната инсталация на OSX iTunes в XBMC</description>
@@ -32,6 +33,7 @@
     <description lang="nl">Dankzij iTunes-visualisaties kan XBMC gebruik maken van de visualisaties van uw iTunesinstallatie in OS X</description>
     <description lang="pl">Wrapper pozwala XBMC na użycie wizualizacji z iTunes (tylko system OSX)</description>
     <description lang="pt">O iTunes Visualization Wrapper permite usar visualizações do seu OSX iTunes no XBMC</description>
+    <description lang="ro">Wrapper vizualizare iTunes vă permite să folosiți vizualizări din instalarea iTunes de pe OSX în XBMC</description>
     <description lang="se">iTunes visualiseringsomslag tillåter dig att använda visualiseringar från din OSX iTunes installation i XBMC</description>
     <description lang="zh">iTunes可视化效果包允许你使用安装到XBMC的来自于OSX iTunes的可视化效果</description>
     <platform>osx</platform>
index a9ae857..16e51ff 100644 (file)
@@ -26,6 +26,7 @@
     <summary lang="ko">projectM 은 사운드웨이브 속으로 날아가는듯한 효과를 보여줍니다.</summary>
     <summary lang="pl">projectM zabiera Cię w niesamowity lot w chmurach aktualnie słuchanych dźwięków</summary>
     <summary lang="pt">O projectM leva-o a voar nas ondas sonoras que está a ouvir</summary>
+    <summary lang="ro">projectM te plimbă printre undele sonore pe care le asculți</summary>
     <summary lang="se">projectM tar dig flygande genom ljudvågorna du hör</summary>
     <summary lang="zh">projectM带你与声波一起飞翔</summary>
     <description lang="bg">projectM е страхотна визуализация, плод на упорит труд от страна на общността. В света на Unix не съществува нищо по-добро. Потребители, като вас, създават предварително комбинации от настройки, които ползват като модел за визуализацията и така свързват звука с невероятни визуални ефекти. Пробвайте!
@@ -54,6 +55,9 @@ projectM jest reimplementacją Milkdropa na licencji LGPL i używa OpenGL
 Wszystko czego wymaga projectM, to karta graficzna wspierająca akcelerację 3D oraz zasoby Twojej muzyki.</description>
     <description lang="pt">O projectM é um fantástico visualizador de música. Não existe nenhum melhor no mundo Unix. A grandeza do projectM advém do trabalho árduo da comunidade. Utilizadores como você podem criar pré-definições que ligam a música a visualizações incríveis. Experimente!
 O visualizador projectM é uma reimplementação do Milkdrop OpenGL sob uma licença LGPL. Tudo o que o projectM necessita é de uma placa gráfica com aceleração 3D e a sua música favorita.</description>
+       <description lang="ro">projectM este o vizualizare de muzică uimitoare. Nu există nimic mai bun în lumea Unix. Măreția projectM vine din munca întregii comunități. Utilizatori ca și tine pot crea presetări care conectează muzica cu vizualizări incredibile. Încearcă și tu!
+Vizualizarea projectM este o reimplementare LGPL a lui Milkdrop sub OpenGL.
+Tot ceea ce necesită projectM este o placă video cu accelerare 3D și muzica ta favorită.</description>
     <description lang="se">projectM är en fantastisk musikvisualisering. Det finns inget bättre i Unixvärlden. projectM's storhet kommer från hårt arbete i gemenskapen. Användare som dig kan skapa förval som anluter musiken med dom otroliga visualiseringarna. Prova det!
 projectM visualiseringen är en LGPL återskapning av Milkdrop från OpenGL
 Alla projectM kräver ett grafikkort med 3D-acceleration och din favoritmusik.</description>
diff --git a/addons/visualization.projectm/resources/language/Romanian/strings.xml b/addons/visualization.projectm/resources/language/Romanian/strings.xml
new file mode 100644 (file)
index 0000000..ae93b7f
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<strings>
+    <!-- settings labels -->
+    <string id="30000">Calitate randare</string>
+    <string id="30001">Mică</string>
+    <string id="30002">Medie</string>
+    <string id="30003">Mare</string>
+    <string id="30004">Maximă</string>
+    <string id="30005">Mod amestecare</string>
+    <string id="30006">Durată presetare fină</string>
+    <string id="30007">Durată presetare</string>
+    <string id="30008">Senzitivitate bătaie</string>
+    <string id="30009">Pachet presetări</string>
+    <string id="30010">Pachet implicit</string>
+    <string id="30011">Dosar presetări definite de utilizator</string>
+    <string id="30012">Dosar presetări utilizator</string>
+
+    <!-- setting value formats -->
+    <string id="30050">%2.0f sec</string>
+    <string id="30051">%2.0f %%</string>
+</strings>
index d13e3a5..3205923 100644 (file)
@@ -35,7 +35,7 @@
     <description lang="nl">Waveform is een simpele muziekvisualisatie die twee golfvormen op het scherm toont, respectievelijk voor het linker- en rechtergeluidskanaal. De golfvormen bewegen mee met de beat van de muziek.</description>
     <description lang="pl">Waveform jest prostą wizualizacją pokazującą dwie fale dźwiękowe na ekranie. Każda na jeden kanał dźwięku.</description>
     <description lang="pt">O Waveform é um visualizador simples que mostra 2 gráficos ondulantes no ecrã, um para cada canal estéreo.</description>
-    <description lang="ro">Waveform este o vizualizare simplă care arată 2 grafice Waveform pe ecran, câte unul pentru fiecare canal stâng și drept și care se mișcă după bătăile muzicii</description>
+    <description lang="ro">Waveform este o vizualizare simplă care arată 2 grafice în formă de undă pe ecran, câte unul pentru fiecare canal stâng și drept și care se mișcă după bătăile muzicii.</description>
     <description lang="se">Waveform är en enkel visualisering som visar 2 vågformsgrafer på skärmen, en för vänster och en för höger kanal som rör sig i takt med musiken</description>
     <description lang="zh">Waveform是一个简单的可视化效果,它在屏幕上显示两个波形图,分别与音乐左右声道的节拍相呼应。</description>
     <platform>all</platform>
index 06e5deb..9396393 100644 (file)
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="weather.wunderground" name="Weather Underground" version="0.0.5" provider-name="Team XBMC">
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<addon id="weather.wunderground" name="Weather Underground" version="0.0.9" provider-name="Team XBMC">
        <requires>
                <import addon="xbmc.python" version="2.0"/>
                <import addon="script.module.simplejson" version="2.0.10"/>
@@ -8,13 +8,16 @@
        <extension point="xbmc.addon.metadata">
                <summary lang="bg">Синоптична прогноза от wunderground.com</summary>
                <summary lang="en">Weather forecast from wunderground.com</summary>
+               <summary lang="fi">Sääennusteet wunderground.com -sivustolta</summary>
                <summary lang="se">Väderprognos från wunderground.com</summary>
                <summary lang="zh">来自wunderground.com的天气预报</summary>
                <description lang="bg">Прогноза за времето осигурена от Weather Underground (http://www.wunderground.com/)</description>
                <description lang="en">Weather forecast provided by Weather Underground (http://www.wunderground.com/)</description>
+               <description lang="fi">Sääennusteet Weather Underground -sivuston tarjoamina (http://www.wunderground.com/)</description>
                <description lang="se">Väderprognos tillhandahållen av Weather Underground (http://www.wunderground.com/)</description>
                <description lang="zh">由Weather Underground(http://www.wunderground.com/)提供的天气预报</description>
                <disclaimer lang="en">Use of this add-on implies that you have agreed to the Terms of Service located at http://www.wunderground.com/weather/api/d/terms.html</disclaimer>
+               <disclaimer lang="fi">Tämän lisäosan käyttäminen tarkoittaa, että olet hyväksynyt käyttöehdot, jotka sijaitsevat osoitteessa http://www.wunderground.com/weather/api/d/terms.html</disclaimer>
                <disclaimer lang="se">Användning av detta tillägg innebär att du har godkänt Terms of Service från http://www.wunderground.com/weather/api/d/terms.html</disclaimer>
                <disclaimer lang="zh">使用此扩展功能意味着你同意此连接下的服务条款:http://www.wunderground.com/weather/api/d/terms.html</disclaimer>
                <platform>all</platform>
index 62596ec..f9c0fe0 100644 (file)
@@ -1,3 +1,17 @@
+v0.0.9
+- clear 7 day labels not 6
+- save only the actual location code
+
+v0.0.8
+- fix error if no internet connection is available when searching for a location
+
+v0.0.7
+- fix: import error on Windows with non/extended-ascii profile paths
+
+v0.0.6
+- ignore various n/a values in wu data
+- use kph value for windspeed
+
 v0.0.5
 - add geoip support
 - fetch 7 day forecast
index 86d07c7..5d7eae4 100644 (file)
@@ -20,14 +20,14 @@ import xbmcgui, xbmcaddon
 __addon__      = xbmcaddon.Addon()
 __provider__   = __addon__.getAddonInfo('name')
 __cwd__        = __addon__.getAddonInfo('path')
-__resource__   = xbmc.translatePath(os.path.join(__cwd__, 'resources', 'lib'))
+__resource__   = xbmc.translatePath(os.path.join(__cwd__, 'resources', 'lib')).decode("utf-8")
 
 sys.path.append (__resource__)
 
 from utilities import *
 
 LOCATION_URL    = 'http://autocomplete.wunderground.com/aq?query=%s&format=JSON'
-WEATHER_URL     = 'http://api.wunderground.com/api/%s/conditions/forecast7day/hourly%s.json'
+WEATHER_URL     = 'http://api.wunderground.com/api/%s/conditions/forecast7day/hourly/q/%s.json'
 GEOIP_URL       = 'http://api.wunderground.com/api/%s/geolookup/q/autoip.json'
 A_I_K           = 'NDEzNjBkMjFkZjFhMzczNg=='
 WEATHER_WINDOW  = xbmcgui.Window(12600)
@@ -68,7 +68,8 @@ def fetch(url):
     except:
         json_string = ''
     try:
-        parsed_json = simplejson.loads(json_string)
+        json_clean = json_string.replace('"-9999.00"','""').replace('"-9998"','""').replace('"NA"','""')
+        parsed_json = simplejson.loads(json_clean)
     except:
         parsed_json = ''
     return parsed_json
@@ -77,17 +78,18 @@ def location(string):
     loc   = []
     locid = []
     query = fetch(LOCATION_URL % (urllib2.quote(string)))
-    for item in query['RESULTS']:
-        location   = item['name']
-        locationid = item['l']
-        loc.append(location)
-        locid.append(locationid)
+    if query != '':
+        for item in query['RESULTS']:
+            location   = item['name']
+            locationid = item['l'][3:]
+            loc.append(location)
+            locid.append(locationid)
     return loc, locid
 
 def geoip():
     data = fetch(GEOIP_URL % aik[::-1])
     if data != '' and data.has_key('location'):
-        location = data['location']['l']
+        location = data['location']['l'][3:]
         __addon__.setSetting('Location1', data['location']['city'])
         __addon__.setSetting('Location1id', location)
     else:
@@ -103,7 +105,7 @@ def properties(query):
     weathercode = WEATHER_CODES[query['current_observation']['icon_url'][31:-4]]
     set_property('Current.Condition'     , query['current_observation']['weather'])
     set_property('Current.Temperature'   , str(query['current_observation']['temp_c']))
-    set_property('Current.Wind'          , str(int(query['current_observation']['wind_mph'] * 1.609344)))
+    set_property('Current.Wind'          , str(query['current_observation']['wind_kph']))
     set_property('Current.WindDirection' , query['current_observation']['wind_dir'])
     set_property('Current.Humidity'      , query['current_observation']['relative_humidity'].rstrip('%'))
     set_property('Current.FeelsLike'     , str((int(query['hourly_forecast'][0]['feelslike']['english'])-32)*5/9))
@@ -146,9 +148,10 @@ else:
     if location == '':
         location = geoip()
     if not location == '':
+        if location.startswith('/q/'): # backwards compatibility
+            location = location[3:]
         forecast(location)
     else:
-        # workaround to fix incrementing values on each weather refresh when no locations are set up:
         set_property('Current.Condition'     , 'N/A')
         set_property('Current.Temperature'   , '0')
         set_property('Current.Wind'          , '0')
@@ -159,7 +162,7 @@ else:
         set_property('Current.DewPoint'      , '0')
         set_property('Current.OutlookIcon'   , 'na.png')
         set_property('Current.FanartCode'    , 'na')
-        for count in range (0, MAXDAYS):
+        for count in range (0, MAXDAYS+1):
             set_property('Day%i.Title'       % count, 'N/A')
             set_property('Day%i.HighTemp'    % count, '0')
             set_property('Day%i.LowTemp'     % count, '0')
index ab8b025..bf8ec85 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <strings>
        <string id="30101">所在地设置</string>
        <string id="30111">更改地点1</string>
diff --git a/addons/weather.wunderground/resources/language/Dutch/strings.xml b/addons/weather.wunderground/resources/language/Dutch/strings.xml
new file mode 100644 (file)
index 0000000..ad380a7
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<strings>
+       <string id="30101">Plaatsen Instellen</string>
+       <string id="30111">Wijzig plaats 1</string>
+       <string id="30112">Wijzig plaats 2</string>
+       <string id="30113">Wijzig plaats 3</string>
+</strings>
index a81b2b8..9076851 100644 (file)
@@ -6,7 +6,7 @@
   provider-name="Team XBMC">
   <requires>
     <import addon="xbmc.gui" version="3.00"/>
-    <import addon="xbmc.json" version="2.00"/>
+    <import addon="xbmc.json" version="4.00"/>
   </requires>
   <extension
     point="xbmc.gui.webinterface"/>
     <summary lang="bg">Уебинтерфейс на Team XBMC. (стандартният уебинтерфейс на XBMC)</summary>
     <summary lang="en">Team XBMC Web Interface. (XBMC's default web interface)</summary>
     <summary lang="es">Interface web de XBMC. (Interface web por defecto de XBMC)</summary>
+    <summary lang="fi">Team XBMC:n WWW-käyttöliittymä. (XBMC:n oletus WWW-käyttöliittymä)</summary>
     <summary lang="nl">Team XBMC Webinterface. (XBMC's standaard webinterface)</summary>
     <summary lang="pl">Standardowy interfejs WWW XBMC.</summary>
     <summary lang="pt">Interface Web da Team XBMC. (Interface Web padrão do XBMC)</summary>
-    <summary lang="ro">Interfață web XBMC. (Interfață web implicită pentru XBMC)</summary>
+    <summary lang="ro">Interfață web XBMC. (interfață web implicită pentru XBMC)</summary>
     <summary lang="se">Team XBMC webbgränssnitt. (XBMC's standardwebbgränssnitt)</summary>
     <summary lang="zh">Team XBMC Web 界面。(XBMC 的默认 web 界面)</summary>
     <description lang="de">Standard XBMC Webinterface; Für alle Geräte und Auflösungen geeignet</description>
     <description lang="bg">Стандартния уебинтерфейс на XBMC; Направен е за устройства с най-различни резолюции</description>
     <description lang="en">Default web interface for XBMC; Designed for devices of all resolutions</description>
     <description lang="es">Interface web por defecto de XBMC. Diseñada para dispositivos de cualquier resolución</description>
+    <description lang="fi">Oletus WWW-käyttöliittymä XBMC:lle. Suunniteltu käytettäväksi kaiken kokoisilla laitteilla.</description>
     <description lang="nl">Standaard XBMC-webinterface; geschikt voor alle resoluties</description>
     <description lang="pl">Domyślny interfejs WWW dla XBMC; Zaprojektowany dla urządzeń z dowolną rozdzielczością</description>
     <description lang="pt">Interface Web padrão do XBMC. Desenhada para dispositivos com qualquer resolução</description>
-    <description lang="ro">Interfață web implicită pentru XBMC, realizată de echipa XBMC pentru dispozitive cu orice rezoluție</description>
+    <description lang="ro">Interfață web implicită pentru XBMC, realizată de echipa XBMC pentru dispozitive cu orice rezoluție.</description>
     <description lang="se">XBMC's standardwebbgränsnitt; Designat för alla upplösningar</description>
     <description lang="zh">XBMC 的默认 web 界面;适应所有分辨率模式</description>
     <platform>all</platform>
index 18a48e6..1033cc7 100755 (executable)
@@ -22,7 +22,7 @@
 var MediaLibrary = function() {
   this.init();
   return true;
-}
+};
 
 MediaLibrary.prototype = {
   playlists: { },
@@ -69,6 +69,7 @@ MediaLibrary.prototype = {
   getPlaylists: function() {
     jQuery.ajax({
       type: 'POST',
+      contentType: 'application/json',
       url: JSON_RPC + '?GetPlaylists',
       data: '{"jsonrpc": "2.0", "method": "Playlist.GetPlaylists", "id": 1}',
       timeout: 3000,
@@ -153,62 +154,190 @@ MediaLibrary.prototype = {
     //common part
     switch(keyPressed) {
       case 'cleanlib_a':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "AudioLibrary.Clean", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "AudioLibrary.Clean", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'updatelib_a':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "AudioLibrary.Scan", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "AudioLibrary.Scan", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'cleanlib_v':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "VideoLibrary.Clean", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "VideoLibrary.Clean", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'updatelib_v':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "VideoLibrary.Scan", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "VideoLibrary.Scan", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'back':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Back", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "Input.Back", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'home':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Home", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "Input.Home", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'mute':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Application.SetMute", "params": { "mute": "toggle" }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "Application.SetMute", "params": { "mute": "toggle" }, "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'power':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "System.Shutdown", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "System.Shutdown", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'volumeup':
-      jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": { "properties": [ "volume" ] }, "id": 1}', function(data){
-        var volume = data.result.volume + 1;
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Application.SetVolume", "params": { "volume": '+volume+' }, "id": 1}', function(data){
-          $('#spinner').hide();
-        }, 'json');
-       }, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": { "properties": [ "volume" ] }, "id": 1}',
+          success: jQuery.proxy(function(data) {
+            var volume = data.result.volume + 1;
+            jQuery.ajax({
+              type: 'POST',
+              contentType: 'application/json',
+              url: JSON_RPC + '?SendRemoteKey',
+              data: '{"jsonrpc": "2.0", "method": "Application.SetVolume", "params": { "volume": '+volume+' }, "id": 1}',
+              success: jQuery.proxy(function(data) {
+                $('#spinner').hide();
+              }, this),
+              dataType: 'json'});
+          }, this),
+          dataType: 'json'});
         return;
       case 'volumedown':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": { "properties": [ "volume" ] }, "id": 1}', function(data){
-          var volume = data.result.volume - 1;
-          jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Application.SetVolume", "params": { "volume": '+volume+' }, "id": 1}', function(data){
-            $('#spinner').hide();
-          }, 'json');
-       }, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": { "properties": [ "volume" ] }, "id": 1}',
+          success: jQuery.proxy(function(data) {
+            var volume = data.result.volume - 1;
+            jQuery.ajax({
+              type: 'POST',
+              contentType: 'application/json',
+              url: JSON_RPC + '?SendRemoteKey',
+              data: '{"jsonrpc": "2.0", "method": "Application.SetVolume", "params": { "volume": '+volume+' }, "id": 1}',
+              success: jQuery.proxy(function(data) {
+                $('#spinner').hide();
+              }, this),
+              dataType: 'json'});
+          }, this),
+          dataType: 'json'});
         return;
     }
 
     switch(keyPressed) {
       case 'up':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Up", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "Input.Up", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'down':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Down", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "Input.Down", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'left':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Left", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "Input.Left", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'right':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Right", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "Input.Right", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
       case 'ok':
-        jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Select", "id": 1}', function(data){$('#spinner').hide();}, 'json');
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?SendRemoteKey',
+          data: '{"jsonrpc": "2.0", "method": "Input.Select", "id": 1}',
+          success: jQuery.proxy(function(data) {
+            $('#spinner').hide();
+          }, this),
+          dataType: 'json'});
         return;
     }
 
@@ -216,22 +345,70 @@ MediaLibrary.prototype = {
     {
       switch(keyPressed) {
         case 'playpause':
-          jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.PlayPause", "params": { "playerid": ' + player + ' }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
+          jQuery.ajax({
+            type: 'POST',
+            contentType: 'application/json',
+            url: JSON_RPC + '?SendRemoteKey',
+            data: '{"jsonrpc": "2.0", "method": "Player.PlayPause", "params": { "playerid": ' + player + ' }, "id": 1}',
+            success: jQuery.proxy(function(data) {
+              $('#spinner').hide();
+            }, this),
+            dataType: 'json'});
           return;
         case 'stop':
-          jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.Stop", "params": { "playerid": ' + player + ' }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
+          jQuery.ajax({
+            type: 'POST',
+            contentType: 'application/json',
+            url: JSON_RPC + '?SendRemoteKey',
+            data: '{"jsonrpc": "2.0", "method": "Player.Stop", "params": { "playerid": ' + player + ' }, "id": 1}',
+            success: jQuery.proxy(function(data) {
+              $('#spinner').hide();
+            }, this),
+            dataType: 'json'});
           return;
         case 'next':
-          jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.GoNext", "params": { "playerid": ' + player + ' }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
+          jQuery.ajax({
+            type: 'POST',
+            contentType: 'application/json',
+            url: JSON_RPC + '?SendRemoteKey',
+            data: '{"jsonrpc": "2.0", "method": "Player.GoNext", "params": { "playerid": ' + player + ' }, "id": 1}',
+            success: jQuery.proxy(function(data) {
+              $('#spinner').hide();
+            }, this),
+            dataType: 'json'});
           return;
         case 'previous':
-          jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.GoPrevious", "params": { "playerid": ' + player + ' }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
+          jQuery.ajax({
+            type: 'POST',
+            contentType: 'application/json',
+            url: JSON_RPC + '?SendRemoteKey',
+            data: '{"jsonrpc": "2.0", "method": "Player.GoPrevious", "params": { "playerid": ' + player + ' }, "id": 1}',
+            success: jQuery.proxy(function(data) {
+              $('#spinner').hide();
+            }, this),
+            dataType: 'json'});
           return;
         case 'forward':
-          jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.SetSpeed", "params": { "playerid": ' + player + ', "speed": "increment" }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
+          jQuery.ajax({
+            type: 'POST',
+            contentType: 'application/json',
+            url: JSON_RPC + '?SendRemoteKey',
+            data: '{"jsonrpc": "2.0", "method": "Player.SetSpeed", "params": { "playerid": ' + player + ', "speed": "increment" }, "id": 1}',
+            success: jQuery.proxy(function(data) {
+              $('#spinner').hide();
+            }, this),
+            dataType: 'json'});
           return;
         case 'rewind':
-          jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.SetSpeed", "params": { "playerid": ' + player + ', "speed": "decrement" }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
+          jQuery.ajax({
+            type: 'POST',
+            contentType: 'application/json',
+            url: JSON_RPC + '?SendRemoteKey',
+            data: '{"jsonrpc": "2.0", "method": "Player.SetSpeed", "params": { "playerid": ' + player + ', "speed": "decrement" }, "id": 1}',
+            success: jQuery.proxy(function(data) {
+              $('#spinner').hide();
+            }, this),
+            dataType: 'json'});
           return;
       }
     }
@@ -248,23 +425,29 @@ MediaLibrary.prototype = {
       libraryContainer.attr('id', 'libraryContainer')
                       .addClass('contentContainer');
       $('#content').append(libraryContainer);
-      jQuery.post(JSON_RPC + '?GetAlbums', '{"jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": { "limits": { "start": 0 }, "properties": ["description", "theme", "mood", "style", "type", "albumlabel", "artist", "genre", "rating", "title", "year", "thumbnail"], "sort": { "method": "artist" } }, "id": 1}', jQuery.proxy(function(data) {
-        if (data && data.result && data.result.albums) {
-          this.albumList = data.result.albums;
-          $.each($(this.albumList), jQuery.proxy(function(i, item) {
-            var floatableAlbum = this.generateThumb('album', item.thumbnail, item.title, item.artist);
-            floatableAlbum.bind('click', { album: item }, jQuery.proxy(this.displayAlbumDetails, this));
-            libraryContainer.append(floatableAlbum);
-          }, this));
-          libraryContainer.append($('<div>').addClass('footerPadding'));
-          $('#spinner').hide();
-          libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
-          libraryContainer.trigger('scroll');
-          myScroll = new iScroll('libraryContainer');
-        } else {
-          libraryContainer.html('');
-        }
-      }, this), 'json');
+      jQuery.ajax({
+        type: 'POST',
+        contentType: 'application/json',
+        url: JSON_RPC + '?GetAlbums',
+        data: '{"jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": { "limits": { "start": 0 }, "properties": ["description", "theme", "mood", "style", "type", "albumlabel", "artist", "genre", "rating", "title", "year", "thumbnail"], "sort": { "method": "artist" } }, "id": 1}',
+        success: jQuery.proxy(function(data) {
+          if (data && data.result && data.result.albums) {
+            this.albumList = data.result.albums;
+            $.each($(this.albumList), jQuery.proxy(function(i, item) {
+              var floatableAlbum = this.generateThumb('album', item.thumbnail, item.title, item.artist);
+              floatableAlbum.bind('click', { album: item }, jQuery.proxy(this.displayAlbumDetails, this));
+              libraryContainer.append(floatableAlbum);
+            }, this));
+            libraryContainer.append($('<div>').addClass('footerPadding'));
+            $('#spinner').hide();
+            libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
+            libraryContainer.trigger('scroll');
+            myScroll = new iScroll('libraryContainer');
+          } else {
+            libraryContainer.html('');
+          }
+        }, this),
+        dataType: 'json'});
     } else {
       libraryContainer.show();
       libraryContainer.trigger('scroll');
@@ -353,71 +536,77 @@ MediaLibrary.prototype = {
     $('#topScrollFade').hide();
     if (!albumDetailsContainer || albumDetailsContainer.length == 0) {
       $('#spinner').show();
-      jQuery.post(JSON_RPC + '?GetSongs', '{"jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "params": { "properties": ["title", "artist", "genre", "track", "duration", "year", "rating", "playcount"], "albumid" : ' + event.data.album.albumid + ' }, "id": 1}', jQuery.proxy(function(data) {
-        albumDetailsContainer = $('<div>');
-        albumDetailsContainer.attr('id', 'albumDetails' + event.data.album.albumid)
-                   .addClass('contentContainer')
-                   .addClass('albumContainer')
-                   .html('<table class="albumView"><thead><tr class="headerRow"><th>Artwork</th><th>&nbsp;</th><th>Name</th><th class="time">Time</th><th>Artist</th><th>Genre</th></tr></thead><tbody class="resultSet"></tbody></table>');
-        $('.contentContainer').hide();
-        $('#content').append(albumDetailsContainer);
-        var albumThumbnail = event.data.album.thumbnail;
-        var albumTitle = event.data.album.title||'Unknown Album';
-        var albumArtist = event.data.album.artist||'Unknown Artist';
-        var trackCount = data.result.limits.total;
-        $.each($(data.result.songs), jQuery.proxy(function(i, item) {
-          if (i == 0) {
-            var trackRow = $('<tr>').addClass('trackRow').addClass('tr' + i % 2);
-            trackRow.append($('<td>').attr('rowspan', ++trackCount + 1).addClass('albumThumb'));
-            for (var a = 0; a < 5; a++) {
-              trackRow.append($('<td>').html('&nbsp').attr('style', 'display: none'));
+      jQuery.ajax({
+        type: 'POST',
+        contentType: 'application/json',
+        url: JSON_RPC + '?GetSongs',
+        data: '{"jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "params": { "properties": ["title", "artist", "genre", "track", "duration", "year", "rating", "playcount"], "albumid" : ' + event.data.album.albumid + ' }, "id": 1}',
+        success: jQuery.proxy(function(data) {
+          albumDetailsContainer = $('<div>');
+          albumDetailsContainer.attr('id', 'albumDetails' + event.data.album.albumid)
+                     .addClass('contentContainer')
+                     .addClass('albumContainer')
+                     .html('<table class="albumView"><thead><tr class="headerRow"><th>Artwork</th><th>&nbsp;</th><th>Name</th><th class="time">Time</th><th>Artist</th><th>Genre</th></tr></thead><tbody class="resultSet"></tbody></table>');
+          $('.contentContainer').hide();
+          $('#content').append(albumDetailsContainer);
+          var albumThumbnail = event.data.album.thumbnail;
+          var albumTitle = event.data.album.title||'Unknown Album';
+          var albumArtist = event.data.album.artist||'Unknown Artist';
+          var trackCount = data.result.limits.total;
+          $.each($(data.result.songs), jQuery.proxy(function(i, item) {
+            if (i == 0) {
+              var trackRow = $('<tr>').addClass('trackRow').addClass('tr' + i % 2);
+              trackRow.append($('<td>').attr('rowspan', ++trackCount + 1).addClass('albumThumb'));
+              for (var a = 0; a < 5; a++) {
+                trackRow.append($('<td>').html('&nbsp').attr('style', 'display: none'));
+              }
+              $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
             }
-            $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
-          }
-          var trackRow = $('<tr>').addClass('trackRow').addClass('tr' + i % 2).bind('click', { album: event.data.album, itmnbr: i }, jQuery.proxy(this.playTrack,this));
-          var trackNumberTD = $('<td>')
-            .html(item.track)
+            var trackRow = $('<tr>').addClass('trackRow').addClass('tr' + i % 2).bind('click', { album: event.data.album, itmnbr: i }, jQuery.proxy(this.playTrack,this));
+            var trackNumberTD = $('<td>')
+              .html(item.track)
 
-          trackRow.append(trackNumberTD);
-          var trackTitleTD = $('<td>')
-            .html(item.title);
+            trackRow.append(trackNumberTD);
+            var trackTitleTD = $('<td>')
+              .html(item.title);
 
-          trackRow.append(trackTitleTD);
-          var trackDurationTD = $('<td>')
-            .addClass('time')
-            .html(durationToString(item.duration));
+            trackRow.append(trackTitleTD);
+            var trackDurationTD = $('<td>')
+              .addClass('time')
+              .html(durationToString(item.duration));
 
-          trackRow.append(trackDurationTD);
-          var trackArtistTD = $('<td>')
-            .html(item.artist);
+            trackRow.append(trackDurationTD);
+            var trackArtistTD = $('<td>')
+              .html(item.artist);
 
-          trackRow.append(trackArtistTD);
-          var trackGenreTD = $('<td>')
-            .html(item.genre);
+            trackRow.append(trackArtistTD);
+            var trackGenreTD = $('<td>')
+              .html(item.genre);
 
-          trackRow.append(trackGenreTD);
-          $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
-        }, this));
-        if (trackCount > 0) {
-          var trackRow = $('<tr>').addClass('fillerTrackRow');
-          for (var i = 0; i < 5; i++) {
-            trackRow.append($('<td>').html('&nbsp'));
-          }
-          $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
+            trackRow.append(trackGenreTD);
+            $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
+          }, this));
+          if (trackCount > 0) {
+            var trackRow = $('<tr>').addClass('fillerTrackRow');
+            for (var i = 0; i < 5; i++) {
+              trackRow.append($('<td>').html('&nbsp'));
+            }
+            $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
 
-          var trackRow2 = $('<tr>').addClass('fillerTrackRow2');
-          trackRow2.append($('<td>').addClass('albumBG').html('&nbsp'));
-          for (var i = 0; i < 5; i++) {
-            trackRow2.append($('<td>').html('&nbsp'));
+            var trackRow2 = $('<tr>').addClass('fillerTrackRow2');
+            trackRow2.append($('<td>').addClass('albumBG').html('&nbsp'));
+            for (var i = 0; i < 5; i++) {
+              trackRow2.append($('<td>').html('&nbsp'));
+            }
+            $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow2);
           }
-          $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow2);
-        }
-        $('#albumDetails' + event.data.album.albumid + ' .albumThumb')
-          .append(this.generateThumb('album', albumThumbnail, albumTitle, albumArtist))
-          .append($('<div>').addClass('footerPadding'));
-        $('#spinner').hide();
-        myScroll = new iScroll('albumDetails' + event.data.album.albumid);
-      }, this), 'json');
+          $('#albumDetails' + event.data.album.albumid + ' .albumThumb')
+            .append(this.generateThumb('album', albumThumbnail, albumTitle, albumArtist))
+            .append($('<div>').addClass('footerPadding'));
+          $('#spinner').hide();
+          myScroll = new iScroll('albumDetails' + event.data.album.albumid);
+        }, this),
+        dataType: 'json'});
     } else {
       $('.contentContainer').hide();
       $('#albumDetails' + event.data.album.albumid).show();
@@ -463,57 +652,63 @@ MediaLibrary.prototype = {
     toggle=this.toggle.detach();
     if (!tvshowDetailsContainer || tvshowDetailsContainer.length == 0) {
       $('#spinner').show();
-      jQuery.post(JSON_RPC + '?GetTVShowSeasons', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetSeasons", "params": { "properties": [ "season", "showtitle", "playcount", "episode", "thumbnail","fanart" ], "tvshowid" : ' + event.data.tvshow.tvshowid + ' }, "id": 1}', jQuery.proxy(function(data) {
-        tvshowDetailsContainer = $('<div>');
-        tvshowDetailsContainer.attr('id', 'tvShowDetails' + event.data.tvshow.tvshowid)
-                              .css('display', 'none')
-                              .addClass('contentContainer')
-                              .addClass('tvshowContainer');
-        var showThumb = this.generateThumb('tvshowseason', event.data.tvshow.thumbnail, event.data.tvshow.title);
-        if (data && data.result && data.result.seasons && data.result.seasons.length > 0) {
-          var showDetails = $('<div>').addClass('showDetails');
-          showDetails.append(toggle);
-          showDetails.append($('<p>').html(data.result.seasons[0].showtitle).addClass('showTitle'));
-          var seasonSelectionSelect = $('<select>').addClass('seasonPicker');
-          //var episodeCount = 0;
-          this.tvActiveShowContainer = tvshowDetailsContainer;
-          //var fanart;
-          $.each($(data.result.seasons), jQuery.proxy(function(i, item) {
-//              if(fanart==null && item.fanart!=null){
-//                fanart=item.fanart;
-//              }
-//              //episodeCount += item.episode;
-            var season = $('<option>').attr('value',i);
-            season.text(item.label);
-            seasonSelectionSelect.append(season);
+      jQuery.ajax({
+        type: 'POST',
+        contentType: 'application/json',
+        url: JSON_RPC + '?GetTVShowSeasons',
+        data: '{"jsonrpc": "2.0", "method": "VideoLibrary.GetSeasons", "params": { "properties": [ "season", "showtitle", "playcount", "episode", "thumbnail","fanart" ], "tvshowid" : ' + event.data.tvshow.tvshowid + ' }, "id": 1}',
+        success: jQuery.proxy(function(data) {
+          tvshowDetailsContainer = $('<div>');
+          tvshowDetailsContainer.attr('id', 'tvShowDetails' + event.data.tvshow.tvshowid)
+                                .css('display', 'none')
+                                .addClass('contentContainer')
+                                .addClass('tvshowContainer');
+          var showThumb = this.generateThumb('tvshowseason', event.data.tvshow.thumbnail, event.data.tvshow.title);
+          if (data && data.result && data.result.seasons && data.result.seasons.length > 0) {
+            var showDetails = $('<div>').addClass('showDetails');
+            showDetails.append(toggle);
+            showDetails.append($('<p>').html(data.result.seasons[0].showtitle).addClass('showTitle'));
+            var seasonSelectionSelect = $('<select>').addClass('seasonPicker');
+            //var episodeCount = 0;
+            this.tvActiveShowContainer = tvshowDetailsContainer;
+            //var fanart;
+            $.each($(data.result.seasons), jQuery.proxy(function(i, item) {
+  //              if(fanart==null && item.fanart!=null){
+  //                fanart=item.fanart;
+  //              }
+  //              //episodeCount += item.episode;
+              var season = $('<option>').attr('value',i);
+              season.text(item.label);
+              seasonSelectionSelect.append(season);
 
-          }, this));
-//            if(fanart!=null)
-//            {
-//              $('.contentContainer').css('background','url("'+this.getThumbnailPath(fanart)+'")').css('background-size','cover');
-//            }
-          seasonSelectionSelect.bind('change', {tvshow: event.data.tvshow.tvshowid, seasons: data.result.seasons, element: seasonSelectionSelect}, jQuery.proxy(this.displaySeasonListings, this));
-          //showDetails.append($('<p>').html('<span class="heading">Episodes:</span> ' + episodeCount));
-          showDetails.append(seasonSelectionSelect);
-          tvshowDetailsContainer.append(showDetails);
-          tvshowDetailsContainer.append(showThumb);
-          seasonSelectionSelect.trigger('change');
-          $('#content').append(tvshowDetailsContainer);
-          if(getCookie('TVView')!=null && getCookie('TVView')!='banner'){
-          var view=getCookie('TVView');
-          switch(view) {
-            case 'poster':
-              togglePoster.trigger('click');
-              break;
-            case 'landscape':
-              toggleLandscape.trigger('click')
-              break;
+            }, this));
+  //            if(fanart!=null)
+  //            {
+  //              $('.contentContainer').css('background','url("'+this.getThumbnailPath(fanart)+'")').css('background-size','cover');
+  //            }
+            seasonSelectionSelect.bind('change', {tvshow: event.data.tvshow.tvshowid, seasons: data.result.seasons, element: seasonSelectionSelect}, jQuery.proxy(this.displaySeasonListings, this));
+            //showDetails.append($('<p>').html('<span class="heading">Episodes:</span> ' + episodeCount));
+            showDetails.append(seasonSelectionSelect);
+            tvshowDetailsContainer.append(showDetails);
+            tvshowDetailsContainer.append(showThumb);
+            seasonSelectionSelect.trigger('change');
+            $('#content').append(tvshowDetailsContainer);
+            if(getCookie('TVView')!=null && getCookie('TVView')!='banner'){
+            var view=getCookie('TVView');
+            switch(view) {
+              case 'poster':
+                togglePoster.trigger('click');
+                break;
+              case 'landscape':
+                toggleLandscape.trigger('click')
+                break;
+            }
           }
-        }
-          tvshowDetailsContainer.fadeIn();
-        }
-        $('#spinner').hide();
-      }, this), 'json');
+            tvshowDetailsContainer.fadeIn();
+          }
+          $('#spinner').hide();
+        }, this),
+        dataType: 'json'});
     } else {
       $('.contentContainer').hide();
       $('#tvShowDetails' + event.data.tvshow.tvshowid).show();
@@ -530,24 +725,29 @@ MediaLibrary.prototype = {
     //Update ActiveSeason
     this.tvActiveSeason = selectedVal;
     //Populate new listings
-    jQuery.post(JSON_RPC + '?GetTVSeasonEpisodes', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": { "properties": [ "title", "thumbnail","episode","plot","season"], "season" : ' + seasons[selectedVal].season + ', "tvshowid" : ' + event.data.tvshow + ' }, "id": 1}', jQuery.proxy(function(data) {
-      var episodeListingsContainer = $('<div>').addClass('episodeListingsContainer');
-      var episodeTable= $('<table>').addClass('seasonView').html('<thead><tr class="headerRow"><th class="thumbHeader">N&deg;</th><th>Title</th><th class="thumbHeader">Thumb</th><th class="thumbHeader">Details</th></tr></thead><tbody class="resultSet"></tbody>');
-      $.each($(data.result.episodes), jQuery.proxy(function(i, item) {
-        var episodeRow = $('<tr>').addClass('episodeRow').addClass('tr' + i % 2);
-        var episodePictureImg = $('<img>').bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this)).css('cursor','pointer');
-        episodePictureImg.attr('src', this.getThumbnailPath(item.thumbnail));
-        var episodePicture=$('<td>').addClass('episodeThumb').append(episodePictureImg).bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this));
-        var episodeNumber = $('<td>').addClass('episodeNumber').html(item.episode).bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this));
-        var episodeTitle = $('<td>').html(item.title).bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this));
-        var episodeDetails = $('<td class="info">').html('').bind('click',{episode:item}, jQuery.proxy(this.displayEpisodeDetails, this)).css('cursor','pointer');
-        episodeRow.append(episodeNumber).append(episodeTitle).append(episodePicture).append(episodeDetails);
-        episodeTable.append(episodeRow);
-      }, this));
-      episodeListingsContainer.append(episodeTable);
-      $(this.tvActiveShowContainer).append(episodeListingsContainer);
-    }, this), 'json');
-
+    jQuery.ajax({
+      type: 'POST',
+      contentType: 'application/json',
+      url: JSON_RPC + '?GetTVSeasonEpisodes',
+      data: '{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": { "properties": [ "title", "thumbnail","episode","plot","season"], "season" : ' + seasons[selectedVal].season + ', "tvshowid" : ' + event.data.tvshow + ' }, "id": 1}',
+      success: jQuery.proxy(function(data) {
+        var episodeListingsContainer = $('<div>').addClass('episodeListingsContainer');
+        var episodeTable= $('<table>').addClass('seasonView').html('<thead><tr class="headerRow"><th class="thumbHeader">N&deg;</th><th>Title</th><th class="thumbHeader">Thumb</th><th class="thumbHeader">Details</th></tr></thead><tbody class="resultSet"></tbody>');
+        $.each($(data.result.episodes), jQuery.proxy(function(i, item) {
+          var episodeRow = $('<tr>').addClass('episodeRow').addClass('tr' + i % 2);
+          var episodePictureImg = $('<img>').bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this)).css('cursor','pointer');
+          episodePictureImg.attr('src', this.getThumbnailPath(item.thumbnail));
+          var episodePicture=$('<td>').addClass('episodeThumb').append(episodePictureImg).bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this));
+          var episodeNumber = $('<td>').addClass('episodeNumber').html(item.episode).bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this));
+          var episodeTitle = $('<td>').html(item.title).bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this));
+          var episodeDetails = $('<td class="info">').html('').bind('click',{episode:item}, jQuery.proxy(this.displayEpisodeDetails, this)).css('cursor','pointer');
+          episodeRow.append(episodeNumber).append(episodeTitle).append(episodePicture).append(episodeDetails);
+          episodeTable.append(episodeRow);
+        }, this));
+        episodeListingsContainer.append(episodeTable);
+        $(this.tvActiveShowContainer).append(episodeListingsContainer);
+      }, this),
+      dataType: 'json'});
   },
 
   displayEpisodeDetails: function(event) {
@@ -587,9 +787,15 @@ MediaLibrary.prototype = {
   },
 
   playTVShow: function(event) {
-    jQuery.post(JSON_RPC + '?AddTvShowToPlaylist', '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "episodeid": ' + event.data.episode.episodeid + ' } }, "id": 1}', jQuery.proxy(function(data) {
-      this.hideOverlay();
-    }, this), 'json');
+    jQuery.ajax({
+      type: 'POST',
+      contentType: 'application/json',
+      url: JSON_RPC + '?AddTvShowToPlaylist',
+      data: '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "episodeid": ' + event.data.episode.episodeid + ' } }, "id": 1}',
+      success: jQuery.proxy(function(data) {
+        this.hideOverlay();
+      }, this),
+      dataType: 'json'});
   },
   hideOverlay: function(event) {
     if (this.activeCover) {
@@ -620,9 +826,15 @@ MediaLibrary.prototype = {
     }
   },
   playMovie: function(event) {
-    jQuery.post(JSON_RPC + '?PlayMovie', '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "movieid": ' + event.data.movie.movieid + ' } }, "id": 1}', jQuery.proxy(function(data) {
-      this.hideOverlay();
-    }, this), 'json');
+    jQuery.ajax({
+      type: 'POST',
+      contentType: 'application/json',
+      url: JSON_RPC + '?PlayMovie',
+      data: '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "movieid": ' + event.data.movie.movieid + ' } }, "id": 1}',
+      success: jQuery.proxy(function(data) {
+        this.hideOverlay();
+      }, this),
+      dataType: 'json'});
   },
   displayMovieDetails: function(event) {
     var movieDetails = $('<div>').attr('id', 'movie-' + event.data.movie.movieid).addClass('moviePopoverContainer');
@@ -654,13 +866,32 @@ MediaLibrary.prototype = {
     this.updatePlayButtonLocation();
   },
   playTrack: function(event) {
-    jQuery.post(JSON_RPC + '?ClearPlaylist', '{"jsonrpc": "2.0", "method": "Playlist.Clear", "params": { "playlistid": ' + this.playlists["audio"] + ' }, "id": 1}', jQuery.proxy(function(data) {
-      //check that clear worked.
-      jQuery.post(JSON_RPC + '?AddAlbumToPlaylist', '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "playlistid": ' + this.playlists["audio"] + ', "item": { "albumid": ' + event.data.album.albumid + ' } }, "id": 1}', jQuery.proxy(function(data) {
-        //play specific song in playlist
-        jQuery.post(JSON_RPC + '?PlaylistItemPlay', '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "playlistid": ' + this.playlists["audio"] + ', "position": '+ event.data.itmnbr + ' } }, "id": 1}', function() {}, 'json');
-      }, this), 'json');
-    }, this), 'json');
+    jQuery.ajax({
+      type: 'POST',
+      contentType: 'application/json',
+      url: JSON_RPC + '?ClearPlaylist',
+      data: '{"jsonrpc": "2.0", "method": "Playlist.Clear", "params": { "playlistid": ' + this.playlists["audio"] + ' }, "id": 1}',
+      success: jQuery.proxy(function(data) {
+        //check that clear worked.
+        jQuery.ajax({
+          type: 'POST',
+          contentType: 'application/json',
+          url: JSON_RPC + '?AddAlbumToPlaylist',
+          data: '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "playlistid": ' + this.playlists["audio"] + ', "item": { "albumid": ' + event.data.album.albumid + ' } }, "id": 1}',
+          success: jQuery.proxy(function(data) {
+            //play specific song in playlist
+            jQuery.ajax({
+              type: 'POST',
+              contentType: 'application/json',
+              url: JSON_RPC + '?PlaylistItemPlay',
+              data: '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "playlistid": ' + this.playlists["audio"] + ', "position": '+ event.data.itmnbr + ' } }, "id": 1}',
+              success: jQuery.proxy(function(data) {
+              }, this),
+              dataType: 'json'});
+          }, this),
+          dataType: 'json'});
+      }, this),
+      dataType: 'json'});
   },
   movieLibraryOpen: function() {
     this.resetPage();
@@ -669,28 +900,34 @@ MediaLibrary.prototype = {
     var libraryContainer = $('#movieLibraryContainer');
     if (!libraryContainer || libraryContainer.length == 0) {
       $('#spinner').show();
-      jQuery.post(JSON_RPC + '?GetMovies', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": { "limits": { "start": 0 }, "properties": [ "genre", "director", "trailer", "tagline", "plot", "plotoutline", "title", "originaltitle", "lastplayed", "runtime", "year", "playcount", "rating", "thumbnail", "file" ], "sort": { "method": "sorttitle", "ignorearticle": true } }, "id": 1}', jQuery.proxy(function(data) {
-        if (data && data.result && data.result.movies) {
-            libraryContainer = $('<div>');
-            libraryContainer.attr('id', 'movieLibraryContainer')
-                    .addClass('contentContainer');
-            $('#content').append(libraryContainer);
-        } else {
-          libraryContainer.html('');
-        }
-        //data.result.movies.sort(jQuery.proxy(this.movieTitleSorter, this));
-        $.each($(data.result.movies), jQuery.proxy(function(i, item) {
-          var floatableMovieCover = this.generateThumb('movie', item.thumbnail, item.title);
-          floatableMovieCover.bind('click', { movie: item }, jQuery.proxy(this.displayMovieDetails, this));
-          libraryContainer.append(floatableMovieCover);
-        }, this));
-        libraryContainer.append($('<div>').addClass('footerPadding'));
-        $('#spinner').hide();
-        libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
-        libraryContainer.trigger('scroll');
-        //$('#libraryContainer img').lazyload();
-        myScroll = new iScroll('movieLibraryContainer');
-      }, this), 'json');
+      jQuery.ajax({
+        type: 'POST',
+        contentType: 'application/json',
+        url: JSON_RPC + '?GetMovies',
+        data: '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": { "limits": { "start": 0 }, "properties": [ "genre", "director", "trailer", "tagline", "plot", "plotoutline", "title", "originaltitle", "lastplayed", "runtime", "year", "playcount", "rating", "thumbnail", "file" ], "sort": { "method": "sorttitle", "ignorearticle": true } }, "id": 1}',
+        success: jQuery.proxy(function(data) {
+          if (data && data.result && data.result.movies) {
+              libraryContainer = $('<div>');
+              libraryContainer.attr('id', 'movieLibraryContainer')
+                      .addClass('contentContainer');
+              $('#content').append(libraryContainer);
+          } else {
+            libraryContainer.html('');
+          }
+          //data.result.movies.sort(jQuery.proxy(this.movieTitleSorter, this));
+          $.each($(data.result.movies), jQuery.proxy(function(i, item) {
+            var floatableMovieCover = this.generateThumb('movie', item.thumbnail, item.title);
+            floatableMovieCover.bind('click', { movie: item }, jQuery.proxy(this.displayMovieDetails, this));
+            libraryContainer.append(floatableMovieCover);
+          }, this));
+          libraryContainer.append($('<div>').addClass('footerPadding'));
+          $('#spinner').hide();
+          libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
+          libraryContainer.trigger('scroll');
+          //$('#libraryContainer img').lazyload();
+          myScroll = new iScroll('movieLibraryContainer');
+        }, this),
+        dataType: 'json'});
     } else {
       libraryContainer.show();
       libraryContainer.trigger('scroll');
@@ -719,38 +956,44 @@ MediaLibrary.prototype = {
             .bind('click',{mode: 'landscape'},jQuery.proxy(this.togglePosterView,this));
       toggle.append(toggleBanner).append(' | ').append(togglePoster).append(' | ').append(toggleLandscape);
       this.toggle=toggle;
-      jQuery.post(JSON_RPC + '?GetTVShows', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "properties": ["genre", "plot", "title", "lastplayed", "episode", "year", "playcount", "rating", "thumbnail", "studio", "mpaa", "premiered"] }, "id": 1}', jQuery.proxy(function(data) {
-        if (data && data.result && data.result.tvshows) {
-            libraryContainer = $('<div>');
-            libraryContainer.append(toggle);
-            libraryContainer.attr('id', 'tvshowLibraryContainer')
-                    .addClass('contentContainer');
-            $('#content').append(libraryContainer);
-        } else {
-          libraryContainer.html('');
-        }
-        $.each($(data.result.tvshows), jQuery.proxy(function(i, item) {
-          var floatableTVShowCover = this.generateThumb('tvshow', item.thumbnail, item.title);
-          floatableTVShowCover.bind('click', { tvshow: item }, jQuery.proxy(this.displayTVShowDetails, this));
-          libraryContainer.append(floatableTVShowCover);
-        }, this));
-        libraryContainer.append($('<div>').addClass('footerPadding'));
-        $('#spinner').hide();
-        libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
-        libraryContainer.trigger('scroll');
-        myScroll = new iScroll('tvshowLibraryContainer');
-        if(getCookie('TVView')!=null && getCookie('TVView')!='banner'){
-          var view=getCookie('TVView');
-          switch(view) {
-            case 'poster':
-              togglePoster.trigger('click');
-              break;
-            case 'landscape':
-              toggleLandscape.trigger('click')
-              break;
+      jQuery.ajax({
+        type: 'POST',
+        contentType: 'application/json',
+        url: JSON_RPC + '?GetTVShows',
+        data: '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "properties": ["genre", "plot", "title", "lastplayed", "episode", "year", "playcount", "rating", "thumbnail", "studio", "mpaa", "premiered"] }, "id": 1}',
+        success: jQuery.proxy(function(data) {
+          if (data && data.result && data.result.tvshows) {
+              libraryContainer = $('<div>');
+              libraryContainer.append(toggle);
+              libraryContainer.attr('id', 'tvshowLibraryContainer')
+                      .addClass('contentContainer');
+              $('#content').append(libraryContainer);
+          } else {
+            libraryContainer.html('');
           }
-        }
-      }, this), 'json');
+          $.each($(data.result.tvshows), jQuery.proxy(function(i, item) {
+            var floatableTVShowCover = this.generateThumb('tvshow', item.thumbnail, item.title);
+            floatableTVShowCover.bind('click', { tvshow: item }, jQuery.proxy(this.displayTVShowDetails, this));
+            libraryContainer.append(floatableTVShowCover);
+          }, this));
+          libraryContainer.append($('<div>').addClass('footerPadding'));
+          $('#spinner').hide();
+          libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
+          libraryContainer.trigger('scroll');
+          myScroll = new iScroll('tvshowLibraryContainer');
+          if(getCookie('TVView')!=null && getCookie('TVView')!='banner') {
+            var view=getCookie('TVView');
+            switch(view) {
+              case 'poster':
+                togglePoster.trigger('click');
+                break;
+              case 'landscape':
+                toggleLandscape.trigger('click')
+                break;
+            }
+          }
+        }, this),
+        dataType: 'json'});
     } else {
       libraryContainer.prepend($(".toggle").detach()).show();
       libraryContainer.trigger('scroll');
@@ -765,7 +1008,14 @@ MediaLibrary.prototype = {
     }
   },
   startSlideshow: function(event) {
-    jQuery.post(JSON_RPC + '?StartSlideshow', '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "recursive" : "true", "random":"true", "path" : "' + this.replaceAll(event.data.directory.file, "\\", "\\\\") + '" } }, "id": 1}', null, 'json');
+    jQuery.ajax({
+      type: 'POST',
+      contentType: 'application/json',
+      url: JSON_RPC + '?StartSlideshow',
+      data: '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "recursive" : "true", "random": "true", "path" : "' + this.replaceAll(event.data.directory.file, "\\", "\\\\") + '" } }, "id": 1}',
+      success: jQuery.proxy(function(data) {
+      }, this),
+      dataType: 'json'});
   },
   showDirectory: function(event) {
     var directory = event.data.directory.file;
@@ -776,53 +1026,59 @@ MediaLibrary.prototype = {
     var libraryContainer = $('#pictureLibraryDirContainer' + directory);
     if (!libraryContainer || libraryContainer.length == 0) {
       $('#spinner').show();
-      jQuery.post(JSON_RPC + '?GetDirectory', '{"jsonrpc": "2.0", "method": "Files.GetDirectory", "params": { "media" : "pictures", "directory": "' + jsonDirectory + '" }, "id": 1}', jQuery.proxy(function(data) {
-        if (data && data.result && ( data.result.directories || data.result.files )) {
-          libraryContainer = $('<div>');
-          libraryContainer.attr('id', 'pictureLibraryDirContainer' + directory)
-                  .addClass('contentContainer');
-          $('#content').append(libraryContainer);
-          var breadcrumb = $('<div>');
-          var seperator = '/';
-          var item = '';
-          var directoryArray = directory.split(seperator);
-          jQuery.each(directoryArray, function(i,v) {
-            if(v != '') {
-              item += v + seperator;
-              //tmp.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));
-              breadcrumb.append($('<div>').text(' > ' + v).css('float','left').addClass('breadcrumb'));
-            }
-          });
-          libraryContainer.append(breadcrumb);
-          libraryContainer.append($('<div>').css('clear','both'));
-          if (data.result.files) {
-            $.each($(data.result.files), jQuery.proxy(function(i, item) {
-              if (item.filetype == "file")
-              {
-                var floatableImage = this.generateThumb('image', item.file, item.label);
-                libraryContainer.append(floatableImage);
-              }
-              else if (item.filetype == "directory")
-              {
-                var floatableShare = this.generateThumb('directory', item.thumbnail, item.label);
-                floatableShare.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));
-                //var slideshow = $('<div">');
-                //slideshow.html('<div>Slideshow</div>');
-                //slideshow.bind('click', { directory: item }, jQuery.proxy(this.startSlideshow, this));
-                //floatableShare.append(slideshow);
-                libraryContainer.append(floatableShare);
+      jQuery.ajax({
+        type: 'POST',
+        contentType: 'application/json',
+        url: JSON_RPC + '?GetDirectory',
+        data: '{"jsonrpc": "2.0", "method": "Files.GetDirectory", "params": { "media" : "pictures", "directory": "' + jsonDirectory + '" }, "id": 1}',
+        success: jQuery.proxy(function(data) {
+          if (data && data.result && ( data.result.directories || data.result.files )) {
+            libraryContainer = $('<div>');
+            libraryContainer.attr('id', 'pictureLibraryDirContainer' + directory)
+                    .addClass('contentContainer');
+            $('#content').append(libraryContainer);
+            var breadcrumb = $('<div>');
+            var seperator = '/';
+            var item = '';
+            var directoryArray = directory.split(seperator);
+            jQuery.each(directoryArray, function(i,v) {
+              if(v != '') {
+                item += v + seperator;
+                //tmp.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));
+                breadcrumb.append($('<div>').text(' > ' + v).css('float','left').addClass('breadcrumb'));
               }
-            }, this));
+            });
+            libraryContainer.append(breadcrumb);
+            libraryContainer.append($('<div>').css('clear','both'));
+            if (data.result.files) {
+              $.each($(data.result.files), jQuery.proxy(function(i, item) {
+                if (item.filetype == "file")
+                {
+                  var floatableImage = this.generateThumb('image', item.file, item.label);
+                  libraryContainer.append(floatableImage);
+                }
+                else if (item.filetype == "directory")
+                {
+                  var floatableShare = this.generateThumb('directory', item.thumbnail, item.label);
+                  floatableShare.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));
+                  //var slideshow = $('<div">');
+                  //slideshow.html('<div>Slideshow</div>');
+                  //slideshow.bind('click', { directory: item }, jQuery.proxy(this.startSlideshow, this));
+                  //floatableShare.append(slideshow);
+                  libraryContainer.append(floatableShare);
+                }
+              }, this));
+            }
+            libraryContainer.append($('<div>').addClass('footerPadding'));
+          } else {
+            libraryContainer.html('');
           }
-          libraryContainer.append($('<div>').addClass('footerPadding'));
-        } else {
-          libraryContainer.html('');
-        }
-        $('#spinner').hide();
-        libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
-        libraryContainer.trigger('scroll');
-        myScroll = new iScroll('#pictureLibraryDirContainer' + directory);
-      }, this), 'json');
+          $('#spinner').hide();
+          libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
+          libraryContainer.trigger('scroll');
+          myScroll = new iScroll('#pictureLibraryDirContainer' + directory);
+        }, this),
+        dataType: 'json'});
     } else {
       libraryContainer.show();
       libraryContainer.trigger('scroll');
@@ -835,26 +1091,32 @@ MediaLibrary.prototype = {
     var libraryContainer = $('#pictureLibraryContainer');
     if (!libraryContainer || libraryContainer.length == 0) {
       $('#spinner').show();
-      jQuery.post(JSON_RPC + '?GetSources', '{"jsonrpc": "2.0", "method": "Files.GetSources", "params": { "media" : "pictures" }, "id": 1}', jQuery.proxy(function(data) {
-        if (data && data.result && data.result.shares) {
-          libraryContainer = $('<div>');
-          libraryContainer.attr('id', 'pictureLibraryContainer')
-                          .addClass('contentContainer');
-          $('#content').append(libraryContainer);
-        } else {
-          libraryContainer.html('');
-        }
-        $.each($(data.result.shares), jQuery.proxy(function(i, item) {
-          var floatableShare = this.generateThumb('directory', item.thumbnail, item.label);
-          floatableShare.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));
-          libraryContainer.append(floatableShare);
-        }, this));
-        libraryContainer.append($('<div>').addClass('footerPadding'));
-        $('#spinner').hide();
-        libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
-        libraryContainer.trigger('scroll');
-        myScroll = new iScroll('#pictureLibraryContainer');
-      }, this), 'json');
+      jQuery.ajax({
+        type: 'POST',
+        contentType: 'application/json',
+        url: JSON_RPC + '?GetSources',
+        data: '{"jsonrpc": "2.0", "method": "Files.GetSources", "params": { "media" : "pictures" }, "id": 1}',
+        success: jQuery.proxy(function(data) {
+          if (data && data.result && data.result.shares) {
+            libraryContainer = $('<div>');
+            libraryContainer.attr('id', 'pictureLibraryContainer')
+                            .addClass('contentContainer');
+            $('#content').append(libraryContainer);
+          } else {
+            libraryContainer.html('');
+          }
+          $.each($(data.result.shares), jQuery.proxy(function(i, item) {
+            var floatableShare = this.generateThumb('directory', item.thumbnail, item.label);
+            floatableShare.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));
+            libraryContainer.append(floatableShare);
+          }, this));
+          libraryContainer.append($('<div>').addClass('footerPadding'));
+          $('#spinner').hide();
+          libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
+          libraryContainer.trigger('scroll');
+          myScroll = new iScroll('#pictureLibraryContainer');
+        }, this),
+        dataType: 'json'});
     } else {
       libraryContainer.show();
       libraryContainer.trigger('scroll');
index a9add9e..43ecdd2 100755 (executable)
@@ -44,6 +44,7 @@ NowPlayingManager.prototype = {
   updateState: function() {
     jQuery.ajax({
       type: 'POST',
+      contentType: 'application/json',
       url: JSON_RPC + '?UpdateState',
       data: '{"jsonrpc": "2.0", "method": "Player.GetActivePlayers", "id": 1}',
       timeout: 3000,
@@ -99,9 +100,12 @@ NowPlayingManager.prototype = {
       dataType: 'json'});
   },
   updatePlayer: function() {
-    jQuery.post(JSON_RPC + '?UpdatePlayer',
-      '{"jsonrpc": "2.0", "method": "Player.GetProperties", "params": { "playerid": ' + this.activePlayerId + ', "properties": [ "playlistid", "speed", "position", "totaltime", "time" ] }, "id": 1}',
-      jQuery.proxy(function(data) {
+    jQuery.ajax({
+      type: 'POST',
+      contentType: 'application/json',
+      url: JSON_RPC + '?UpdatePlayer',
+      data: '{"jsonrpc": "2.0", "method": "Player.GetProperties", "params": { "playerid": ' + this.activePlayerId + ', "properties": [ "playlistid", "speed", "position", "totaltime", "time" ] }, "id": 1}',
+      success: jQuery.proxy(function(data) {
         if (data && data.result)
         {
           this.playlistid = data.result.playlistid;
@@ -124,7 +128,8 @@ NowPlayingManager.prototype = {
           this.activeItemTimer = 1;
           setTimeout(jQuery.proxy(this.updateActiveItemDurationLoop, this), 1000);
         }
-      }, this), 'json');
+      }, this),
+      dataType: 'json'});
   },
   bindPlaybackControls: function() {
     $('#pbNext').bind('click', jQuery.proxy(this.nextTrack, this));
@@ -153,49 +158,73 @@ NowPlayingManager.prototype = {
   },
   nextTrack: function() {
     if (this.activePlayer) {
-      jQuery.post(JSON_RPC + '?SkipNext', '{"jsonrpc": "2.0", "method": "Player.GoNext", "params": { "playerid": ' + this.activePlayerId + ' }, "id": 1}', jQuery.proxy(function(data) {
-        if (data && data.result == 'OK') {
-          //this.updateAudioPlaylist(true);
-        }
-      }, this), 'json');
+      jQuery.ajax({
+        type: 'POST',
+        contentType: 'application/json',
+        url: JSON_RPC + '?SkipNext',
+        data: '{"jsonrpc": "2.0", "method": "Player.GoNext", "params": { "playerid": ' + this.activePlayerId + ' }, "id": 1}',
+        success: jQuery.proxy(function(data) {
+          if (data && data.result == 'OK') {
+            //this.updateAudioPlaylist(true);
+          }
+        }, this),
+        dataType: 'json'});
     }
   },
   prevTrack: function() {
     if (this.activePlayer) {
-      jQuery.post(JSON_RPC + '?SkipPrevious', '{"jsonrpc": "2.0", "method": "Player.GoPrevious", "params": { "playerid": ' + this.activePlayerId + ' }, "id": 1}', jQuery.proxy(function(data) {
-        if (data && data.result == 'OK') {
-          //this.updateAudioPlaylist(true);
-        }
-      }, this), 'json');
+      jQuery.ajax({
+        type: 'POST',
+        contentType: 'application/json',
+        url: JSON_RPC + '?SkipPrevious',
+        data: '{"jsonrpc": "2.0", "method": "Player.GoPrevious", "params": { "playerid": ' + this.activePlayerId + ' }, "id": 1}',
+        success: jQuery.proxy(function(data) {
+          if (data && data.result == 'OK') {
+            //this.updateAudioPlaylist(true);
+          }
+        }, this),
+        dataType: 'json'});
     }
   },
   stopTrack: function() {
     if (this.activePlayer) {
-      jQuery.post(JSON_RPC + '?Stop', '{"jsonrpc": "2.0", "method": "Player.Stop", "params": { "playerid": ' + this.activePlayerId + ' }, "id": 1}', jQuery.proxy(function(data) {
-        if (data && data.result == 'OK') {
-          this.playing = false;
-          this.paused = false;
-          this.trackBaseTime = 0;
-          this.trackDurationTime = 0;
-          this.showPlayButton();
-        }
-      }, this), 'json');
+      jQuery.ajax({
+        type: 'POST',
+        contentType: 'application/json',
+        url: JSON_RPC + '?Stop',
+        data: '{"jsonrpc": "2.0", "method": "Player.Stop", "params": { "playerid": ' + this.activePlayerId + ' }, "id": 1}',
+        success: jQuery.proxy(function(data) {
+          if (data && data.result == 'OK') {
+            this.playing = false;
+            this.paused = false;
+            this.trackBaseTime = 0;
+            this.trackDurationTime = 0;
+            this.showPlayButton();
+          }
+        }, this),
+        dataType: 'json'});
     }
   },
   playPauseTrack: function() {
     if (this.activePlayer) {
       var method = ((this.playing || this.paused) ? 'Player.PlayPause' : 'Playlist.Play');
-      jQuery.post(JSON_RPC + '?PlayPause', '{"jsonrpc": "2.0", "method": "' + method + '", "params": { "playerid": ' + this.activePlayerId + ' }, "id": 1}', jQuery.proxy(function(data) {
-        if (data && data.result) {
-          this.playing = data.result.speed != 0;
-          this.paused = data.result.speed == 0;
-          if (this.playing) {
-            this.showPauseButton();
-          } else {
-            this.showPlayButton();
+      jQuery.ajax({
+        type: 'POST',
+        contentType: 'application/json',
+        url: JSON_RPC + '?PlayPause',
+        data: '{"jsonrpc": "2.0", "method": "' + method + '", "params": { "playerid": ' + this.activePlayerId + ' }, "id": 1}',
+        success: jQuery.proxy(function(data) {
+          if (data && data.result) {
+            this.playing = data.result.speed != 0;
+            this.paused = data.result.speed == 0;
+            if (this.playing) {
+              this.showPauseButton();
+            } else {
+              this.showPlayButton();
+            }
           }
-        }
-      }, this), 'json');
+        }, this),
+        dataType: 'json'});
     }
   },
   showPauseButton: function() {
@@ -221,7 +250,15 @@ NowPlayingManager.prototype = {
   playPlaylistItem: function(sender) {
     var sequenceId = $(sender.currentTarget).attr('seq');
     if (!this.activePlaylistItem || (this.activePlaylistItem !== undefined && sequenceId != this.activePlaylistItem.seq)) {
-      jQuery.post(JSON_RPC + '?PlaylistItemPlay', '{"jsonrpc": "2.0", "method": "Player.GoTo", "params": { "playerid": ' + this.activePlayerId + ', "item": ' + sequenceId + '}, "id": 1}', function() {}, 'json');
+      jQuery.ajax({
+      type: 'POST',
+      contentType: 'application/json',
+      url: JSON_RPC + '?PlaylistItemPlay',
+      data: '{"jsonrpc": "2.0", "method": "Player.GoTo", "params": { "playerid": ' + this.activePlayerId + ', "item": ' + sequenceId + '}, "id": 1}',
+      success: jQuery.proxy(function(data) {
+      
+      }, this),
+      dataType: 'json'});
     }
     this.hidePlaylist();
   },
@@ -245,6 +282,7 @@ NowPlayingManager.prototype = {
   updateAudioPlaylist: function() {
     jQuery.ajax({
       type: 'POST',
+      contentType: 'application/json',
       url: JSON_RPC + '?updateAudioPlaylist',
       data: '{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "playlistid": ' + this.playlistid + ', "properties": [ "title", "album", "artist", "duration", "thumbnail" ] }, "id": 1}',
       success: jQuery.proxy(function(data) {
@@ -452,6 +490,7 @@ NowPlayingManager.prototype = {
   updateVideoPlaylist: function() {
     jQuery.ajax({
       type: 'POST',
+      contentType: 'application/json',
       url: JSON_RPC + '?updateVideoPlaylist',
       data: '{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "playlistid": ' + this.playlistid + ', "properties": ["title", "season", "episode", "plot", "runtime", "showtitle","thumbnail"] }, "id": 1}',
       success: jQuery.proxy(function(data) {
index ac9a69a..ce7f05a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<addon id="xbmc.addon" version="1.0" provider-name="Team XBMC">
+<addon id="xbmc.addon" version="11.0" provider-name="Team XBMC">
   <requires>
     <import addon="xbmc.core" version="0.1"/>
   </requires>
index 8907583..5fa71cb 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<addon id="xbmc.gui" version="3.00" provider-name="Team XBMC">
-  <backwards-compatibility abi="2.1"/>
+<addon id="xbmc.gui" version="3.0.1" provider-name="Team XBMC">
+  <backwards-compatibility abi="3.00"/>
   <requires>
     <import addon="xbmc.core" version="0.1"/>
   </requires>
index 5632135..fb56119 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<addon id="xbmc.json" version="2.0" provider-name="Team XBMC">
+<addon id="xbmc.json" version="4.0" provider-name="Team XBMC">
   <requires>
     <import addon="xbmc.core" version="0.1"/>
   </requires>
index c55488c..071b419 100755 (executable)
@@ -473,7 +473,6 @@ case $host in
      fi
      ARCH="arm-osx"
      use_arch="arm"
-     AC_SUBST(ARCH_DEFINES, "-D_ARMEL")
      PYTHON_VERSION="2.6"
      PYTHON_LDFLAGS="-L${prefix}/lib -lpython2.6"
      PYTHON_CPPFLAGS="-I${prefix}/include/python2.6"
@@ -510,7 +509,7 @@ case $host in
      use_texturepacker=no
      ARCH="arm"
      use_arch="arm"
-     AC_SUBST(ARCH_DEFINES, "-DTARGET_POSIX -DTARGET_LINUX -D_LINUX -D_ARMEL")
+     AC_SUBST(ARCH_DEFINES, "-DTARGET_POSIX -DTARGET_LINUX -D_LINUX")
      ;;
   *)
      AC_MSG_ERROR(unsupported host ($host))
@@ -1173,7 +1172,7 @@ if test "x$use_libcec" != "xno"; then
 
   # libcec is dyloaded, so we need to check for its headers and link any depends.
   if test "x$use_libcec" != "xno"; then
-    PKG_CHECK_MODULES([CEC],[libcec >= 1.1.0],,[use_libcec="no";AC_MSG_RESULT($libcec_disabled)])
+    PKG_CHECK_MODULES([CEC],[libcec >= 1.5.0],,[use_libcec="no";AC_MSG_RESULT($libcec_disabled)])
 
     if test "x$use_libcec" != "xno"; then
       INCLUDES="$INCLUDES $CEC_CFLAGS"
@@ -2145,7 +2144,7 @@ XB_CONFIG_MODULE([lib/libid3tag/libid3tag],[
   ./configure \
     CC="$CC" \
     CXX="$CXX" \
-    CFLAGS="$CFLAGS $ARCH_DEFINES" \ 
+    CFLAGS="$CFLAGS" \ 
     CXXFLAGS="$CXXFLAGS" \
     --prefix="${prefix}" --includedir="${includedir}" --libdir="${libdir}" --datadir="${datadir}" \
     --host=$host_alias \
index bc74e24..5bb6ccc 100644 (file)
   <string id="10019">设置-&gt;用户界面</string>
   <string id="10020">脚本</string>
   <string id="10021">网页浏览器</string>
-
+  <string id="10025">视频</string>
   <string id="10028">视频/播放列表</string>
+  <string id="10029">登录屏</string>
   <string id="10034">设置-&gt;用户配置</string>
+  <string id="10040">扩展功能浏览器</string>
 
   <string id="10100">"是/否"对话框</string>
   <string id="10101">进度对话框</string>
index d830898..232c30f 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <!--Language file translated with Team XBMC Translator-->
-<!--Date of translation: 12/09/2011-->
+<!--Date of translation: 03/07/2012-->
 <!--$Revision$-->
 <strings>
   <string id="0">程式</string>
   <string id="10019">設定 - 佈景主題</string>
   <string id="10020">腳本</string>
   <string id="10021">網路瀏覽器</string>
+  <string id="10025">視訊</string>
   <string id="10028">視訊/播放列表</string>
+  <string id="10029">登入畫面</string>
   <string id="10034">設定 - 使用者設定檔</string>
+  <string id="10040">附加元件瀏覽器</string>
   <string id="10100">確認對話框</string>
   <string id="10101">進度對話框</string>
   <string id="10210">正在尋找字幕…</string>
   <string id="16317">時間平滑 (不完全)</string>
   <string id="16318">時間/空間平滑(不完全)</string>
   <string id="16319">DXVA</string>
+  <string id="16324">軟體混合</string>
   <string id="16400">視訊後處理</string>
   <string id="17500">顯示休眠逾時</string>
   <string id="19000">切換到頻道</string>
   <string id="20326">重設螢幕校正值為 %s</string>
   <string id="20327">還原為預設值</string>
   <string id="20328">瀏覽目的</string>
+  <string id="20329">電影個別存放在和電影相同名稱的資料夾</string>
   <string id="20330">以資料夾名稱搜尋</string>
   <string id="20331">檔案</string>
   <string id="20332">以檔案或資料夾名稱來搜尋?</string>
   <string id="20455">電台</string>
   <string id="20456">設定電影劇照</string>
   <string id="20457">電影集</string>
+  <string id="20458">按同系列電影分組</string>
   <string id="21330">顯示隱藏檔案和目錄</string>
   <string id="21331">TuxBox 客戶端</string>
   <string id="21332">警告:目標 TuxBox 裝置在錄影模式!</string>
   <string id="21451">需要網際網路連線。</string>
   <string id="21452">取得更多...</string>
   <string id="21453">檔案系統 Root Filesystem</string>
+  <string id="21454">完整快取</string>
+  <string id="21455">只快取到足夠連續播放的資料量</string>
   <string id="21460">字幕位置</string>
   <string id="21461">固定</string>
   <string id="21462">影片底部</string>
   <string id="33008">儲存中</string>
   <string id="33009">複製中</string>
   <string id="33010">設定下載目錄</string>
+  <string id="33011">搜尋持續時間</string>
   <string id="33012">短</string>
   <string id="33013">長</string>
   <string id="33014">用 DVD player 代替預設播放機</string>
   <string id="33101">網站伺服器</string>
   <string id="33102">事件伺服器</string>
   <string id="33103">遠端通訊伺服器</string>
+  <string id="33200">偵測新的連線</string>
   <string id="34000">Lame</string>
   <string id="34001">Vorbis</string>
   <string id="34002">Wav</string>
   <string id="34110">7.1</string>
   <string id="34201">找不到下一個播放項目</string>
   <string id="34202">找不到前一個播放項目</string>
+  <string id="34300">Zeroconf啟動失敗</string>
+  <string id="34301">已經啟用蘋果的 Bonjour 服務了嗎?請查閱記錄以取得更多資訊。</string>
+  <string id="34400">視訊渲染</string>
+  <string id="34401">影像濾鏡/放大器初始化失敗,改用預設的雙線性放大</string>
+  <string id="34402">初始化音訊裝置失敗</string>
+  <string id="34403">檢查你的音訊設定</string>
   <string id="35000">周邊裝置</string>
   <string id="35001">通用 HID 裝置</string>
   <string id="35002">通用網路配接器</string>
   <string id="35503">供應商</string>
   <string id="35504">產品 ID</string>
   <string id="36000">Pulse-Eight CEC 配接器</string>
+  <string id="36002">切換到鍵盤命令</string>
+  <string id="36003">切換到遙控器命令</string>
+  <string id="36004">按下"使用者"按鈕命令</string>
+  <string id="36005">啟用命令模式切換</string>
   <string id="36006">無法開啟配接器</string>
   <string id="36007">開啟 XBMC 時打開這台電視</string>
   <string id="36008">當停止 XBMC 時關閉裝置</string>
   <string id="36014">如果關掉這台電視,讓這台電腦進入待機模式</string>
   <string id="36015">HDMI連接埠編號</string>
   <string id="36016">已連接</string>
+  <string id="36017">找到配接器,但無法取得 libcec</string>
   <string id="36018">使用這個電視的語言設定</string>
-</strings>
\ No newline at end of file
+</strings>
index 898806d..f226720 100644 (file)
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <!--Language file translated with Team XBMC Translator-->
 <!--Translator: ezechiel1917-->
-<!--Date of translation: 26/09/2010-->
-<!--updated 3/12/2011 by mirek-->
+<!--Date of translation: 26.09.2010-->
+<!--Updated 03.12.2011 by mirek-->
+<!--Updated 06.01.2012 by babča-->
 <strings>
   <string id="0">Programy</string>
   <string id="1">Obrázky</string>
@@ -56,7 +57,7 @@
   <string id="60">říj</string>
   <string id="61">lis</string>
   <string id="62">pro</string>
-  
+
   <string id="71">S</string>
   <string id="72">SSV</string>
   <string id="73">SV</string>
 
   <string id="13100">Filtr blikání</string>
   <string id="13101">Ponechat nastavení ovladače (vyžadován restart)</string>
-  
+
   <string id="13105">Vertikální synchronizace obrazovky (V-Sync)</string>
   <string id="13106">Vypnuto</string>
   <string id="13107">Zapnuto při přehrávání videa</string>
 
   <string id="13200">Profily</string>
   <string id="13201">Odstranit profil '%s'?</string>
-  
+
   <string id="13204">Naposledy načtený profil:</string>
   <string id="13205">Neznámý</string>
   <string id="13206">Přepsat</string>
-  
+
   <string id="13208">Budík</string>
   <string id="13209">Interval budíku (v min)</string>
   <string id="13210">Budík nastaven na %im</string>
   <string id="13359">Přiřadit ikonu interpreta</string>
   <string id="13360">Automaticky generovat náhledy</string>
   <string id="13361">Povolit úpravu hlasu</string>
-  
+
   <string id="13375">Povolit zařízení</string>
   <string id="13376">Hlasitost</string>
   <string id="13377">Výchozí nastavení zobrazení</string>
   <string id="14080">Časové pásmo</string>
   <string id="14081">Soubory a složky</string>
   <string id="14082">Zobrazovat EXIF informace o obrázku</string>
-  <string id="14083">Upřednostňovat režim celé obrazovky na velikost okna</string>
+  <string id="14083">Otevřít v okně přes celou obrazovku namísto pravého fullscreen režimu</string>
   <string id="14084">Přidávat skladby do fronty při jejich výběru</string>
   <string id="14085">Automaticky přehrávat Audio CD</string>
   <string id="14086">Přehrávání</string>
   <string id="16039">Off</string>
   <string id="16040">Auto</string>
   <string id="16041">On</string>
-  
+
   <string id="16100">Všechna videa</string>
   <string id="16101">Nezhlédnuté</string>
   <string id="16102">Zhlédnuté</string>
   <string id="16322">Spline36</string>
   <string id="16323">Spline36 optimized</string>
   <string id="16324">Software Blend</string>
-  
+
   <string id="16400">Post-processing</string>
 
   <string id="17500">Zobrazovat odpočet do uspání</string>
   <string id="20069">Nemohu vytvořit složku</string>
   <string id="20070">Složka profilu</string>
   <string id="20071">Chcete nastavit výchozí zdroje médií</string>
-  <string id="20072">Ujistěte se, zda je do vybráné složky možnost zápisu</string>
+  <string id="20072">Ujistěte se, zda je do vybrané složky možnost zápisu</string>
   <string id="20073">a nový název složky v pořádku</string>
   <string id="20074">Přístupnost</string>
   <string id="20075">Zadejte hlavní kód rodičovského zámku</string>
   <string id="21366">Složka s titulky</string>
   <string id="21367">Video a alternativní složka s titulky</string>
   <string id="21368">Přepsat písmo v ASS/SSA titulcích</string>
-  
+
   <string id="21369">Povolit kurzor myši</string>
   <string id="21370">Přehrávat zvuky při přehrávání multimediálních souborů</string>
   <string id="21371">Náhledy</string>
   <string id="21805">Rozlišení</string>
   <string id="21806">Komentář</string>
   <string id="21807">Barva/ČB</string>
-  <string id="21808">Zpracování Jpeg</string>
+  <string id="21808">Zpracování JPEG</string>
 
   <string id="21820">Datum/Čas</string>
   <string id="21821">Popis</string>
   <string id="21822">Značka fotoaparátu</string>
   <string id="21823">Model fotoaparátu</string>
-  <string id="21824">Exif komentář</string>
+  <string id="21824">EXIF komentář</string>
   <string id="21825">Firmware</string>
   <string id="21826">Clona</string>
   <string id="21827">Ohnisko objektivu</string>
   <string id="21892">Hudební nástroje</string>
   <string id="21893">Datum narození</string>
   <string id="21894">Datum seskupení</string>
-  <string id="21895">Tématické zaměření</string>
+  <string id="21895">Tematické zaměření</string>
   <string id="21896">Datum rozpuštění</string>
   <string id="21897">Datum úmrtí</string>
   <string id="21898">Aktivní v letech</string>
   <string id="35502">Název</string>
   <string id="35503">Výrobce</string>
   <string id="35504">ID produktu</string>
-  
+
   <string id="36000">Pulse-Eight CEC adaptér</string>
   <string id="36001">Pulse-Eight Nyxboard</string>
   <string id="36002">Switch to keyboard side command</string>
index 58d0003..8452a88 100644 (file)
   <string id="13005">Computer uitschakelen</string>
 
   <string id="13008">Standaard afsluitmethode</string>
-  <string id="13009">XBMC afsluiten</string>
+  <string id="13009">Afsluiten</string>
   <string id="13010">Sluimerstand</string>
   <string id="13011">Slaapstand</string>
   <string id="13012">Stoppen</string>
   <string id="21414">Standaard tv-serie scraper</string>
   <string id="21415">Standaard muziekvideo scraper</string>
   <string id="21416">Alternatieven toestaan op basis van originele scraper taal</string>
-  <string id="21417">- Instellingen schermbeveiliging</string>
+  <string id="21417">- Instellingen</string>
   <string id="21418">Meertalig</string>
   <string id="21419">Geen scrapers beschikbaar</string>
   <string id="21420">Waarde gelijk aan</string>
   <string id="36004">Druk op "user" knop commando</string>
   <string id="36005">Schakel commando's in bij het wisselen van kant</string>
   <string id="36006">Kon de adapter niet openen</string>
-  <string id="36007">Schakel de TV in bij het opstarten van XBMC</string>
+  <string id="36007">Schakel apparatuur in bij het opstarten van XBMC</string>
   <string id="36008">Schakel apparatuur uit bij het stoppen van XBMC</string>
   <string id="36009">Schakel app. uit zolang de schermbeveiliging actief is</string>
   <string id="36010"></string>
-  <string id="36011">Kon de CEC poort niet detecteren. Stel het manueel in.</string>
-  <string id="36012">Kon de CEC adapter niet detecteren.</string>
-  <string id="36013">Versie %d van de libcec interface version wordt niet ondersteund door XBMC (> %d)</string>
+  <string id="36011">Kon de COM poort niet detecteren. Stel het manueel in.</string>
+  <string id="36012">Kon de CEC adapter niet initialiseren.</string>
+  <string id="36013">Versie %d van de libCEC interface version wordt niet ondersteund door XBMC (> %d)</string>
   <string id="36014">Zet XBMC in standby wanneer de TV uitgeschakeld wordt</string>
   <string id="36015">HDMI poort nummer</string>
   <string id="36016">Verbonden</string> <!-- max. 13 characters -->
-  <string id="36017">Adapter gevonden, maar libcec is niet beschikbaar</string>
+  <string id="36017">Adapter gevonden, maar libCEC is niet beschikbaar</string>
   <string id="36018">Gebruik de taalinstelling van de TV</string>
+  <string id="36019">Verbonden met HDMI apparaat</string>
+  <string id="36020">Maak XBMC de actieve bron bij het opstarten</string>
+  <string id="36021">Physiek adres (overschrijft HDMI poort)</string>
+  <string id="36022">COM poort (laat leeg, tenzij noodzakelijk)</string>
+  <string id="36023">Configuratie aangepast</string>
+  <string id="36024">Kon de nieuwe configuratie niet instellen. Controleer de instellingen.</string>
+  <string id="36025">Verstuur 'inactieve bron' commando bij het stoppen</string>
 </strings>
\ No newline at end of file
index ca2ac4d..cbfe652 100644 (file)
   <string id="787">Interface disabled</string>
   <string id="788">Network interface disabled successfully.</string>
   <string id="789">Wireless network name (ESSID)</string>
-
+  <string id="790">Remote control</string>
   <string id="791">Allow programs on this system to control XBMC</string>
   <string id="792">Port</string>
   <string id="793">Port range</string>
   <string id="1256">Ping interval</string>
   <string id="1257">Would you like to connect to the auto-detected system?</string>
 
+  <string id="1259">Zeroconf</string>
   <string id="1260">Announce these services to other systems via Zeroconf</string>
   <string id="1270">Allow XBMC to receive AirPlay content</string>
   <string id="1271">Device name</string>
   <string id="1272">- Use password protection</string>
+  <string id="1273">AirPlay</string>
 
   <string id="1300">Custom audio device</string>
   <string id="1301">Custom passthrough device</string>
   <string id="20184">Rotate pictures using EXIF information</string>
   <string id="20185">Use poster view styles for TV shows</string>
   <string id="20186">Please wait</string>
+  <string id="20187">UPnP</string>
 
   <string id="20189">Enable auto scrolling for plot &amp; review</string>
   <string id="20190">Custom</string>
   <string id="35006">Device removed</string>
   <string id="35007">Keymap to use for this device</string>
   <string id="35008">Keymap enabled</string>
+  <string id="35009">Do not use the custom keymap for this device</string>
 
   <string id="35500">Location</string>
   <string id="35501">Class</string>
   <string id="36004">Press "user" button command</string>
   <string id="36005">Enable switch side commands</string>
   <string id="36006">Could not open the adapter</string>
-  <string id="36007">Power on the TV when starting XBMC</string>
-  <string id="36008">Power off devices when stopping XBMC</string>
+  <string id="36007">Devices to power on when starting XBMC</string>
+  <string id="36008">Devices to power off when stopping XBMC</string>
   <string id="36009">Put devices in standby mode when activating screensaver</string>
   <string id="36010"></string>
   <string id="36011">Could not detect the CEC port. Set it up manually.</string>
-  <string id="36012">Could not detect the CEC adapter.</string>
-  <string id="36013">Unsupported libcec interface version. %d is greater than the version XBMC supports (%d)</string>
+  <string id="36012">Could not initialise the CEC adapter. Check your settings.</string>
+  <string id="36013">Unsupported libCEC interface version. %d is greater than the version XBMC supports (%d)</string>
   <string id="36014">Put this PC in standby mode when the TV is switched off</string>
   <string id="36015">HDMI port number</string>
   <string id="36016">Connected</string> <!-- max. 13 characters -->
-  <string id="36017">Adapter found, but libcec is not available</string>
+  <string id="36017">Adapter found, but libCEC is not available</string>
   <string id="36018">Use the TV's language setting</string>
+  <string id="36019">Connected to HDMI device</string>
+  <string id="36020">Make XBMC the active source when starting</string>
+  <string id="36021">Physical address (overrules HDMI port)</string>
+  <string id="36022">COM port (leave empty unless needed)</string>
+  <string id="36023">Configuration updated</string>
+  <string id="36024">Failed to set the new configuration. Please check your settings.</string>
+  <string id="36025">Send 'inactive source' command when stopping XBMC</string>
 </strings>
index 8200a2e..22c0631 100644 (file)
   <string id="170">Säädä näytön päivitysnopeus elokuvaan sopivaksi</string>
 
   <string id="172">Julkaistu</string>
-  <string id="173">4:3 videoiden näyttömuoto</string>
+  <string id="173">4:3-videoiden näyttömuoto</string>
 
   <string id="175">Musiikkityyli</string>
   <string id="176">Tyylilaji</string>
   <string id="251">Valitse kohdehakemisto</string>
   <string id="252">Syötä stereoääni kaikille kaiuttimille</string>
   <string id="253">Kanavien määrä</string>
-  <string id="254">- DTS yhteensopiva vastaanotin</string>
+  <string id="254">- DTS-yhteensopiva vastaanotin</string>
   <string id="255">CD-tietokanta</string>
   <string id="256">Noudetaan CD-tietoja</string>
   <string id="257">Virhe</string>
   <string id="296">Poista kirjanmerkit</string>
   <string id="297">Äänen ajoitus</string>
   <string id="298">Kirjanmerkit</string>
-  <string id="299">- AAC yhteensopiva vastaanotin</string>
-  <string id="300">- MP1 yhteensopiva vastaanotin</string>
-  <string id="301">- MP2 yhteensopiva vastaanotin</string>
-  <string id="302">- MP3 yhteensopiva vastaanotin</string>
+  <string id="299">- AAC-yhteensopiva vastaanotin</string>
+  <string id="300">- MP1-yhteensopiva vastaanotin</string>
+  <string id="301">- MP2-yhteensopiva vastaanotin</string>
+  <string id="302">- MP3-yhteensopiva vastaanotin</string>
   <string id="303">Viive</string>
   <string id="304">Kieli</string>
   <string id="305">Käytössä</string>
   <string id="336">Kuvataajuuden muunto</string>
   <string id="337">Äänilähtö</string>
   <string id="338">Analoginen</string>
-  <string id="339">Optinen/Koaksiaali</string>
+  <string id="339">Optinen/koaksiaali</string>
   <string id="340">Eri esittäjiä</string>
   <string id="341">Toista levy</string>
   <string id="342">Elokuvat</string>
   <string id="361">Kaikkien kuvaesitys</string>
   <string id="362">Näytönsäästäjän läpinäkyvyys</string>
   <string id="363">Järjestä: Tiedostonimi</string>
-  <string id="364">- Dolby Digital (AC3) yhteensopiva vastaanotin</string>
+  <string id="364">- Dolby Digital (AC3) -yhteensopiva vastaanotin</string>
   <string id="365">Järjestä: Nimi</string>
   <string id="366">Järjestä: Vuosi</string>
   <string id="367">Järjestä: Arvosana</string>
   <string id="543">DVD</string>
   <string id="544">Mediatiedot</string>
   <string id="545">Äänen ulostulo</string>
-  <string id="546">Äänen ulostulon laite</string>
+  <string id="546">Pakatun äänen ulostulo</string>
   <string id="547">Esittäjästä ei ole tietoja</string>
   <string id="548">Yhdistä monikanavaiset äänet stereoksi</string>
 
   <string id="633">Leveyden zoomaus</string>
   <string id="634">Venytä kokoon 16:9</string>
   <string id="635">Alkuperäinen koko</string>
-  <string id="636">Oma asetus</string>
+  <string id="636">Mukautettu</string>
   <string id="637">Tasonkorjaus</string>
   <string id="638">Tasonkorjaus-tilan säädöt</string>
   <string id="639">Käytä kappaletasoja</string>
   <string id="788">Verkkoliitäntä poistettu käytöstä.</string>
   <string id="789">Langattoman verkon nimi (ESSID)</string>
 
-  <string id="791">Tämän järjestelmän ohjelmat voi ohjata XBMC:aa</string>
+  <string id="791">Salli tämän järjestelmän ohjelmien ohjata XBMC:iä</string>
   <string id="792">Portti</string>
   <string id="793">Porttialue</string>
-  <string id="794">Muiden järjestelmien ohjelmat voi ohjata XBMC:aa</string>
+  <string id="794">Salli muiden järjestelmien ohjelmien ohjata XBMC:iä</string>
   <string id="795">Kertatapahtuman viive (ms)</string>
   <string id="796">Jatkuvan toiston viive (ms)</string>
   <string id="797">Yhteyksien enimmäismäärä</string>
   <string id="798">Internet-yhteys</string>
 
   <string id="850">Syötetty portin arvo on sopimaton</string>
-  <string id="851">Portti oltava väliltä 1-65535</string>
-  <string id="852">Portti oltava väliltä 1024-65535</string>
+  <string id="851">Portin oltava väliltä 1-65535</string>
+  <string id="852">Portin oltava väliltä 1024-65535</string>
 
   <string id="998">Lisää musiikkia...</string>
   <string id="999">Lisää videoita...</string>
   <string id="1256">Pingauksen väli</string>
   <string id="1257">Yhdistetäänkö havaittuun järjestelmään?</string>
 
-  <string id="1260">Julkista nämä palvelut toisiin järjestelmiin Zeroconf publishing:in kautta</string>
-  <string id="1270">Salli XBMC:n vastaanottaa AirPlay sisältöä</string>
+  <string id="1260">Julkista nämä palvelut toisiin järjestelmiin Zeroconf-julkaisujärjestelmän kautta</string>
+  <string id="1270">Salli XBMC:n vastaanottaa AirPlay-sisältöä</string>
   <string id="1271">Laitteen nimi</string>
   <string id="1272">- Käytä salasanaa</string>
 
-  <string id="1300">Valinnainen äänilaite</string>
-  <string id="1301">Valinnainen äänen ulostulon laite</string>
+  <string id="1300">Mukautettu äänilaite</string>
+  <string id="1301">Mukautettu pakatun äänen laite</string>
 
   <string id="1396">kasaantuvaa</string>
   <string id="1397">ja</string>
   <string id="10019">Asetukset - Käyttöliittymä</string>
   <string id="10020">Skriptit</string>
   <string id="10021">Nettiselain</string>
-
+  <string id="10025">Videot</string>
   <string id="10028">Videot/Toistolista</string>
+  <string id="10029">Kirjautumisikkuna</string>
   <string id="10034">Asetukset - Profiilit</string>
+  <string id="10040">Lisäosaselain</string>
 
   <string id="10100">Kyllä/Ei -dialogi</string>
   <string id="10101">Tila -dialogi</string>
   <string id="13119">Sinc</string>
   <string id="13120">VDPAU</string>
   <string id="13121">VDPAU HQ skaalaustaso</string>
-  <string id="13122">VDPAU studiotasoinen värimuunnos</string>
+  <string id="13122">VDPAU:n studiotasoinen värimuunnos</string>
 
   <string id="13130">Tyhjennä muut näytöt</string>
   <string id="13131">Ei käytössä</string>
   <string id="13414">Sisällytä vain kokoelmilla olevat esittäjät</string>
   <string id="13415">Renderöintimenetelmä</string>
   <string id="13416">Automaattinen tunnistus</string>
-  <string id="13417">Basic Shaders (ARB)</string>
-  <string id="13418">Advanced Shaders (GLSL)</string>
+  <string id="13417">Yksinkertaiset varjostimet (ARB)</string>
+  <string id="13418">Edistyneet varjostimet (GLSL)</string>
   <string id="13419">Ohjelmallinen</string>
   <string id="13420">Poista turvallisesti</string>
   <string id="13421">VDPAU</string>
   <string id="13422">Aloita kuvaesitys tästä</string>
   <string id="13423">Muista tämä polku</string>
-  <string id="13424">Pixel buffer objects käytössä</string>
+  <string id="13424">Käytä pikselipuskuriobjekteja</string>
   <string id="13425">Laitteistopohjainen kiihdytys (VDPAU)</string>
   <string id="13426">Laitteistopohjainen kiihdytys (VAAPI)</string>
   <string id="13427">Laitteistopohjainen kiihdytys (DXVA2)</string>
 
   <string id="13500">A/V-tahdistusmenetelmä</string>
   <string id="13501">Äänen kello</string>
-  <string id="13502">Videon kello (poista/lisää ääntä)</string>
+  <string id="13502">Videon kello (poista/kopioi ääninäytteitä)</string>
   <string id="13503">Videon kello (äänen uudelleennäytteistys)</string>
-  <string id="13504">Maksimi uudelleennäytteistys (%)</string>
+  <string id="13504">Maksimiuudelleennäytteistys (%)</string>
   <string id="13505">Uudellennäytteistyksen laatu</string>
-  <string id="13506">Matala(nopea)</string>
+  <string id="13506">Matala (nopea)</string>
   <string id="13507">Keski</string>
   <string id="13508">Korkea</string>
-  <string id="13509">Todella korkea(hidas)</string>
+  <string id="13509">Todella korkea (hidas)</string>
   <string id="13510">Tahdista toisto näyttöön</string>
 
   <string id="13550">Pysäytä toisto virkistystaajuuden vaihtamisen ajaksi</string>
   <string id="13600">Apple remote -kauko-ohjain</string>
 
   <string id="13602">XBMC voidaan käynnistää kauko-ohjaimella</string>
-  <string id="13603">Jaksottainen viive</string>
+  <string id="13603">Jaksoittainen viive</string>
 
   <string id="13610">Ei käytössä</string>
   <string id="13611">Normaali</string>
   <string id="14038">Verkkoasetuksia muutettu</string>
   <string id="14039">XBMC täytyy käynnistää uudelleen, jotta uudet</string>
   <string id="14040">asetukset tulevat käyttöön. Käynnistetäänkö uudelleen nyt?</string>
-  <string id="14041">Internet-yhteyden kaistan rajoitus</string>
+  <string id="14041">Internet-yhteyden kaistanrajoitus</string>
 
   <string id="14043">- Sammuta kesken toiston</string>
   <string id="14044">%i min</string>
   <string id="16309">Sinc (ohjelmallinen)</string>
   <string id="16310">Temporal</string>
   <string id="16311">Temporal/Spatial</string>
-  <string id="16312">(VDPAU)Kohinanvähennys</string>
-  <string id="16313">(VDPAU)Terävyys</string>
+  <string id="16312">(VDPAU) Kohinanvähennys</string>
+  <string id="16313">(VDPAU) Terävyys</string>
   <string id="16314">Inverse Telecine</string>
   <string id="16315">Lanczos3 optimoitu</string>
   <string id="16316">Automaattinen</string>
   <string id="20326">Tämä palauttaa asettamasi %s kalibroinnin arvot</string>
   <string id="20327">oletusarvoiksi</string>
   <string id="20328">Valitse kohdesijainti</string>
-
+  <string id="20329">Elokuvan tiedostot ovat eri kansioissa, jotka ovat nimetty elokuvan mukaan</string>
   <string id="20330">Hae kansionimiä</string>
   <string id="20331">Tiedostonimet</string>
   <string id="20332">Käytetäänkö haettaessa tiedosto- vai kansionimiä?</string>
   <string id="20416">Ensiesitys</string>
   <string id="20417">Käsikirjoittaja</string>
   <string id="20418"></string>
-  <string id="20419">Näytä metatiedot "Tiedostot"-näkymässä</string>
+  <string id="20419">Korvaa tiedostojen nimet kirjaston sisältämillä nimillä</string>
 
   <string id="20420">Ei koskaan</string>
   <string id="20421">Jos samalta tuotantokaudelta</string>
   <string id="20455">Kuuntelijat</string>
   <string id="20456">Aseta elokuvasetin fanitaide</string>
   <string id="20457">Elokuvasetti</string>
+  <string id="20458">Ryhmittele elokuvat settien mukaan</string>
   <!-- up to 21329 is reserved for the video db !! !-->
 
   <string id="21330">Näytä piilotetut tiedostot ja kansiot</string>
   <string id="21451">Internet-yhteys vaaditaan.</string>
   <string id="21452">Nouda lisää...</string>
   <string id="21453">Juurikansio</string>
+  <string id="21454">Välimuisti täynnä</string>
+  <string id="21455">Välimuisti täyttyi ennen toistoon tarvittavaa määrää</string>
 
   <string id="21460">Tekstityksen sijainti</string>
   <string id="21461">Kiinteä</string>
   <string id="22004">Viivästetty: %2.3fs</string>
   <string id="22005">Aiennettu: %2.3fs</string>
   <string id="22006">Tekstityksen ajoitus</string>
-  <string id="22007">OpenGL-valmistaja:</string>
-  <string id="22008">OpenGL-renderoija:</string>
+  <string id="22007">OpenGL-toimittaja:</string>
+  <string id="22008">OpenGL-renderöijä:</string>
   <string id="22009">OpenGL-versio:</string>
   <string id="22010">GPU:n lämpötila:</string>
   <string id="22011">CPU:n lämpötila:</string>
   <string id="22012">Kokonaismuisti</string>
   <string id="22013">Profiilin tiedot</string>
-  <string id="22014">Himmennä jos videon toisto keskeytetään</string>
+  <string id="22014">Himmennä keskeytettäessä videon toisto</string>
   <string id="22015">Kaikki tallennukset</string>
   <string id="22016">Nimet</string>
   <string id="22017">Ryhmät</string>
   <string id="22020">Ohjelmaopas</string>
   <string id="22021">Sallittu kuvasuhdevirhe mustien palkkien minimoimiseksi</string>
   <string id="22022">Näytä videotiedostot listauksissa</string>
-  <string id="22023">DirectX valmistaja:</string>
-  <string id="22024">Direct3D versio:</string>
+  <string id="22023">DirectX-toimittaja:</string>
+  <string id="22024">Direct3D-versio:</string>
 
   <!-- strings 22030 thru 22060 reserved for karaoke -->
   <string id="22030">Kirjasin</string>
   <string id="33102">Tapahtumapalvelin</string>
   <string id="33103">Etäviestipalvelin</string>
 
+  <string id="33200">Uusi yhteys tunnistettu</string>
+
   <!-- translators: no need to add these to your language files -->
   <string id="34000">Lame</string>
   <string id="34001">Vorbis</string>
   <string id="34201">Seuraavaa kohdetta ei löydy</string>
   <string id="34202">Edellistä kohdetta ei löydy</string>
 
+  <string id="34300">Zeroconf-palvelua ei voitu käynnistää</string>
+  <string id="34301">Onko Applen Bonjour -palvelu asennettu? Katso lokitiedostosta lisätietoja.</string>
+
+  <string id="34400">Videon renderöintitapa</string>
+  <string id="34401">Ei voitu käyttää videon suodatin/skaalaus -asetuksia, otetaan käyttöön bilineaarinen skaalausmenetelmä</string>
+  <string id="34402">Äänilaitteen alustaminen epäonnistui</string>
+  <string id="34403">Tarkista ääniasetukset</string>
+
   <string id="35000">Oheislaitteet</string>
 
   <string id="35001">Yleinen HID-laite</string>
index 4d34279..0760cb3 100644 (file)
@@ -19,7 +19,7 @@
   <regions>
     <region name="France" locale="FR">
       <dateshort>DD/MM/YYYY</dateshort>
-      <datelong>DDDD, D MMMM YYYY</datelong>
+      <datelong>DDDD D MMMM YYYY</datelong>
       <time symbolAM="" symbolPM="">H:mm:ss</time>
       <tempunit>C</tempunit>
       <speedunit>kmh</speedunit>
@@ -28,7 +28,7 @@
 
     <region name="Belgique" locale="BE">
       <dateshort>DD/MM/YYYY</dateshort>
-      <datelong>DDDD, D MMMM YYYY</datelong>
+      <datelong>DDDD D MMMM YYYY</datelong>
       <time symbolAM="" symbolPM="">H:mm:ss</time>
       <tempunit>C</tempunit>
       <speedunit>kmh</speedunit>
@@ -37,7 +37,7 @@
 
     <region name="Luxembourg" locale="LU">
       <dateshort>DD/MM/YYYY</dateshort>
-      <datelong>DDDD, D MMMM YYYY</datelong>
+      <datelong>DDDD D MMMM YYYY</datelong>
       <time symbolAM="" symbolPM="">H:mm:ss</time>
       <tempunit>C</tempunit>
       <speedunit>kmh</speedunit>
@@ -46,7 +46,7 @@
 
     <region name="Suisse" locale="CH">
       <dateshort>DD/MM/YYYY</dateshort>
-      <datelong>DDDD, D MMMM YYYY</datelong>
+      <datelong>DDDD D MMMM YYYY</datelong>
       <time symbolAM="" symbolPM="">H:mm:ss</time>
       <tempunit>C</tempunit>
       <speedunit>kmh</speedunit>
@@ -55,7 +55,7 @@
 
     <region name="Principauté de Monaco" locale="MC">
       <dateshort>DD/MM/YYYY</dateshort>
-      <datelong>DDDD, D MMMM YYYY</datelong>
+      <datelong>DDDD D MMMM YYYY</datelong>
       <time symbolAM="" symbolPM="">H:mm:ss</time>
       <tempunit>C</tempunit>
       <speedunit>kmh</speedunit>
@@ -64,7 +64,7 @@
 
     <region name="Canada" locale="CA">
       <dateshort>DD/MM/YYYY</dateshort>
-      <datelong>DDDD, D MMMM YYYY</datelong>
+      <datelong>DDDD D MMMM YYYY</datelong>
       <time symbolAM="" symbolPM="">H:mm:ss</time>
       <tempunit>C</tempunit>
       <speedunit>kmh</speedunit>
index 20a403c..64b3a5a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!--$Revision$-->
+<!--Based on English 0ee1ef09238e4d913cf6c47fa18138c3654cd33e (08.02.2012)-->
 <strings>
   <string id="0">Programmes</string>
   <string id="1">Images</string>
@@ -11,7 +11,7 @@
   <string id="7">Fichiers</string>
   <string id="8">Météo</string>
   <string id="9">Xbmc media center</string>
-  
+
   <string id="11">Lundi</string>
   <string id="12">Mardi</string>
   <string id="13">Mercredi</string>
@@ -19,7 +19,7 @@
   <string id="15">Vendredi</string>
   <string id="16">Samedi</string>
   <string id="17">Dimanche</string>
-  
+
   <string id="21">Janvier</string>
   <string id="22">Février</string>
   <string id="23">Mars</string>
@@ -32,7 +32,7 @@
   <string id="30">Octobre</string>
   <string id="31">Novembre</string>
   <string id="32">Décembre</string>
-  
+
   <string id="41">Lun</string>
   <string id="42">Mar</string>
   <string id="43">Mer</string>
@@ -40,7 +40,7 @@
   <string id="45">Ven</string>
   <string id="46">Sam</string>
   <string id="47">Dim</string>
-  
+
   <string id="51">Jan</string>
   <string id="52">Fev</string>
   <string id="53">Mar</string>
@@ -53,7 +53,7 @@
   <string id="60">Oct</string>
   <string id="61">Nov</string>
   <string id="62">Dec</string>
-  
+
   <string id="71">N</string>
   <string id="72">NNE</string>
   <string id="73">NE</string>
@@ -71,7 +71,7 @@
   <string id="85">NO</string>
   <string id="86">NNO</string>
   <string id="87">VAR</string>
-  
+
   <string id="98">Vue : Auto</string>
   <string id="99">Vue : Auto Grand</string>
   <string id="100">Vue : Icônes</string>
@@ -87,8 +87,8 @@
   <string id="110">Créer vignettes</string>
   <string id="111">Raccourcis</string>
   <string id="112">PAUSE</string>
-  <string id="113">Echec Mise-à-jour</string>
-  <string id="114">Echec Installation</string>  
+  <string id="113">Échec mise-à-jour</string>
+  <string id="114">Échec installation</string>
   <string id="115">Copier</string>
   <string id="116">Déplacer</string>
   <string id="117">Effacer</string>
 
   <string id="169">Résolution</string>
   <string id="170">Ajuster le taux de rafraîchissement sur la vidéo</string>
-  
+
   <string id="172">Version du</string>
   <string id="173">Affichage 4:3</string>
-  
+
   <string id="175">Sonorités</string>
   <string id="176">Styles</string>
-  
+
   <string id="179">Chanson</string>
   <string id="180">Durée</string>
   <string id="181">Sélectionner un album</string>
   <string id="197">Demande d'info sur %s</string>
   <string id="198">Chargement des détails du film</string>
   <string id="199">Interface Web</string>
-  
+
   <string id="202">Critiques</string>
   <string id="203">Intrigue</string>
-  
+
   <string id="205">Votes</string>
   <string id="206">Casting</string>
   <string id="207">Résumé</string>
   <string id="221">Le réseau n'est pas connecté</string>
   <string id="222">Annuler</string>
   <string id="224">Vitesse</string>
-  
+
   <string id="225">Hauteur de l'image</string>
   <string id="226">Afficher la mire...</string>
   <string id="227">Rechercher le nom des pistes CD Audio sur freedb.org</string>
   <string id="238">Optique (+)</string>
   <string id="239">Effacer la playliste à la fin de la lecture</string>
   <string id="240">Mode d'affichage</string>
-  <string id="241">Plein Ecran #%d</string>
+  <string id="241">Plein écran #%d</string>
   <string id="242">Fenêtré</string>
   <string id="243">Taux de rafraîchissement</string>
   <string id="244">Plein écran</string>
   <string id="245">Sizing : (%i,%i)->(%i,%i) (Zoom x%2.2f) AR :%2.2f :1 (Pixels : %2.2f :1)</string>
-  
+
   <string id="247">Scripts</string>
   <string id="248">Langue</string>
   <string id="249">Musique</string>
   <string id="303">Délai</string>
   <string id="304">Langue</string>
   <string id="305">Activé</string>
-  <string id="306">Non Entrelacé</string>
+  <string id="306">Non entrelacé</string>
 
   <string id="312">(0=auto)</string>
   <string id="313">Nettoyage de la base de données</string>
   <string id="379">Après-midi</string>
   <string id="380">Averses</string>
   <string id="381">Quelques</string>
-  <string id="382">Eparse</string>
+  <string id="382">Éparse</string>
   <string id="383">Vent</string>
   <string id="384">Fort</string>
   <string id="385">Beau</string>
   <string id="418">Min.</string>
   <string id="419">Max.</string>
   <string id="420">HDMI</string>
-  
+
   <string id="422">Supprimer les infos album</string>
   <string id="423">Supprimer les infos CD</string>
   <string id="424">Valider</string>
   <string id="432">Retirer le film de la médiathèque</string>
   <string id="433">Êtes-vous sûr(e) de retirer '%s' ?</string>
   <string id="434">%s à %i %s</string> <!--From <wind dir.> at <speed> <unit>-->
-  
+
   <string id="437">Disque amovible</string>
   <string id="438">Ouverture du fichier</string>
   <string id="439">Cache</string>
   <string id="480">Apparence</string>
   <string id="481">Options Audio</string>
   <string id="482">À propos de XBMC</string>
-  
+
   <string id="485">Supprimer l'album</string>
   <string id="486">Répéter</string>
   <string id="487">Répéter une fois</string>
   <string id="513">Accueil</string>
   <string id="514">Configuration manuelle</string>
   <string id="515">Genre</string>
-  
+
   <string id="517">Albums récemment joués</string>
   <string id="518">Lancer</string>
   <string id="519">Lancer en...</string>
   <string id="546">Passthrough vers le périphérique de sortie</string>
   <string id="547">Pas de biographie pour cet artiste</string>
   <string id="548">Dé-multiplexer l'audio multi-canal en stéréo</string>
-  
+
   <string id="550">Trier par : %s</string>
   <string id="551">Nom</string>
   <string id="552">Date</string>
   <string id="572">Studio</string>
   <string id="573">Chemin</string>
   <string id="574">Pays</string>
-  <string id="575">En cours</string>  
-  
+  <string id="575">En cours</string>
+  <string id="576">Nombre de Lectures</string>
+
   <string id="580">Direction du tri</string>
   <string id="581">Méthode du tri</string>
   <string id="582">Mode de vue</string>
   <string id="595">Répéter : Non</string>
   <string id="596">Répéter : Une fois</string>
   <string id="597">Répéter : Tous</string>
-  
+
   <string id="600">Importer le CD</string>
   <string id="601">Moyenne</string>
   <string id="602">Standard</string>
   <string id="603">Excellente</string>
   <string id="604">Débit constant</string>
   <string id="605">Importation en cours...</string>
-  
+
   <string id="607">Destination :</string>
   <string id="608">Impossible d'importer le CD ou la piste</string>
   <string id="609">Le chemin CDDA d'importation n'est pas défini.</string>
   <string id="610">Importer une piste audio</string>
   <string id="611">Entrer le numéro</string>
   <string id="612">Bits/Sample</string>
-  <string id="613">Fréquence d'échantillonage</string>  
-  
+  <string id="613">Fréquence d'échantillonage</string>
+
   <string id="620">CDs audio</string>
   <string id="621">Encodeur</string>
   <string id="622">Qualité</string>
   <string id="640">Utiliser le volume de l'album</string>
   <string id="641">Amplification des fichiers Replay gain</string>
   <string id="642">Amplification des fichiers non Replay gain</string>
-  <string id="643">Eviter les coupures sur les fichiers replay gain</string>
+  <string id="643">Éviter les coupures sur les fichiers replay gain</string>
   <string id="644">Couper les barres noires</string>
   <string id="645">Besoin de décompresser un gros fichier. Continuer ?</string>
   <string id="646">Retirer de la médiathèque</string>
   <string id="656">Recherche d'une playliste</string>
   <string id="657">Recherche d'un dossier</string>
   <string id="658">Information de la chanson</string>
-  <string id="659">Etirement non-linéaire</string>
-  
+  <string id="659">Étirement non-linéaire</string>
+
   <string id="660">Volume d'amplification</string>
   <string id="661">Choisissez le dossier d'exportation</string>
   <string id="662">Ce fichier n'est plus disponible.</string>
   <string id="663">Souhaitez-vous le supprimer de la médiathèque ?</string>
   <string id="664">Rechercher un script</string>
   <string id="665">Niveau de compression</string>
-  
+
   <string id="700">Nettoyage de la médiathèque</string>
   <string id="701">Suppression des anciens morceaux de la médiathèque</string>
   <string id="702">Ce dossier a déjà été scanné</string>
   <string id="705">Réseau</string>
   <string id="706">- Serveur</string>
-  
+
   <string id="708">Utiliser un serveur proxy HTTP pour accéder à internet</string>
-  
+
   <string id="711">Protocole Internet (IP)</string>
   <string id="712">Port spécifié invalide. Doit être compris entre 1 et 65535.</string>
   <string id="713">Proxy HTTP</string>
-  
+
   <string id="715">- Attribution</string>
   <string id="716">Automatique (DHCP)</string>
   <string id="717">Manuelle (Statique)</string>
   <string id="749">Retourner l'image</string>
   <string id="750">Êtes-vous sûr(e) ?</string>
   <string id="751">Supprimer la source</string>
-  
+
   <string id="754">Ajouter un lien programme</string>
   <string id="755">Éditer le chemin du programme</string>
   <string id="756">Éditer le nom du programme</string>
   <string id="757">Éditer la profondeur du chemin</string>
-  
+
   <string id="759">Vue : Grande liste</string>
   <string id="760">Jaune</string>
   <string id="761">Blanc</string>
   <string id="787">Interface désactivée</string>
   <string id="788">L'interface réseau a été désactivée avec succès.</string>
   <string id="789">Nom réseau sans fil (ESSID)</string>
-  
+
   <string id="791">Autoriser le contrôle de XBMC par des programmes locaux</string>
   <string id="792">Port</string>
   <string id="793">Port série</string>
   <string id="796">Délai répétition continue (ms)</string>
   <string id="797">Nombre maximum de clients</string>
   <string id="798">Accès Internet</string>
-  
+
   <string id="850">Numéro de port invalide</string>
   <string id="851">Port valide compris entre 1-65535</string>
   <string id="852">Port valide compris entre 1024-65535</string>
-  
+
   <string id="998">Ajouter une source musicale...</string>
   <string id="999">Ajouter une source vidéo...</string>
   <string id="1000">- Prévisualiser</string>
   <string id="1002">XBMC ne peut pas se connecter au chemin réseau.</string>
   <string id="1003">Vérifiez votre chemin ou votre installation réseau.</string>
   <string id="1004">Désirez-vous tout de même l'ajouter ?</string>
-  
+
   <string id="1006">Adresse IP</string>
   <string id="1007">Ajouter un chemin réseau</string>
   <string id="1008">Protocole</string>
   <string id="1049">Paramètres du Script</string>
   <string id="1050">Singles</string>
   <string id="1051">Entrez l'adresse web</string>
-  
+
   <string id="1200">Client SMB</string>
   <string id="1202">Groupe de travail</string>
   <string id="1203">Utilisateur par défaut</string>
   <string id="1204">Mot de passe par défaut</string>
-  
+
   <string id="1207">Serveur WINS</string>
   <string id="1208">Monter les partages SMB</string>
-  
+
   <string id="1210">Supprimer</string>
   <string id="1211">Musique</string>
   <string id="1212">Vidéo</string>
   <string id="1250">Auto-détection</string>
   <string id="1251">Auto-détection du système</string>
   <string id="1252">Pseudo</string>
-  
+
   <string id="1254">Demander pour se connecter</string>
   <string id="1255">Envoyer les Mot de Passe et Nom d'Utilisateur FTP</string>
   <string id="1256">Temps de réponse (ping)</string>
   <string id="1257">Souhaitez-vous vous connecter à l'auto-détection du système ?</string>
-  
+
   <string id="1260">Annoncer ces services à d'autres systèmes via Zéroconf</string>
   <string id="1270">Autoriser XBMC à recevoir du contenu AirPlay</string>
   <string id="1271">Nom du dispositif</string>
   <string id="1272">- Protection par mot de passe</string>
-  
+
   <string id="1300">Personnaliser le périphérique audio</string>
   <string id="1301">Personnaliser le périphérique passthrough</string>
-  
+
   <string id="1396">Dérivant</string>
   <string id="1397">et</string>
   <string id="1398">gelant</string>
   <string id="1420">Modéré</string>
   <string id="1421">Très Fort</string>
   <string id="1422">Venteux</string>
-  <string id="1423">Brouillard</string>  
+  <string id="1423">Brouillard</string>
 
   <!-- strings through to 1450 reserved for weather translation -->
 
   <!-- strings through to 1470 reserved for power-saving -->
 
   <string id="2050">Durée</string>
-  
+
   <string id="2100">Échec du script ! : %s</string>
   <string id="2101">Nouvelle version requise - Voir le log</string>
-  
+
   <string id="4501">Activer LCD/VFD</string>
-  
+
   <string id="10000">Accueil</string>
   <string id="10001">Programmes</string>
   <string id="10002">Images</string>
   <string id="10019">Paramètres - Apparence</string>
   <string id="10020">Scripts</string>
   <string id="10021">Navigateur</string>
-  
+  <string id="10025">Vidéos</string>
   <string id="10028">Vidéos/Playliste</string>
+  <string id="10029">Écran de connexion</string>
   <string id="10034">Paramètres - Profils</string>
-  
+  <string id="10040">Gestionnaire d'add-ons</string>
+
   <string id="10100">Dialogues Oui/Non</string>
   <string id="10101">Dialogues Progression</string>
-  
+
   <string id="10210">Recherche de sous-titres...</string>
   <string id="10211">Recherche de sous-titres mis en cache...</string>
   <string id="10212">Finalisation</string>
   <string id="10213">Mise en cache</string>
   <string id="10214">Ouverture du flux</string>
-  
+
   <string id="10500">Musique/Playliste</string>
   <string id="10501">Musique/Fichiers</string>
   <string id="10502">Musique/Médiathèque</string>
   <string id="10509">Jeux en réseau</string>
   <string id="10510">Extensions</string>
   <string id="10511">Infos Système</string>
-  
+
   <string id="10516">Musique - Médiath.</string>
   <string id="10517">Musique - Lecture en cours</string>
-  
+
   <string id="10522">Vidéos - Lecture en cours</string>
   <string id="10523">Infos Album</string>
   <string id="10524">Infos Film</string>
-  
+
   <string id="12000">Choisir un dialogue</string>
   <string id="12001">Musique/info</string>
   <string id="12002">Dialogues OK</string>
   <string id="12004">Scripts/Info</string>
   <string id="12005">Vidéo plein écran</string>
   <string id="12006">Visualisation audio</string>
-  
+
   <string id="12008">Dialogue empiler fichiers</string>
   <string id="12009">Reconstruire l'index...</string>
   <string id="12010">Revenir à l'écran musique</string>
 
   <string id="12021">Reprendre depuis le début</string>
   <string id="12022">Reprendre à partir de %s</string>
-  
+
   <string id="12310">0</string>
   <string id="12311">1</string>
   <string id="12312">2</string>
   <string id="12357">Verrou sources</string>
   <string id="12358">Le mot de passe entré est vide. Recommencez.</string>
   <string id="12360">Verrou admin.</string>
-  <string id="12362">Eteindre le système après trop de tentatives</string>
+  <string id="12362">Éteindre le système après trop de tentatives</string>
   <string id="12367">Le code Admin n'est pas valide</string>
   <string id="12368">Merci d'entrer un code Admin valide</string>
   <string id="12373">Paramètres &amp; Fichiers</string>
   <string id="12384">Horloge 24 Heures</string>
   <string id="12385">Jour/Mois</string>
   <string id="12386">Mois/Jour</string>
-  
+
   <string id="12390">Système démarré depuis</string>
   <string id="12391">minutes</string>
   <string id="12392">heures</string>
   <string id="12393">jours</string>
   <string id="12394">Temps de fonctionnement total</string>
   <string id="12395">Niveau de batterie</string>
-  
+
   <string id="12600">Météo</string>
-  
+
   <string id="12900">Écran de veille</string>
   <string id="12901">Réglages plein écran</string>
-  
+
   <string id="13000">Système</string>
   <string id="13001">Ralentissement immédiat du DD</string>
   <string id="13002">Vidéo seulement</string>
   <string id="13003">- Délai</string>
   <string id="13004">- Durée minimale du fichier</string>
-  <string id="13005">Eteindre</string>
+  <string id="13005">Éteindre</string>
 
   <string id="13008">Mode d'arrêt par défaut</string>
   <string id="13009">Quitter</string>
   <string id="13014">Minimiser</string>
   <string id="13015">Action du bouton Power</string>
   <string id="13016">Arrêt du système</string>
-  
+
   <string id="13020">Une autre session est en cours, peut être en ssh ?</string>
   <string id="13021">Disque dur externe monté</string>
   <string id="13022">Déconnexion non sécurisée du périphérique</string>
   <string id="13023">Périphérique déconnecté avec succès</string>
   <string id="13024">Manette connectée</string>
   <string id="13025">Manette déconnectée</string>
-  
+
   <string id="13050">Batterie faible</string>
 
   <string id="13100">Filtre de scintillement</string>
   <string id="13109">Tester &amp; appliquer la résolution</string>
   <string id="13110">Appliquer cette résolution ?</string>
   <string id="13111">Voulez-vous garder cette résolution ?</string>
-  
+
   <string id="13112">Upscaling Haute Qualité</string>
   <string id="13113">Désactivé</string>
   <string id="13114">Activé pour contenu SD</string>
   <string id="13115">Toujours activé</string>
-  
+
   <string id="13116">Méthode d'Upscaling</string>
   <string id="13117">Bicubique</string>
   <string id="13118">Lanczos</string>
   <string id="13120">VDPAU</string>
   <string id="13121">VDPAU niveau Upscaling HQ</string>
   <string id="13122">VDPAU niveau Studio conversion des couleurs</string>
-  
+
   <string id="13130">Vider les autres écrans</string>
   <string id="13131">Désactivé</string>
   <string id="13132">Activer Blanking</string>
-  
+
   <string id="13140">Connexions actives détectées !</string>
   <string id="13141">Si vous continuez vous ne serez plus en mesure de</string>
-  <string id="13142"> contrôler XBMC. Etes-vous sur d'arréter le serveur ?</string>
-  
+  <string id="13142"> contrôler XBMC. Êtes-vous sûr d'arrêter le serveur ?</string>
+
   <string id="13144">Changer le mode Apple Remote ?</string>
   <string id="13145">Si vous utilisez actuellement la télécommande Apple pour contrôler</string>
   <string id="13146">XBMC, le changement de ce paramètre peut affecter la capacité</string>
   <string id="13147">à contrôler celui-ci. Effectuer la modification ?</string>
-  
+
   <string id="13159">Masque de sous-réseau</string>
   <string id="13160">Passerelle</string>
   <string id="13161">DNS Primaire</string>
   <string id="13162">Échec lors de l'initialisation</string>
-  
+
   <string id="13170">Jamais</string>
   <string id="13171">Immédiatement</string>
   <string id="13172">Après %i secs</string>
   <string id="13173">HDD Installé le :</string>
   <string id="13174">HDD Nb. de cycles marche/arrêt complets :</string>
-  
+
   <string id="13200">Profils</string>
   <string id="13201">Supprimer le profil '%s' ?</string>
   <string id="13204">Dernier profil chargé</string>
   <string id="13212">Annulé avec %im%is restantes</string>
   <string id="13213">%2.0fm</string> <!--minutes (left from countdown)-->
   <string id="13214">%2.0fs</string> <!--seconds (left from countdown)-->
-  
+
   <string id="13249">Recherche de sous-titres dans les RARs</string>
   <string id="13250">Recherche d'un sous-titre...</string>
   <string id="13251">Déplacer</string>
   <string id="13252">Déplacer ici</string>
   <string id="13253">Annuler le déplacement</string>
-  
+
   <string id="13270">Matériel :</string>
   <string id="13271">Utilisation CPU :</string>
-  
+
   <string id="13274">Connecté, mais aucun DNS disponible.</string>
   <string id="13275">Disque Dur</string>
   <string id="13276">DVD-ROM</string>
   <string id="13279">Réseau</string>
   <string id="13280">Vidéo</string>
   <string id="13281">Matériel</string>
-  
+
   <string id="13283">Système d'exploitation :</string>
   <string id="13284">Vitesse du CPU :</string>
 
   <string id="13342">Orange</string>
   <string id="13343">Rouge</string>
   <string id="13344">Cyclique</string>
-  <string id="13345">Eteindre la LED pendant la lecture</string>
+  <string id="13345">Éteindre la LED pendant la lecture</string>
   <string id="13346">Informations du film</string>
   <string id="13347">Ajouter</string>
   <string id="13348">Chercher sur IMDb...</string>
   <string id="13430">Activer l'accélération matérielle (OpenMax)</string>
   <string id="13431">Pixel Shaders</string>
   <string id="13432">Autoriser l'accélération matérielle (VideoToolbox)</string>
-  
+
   <string id="13500">Méthode de synchro. A/V</string>
   <string id="13501">Horloge audio</string>
   <string id="13502">Horloge vidéo (Drop/Dupe audio)</string>
   <string id="13551">Off</string>
   <string id="13552">%.1f Seconde</string>
   <string id="13553">%.1f Secondes</string>
-  
+
   <string id="13600">Télécommande Apple</string>
-  
+
   <string id="13602">Permettre le démarrage de XBMC par la télécommande</string>
   <string id="13603">Temps de délai de séquence</string>
-  
+
   <string id="13610">Désactivé</string>
   <string id="13611">Standard</string>
   <string id="13612">Télécommande universelle</string>
   <string id="13613">Télécommande multiple (Harmony)</string>
-  
+
   <string id="13620">Erreur Apple Remote.</string>
   <string id="13621">Le support de la télécommande Apple ne peut être activé.</string>
-  
+
   <string id="14000">Empiler</string>
   <string id="14001">Dépiler</string>
   <string id="14003">Téléchargement de la playliste...</string>
   <string id="14005">Scan de la liste des flux...</string>
   <string id="14006">Échec du téléchargement de la liste des flux</string>
   <string id="14007">Échec du téléchargement de la playliste</string>
-  
+
   <string id="14009">Répertoire des jeux</string>
   <string id="14010">Basculement des vignettes basées sur</string>
   <string id="14011">Activer le basculement</string>
   <string id="14034">Cache DVD - DVDRom</string>
   <string id="14035">- Réseau Local</string>
   <string id="14036">Services</string>
-  
+
   <string id="14038">Les paramètres réseau ont été changés</string>
   <string id="14039">Vous venez de modifier les paramètres réseau.</string>
   <string id="14040">Redémarrer XBMC pour appliquer les changements ?</string>
   <string id="14041">Limiter la bande passante de la connexion Internet</string>
-  
-  <string id="14043">- Eteindre pendant la lecture</string>
+
+  <string id="14043">- Éteindre pendant la lecture</string>
   <string id="14044">%i min</string>
   <string id="14045">%i sec</string>
   <string id="14046">%i ms</string>
   <string id="14051">Format de l'heure</string>
   <string id="14052">Format de la date</string>
   <string id="14053">Filtres Interface</string>
-  
+
   <string id="14055">Utiliser le scan en tâche de fond</string>
   <string id="14056">Stopper le scan</string>
   <string id="14057">Impossible d'afficher les infos lors du scan</string>
   <string id="14069">Voulez-vous appliquer cette configuration ?</string>
   <string id="14070">Appliquer les changements maintenant</string>
   <string id="14071">Permettre de renommer et supprimer</string>
-  
+
   <string id="14074">Définir le fuseau horaire</string>
   <string id="14075">Ajuster l'horloge pour l'observation auto. de l'heure d'été</string>
   <string id="14076">Ajouter aux favoris</string>
   <string id="14093">Sécurité</string>
   <string id="14094">Périphériques</string>
   <string id="14095">Gestion de l'énergie</string>
-  
+
   <string id="15015">Supprimer</string>
   <string id="15016">Jeux</string>
-  
+
   <string id="15019">Ajouter</string>
-  
+
   <string id="15052">Mot de passe</string>
-  
+
   <string id="15100">Médiathèque</string>
   <string id="15101">Base de données</string>
   <string id="15102">* Tous les albums</string>
   <string id="15103">* Tous les artistes</string>
   <string id="15104">* Toutes les chansons</string>
   <string id="15105">* Tous les genres</string>
-  
+
   <string id="15107">Mise en cache...</string>
   <string id="15108">Sons de navigation</string>
   <string id="15109">Skin par défaut</string>
   <string id="15111">- Thème</string>
   <string id="15112">Thème par défaut</string>
-  
+
   <string id="15200">Last.fm</string>
   <string id="15201">Soumettre les chansons à Last.fm</string>
   <string id="15202">Nom d'utilisateur Last.fm</string>
   <string id="15219">Mot de passe Libre.fm</string>
   <string id="15220">Libre.fm</string>
   <string id="15221">Soumettre un titre</string>
-  
+
   <string id="15250">Soumettre la radio Last.fm à Last.fm</string>
   <string id="15251">Connexion à Last.fm...</string>
   <string id="15252">Sélection de la station...</string>
   <string id="15296">Réhabiliter</string>
   <string id="15297">Voulez-vous supprimer ce morceau de vos coups de coeur ?</string>
   <string id="15298">Voulez-vous réhabiliter ce morceau ?</string>
-  
+
   <string id="15300">Chemin non trouvé ou invalide</string>
   <string id="15301">Impossible de se connecter au serveur</string>
   <string id="15302">Serveur non trouvé</string>
   <string id="15303">Groupe de travail non trouvé</string>
-  
+
   <string id="15310">Ouverture des sources multi-chemin</string>
   <string id="15311">Chemin :</string>
-  
+
   <string id="16000">Général</string>
-  
+
   <string id="16002">Recherche internet</string>
   <string id="16003">Lecteur</string>
   <string id="16004">Jouer les médias depuis le disque</string>
-  
+
   <string id="16008">Saisissez le nouveau titre</string>
   <string id="16009">Saisissez le nom du film</string>
   <string id="16010">Saisissez le nom du profil</string>
   <string id="16039">Off</string>
   <string id="16040">Auto</string>
   <string id="16041">On</string>
-  
+
   <string id="16100">Toutes les vidéos</string>
   <string id="16101">Non vues</string>
   <string id="16102">Vues</string>
   <string id="16103">Marquer comme vue</string>
   <string id="16104">Marquer comme non vue</string>
   <string id="16105">Éditer le titre</string>
-  
+
   <string id="16200">Opération annulée</string>
   <string id="16201">La copie a échouée</string>
   <string id="16202">Un ou plusieurs fichiers n’ont pas été copiés</string>
   <string id="16204">Un ou plusieurs fichiers n’ont pas été déplacés</string>
   <string id="16205">La suppression a échoué</string>
   <string id="16206">Un ou plusieurs fichiers n’ont pas été supprimés</string>
-  
+
   <string id="16300">Méthode de mise à l'échelle</string>
   <string id="16301">La plus proche</string>
   <string id="16302">Bilinéaire</string>
   <string id="16324">Software Blend</string>
 
   <string id="16400">Post-processing Vidéo</string>
-  
+
   <string id="17500">Afficher le temps avant la mise en veille</string>
 
   <string id="17997">%i Mo</string>
   <string id="17998">%i heures</string>
   <string id="17999">%i jours</string>
-  
+
   <string id="19000">Changer de canal</string>
-  
+
   <string id="20000">Dossier des enregistrements musique</string>
   <string id="20001">Utiliser un lecteur DVD externe</string>
   <string id="20002">Lecteur DVD externe</string>
   <string id="20003">Dossier des trainers</string>
   <string id="20004">Dossier des captures d'écran</string>
-  
+
   <string id="20006">Dossier des playlistes</string>
   <string id="20007">Enregistrements</string>
   <string id="20008">Captures d'écran</string>
   <string id="20009">Utiliser XBMC</string>
-  
+
   <string id="20011">Playlistes musicales</string>
   <string id="20012">Playlistes vidéo</string>
   <string id="20013">Voulez-vous lancer le jeu ?</string>
   <string id="20017">Locale</string>
   <string id="20018">Aucune</string>
   <string id="20019">Choisir une vignette</string>
-  
+
   <!-- string id 20022 will always be set to an empty string (LocalizeStrings.cpp)-->
   <string id="20022"></string>
   <string id="20023">Conflit</string>
   <string id="20024">Scanner les nouveaux</string>
   <string id="20025">Tout scanner</string>
   <string id="20026">Région</string>
-  
+
   <!-- string id's 20027 thru 20034 are reserved for temperature strings (LocalizeStrings.cpp)-->
 
   <string id="20037">Sommaire</string>
   <string id="20053">Vous quittez le mode Admin.</string>
   <string id="20054">Vous entrez en mode Admin.</string>
   <string id="20055">Vignette Allmusic.com</string>
-  
+
   <string id="20057">Supprimer la vignette</string>
   <string id="20058">Ajouter un profil...</string>
   <string id="20059">Infos pour tous les albums</string>
   <string id="20190">Personnaliser</string>
   <string id="20191">Activer le mode debug</string>
   <string id="20192">Télécharger les infos supplémentaires lors des mises à jour</string>
-  <string id="20193">Service d'informations par défaut - Album</string>  
+  <string id="20193">Service d'informations par défaut - Album</string>
   <string id="20194">Service d'informations par défaut - Artiste</string>
   <string id="20195">Changer le scraper</string>
   <string id="20196">Exporter la médiathèque musicale</string>
   <string id="20197">Importer une médiathèque musicale</string>
   <string id="20198">Aucun artiste trouvé !</string>
   <string id="20199">Échec du téléchargement des infos Artiste</string>
-  
+
   <!-- string id's 20200 thru 20211 are reserved for speedstrings (LocalizeStrings.cpp)-->
 
   <string id="20250">C'est Party ! (vidéos)</string>
   <string id="20259">Network Filesystem (NFS)</string>
   <string id="20260">Secure Shell (SSH/SFTP)</string>
   <string id="20261">Apple File Protocol (AFP)</string>
-   
+
   <string id="20300">Dossier Server Web (HTTP)</string>
   <string id="20301">Dossier Server Web (HTTPS)</string>
   <string id="20302">Impossible d'écrire dans le dossier</string>
   <string id="20303">Voulez-vous passer et continuer ?</string>
   <string id="20304">Flux RSS</string>
-  
+
   <string id="20307">DNS secondaire</string>
   <string id="20308">Serveur DHCP</string>
   <string id="20309">Créer un nouveau dossier</string>
   <string id="20326">Ceci remettra à zéro les valeurs de calibrage pour %s</string>
   <string id="20327">aux valeurs par défaut.</string>
   <string id="20328">Parcourir pour une destination</string>
-  
+  <string id="20329">Chaque film dans un dossier séparé, libellé avec son titre</string>
   <string id="20330">Consultation avec les noms des dossiers</string>
   <string id="20331">Fichier</string>
   <string id="20332">Utiliser le nom des dossiers ou fichiers pour la consultation ?</string>
   <string id="20401">Jouer le clip</string>
   <string id="20402">Télécharger les vignettes d'acteurs lors de l'ajout à la médiathèque</string>
   <string id="20403">Définir la vignette Acteur</string>
-  
+
   <string id="20405">Supprimer le signet d'épisode</string>
   <string id="20406">Créer un signet d'épisode</string>
   <string id="20407">Paramètres du scraper</string>
   <string id="20431">Écraser les anciens fichiers ?</string>
   <string id="20432">Exclure le chemin de la MAJ médiathèque</string>
   <string id="20433">Extraire les vignettes et les informations vidéo</string>
-  <string id="20434">Groupes</string>
+  <string id="20434">Sagas</string>
   <string id="20435">Définir une vignette de saga</string>
   <string id="20436">Exporter les vignettes acteur</string>
   <string id="20437">Choisir un fanart</string>
   <string id="20452">épisode</string>
   <string id="20453">épisodes</string>
   <string id="20454">Auditeur</string>
-  <string id="20455">Auditeurs</string>  
+  <string id="20455">Auditeurs</string>
   <string id="20456">Choisir le Fanart de la saga</string>
   <string id="20457">Saga</string>
+  <string id="20458">Grouper les films en saga</string>
   <!-- up to 21329 is reserved for the video db  !!  !-->
 
   <string id="21330">Afficher les dossiers et les fichiers cachés</string>
-  
+
   <string id="21331">Client TuxBox</string>
   <string id="21332">AVERTISSEMENT : le dispositif TuxBox est en mode d'enregistrement !</string>
   <string id="21333">Le flux sera arrêté !</string>
 
   <string id="21359">Ajouter un partage média...</string>
   <string id="21360">Partager les médiathèques vidéos et musique via l'UPnP</string>
-  
+
   <string id="21364">Éditer le partage média</string>
   <string id="21365">Effacer le partage média</string>
   <string id="21366">Dossier de sous-titres</string>
   <string id="21451">Connexion Internet requise.</string>
   <string id="21452">Plus...</string>
   <string id="21453">Racine</string>
+  <string id="21454">Cache plein</string>
+  <string id="21455">Cache rempli mais insuffisant pour une lecture continue</string>
 
   <string id="21460">Emplacement du sous-titre</string>
   <string id="21461">Fixe</string>
   <string id="21463">Sous la vidéo</string>
   <string id="21464">En haut de la vidéo</string>
   <string id="21465">Au-dessus de la vidéo</string>
-  
+
   <string id="21800">Nom du fichier</string>
   <string id="21801">Répertoire du fichier</string>
   <string id="21802">Taille du fichier</string>
   <string id="21806">Commentaire</string>
   <string id="21807">Couleur/N&amp;B</string>
   <string id="21808">Traitement JPEG</string>
-  
+
   <string id="21820">Date/Heure</string>
   <string id="21821">Description</string>
   <string id="21822">Marque de l'appareil</string>
   <string id="21841">Longitude GPS</string>
   <string id="21842">Altitude GPS</string>
   <string id="21843">Orientation</string>
-  
+
   <string id="21860">Catégories supplémentaires</string>
   <string id="21861">Mots-clés</string>
   <string id="21862">Légende</string>
   <string id="21898">Années actives</string>
   <string id="21899">Label(s)</string>
   <string id="21900">Naissance/Création</string>
-  
+
   <!-- strings 21900 thru 21999 reserved for slideshow info -->
 
   <string id="22000">Actualiser la médiathèque au démarrage</string>
   <string id="22001">Masquer l'avancement lors de la màj de la mediathèque</string>
   <string id="22002">- Suffixe DNS</string>
-  
-  <string id="22003">%2.3fs</string>  
+
+  <string id="22003">%2.3fs</string>
   <string id="22004">Retarder de : %2.3fs</string>
   <string id="22005">Avancer de : %2.3fs</string>
   <string id="22006">Décalage sous-titres</string>
   <string id="22022">Afficher les fichiers vidéo dans les listes</string>
   <string id="22023">Vendor DirectX :</string>
   <string id="22024">Version Direct3D :</string>
-  
+
   <!-- strings 22030 thru 22060 reserved for karaoke -->
   <string id="22030">Police</string>
   <string id="22031">- Taille</string>
   <string id="22081">Afficher Infos</string>
   <string id="22082">Plus...</string>
   <string id="22083">Tout jouer</string>
-  
+
   <string id="23049">Teletext non disponible</string>
   <string id="23050">Activer le télétexte</string>
   <string id="23051">Partie %i</string>
   <string id="23052">%i octets mis en cache</string>
   <string id="23053">Arrêt en cours</string>
   <string id="23054">Lecture en cours</string>
-  
+
   <!-- strings 23100 thru 23150 reserved for external player -->
   <string id="23100">Lecteur externe actif</string>
   <string id="23101">Cliquez sur OK pour arrêter le lecteur</string>
-  
+
   <string id="23104">Cliquez sur OK lorsque la lecture est terminée</string>
-  
+
   <!-- strings 24000 thru 24299 reserved for the Add-ons framework -->
   <string id="24000">Add-on</string>
   <string id="24001">Add-ons</string>
   <string id="24002">Options Add-on</string>
   <string id="24003">Infos Add-on</string>
-  
+
   <string id="24005">Sources media</string>
   <string id="24007">Infos Film</string>
-  <string id="24008">Ecran de veille</string>
+  <string id="24008">Écran de veille</string>
   <string id="24009">Script</string>
   <string id="24010">Visualisation</string>
   <string id="24011">Dépots d'add-ons</string>
   <string id="24016">Infos album</string>
   <string id="24017">Infos artiste</string>
   <string id="24018">Services</string>
-  
+
   <string id="24020">Configurer</string>
   <string id="24021">Désactiver</string>
   <string id="24022">Activer</string>
   <string id="24067">Téléchargements en cours</string>
   <string id="24068">Mise-à-jour disponible</string>
   <string id="24069">Mise-à-jour</string>
-  
+
   <string id="24070">L'Add-on n'a pu être chargé.</string>
   <string id="24071">Une erreur inconnue rencontrée.</string>
   <string id="24072">Paramètres obligatoires</string>
   <string id="24073">Connexion impossible</string>
   <string id="24074">Redémarrage requis</string>
   <string id="24075">Désactiver</string>
+  <string id="24076">Add-on requis</string>
   <string id="24080">Tenter la reconnexion ?</string>
   <string id="24089">Redémarrage de l'Add-on</string>
   <string id="24090">Verrouiller le gestionnaire d'Add-on</string>
-  
+
   <string id="24094">(actuel)</string>
   <string id="24095">(sur liste noire)</string>
   <string id="24096">Le dépot indique cet add-on comme inutilisable.</string>
   <string id="24097">Voulez-vous le désactiver sur votre système ?</string>
   <string id="24098">Cassé</string>
   <string id="24099">Voulez-vous basculer vers ce thème ?</string>
+  <string id="24100">Pour utiliser cette fonctionnalité, vous devez télécharger un Add-on :</string>
+  <string id="24101">Voulez-vous télécharger cet Add-on ?</string>
   <string id="25000">Notifications</string>
-  
+
   <!-- strings 29800 thru 29998 reserved strings used only in the default Project Mayhem III skin and not c++ code -->
   <string id="29800">Médiathèque</string>
   <string id="29801">Clavier QWERTY</string>
   <string id="29802">Passthrough Audio en cours</string>
-  
+
   <!-- strings 30000 thru 30999 reserved for plugins and plugin settings -->
   <!-- strings 31000 thru 31999 reserved for skins -->
   <!-- strings 32000 thru 32999 reserved for scripts -->
   <!-- strings 33000 thru 33999 reserved for common strings used in Add-ons -->
-  <string id="30011">Chercher la durée</string>
   <string id="33001">Qualité du trailer</string>
   <string id="33002">Flux</string>
   <string id="33003">Télécharger</string>
   <string id="33008">Enregistrement en cours</string>
   <string id="33009">Copie en cours</string>
   <string id="33010">Définir le répertoire de téléchargement</string>
+  <string id="33011">Durée de la recherche</string>
   <string id="33012">Court</string>
   <string id="33013">Long</string>
   <string id="33014">Utiliser le lecteur DVD au lieu du lecteur habituel</string>
   <string id="33081">Ce fichier est empilé, sélectionnez la partie que vous souhaitez lire.</string>
   <string id="33082">Chemin du script</string>
   <string id="33083">Activer le bouton de script personnalisé</string>
-  
-  <string id="33100">Echec du lancement</string>
+
+  <string id="33100">Échec du lancement</string>
   <string id="33101">Serveur Web</string>
   <string id="33102">Serveur d'évènement</string>
   <string id="33103">Communication à distance avec le serveur</string>
 
+  <string id="33200">Nouvelle connexion détectée</string>
+
   <!-- translators : no need to add these to your language files -->
   <string id="34000">Lame</string>
   <string id="34001">Vorbis</string>
   <string id="34003">DXVA2</string>
   <string id="34004">VAAPI</string>
   <string id="34005">Flac</string>
-  
+
   <string id="34100">Configuration des Haut-Parleurs</string>
   <string id="34101">2.0</string>
   <string id="34102">2.1</string>
 
   <string id="34201">Aucun média à suivre</string>
   <string id="34202">Aucun média précédent</string>
-  
+
+  <string id="34300">Échec du démarrage zeroconf</string>
+  <string id="34301">Est-ce que le service d'Apple Bonjour est installé ? Consultez le log pour plus d'infos.</string>
+
+  <string id="34400">Rendu Vidéo</string>
+  <string id="34401">Échec du filtre/redimensionnement vidéo, utilisation du redimensionnement bilinéaire à la place</string>
+  <string id="34402">Échec d'initialisation du périphérique audio</string>
+  <string id="34403">Vérifiez vos paramètres audio</string>
+
   <string id="35000">Périphériques</string>
 
   <string id="35001">Périphérique HID générique</string>
   <string id="35502">Nom</string>
   <string id="35503">Vendor</string>
   <string id="35504">ID du produit</string>
-  
+
   <string id="36000">Adaptateur CEC Pulse-Eight</string>
   <string id="36001">Nyxboard Pulse-Eight</string>
   <string id="36002">Basculer le contrôle côté clavier</string>
   <string id="36005">Activer les contrôles de bascule</string>
   <string id="36006">Impossible d'ouvrir l'adaptateur</string>
   <string id="36007">Allumer la TV au démarrage de XBMC</string>
-  <string id="36008">Eteindre les dispositifs à l'arrêt de XBMC</string>
+  <string id="36008">Éteindre les dispositifs à l'arrêt de XBMC</string>
   <string id="36009">Placer les dispositifs en veille si l'écran de veille est activé</string>
   <string id="36010"></string>
   <string id="36011">Impossible de détecter le port CEC. Le paramétrer manuellement.</string>
   <string id="36015">Numéro de port HDMI</string>
   <string id="36016">Connecté</string> <!-- max. 13 characters -->
   <string id="36017">Adaptateur trouvé, mais libcec indisponible</string>
-  <string id="36018">Utiliser le paramètre de langage de la TV.</string> 
+  <string id="36018">Utiliser le paramètre de langage de la TV.</string>
 </strings>
index 0b54cdd..0bca3e0 100644 (file)
   <string id="787">Karte deaktiviert</string>
   <string id="788">Netzwerkkarte erfolgreich deaktiviert.</string>
   <string id="789">Wireless Netzwerkname (ESSID)</string>
+  <string id="790">Fernsteuerung</string>
 
   <string id="791">Steuerung über lokale Programme zulassen</string>
   <string id="792">Port</string>
   <string id="10021">Webbrowser</string>
 
   <string id="10028">Videos/Playlisten</string>
+  <string id="10029">Anmeldebildschirm</string>
   <string id="10034">Einstellungen-&gt;Profile</string>
+  <string id="10040">Addon-Browser</string>
 
   <string id="10100">Ja/Nein Dialog</string>
   <string id="10101">Fortschrittsanzeige</string>
index b334627..6a4b790 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!--$Revision$--> <!--Translator: Ydatografida / Email: ydatografida@gmail.com / Date of translation: 12/25/2011 / Last update (by CutSickAss): 14/02/2012 / Based on english strings version 1E+42-->
+<!--$Revision$--> <!--Original translator: Ydatografida (ydatografida@gmail.com) / Last update (by CutSickAss): 23/03/2012 -->
 <strings>
   <string id="0">Εφαρμογές</string>
-  <string id="1">ΦÏ\89Ï\84ογÏ\81αÏ\86ίες</string>
+  <string id="1">Î\95ικÏ\8cνες</string>
   <string id="2">Μουσική</string>
   <string id="3">Βίντεο</string>
   <string id="4">Οδηγός τηλεόρασης</string>
   <string id="100">Προβολή: Εικονίδια</string>
   <string id="101">Προβολή: Λίστα</string>
   <string id="102">Σάρωση</string>
-  <string id="103">Ταξιν.: Όνομα</string>
-  <string id="104">Ταξιν.: Ημ/νία</string>
-  <string id="105">Ταξιν.: Μέγεθος</string>
+  <string id="103">Ταξ.: Όνομα</string>
+  <string id="104">Ταξ.: Ημ/νία</string>
+  <string id="105">Ταξ.: Μέγεθος</string>
   <string id="106">Όχι</string>
   <string id="107">Ναι</string>
-  <string id="108">Παρουσίαση</string>
+  <string id="108">Παρουσίαση διαφανειών</string>
   <string id="109">Δημιουργία εικονιδίων</string>
   <string id="110">Δημιουργία μικρογραφιών</string>
   <string id="111">Συντομεύσεις</string>
   <string id="126">Λειτουργία</string>
   <string id="127">Αντικείμενα</string>
   <string id="128">Γενικά</string>
-  <string id="129">Παρουσίαση</string>
+  <string id="129">Παρουσίαση διαφανειών</string>
   <string id="130">Πληροφορίες συστήματος</string>
   <string id="131">Απεικόνιση</string>
   <string id="132">Άλμπουμ</string>
   <string id="146">Τύπος:</string>
   <string id="147">Στατική</string>
   <string id="148">DHCP</string>
-  <string id="149">ΦÏ\85Ï\83ική Î´Î¹ÎµÏ\8dθÏ\85νÏ\83η</string>
+  <string id="149">Î\94ιεÏ\8dθÏ\85νÏ\83η MAC</string>
   <string id="150">Διεύθυνση IP</string>
   <string id="151">Σύνδεση:</string>
   <string id="152">Μονόδρομη</string>
   <string id="159">Καμία σύνδεση</string>
   <string id="160">Ελεύθερα</string>
   <string id="161">Μη διαθέσιμο</string>
-  <string id="162">Î\86νοιγμα Î¼Î¿Î½Î¬Î´Î±Ï\82</string>
+  <string id="162">Î\98Ï\8dÏ\81α Î´Î¯Ï\83κοÏ\85 Î±Î½Î¿Î¹ÎºÏ\84ή</string>
   <string id="163">Ανάγνωση</string>
   <string id="164">Δεν υπάρχει δίσκος</string>
   <string id="165">Υπάρχει δίσκος</string>
   <string id="166">Κέλυφος</string>
 
   <string id="169">Ανάλυση</string>
-  <string id="170">Προσαρμογή του ρυθμού ανανέωσης</string>
+  <string id="170">Προσαρμογή του ρυθμού ανανέωσης για να ταιριάζει με το βίντεο</string>
 
   <string id="172">Ημερομηνία κυκλοφορίας</string>
   <string id="173">Προβολή των βίντεο με αναλογία 4:3 ως</string>
 
-  <string id="175">Î\94ιάθεÏ\83η</string>
+  <string id="175">ΤάÏ\83ειÏ\82</string>
   <string id="176">Στυλ</string>
 
   <string id="179">Τραγούδι</string>
   <string id="194">Αναζήτηση...</string>
   <string id="195">Δεν βρέθηκαν πληροφορίες!</string>
   <string id="196">Επιλογή ταινίας:</string>
-  <string id="197">Î\91ναζήÏ\84ηση πληροφοριών %s</string>
+  <string id="197">Î\95Ï\8dÏ\81εση πληροφοριών %s</string>
   <string id="198">Φόρτωση πληροφοριών ταινίας</string>
   <string id="199">Διεπαφή ιστού</string>
 
-  <string id="202">Σύνθημα</string>
+  <string id="202">Σλόγκαν</string>
   <string id="203">Περίληψη πλοκής</string>
 
   <string id="205">Ψήφοι</string>
-  <string id="206">ΡÏ\8cλοι ÎºÎ±Î¹ Î·Î¸Î¿Ï\80οιοί</string>
+  <string id="206">Î\94ιανομή Ï\81Ï\8cλÏ\89ν</string>
   <string id="207">Πλοκή</string>
   <string id="208">Εκκίνηση</string>
   <string id="209">Επόμενο</string>
   <string id="210">Προηγούμενο</string>
-  <string id="213">Βαθμονόμηση οθόνης</string>
-  <string id="214">Βαθμονόμηση βίντεο</string>
+  <string id="213">Βαθμονόμηση οθόνης...</string>
+  <string id="214">Βαθμονόμηση βίντεο...</string>
   <string id="215">Απάλυνση εικόνας</string>
   <string id="216">Ποσοστό μεγέθυνσης</string>
   <string id="217">Λόγος εικονοστοιχείων</string>
   <string id="225">Κατακόρυφη μετατόπιση</string>
   <string id="226">Δοκιμή μοτίβων...</string>
   <string id="227">Αναζήτηση ονομάτων μουσικών κομματιών από το freedb.org</string>
-  <string id="228">Î\91νακάÏ\84εμα Î»Î¯Ï\83Ï\84αÏ\82 Î±Î½Î±Ï\80αÏ\81αγÏ\89γήÏ\82 ÎºÎ±Ï\84α τη φόρτωση</string>
+  <string id="228">Î\91νακάÏ\84εμα Î»Î¯Ï\83Ï\84αÏ\82 Î±Î½Î±Ï\80αÏ\81αγÏ\89γήÏ\82 ÎºÎ±Ï\84ά τη φόρτωση</string>
   <string id="229">Χρόνος ελάττωσης περιστροφής (Spindown)</string>
   <string id="230">Φίλτρα βίντεο</string>
   <string id="231">Κανένα</string>
   <string id="234">Ανισοτροπικό</string>
   <string id="235">Quincunx</string>
   <string id="236">Gaussian cubic</string>
-  <string id="237">Î\95λαÏ\87ιÏ\83Ï\84οÏ\80οίηση</string>
+  <string id="237">ΣμίκÏ\81Ï\85νση</string>
   <string id="238">Μεγέθυνση</string>
   <string id="239">Εκκαθάριση λίστας αναπαραγωγής στη λήξη</string>
-  <string id="240">Î\9aαÏ\84άÏ\83Ï\84αÏ\83η Ï\80ροβολής</string>
+  <string id="240">Î\9bειÏ\84οÏ\85Ï\81γία Î ροβολής</string>
   <string id="241">Πλήρης οθόνη #%d</string>
   <string id="242">Σε παράθυρο</string>
   <string id="243">Ανανέωση βαθμολογίας</string>
   <string id="244">Πλήρης οθόνη</string>
-  <string id="245">Μέγεθος: (%i,%i)-&gt;(%i,%i) (Εστίαση x%2.2f) AR:%2.2f:1 (Εικονοστοιχεία: %2.2f:1) (ΚΜετατόπιση: %2.2f)</string>
+  <string id="245">Μέγεθος: (%i,%i)->(%i,%i) (Εστίαση x%2.2f) AR:%2.2f:1 (Εικονοστοιχεία: %2.2f:1) (ΚΜετατόπιση: %2.2f)</string>
 
   <string id="247">Scripts</string>
   <string id="248">Γλώσσα</string>
   <string id="249">Μουσική</string>
-  <string id="250">Î\91Ï\80εικÏ\8cνιση</string>
+  <string id="250">Î\9fÏ\80Ï\84ικοÏ\80οίηση</string>
   <string id="251">Επιλογή καταλόγου προορισμού</string>
-  <string id="252">Στέρεο έξοδος σ' όλα τα ηχεία</string>
+  <string id="252">Στέρεο έξοδος σε όλα τα ηχεία</string>
   <string id="253">Αριθμός καναλιών</string>
   <string id="254">- Δέκτης ικανός για αναπαραγωγή DTS</string>
   <string id="255">CDDB</string>
   <string id="258">Ενεργοποίηση ID3 ετικετών</string>
   <string id="259">Άνοιγμα</string>
   <string id="260">Shoutcast</string>
-  <string id="261">Αναμονή για την έναρξη....</string>
+  <string id="261">Αναμονή για την έναρξη...</string>
   <string id="262">Εξαγωγές Scripts</string>
-  <string id="263">Î\88γκÏ\81ιÏ\83η ÎµÎ»Î­Î³Ï\87οÏ\85 Ï\84οÏ\85 XBMC Î±Ï\80Ï\8c Ï\84ο HTTP</string>
+  <string id="263">Î\88γκÏ\81ιÏ\83η ÎµÎ»Î­Î³Ï\87οÏ\85 Ï\84οÏ\85 XBMC Î¼Î­Ï\83Ï\89 HTTP</string>
   <string id="264">Εγγραφή</string>
   <string id="265">Διακοπή εγγραφής</string>
-  <string id="266">Ταξιν.: Κομμάτι</string>
-  <string id="267">Ταξιν.: Έτος</string>
-  <string id="268">Ταξιν.: Τίτλος</string>
-  <string id="269">Ταξιν.: Καλλιτέχνης</string>
-  <string id="270">Ταξιν.: Άλμπουμ</string>
+  <string id="266">Ταξ.: Κομμάτι</string>
+  <string id="267">Ταξ.: Χρόνος</string>
+  <string id="268">Ταξ.: Τίτλος</string>
+  <string id="269">Ταξ.: Καλλιτέχνης</string>
+  <string id="270">Ταξ.: Άλμπουμ</string>
   <string id="271">100 κορυφαία</string>
   <string id="272">Επάνω αριστερή προσαρμογή του ορατού πλαισίου</string>
   <string id="273">Κάτω δεξιά προσαρμογή του ορατού πλαισίου</string>
   <string id="277">Μετακινήστε τη μπάρα για να αλλάξει η θέση των υποτίτλων</string>
   <string id="278">Αλλάξτε το σχήμα ώστε να είναι τέλειο τετράγωνο</string>
   <string id="279">Αδυναμία φόρτωσης των ρυθμίσεων</string>
-  <string id="280">ΧÏ\81ηÏ\83ιμοÏ\80οίηση προεπιλεγμένων ρυθμίσεων</string>
-  <string id="281">Παρακαλώ, ελέγξτε τα αρχεία .xml</string>
+  <string id="280">ΧÏ\81ήση προεπιλεγμένων ρυθμίσεων</string>
+  <string id="281">Παρακαλώ ελέγξτε τα αρχεία .XML</string>
   <string id="282">Βρέθηκαν %i αντικείμενα</string>
   <string id="283">Αποτελέσματα αναζήτησης</string>
   <string id="284">Δεν βρέθηκαν αποτελέσματα</string>
   <string id="292">Ήχος</string>
   <string id="293">Αναζήτηση για υπότιτλους</string>
   <string id="294">Δημιουργία</string>
-  <string id="296">Î\91Ï\80αλοιÏ\86ή</string>
+  <string id="296">Î\95κκαθάÏ\81ιÏ\83η</string>
   <string id="297">Καθυστέρηση ήχου</string>
   <string id="298">Σελιδοδείκτες</string>
   <string id="299">- Δέκτης ικανός για αναπαραγωγή AAC</string>
   <string id="303">Καθυστέρηση</string>
   <string id="304">Γλώσσα</string>
   <string id="305">Ενεργό/ή</string>
-  <string id="306">Μη-διαστρωματωμένο</string>
+  <string id="306">Non-interleaved</string>
 
   <string id="312">(0=αυτόματα)</string>
   <string id="313">Εκκαθάριση βάσης δεδομένων</string>
   <string id="338">Αναλογική</string>
   <string id="339">Οπτική/Coax</string>
   <string id="340">Διάφοροι καλλιτέχνες</string>
-  <string id="341">Έναρξη DVD</string>
+  <string id="341">Έναρξη δίσκου</string>
   <string id="342">Ταινίες</string>
   <string id="343">Προσαρμογή δειγματοληψίας</string>
   <string id="344">Ηθοποιοί</string>
   <string id="352">Αμυδρό φως</string>
   <string id="353">Μαύρη οθόνη</string>
   <string id="354">Ίχνη πλέγματος</string>
-  <string id="355">Î\91ναμονή ÎµÎ½ÎµÏ\81γοÏ\80οίηÏ\83ηÏ\82 Ï\80Ï\81οÏ\86Ï\8dλαξηÏ\82 οθόνης</string>
+  <string id="355">Î\91ναμονή Î³Î¹Î± Ï\80Ï\81οÏ\86Ï\8dλαξη οθόνης</string>
   <string id="356">Λειτουργία προφύλαξης οθόνης</string>
   <string id="357">Λειτουργία χρονοδιακόπτη τερματισμού</string>
   <string id="358">Όλα τα άλμπουμ</string>
   <string id="359">Πρόσφατα άλμπουμ</string>
   <string id="360">Προφύλαξη οθόνης</string>
-  <string id="361">Παρουσίαση</string>
+  <string id="361">Παρουσίαση διαφανειών και των υποφακέλων</string>
   <string id="362">Ποσοστό εξασθένισης της προφύλαξης οθόνης</string>
-  <string id="363">Ταξιν.: Αρχείο</string>
+  <string id="363">Ταξ.: Αρχείο</string>
   <string id="364">- Δέκτης με ικανότητα αναπαραγωγής Dolby Digital (AC3)</string>
-  <string id="365">Ταξιν.: Όνομα</string>
-  <string id="366">Ταξιν.: Έτος</string>
-  <string id="367">Ταξιν.: Βαθμολογία</string>
+  <string id="365">Ταξ.: Όνομα</string>
+  <string id="366">Ταξ.: Έτος</string>
+  <string id="367">Ταξ.: Βαθμολογία</string>
   <string id="368">IMDb</string>
   <string id="369">Τίτλος</string>
   <string id="370">Καταιγίδες</string>
   <string id="371">Διάσπαρτα</string>
-  <string id="372">ΥεÏ\84Ï\8cς</string>
-  <string id="373">Î\91ίθÏ\81ιοÏ\82</string>
+  <string id="372">Î\9aÏ\85Ï\81ίÏ\89ς</string>
+  <string id="373">Î\97λιοÏ\86άνεια</string>
   <string id="374">Νέφη</string>
   <string id="375">Χιόνι</string>
   <string id="376">Βροχή</string>
   <string id="382">Σποραδικά</string>
   <string id="383">Άνεμος</string>
   <string id="384">Δυνατός</string>
-  <string id="385">Î\9dεÏ\86ελÏ\8eδης</string>
+  <string id="385">Î\89Ï\80ιος</string>
   <string id="386">Αίθριος</string>
   <string id="387">Νεφοσκεπής</string>
   <string id="388">τις πρώτες πρωινές ώρες</string>
   <string id="389">Μπόρα</string>
-  <string id="390">ΣÏ\8dνÏ\84ομεÏ\82 Îµλαφρές χιονοπτώσεις</string>
+  <string id="390">Î\95λαφρές χιονοπτώσεις</string>
   <string id="391">Ελαχ.</string>
   <string id="392">Μεσ.</string>
   <string id="393">Μεγ.</string>
   <string id="394">Ομίχλη</string>
-  <string id="395">Î\9aαÏ\84αÏ\87νιά</string>
+  <string id="395">Î\9eηÏ\81ά Î±Ï\87λή</string>
   <string id="396">Επιλογή τοποθεσίας</string>
   <string id="397">Ανανέωση χρόνου</string>
   <string id="398">Μονάδα θερμοκρασίας</string>
   <string id="406">Υγρασία</string>
 
   <string id="409">Προεπιλεγμένα</string>
-  <string id="410">ΠÏ\81Ï\8cÏ\83βαÏ\83η Ï\83Ï\84ο Weather.com</string>
-  <string id="411">ΠληÏ\81οÏ\86οÏ\81ίεÏ\82 ÎºÎ±Î¹Ï\81οÏ\8d:</string>
-  <string id="412">Αδυναμία λήξης δεδομένων καιρού</string>
+  <string id="410">ΠÏ\81Ï\8cÏ\83βαÏ\83η Ï\83Ï\84ην Ï\85Ï\80ηÏ\81εÏ\83ία ÎºÎ±Î¹Ï\81οÏ\8d</string>
+  <string id="411">Î\91νάκÏ\84ηÏ\83η ÎºÎ±Î¹Ï\81οÏ\8d Î³Î¹Î±:</string>
+  <string id="412">Αδυναμία λήψης δεδομένων καιρού</string>
   <string id="413">Χειροκίνητα</string>
   <string id="414">Καμιά κριτική για το άλμπουμ</string>
   <string id="415">Λήψη μικρογραφίας...</string>
   <string id="416">Μη διαθέσιμος πόρος</string>
-  <string id="417">ΠÏ\81οβολή: Î\95ικÏ\8cνεÏ\82</string>
+  <string id="417">ΠÏ\81οβολή: Î\9cεγ. Î\95ικονίδια</string>
   <string id="418">Ελαχ.</string>
   <string id="419">Μεγ.</string>
   <string id="420">HDMI</string>
   <string id="425">Δεν βρέθηκαν πληροφορίες για το άλμπουμ</string>
   <string id="426">Δεν βρέθηκαν πληροφορίες για το CD</string>
   <string id="427">Δίσκος</string>
-  <string id="428">Î\95ιÏ\83αγÏ\89γή Î¿Ï\81θοÏ\8d CD/DVD</string>
+  <string id="428">Î\95ιÏ\83άγεÏ\84ε Ï\84ο Ï\83Ï\89Ï\83Ï\84Ï\8c CD/DVD</string>
   <string id="429">Παρακαλώ, εισάγετε τον ακόλουθο δίσκο:</string>
-  <string id="430">Ταξιν.: DVD#</string>
+  <string id="430">Ταξ.: DVD#</string>
   <string id="431">Δεν υπάρχει ελεύθερη λανθάνουσα μνήμη</string>
   <string id="432">Διαγραφή ταινίας από τη συλλογή</string>
   <string id="433">Να διαγραφεί '%s';</string>
   <string id="440">Σκληρός δίσκος</string>
   <string id="441">UDF</string>
   <string id="442">Τοπικό δίκτυο</string>
-  <string id="443">Internet</string>
+  <string id="443">Διαδίκτυο</string>
   <string id="444">Βίντεο</string>
   <string id="445">Ήχος</string>
   <string id="446">DVD</string>
   <string id="463">Οπίσθιος φωτισμός</string>
   <string id="464">Φωτεινότητα</string>
   <string id="465">Αντίθεση</string>
-  <string id="466">Συντελεστής γάμα</string>
+  <string id="466">ΣÏ\85νÏ\84ελεÏ\83Ï\84ήÏ\82 Î³Î¬Î¼Î¼Î±</string>
   <string id="467">Τύπος</string>
-  <string id="468">Î\9cεÏ\84ακίνηÏ\83η Ï\84ηÏ\82 Î¼Ï\80άÏ\81αÏ\82 Î³Î¹Î± Ï\84ην αλλαγή της θέσης των απεικονίσεων οθόνης (OSD)</string>
+  <string id="468">Î\9cεÏ\84ακινήÏ\83Ï\84ε Ï\84η Î¼Ï\80άÏ\81α Î³Î¹Î± αλλαγή της θέσης των απεικονίσεων οθόνης (OSD)</string>
   <string id="469">Θέση απεικονίσεων οθόνης (OSD)</string>
   <string id="470">Συντελεστές</string>
   <string id="471">Τσιπάκι</string>
 
   <string id="485">Διαγραφή άλμπουμ</string>
   <string id="486">Επανάληψη</string>
-  <string id="487">Î\95Ï\80ανάληÏ\88η Ï\84οÏ\85 Î¹Î´Î¯ου</string>
-  <string id="488">Επανάληψη φακέλων</string>
+  <string id="487">Î\95Ï\80ανάληÏ\88η Ï\84οÏ\85 Î¯Î´Î¹ου</string>
+  <string id="488">Επανάληψη φακέλου</string>
   <string id="489">Αυτόματη αναπαραγωγή επόμενου κομματιού</string>
-  <string id="491">- Χρήση Μ. εικονιδίων</string>
+  <string id="491">- Χρήση Μεγ. εικονιδίων</string>
   <string id="492">Μεγέθυνση υποτίτλων</string>
   <string id="493">Ρυθμίσεις για προχωρημένους!</string>
   <string id="494">Εύρος στάθμης γενικού ήχου</string>
   <string id="495">Αύξηση δειγματοληψίας ανάλυσης σε γραφικό περιβάλλον (GUI)</string>
   <string id="496">Βαθμονόμηση</string>
   <string id="497">Εμφάνιση επεκτάσεων αρχείων</string>
-  <string id="498">Ταξιν: Τύπος</string>
+  <string id="498">Ταξ.: Τύπος</string>
   <string id="499">Αδυναμία σύνδεσης στην υπηρεσία έρευνας</string>
   <string id="500">Απέτυχε η λήψη των πληροφοριών άλμπουμ</string>
   <string id="501">Αναζήτηση για ονόματα άλμπουμ...</string>
   <string id="503">Απασχολημένο</string>
   <string id="504">Κενός</string>
   <string id="505">Φόρτωση πληροφοριών πολυμέσων...</string>
-  <string id="507">Ταξιν: Χρήση</string>
-  <string id="510">Î\95νεÏ\81γοÏ\80οίηÏ\83η Î±Ï\80εικονίσεων</string>
+  <string id="507">Ταξ.: Χρήση</string>
+  <string id="510">Î\95νεÏ\81γοÏ\80οίηÏ\83η Î¿Ï\80Ï\84ικοÏ\80οιήσεων</string>
   <string id="511">Ενεργοποίηση εναλλαγής λειτουργίας βίντεο</string>
   <string id="512">Παράθυρο εκκίνησης</string>
   <string id="513">Αρχική οθόνη</string>
   <string id="518">Εκκίνηση</string>
   <string id="519">Εκκίνηση σε...</string>
 
-  <string id="521">ΣÏ\85λλογές</string>
+  <string id="521">ΣÏ\85νθέÏ\83εις</string>
   <string id="522">Απομάκρυνση πηγής</string>
   <string id="523">Εναλλαγή πολυμέσων</string>
   <string id="524">Επιλογή λίστας αναπαραγωγής</string>
   <string id="526">Προσθήκη στη λίστα αναπαραγωγής</string>
   <string id="527">Χειροκίνητη προσθήκη στη συλλογή</string>
   <string id="528">Εισάγετε τίτλο</string>
-  <string id="529">Σφάλμα: Διπλός τίτλος</string>
+  <string id="529">ΣÏ\86άλμα: Î\94ιÏ\80λÏ\8cÏ\84Ï\85Ï\80οÏ\82 Ï\84ίÏ\84λοÏ\82</string>
   <string id="530">Επιλέξτε είδος</string>
   <string id="531">Νέο είδος</string>
   <string id="532">Χειροκίνητη προσθήκη</string>
   <string id="535">Λίστα</string>
   <string id="536">Εικονίδια</string>
   <string id="537">Μεγάλη λίστα</string>
-  <string id="538">Î\95ικÏ\8cνεÏ\82</string>
+  <string id="538">Î\9cεγ. Î\95ικονίδια</string>
   <string id="539">Ευρεία</string>
   <string id="540">Πολύ ευρεία</string>
-  <string id="541">Εικόνες άλμπουμ</string>
-  <string id="542">Εικόνες DVD</string>
+  <string id="541">Εικον. άλμπουμ</string>
+  <string id="542">Εικον. DVD</string>
   <string id="543">DVD</string>
   <string id="544">Πληροφορίες</string>
   <string id="545">Συσκευή εξόδου ήχου</string>
   <string id="547">Δεν υπάρχει βιογραφία γι΄ αυτόν τον καλλιτέχνη</string>
   <string id="548">Υποβιβασμός πολυκάναλου ήχου σε στερεοφωνικό</string>
 
-  <string id="550">Î\9aαÏ\84άÏ\84αξη: %s</string>
+  <string id="550">Ταξ.: %s</string>
   <string id="551">Όνομα</string>
   <string id="552">Ημερομηνία</string>
   <string id="553">Μέγεθος</string>
   <string id="554">Κομμάτι</string>
-  <string id="555">Î\8fÏ\81α</string>
+  <string id="555">ΧÏ\81Ï\8cνοÏ\82</string>
   <string id="556">Τίτλος</string>
   <string id="557">Καλλιτέχνης</string>
   <string id="558">Άλμπουμ</string>
   <string id="562">Έτος</string>
   <string id="563">Αξιολόγηση</string>
   <string id="564">Τύπος</string>
-  <string id="565">ΧÏ\81ηÏ\83ιμÏ\8cÏ\84ηÏ\84α</string>
-  <string id="566">Î\86λμÏ\80οÏ\85μ ÎºÎ±Î»Î»Î¹Ï\84έÏ\87νη</string>
+  <string id="565">ΧÏ\81ήÏ\83η</string>
+  <string id="566">Î\9aαλλιÏ\84έÏ\87νηÏ\82 Î\86λμÏ\80οÏ\85μ</string>
   <string id="567">Αναπαράχθηκε</string>
   <string id="568">Τελευταία αναπαραγωγή</string>
   <string id="569">Σχόλια</string>
-  <string id="570">Î\97μ/νία Ï\80Ï\81οÏ\83άÏ\81Ï\84ηÏ\83ης</string>
+  <string id="570">Î\97μ/νία Ï\80Ï\81οÏ\83θήκης</string>
   <string id="571">Προεπιλεγμένη</string>
   <string id="572">Εταιρεία (studio)</string>
   <string id="573">Διαδρομή</string>
   <string id="576">Αριθμός αναπαραγωγών</string>
 
   <string id="580">Σειρά ταξινόμησης</string>
-  <string id="581">Î\9aÏ\81ιÏ\84ήÏ\81ια ταξινόμησης</string>
+  <string id="581">Î\9cέθοδοÏ\82 ταξινόμησης</string>
   <string id="582">Λειτουργία Προβολής</string>
   <string id="583">Απομνημόνευση προβολών διαφορετικών φακέλων</string>
   <string id="584">Αύξουσα</string>
   <string id="591">Όχι</string>
   <string id="592">Ένα</string>
   <string id="593">Όλα</string>
-  <string id="594">Î\9dαι</string>
+  <string id="594">Î\8cÏ\87ι</string>
   <string id="595">Επανάληψη: Όχι</string>
   <string id="596">Επανάληψη: Μία φορά</string>
   <string id="597">Επανάληψη: Όλων</string>
 
-  <string id="600">Î\95γγραφή CD ήχου</string>
+  <string id="600">Î\91νÏ\84ιγραφή CD ήχου</string>
   <string id="601">Μεσαία</string>
   <string id="602">Κανονική</string>
   <string id="603">Ακραία</string>
-  <string id="604">Σταθερός ρυθμός</string>
-  <string id="605">Î\95γγραφή...</string>
+  <string id="604">Σταθερό bitrate</string>
+  <string id="605">Î\91νÏ\84ιγραφή...</string>
 
   <string id="607">Προς:</string>
-  <string id="608">Î\91δÏ\85ναμία ÎµÎ³γραφής CD ή κομματιού</string>
-  <string id="609">Î\94εν Î¿Ï\81ίÏ\83θηκε Î´Î¹Î±Î´Ï\81ομή ÎµÎ¾Î±Î³Ï\89γής CDDA.</string>
-  <string id="610">Î\95γγραφή κομματιού</string>
+  <string id="608">Î\91δÏ\85ναμία Î±Î½Ï\84ιγραφής CD ή κομματιού</string>
+  <string id="609">Î\94εν Î¿Ï\81ίÏ\83θηκε Î´Î¹Î±Î´Ï\81ομή Î±Î½Ï\84ιγÏ\81αÏ\86ής CDDA.</string>
+  <string id="610">Î\91νÏ\84ιγραφή κομματιού</string>
   <string id="611">Εισαγωγή αριθμού</string>
   <string id="612">Bits/Sample</string>
   <string id="613">Συχνότητα δειγματοληψίας</string>
 
-  <string id="620">CDs ήχου</string>
+  <string id="620">CD ήχου</string>
   <string id="621">Κωδικοποιητής</string>
   <string id="622">Ποιότητα</string>
-  <string id="623">Ρυθμός</string>
+  <string id="623">Bitrate</string>
   <string id="624">Συμπερίληψη αριθμού κομματιού</string>
   <string id="625">Όλα τα τραγούδια</string>
   <string id="629">Λειτουργία προβολής</string>
 
   <string id="700">Εκκαθάριση συλλογής</string>
   <string id="701">Απομάκρυνση παλαιών τραγουδιών από τη συλλογή</string>
-  <string id="702">Η διαδρομή έχει σαρωθεί προηγούμενος</string>
+  <string id="702">Η διαδρομή έχει σαρωθεί παλαιότερα</string>
   <string id="705">Δίκτυο</string>
   <string id="706">- Διακομιστής</string>
 
-  <string id="708">ΧÏ\81ήÏ\83η ÎµÎ½Ï\8cÏ\82 Î´Î¹Î±Î¼ÎµÏ\83ολαβηÏ\84ή HTTP Î³Î¹Î± Ï\80Ï\81Ï\8cÏ\83βαÏ\83η Ï\83Ï\84ο internet</string>
+  <string id="708">ΧÏ\81ήÏ\83η Î´Î¹Î±Î¼ÎµÏ\83ολαβηÏ\84ή HTTP Î³Î¹Î± Ï\80Ï\81Ï\8cÏ\83βαÏ\83η Ï\83Ï\84ο Î\94ιαδίκÏ\84Ï\85ο</string>
 
   <string id="711">Πρωτόκολλο Internet (IP)</string>
-  <string id="712">ΠÏ\81οÏ\83διοÏ\81ίÏ\83αÏ\84ε Î»Î¬Î¸Î¿Ï\82 Î¸Ï\8dÏ\81α. Î\97 Ï\84ιμή ÎºÏ\85μαίνεÏ\84αι μεταξύ 1 και 65535.</string>
+  <string id="712">Î\9fÏ\81ίÏ\83Ï\84ηκε Î»Î¬Î¸Î¿Ï\82 Î¸Ï\8dÏ\81α. Î\97 Ï\84ιμή Ï\80Ï\81έÏ\80ει Î½Î± ÎµÎ¯Î½αι μεταξύ 1 και 65535.</string>
   <string id="713">Διαμεσολαβητής HTTP</string>
 
-  <string id="715">- Î\95κÏ\87Ï\8eÏ\81ηση</string>
+  <string id="715">- Î\91νάθεση</string>
   <string id="716">Αυτόματη (DHCP)</string>
   <string id="717">Χειροκίνητη (Στατική)</string>
 
   <string id="721">- Προεπιλεγμένη πύλη</string>
   <string id="722">- Διακομιστής DNS</string>
   <string id="723">Αποθήκευση &amp; επανεκκίνηση</string>
-  <string id="724">ΠÏ\81οÏ\83διοÏ\81ίÏ\83Ï\84ηκε ÎµÏ\83Ï\86αλμένη Î´Î¹ÎµÏ\8dθÏ\85νÏ\83η. Î\97 Ï\84ιμή Ï\80ρέπει να έχει τη μορφή AAA.BBB.CCC.DDD</string>
+  <string id="724">Î\9fÏ\81ίÏ\83Ï\84ηκε Î»Î¬Î¸Î¿Ï\82 Î´Î¹ÎµÏ\8dθÏ\85νÏ\83η. Î ρέπει να έχει τη μορφή AAA.BBB.CCC.DDD</string>
   <string id="725">με τιμές μεταξύ 0 και 255.</string>
-  <string id="726">Î\9fι Î±Î»Î»Î±Î³Î­Ï\82 Î´ÎµÎ½ Î±Ï\80οθηκεÏ\8dÏ\84ηκαν. Î£Ï\85νέÏ\87ιÏ\83η χωρίς αποθήκευση;</string>
+  <string id="726">Î\9fι Î±Î»Î»Î±Î³Î­Ï\82 Î´ÎµÎ½ Î±Ï\80οθηκεÏ\8dÏ\84ηκαν. Î£Ï\85νέÏ\87εια χωρίς αποθήκευση;</string>
   <string id="727">Διακομιστής Ιστού</string>
   <string id="728">Διακομιστής FTP</string>
 
 
   <string id="732">Αποθήκευση &amp; εφαρμογή</string>
   <string id="733">- Κωδικός πρόσβασης</string>
-  <string id="734">Χωρίς κωδικό πρόσβασης</string>
+  <string id="734">Χωρίς κωδικό</string>
   <string id="735">- Κωδικοποίηση χαρακτήρων</string>
   <string id="736">- Στυλ</string>
   <string id="737">- Χρώμα</string>
   <string id="742">Λευκό</string>
   <string id="743">Κίτρινο</string>
   <string id="744">Αρχεία</string>
-  <string id="745">Î\94εν Ï\85Ï\80άÏ\81Ï\87ει Ï\80ληÏ\81οÏ\86οÏ\81ία Î³Î¹Î\84 Î±Ï\85Ï\84ή την προβολή</string>
-  <string id="746">Απενεργοποιήστε την λειτουργία συλλογής</string>
-  <string id="747">Σφάλμα κατά την φόρτωση της εικόνας</string>
+  <string id="745">Î\9aαμία Ï\80ληÏ\81οÏ\86οÏ\81ία Î³Î¹Î± Î±Ï\85Ï\84ήν την προβολή</string>
+  <string id="746">Απενεργοποιήστε τη λειτουργία συλλογής</string>
+  <string id="747">Σφάλμα κατά τη φόρτωση της εικόνας</string>
   <string id="748">Επεξεργασία διαδρομής</string>
   <string id="749">Kατοπτρική εικόνα</string>
   <string id="750">Είστε σίγουρος;</string>
   <string id="760">Κίτρινο</string>
   <string id="761">Λευκό</string>
   <string id="762">Μπλε</string>
-  <string id="763">ΦÏ\89Ï\84εινÏ\8c πράσινο</string>
+  <string id="763">Î\88νÏ\84ονο πράσινο</string>
   <string id="764">Κιτρινοπράσινο</string>
   <string id="765">Κυανό</string>
   <string id="766">Ανοικτό γκρι</string>
   <string id="772">Έξοδος ήχου</string>
   <string id="773">Αναζήτηση</string>
   <string id="774">Φάκελος παρουσίασης διαφανειών</string>
-  <string id="775">Διασύνδεση</string>
+  <string id="775">Διασύνδεση δικτύου</string>
   <string id="776">- Όνομα ασύρματου δικτύου (ESSID)</string>
   <string id="777">- Κωδικός πρόσβασης ασύρματου δικτύου</string>
   <string id="778">- Ασφάλεια ασύρματου δικτύου</string>
   <string id="781">WEP</string>
   <string id="782">WPA</string>
   <string id="783">WPA2</string>
-  <string id="784">Εφαρμογή των ρυθμίσεων διασύνδεσης δικτύου. Παρακαλώ, περιμένετε.</string>
-  <string id="785">Επιτυχής εκκίνηση της διασύνδεσης δικτύου.</string>
-  <string id="786">Δεν ήταν επιτυχής η εκκίνηση της διασύνδεσης  δικτύου.</string>
+  <string id="784">Εφαρμογή των ρυθμίσεων διασύνδεσης δικτύου. Παρακαλώ περιμένετε.</string>
+  <string id="785">Επιτυχής επανεκκίνηση της διασύνδεσης δικτύου.</string>
+  <string id="786">Δεν ήταν επιτυχής η εκκίνηση της διασύνδεσης δικτύου.</string>
   <string id="787">Απενεργοποίηση Διασύνδεσης</string>
   <string id="788">Η Διασύνδεση δικτύου απενεργοποιήθηκε επιτυχώς.</string>
   <string id="789">Όνομα ασύρματου δικτύου (ESSID)</string>
 
-  <string id="791">Έγκριση σε προγράμματα απομακρυσμένου ελέγχου να ελέγξουν το XBMC</string>
+  <string id="791">Έγκριση σε προγράμματα του συστήματος να ελέγχουν το XBMC</string>
   <string id="792">Θύρα</string>
-  <string id="793">Î\95Ï\8dÏ\81οÏ\82 Î¸Ï\8dÏ\81αÏ\82</string>
-  <string id="794">Î\88γκÏ\81ιÏ\83η Ï\83ε Ï\80Ï\81ογÏ\81άμμαÏ\84α Î¬Î»Î»Ï\89ν Ï\85Ï\80ολογιÏ\83Ï\84Ï\8eν Î½Î± ÎµÎ»Î­Î³Î¾ουν το XBMC</string>
+  <string id="793">Î\95Ï\8dÏ\81οÏ\82 Î¸Ï\85Ï\81Ï\8eν</string>
+  <string id="794">Î\88γκÏ\81ιÏ\83η Ï\83ε Ï\80Ï\81ογÏ\81άμμαÏ\84α Î¬Î»Î»Ï\89ν Ï\83Ï\85Ï\83Ï\84ημάÏ\84Ï\89ν Î½Î± ÎµÎ»Î­Î³Ï\87ουν το XBMC</string>
   <string id="795">Αρχική καθυστέρηση (ms)</string>
   <string id="796">Συνεχής καθυστέρηση (ms)</string>
   <string id="797">Μέγιστος αριθμός πελατών</string>
-  <string id="798">Πρόσβαση στο internet</string>
+  <string id="798">Πρόσβαση στο Διαδίκτυο</string>
 
-  <string id="850">Î\95ιÏ\83αγÏ\89γή Î¼Î· Î­Î³ÎºÏ\85Ï\81οÏ\85 ÎµÏ\8dÏ\81οÏ\85Ï\82 Ï\84ιμÏ\8eν θύρας</string>
-  <string id="851">Το έγκυρο εύρος τιμών θύρας είναι 1-65535</string>
-  <string id="852">Το έγκυρο εύρος τιμών θύρας είναι 1024-65535</string>
+  <string id="850">Î\95ιÏ\83αγÏ\89γή Î¼Î· Î­Î³ÎºÏ\85Ï\81ηÏ\82 Ï\84ιμήÏ\82 θύρας</string>
+  <string id="851">Το έγκυρο εύρος θυρών είναι 1-65535</string>
+  <string id="852">Το έγκυρο εύρος θυρών είναι 1024-65535</string>
 
   <string id="998">Προσθήκη Μουσικής...</string>
   <string id="999">Προσθήκη Βίντεο...</string>
   <string id="1000">- Προεπισκόπηση</string>
   <string id="1001">Αδυναμία σύνδεσης</string>
-  <string id="1002">Το ΧΒMC είναι ανίκανο να συνδεθεί στο δίκτυο.</string>
-  <string id="1003">Î\91Ï\85Ï\84Ï\8c Î¼Ï\80οÏ\81εί Î½Î± Ï\83Ï\85μβαίνει διότι το δίκτυο δεν είναι συνδεμένο.</string>
-  <string id="1004">Θέλετε οπωσδήποτε να το προσθέσετε;</string>
+  <string id="1002">Το XBMC δεν μπόρεσε να συνδεθεί στο δίκτυο.</string>
+  <string id="1003">Î\91Ï\85Ï\84Ï\8c Î¼Ï\80οÏ\81εί Î½Î± Ï\83Ï\85νέβη διότι το δίκτυο δεν είναι συνδεμένο.</string>
+  <string id="1004">Θέλετε παρ' όλα αυτά να το προσθέσετε;</string>
 
   <string id="1006">Διεύθυνση IP</string>
   <string id="1007">Προσθήκη τοποθεσίας δικτύου</string>
   <string id="1019">Εισαγωγή του ονόματος χρήστη</string>
   <string id="1020">Προσθήκη πηγής %s</string>
   <string id="1021">Εισαγωγή διαδρομών ή αναζήτηση τοποθεσιών πολυμέσων.</string>
-  <string id="1022">Î\95ιÏ\83αγÏ\89γή ÎµÏ\84ικέÏ\84ας για την πηγή πολυμέσων.</string>
+  <string id="1022">Î\95ιÏ\83αγÏ\89γή Î¿Î½Ï\8cμαÏ\84ος για την πηγή πολυμέσων.</string>
   <string id="1023">Αναζήτηση νέου κοινόχρηστου πόρου</string>
   <string id="1024">Αναζήτηση</string>
   <string id="1025">Δεν ήταν δυνατόν να ανακτηθούν οι πληροφορίες καταλόγου.</string>
   <string id="1034">Yπομενού</string>
   <string id="1035">Ενεργοποίηση πλήκτρων υπομενού</string>
   <string id="1036">Αγαπημένα</string>
-  <string id="1037">Î\95Ï\80εκÏ\84άÏ\83ειÏ\82 Î²ίντεο</string>
-  <string id="1038">Î\95Ï\80εκÏ\84άÏ\83ειÏ\82 Î¼ουσικής</string>
-  <string id="1039">Î\95Ï\80εκÏ\84άÏ\83ειÏ\82 Îµικόνας</string>
+  <string id="1037">ΠÏ\81Ï\8cÏ\83θεÏ\84α Î\92ίντεο</string>
+  <string id="1038">ΠÏ\81Ï\8cÏ\83θεÏ\84α Î\9cουσικής</string>
+  <string id="1039">ΠÏ\81Ï\8cÏ\83θεÏ\84α Î\95ικόνας</string>
   <string id="1040">Φόρτωση φακέλου</string>
   <string id="1041">Ανακτήθηκαν %i αντικείμενα</string>
-  <string id="1042">Ανακτήθηκαν %i από %i αντικείμενα</string>
-  <string id="1043">Î\95Ï\80εκÏ\84άÏ\83ειÏ\82 ÎµÏ\86αÏ\81μογής</string>
-  <string id="1044">Ορισμός πρόσθετου σελιδοδείκτη</string>
-  <string id="1045">Ρυθμίσεις επέκτασης</string>
+  <string id="1042">Ανακτήθηκαν %i από τα %i αντικείμενα</string>
+  <string id="1043">ΠÏ\81Ï\8cÏ\83θεÏ\84εÏ\82 Î\95Ï\86αÏ\81μογές</string>
+  <string id="1044">Ορισμός μικρογραφίας plugin</string>
+  <string id="1045">Ρυθμίσεις πρόσθετου</string>
   <string id="1046">Σημεία πρόσβασης</string>
   <string id="1047">Άλλα...</string>
   <string id="1048">- Όνομα χρήστη</string>
   <string id="1203">Προεπιλεγμένο όνομα χρήστη</string>
   <string id="1204">Προεπιλεγμένος κωδικός πρόσβασης</string>
 
-  <string id="1207">WINS διακομιστής</string>
+  <string id="1207">Διακομιστής WINS</string>
   <string id="1208">Προσάρτηση κοινόχρηστων SMB</string>
 
   <string id="1210">Απομάκρυνση</string>
   <string id="1211">Μουσική</string>
   <string id="1212">Βίντεο</string>
-  <string id="1213">ΦÏ\89Ï\84ογÏ\81αÏ\86ίες</string>
+  <string id="1213">Î\95ικÏ\8cνες</string>
   <string id="1214">Αρχεία</string>
   <string id="1215">Μουσική &amp; βίντεο </string>
   <string id="1216">Μουσική &amp; εικόνες</string>
   <string id="1251">Αυτόματος εντοπισμός συστήματος</string>
   <string id="1252">Ψευδώνυμο</string>
 
-  <string id="1254">Î\9dα Î±Ï\80αιÏ\84είÏ\84αι ÎµÏ\80ιβεβαίÏ\89Ï\83η Î³Î¹Î± Î½Î± Ï\83Ï\85νδεθεί</string>
+  <string id="1254">Î\95Ï\80ιβεβαίÏ\89Ï\83η Ï\83Ï\8dνδεÏ\83ηÏ\82</string>
   <string id="1255">Αποστολή ονόματος και κωδικού πρόσβασης χρήστη (FTP)</string>
-  <string id="1256">Î\94ιάÏ\83Ï\84ημα Î¼ÎµÏ\84αλλικοÏ\8d Î¸Î¿Ï\81Ï\8dβοÏ\85</string>
-  <string id="1257">Î\9dα συνδεθείτε στο σύστημα που εντοπίστηκε;</string>
+  <string id="1256">ΧÏ\81ονικÏ\8c Î´Î¹Î¬Ï\83Ï\84ημα ping</string>
+  <string id="1257">Î\95Ï\80ιθÏ\85μείÏ\84ε Î½α συνδεθείτε στο σύστημα που εντοπίστηκε;</string>
 
-  <string id="1260">Î\91ναγγελία Î±Ï\85Ï\84Ï\8eν Ï\84Ï\89ν Ï\85Ï\80ηÏ\81εÏ\83ιÏ\8eν Ï\83ε Î¬Î»Î»Î± Ï\83Ï\85Ï\83Ï\84ήμαÏ\84α Î´Î¹Î±Î¼Î­Ï\83οÏ\85 του Zeroconf</string>
+  <string id="1260">Î\91ναγγελία Î±Ï\85Ï\84Ï\8eν Ï\84Ï\89ν Ï\85Ï\80ηÏ\81εÏ\83ιÏ\8eν Ï\83ε Î¬Î»Î»Î± Ï\83Ï\85Ï\83Ï\84ήμαÏ\84α Î¼Î­Ï\83Ï\89 του Zeroconf</string>
   <string id="1270">Έγκριση στο XBMC να λαμβάνει περιεχόμενο AirPlay</string>
   <string id="1271">Όνομα συσκευής</string>
   <string id="1272">- Χρήση προστασίας με κωδικό</string>
   <string id="1300">Ειδική συσκευή ήχου</string>
   <string id="1301">Ειδική συσκευή διέλευσης</string>
 
-  <string id="1396">ΠÏ\85κνÏ\8c</string>
+  <string id="1396">Î\9cεÏ\84ακινοÏ\8dμενο</string>
   <string id="1397">και</string>
   <string id="1398">Παγωνιά</string>
   <string id="1399">Το βράδυ</string>
   <string id="1408">Πάγος</string>
   <string id="1409">Κρύσταλλοι</string>
   <string id="1410">Άπνοια</string>
-  <string id="1411">και</string>
+  <string id="1411">με</string>
   <string id="1412">θυελλώδης</string>
   <string id="1413">ασθενής βροχή</string>
   <string id="1414">Καταιγίδα</string>
   <string id="1417">Κόκκοι</string>
   <string id="1418">Καταιγίδες (με κεραυνούς)</string>
   <string id="1419">Μπόρες (με κεραυνούς)</string>
-  <string id="1420">Î\9cέÏ\83η</string>
+  <string id="1420">Î\89Ï\80ια</string>
   <string id="1421">Πολύ υψηλή</string>
   <string id="1422">Θυελλώδης</string>
-  <string id="1423">Î\9fμίÏ\87λη</string>
+  <string id="1423">ΥγÏ\81ά Î±Ï\87λή</string>
 
   <!-- strings through to 1450 reserved for weather translation -->
 
-  <string id="1450">Σε ÎºÎ±Ï\84άÏ\83Ï\84αÏ\83η Ï\8dÏ\80νÏ\89Ï\83ης κατά την αναμονή</string>
+  <string id="1450">Î\91Ï\80ενεÏ\81γοÏ\80οίηÏ\83η Î¿Î¸Ï\8cνης κατά την αναμονή</string>
   <!-- strings through to 1470 reserved for power-saving -->
 
   <string id="2050">Διάρκεια</string>
 
   <string id="10000">Αρχική τοποθεσία</string>
   <string id="10001">Εφαρμογές</string>
-  <string id="10002">ΦÏ\89Ï\84ογÏ\81αÏ\86ίες</string>
+  <string id="10002">Î\95ικÏ\8cνες</string>
   <string id="10003">Διαχείριση αρχείων</string>
   <string id="10004">Ρυθμίσεις</string>
   <string id="10005">Μουσική</string>
   <string id="10007">Πληροφορίες συστήματος</string>
   <string id="10008">Ρυθμίσεις - Γενικά</string>
   <string id="10009">Ρυθμίσεις - Οθόνη</string>
-  <string id="10010">ΡÏ\85θμίÏ\83ειÏ\82 - Î\91ιÏ\83θηÏ\84ικά - Βαθμονόμηση γραφικού περιβάλλοντος (GUI)</string>
+  <string id="10010">ΡÏ\85θμίÏ\83ειÏ\82 - Î\95μÏ\86άνιÏ\83η - Βαθμονόμηση γραφικού περιβάλλοντος (GUI)</string>
   <string id="10011">Ρυθμίσεις - Βίντεο - Βαθμονόμηση Οθόνης</string>
-  <string id="10012">ΡÏ\85θμίÏ\83ειÏ\82 - Î¦Ï\89Ï\84ογÏ\81αÏ\86ίες</string>
+  <string id="10012">ΡÏ\85θμίÏ\83ειÏ\82 - Î\95ικÏ\8cνες</string>
   <string id="10013">Ρυθμίσεις - Εφαρμογές</string>
   <string id="10014">Ρυθμίσεις - Καιρός</string>
   <string id="10015">Ρυθμίσεις - Μουσική</string>
   <string id="10034">Ρυθμίσεις - Προφίλ</string>
   <string id="10040">Περιηγητής Πρόσθετων</string>
 
-  <string id="10100">Î\94ιάλογοÏ\82 Ναι/Όχι</string>
-  <string id="10101">Î\94ιάλογοÏ\82 διαδικασίας</string>
+  <string id="10100">ΠαÏ\81άθÏ\85Ï\81ο Ναι/Όχι</string>
+  <string id="10101">ΠαÏ\81άθÏ\85Ï\81ο διαδικασίας</string>
 
   <string id="10210">Αναζήτηση για υπότιτλους...</string>
-  <string id="10211">Προσωρινή αποθήκευση υπότιτλων...</string>
+  <string id="10211">Προσωρινή αποθήκευση υποτίτλων...</string>
   <string id="10212">τερματισμός</string>
   <string id="10213">αποθήκευση</string>
   <string id="10214">Άνοιγμα ροής</string>
   <string id="10507">Ρυθμίσεις</string>
   <string id="10508">Πρόγνωση καιρού</string>
   <string id="10509">Δικτυακό παιχνίδι</string>
-  <string id="10510">Î\9aαÏ\84αλήξεις</string>
+  <string id="10510">Î\95Ï\80εκÏ\84άÏ\83εις</string>
   <string id="10511">Πληροφορίες συστήματος</string>
 
   <string id="10516">Μουσική - Συλλογή</string>
-  <string id="10517">Î\9cοÏ\85Ï\83ική - Î\95κÏ\84ελείÏ\84αι Ï\84Ï\8eÏ\81α</string>
+  <string id="10517">ΤÏ\8eÏ\81α Î\95κÏ\84ελείÏ\84αι - Î\9cοÏ\85Ï\83ική</string>
 
-  <string id="10522">Î\92ίνÏ\84εο - Î\95κÏ\84ελείÏ\84αι Ï\84Ï\8eÏ\81α</string>
-  <string id="10523">Πληροφορίες</string>
+  <string id="10522">ΤÏ\8eÏ\81α Î\95κÏ\84ελείÏ\84αι - Î\92ίνÏ\84εο</string>
+  <string id="10523">Πληροφορίες άλμπουμ</string>
   <string id="10524">Πληροφορίες ταινίας</string>
 
-  <string id="12000">Î\95Ï\80ιλογή Î´Î¹Î±Î»Ï\8cγοÏ\85</string>
+  <string id="12000">ΠαÏ\81άθÏ\85Ï\81ο ÎµÏ\80ιλογήÏ\82</string>
   <string id="12001">Μουσική/Πληροφορίες</string>
-  <string id="12002">Î\94ιάλογοÏ\82 OK</string>
+  <string id="12002">ΠαÏ\81άθÏ\85Ï\81ο 'Î\95Ï\80ιλογή'</string>
   <string id="12003">Βίντεο/Πληροφορίες</string>
   <string id="12004">Scripts/Πληροφορίες</string>
   <string id="12005">Βίντεο πλήρους οθόνης</string>
-  <string id="12006">Î\91Ï\80εικÏ\8cνιÏ\83η Î¼Î¿Ï\85Ï\83ικήÏ\82</string>
+  <string id="12006">Î\9cοÏ\85Ï\83ική Î¿Ï\80Ï\84ικοÏ\80οίηÏ\83η</string>
 
-  <string id="12008">Î\94ιάλογοÏ\82 στοιβαγμένου αρχείου</string>
+  <string id="12008">ΠαÏ\81άθÏ\85Ï\81ο στοιβαγμένου αρχείου</string>
   <string id="12009">Ανακατασκευή περιεχομένων...</string>
   <string id="12010">Επιστροφή στη μουσική</string>
   <string id="12011">Επιστροφή στα βίντεο</string>
 
   <string id="12021">Εκκίνηση από την αρχή</string>
-  <string id="12022">Î\95Ï\80ανεκκίνηÏ\83η από %s</string>
+  <string id="12022">ΣÏ\85νέÏ\87εια από %s</string>
 
   <string id="12310">0</string>
   <string id="12311">1</string>
   <string id="12318">8</string>
   <string id="12319">9</string>
   <string id="12320">c</string>
-  <string id="12321">Εντάξει</string>
+  <string id="12321">Επιλογή</string>
   <string id="12322">*</string>
-  <string id="12325">Î\9aλειδÏ\89μένοÏ\82! Εισαγωγή κωδικού...</string>
+  <string id="12325">Î\9aλειδÏ\8eθηκε! Εισαγωγή κωδικού...</string>
   <string id="12326">Εισαγωγή κωδικού πρόσβασης</string>
   <string id="12327">Εισαγωγή κεντρικού κωδικού</string>
   <string id="12328">Εισάγετε κωδικό ξεκλειδώματος</string>
-  <string id="12329">ή Ï\80αÏ\84ήστε C για ακύρωση</string>
-  <string id="12330">Εισάγετε συνδυασμό πλήκτρων και</string>
-  <string id="12331">Ï\80αÏ\84ήÏ\83Ï\84ε Î\95νÏ\84άξει, Î® Î\95Ï\80ιÏ\83Ï\84Ï\81οÏ\86ή για ακύρωση</string>
-  <string id="12332">ΤοÏ\80οθέÏ\84ηÏ\83η κλειδώματος</string>
+  <string id="12329">ή Ï\80ιέστε C για ακύρωση</string>
+  <string id="12330">Εισάγετε συνδυασμό (combo) πλήκτρων και</string>
+  <string id="12331">Ï\80ιέÏ\83Ï\84ε 'Î\95Ï\80ιλογή', Î® 'Î\95Ï\80ιÏ\83Ï\84Ï\81οÏ\86ή' για ακύρωση</string>
+  <string id="12332">Î\9fÏ\81ιÏ\83μÏ\8cÏ\82 κλειδώματος</string>
   <string id="12333">Ξεκλείδωμα</string>
   <string id="12334">Επανατοποθέτηση κλειδώματος</string>
   <string id="12335">Απομάκρυνση κλειδώματος</string>
   <string id="12337">Αριθμητικός κωδικός πρόσβασης</string>
-  <string id="12338">Συνδυασμός πλήκτρων του μοχλού</string>
+  <string id="12338">Συνδυασμός (combo) πλήκτρων του μοχλού</string>
   <string id="12339">Κωδικός πρόσβασης πλήρους κειμένου</string>
   <string id="12340">Εισαγωγή νέου κωδικού πρόσβασης</string>
   <string id="12341">Επανεισαγωγή νέου κωδικού πρόσβασης</string>
-  <string id="12342">Λάθος κωδικός πρόσβασης.</string>
+  <string id="12342">Λάθος κωδικός πρόσβασης,</string>
   <string id="12343">δοκιμές έμειναν </string>
   <string id="12344">Ο κωδικός πρόσβασης δεν ταιριάζει.</string>
-  <string id="12345">Î\94εν ÎµÏ\80ιÏ\84Ï\81άÏ\80ηκε η πρόσβαση</string>
+  <string id="12345">Î\94εν ÎµÏ\80ιÏ\84Ï\81έÏ\80εÏ\84αι η πρόσβαση</string>
   <string id="12346">Οι δοκιμές εισαγωγής κωδικού πρόσβασης εξαντλήθηκαν.</string>
   <string id="12347">Το σύστημα τώρα θα απενεργοποιηθεί.</string>
   <string id="12348">Το αντικείμενο κλειδώθηκε</string>
   <string id="12360">Κεντρικό κλείδωμα</string>
   <string id="12362">Απενεργοποίηση συστήματος όταν εξαντληθούν οι προσπάθειες εισαγωγής</string>
   <string id="12367">Ο κεντρικός κωδικός δεν είναι έγκυρος</string>
-  <string id="12368">Παρακαλώ, εισάγετε έναν έγκυρο κεντρικό κωδικό</string>
-  <string id="12373">Ρυθμίσεις &amp;  διαχείριση αρχείων</string>
+  <string id="12368">Παρακαλώ εισάγετε έναν έγκυρο κεντρικό κωδικό</string>
+  <string id="12373">Ρυθμίσεις &amp; διαχείριση αρχείων</string>
   <string id="12376">Ορισμός ως προεπιλογή για όλες τις ταινίες</string>
   <string id="12377">Διαγράφει όλες τις προηγούμενες αποθηκευμένες τιμές</string>
   <string id="12378">Χρονικό διάστημα προβολής κάθε εικόνας</string>
   <string id="12379">Εφέ προσαρμογής αναλογιών σήματος (pan &amp; zoom)</string>
 
-  <string id="12383">Î\9aανονικÏ\8c Ï\81ολÏ\8cι</string>
-  <string id="12384">ΨηÏ\86ιακÏ\8c Ï\81ολÏ\8cι</string>
+  <string id="12383">ΡολÏ\8cι 12 Ï\89Ï\81Ï\8eν</string>
+  <string id="12384">ΡολÏ\8cι 24 Ï\89Ï\81Ï\8eν</string>
   <string id="12385">Μέρα/Μήνας</string>
   <string id="12386">Μήνας/Μέρα</string>
 
   <string id="13008">Λειτουργία τερματισμού</string>
   <string id="13009">Έξοδος</string>
   <string id="13010">Αδρανοποίηση</string>
-  <string id="13011">Î\8eÏ\80νÏ\89Ï\83η</string>
+  <string id="13011">Î\91ναÏ\83Ï\84ολή</string>
   <string id="13012">Έξοδος</string>
   <string id="13013">Επανεκκίνηση Συστήματος</string>
   <string id="13014">Ελαχιστοποίηση</string>
   <string id="13015">Ενέργεια πλήκτρου λειτουργίας</string>
   <string id="13016">Απενεργοποίηση συστήματος</string>
 
-  <string id="13020">Είναι ενεργή άλλη συνεδρία (ίσως μέσω ssh);</string>
-  <string id="13021">ΠÏ\81οÏ\83άÏ\81Ï\84ηÏ\83η Î±Î½Î±Î¹Ï\81οÏ\8dμενοÏ\85 Î´Î¯Ï\83κοÏ\85</string>
-  <string id="13022">Î\95Ï\80ισφαλής αφαίρεση συσκευής</string>
+  <string id="13020">Είναι ενεργή άλλη συνεδρία, ίσως μέσω ssh;</string>
+  <string id="13021">ΠÏ\81οÏ\83αÏ\81Ï\84ήθηκε Î±Ï\86αιÏ\81οÏ\8dμενοÏ\82 Î´Î¯Ï\83κοÏ\82</string>
+  <string id="13022">Î\9cη Î±σφαλής αφαίρεση συσκευής</string>
   <string id="13023">Η συσκευή αφαιρέθηκε επιτυχώς</string>
   <string id="13024">Συνδέθηκε χειριστήριο</string>
   <string id="13025">Αποσυνδέθηκε χειριστήριο</string>
   <string id="13106">Ανενεργός</string>
   <string id="13107">Ενεργός κατά την αναπαραγωγή βίντεο</string>
   <string id="13108">Πάντα ενεργός</string>
-  <string id="13109">Δοκιμή ανάλυσης</string>
+  <string id="13109">Δοκιμή &amp; εφαρμογή ανάλυσης</string>
   <string id="13110">Αποθήκευση ανάλυσης;</string>
   <string id="13111">Θέλετε να διατηρήσετε αυτή την ανάλυση;</string>
 
   <string id="13114">Ενεργό για περιεχόμενο SD</string>
   <string id="13115">Πάντα ενεργό</string>
 
-  <string id="13116">Μέθοδος ανακλιμακοθέτησης</string>
-  <string id="13117">Δικυβική</string>
+  <string id="13116">Μέθοδος Upscaling</string>
+  <string id="13117">Bicubic</string>
   <string id="13118">Lanczos</string>
   <string id="13119">Sinc</string>
   <string id="13120">VDPAU</string>
-  <string id="13121">VDPAU HQ ανακλιμακοθέτηση</string>
-  <string id="13122">VDPAU Î\9cεÏ\84αÏ\84Ï\81οÏ\80ή Ï\83Ï\84άθμηÏ\82 Ï\87Ï\81Ï\8eμαÏ\84οÏ\82</string>
+  <string id="13121">VDPAU HQ Upscaling επίπεδο</string>
+  <string id="13122">VDPAU Î\9cεÏ\84αÏ\84Ï\81οÏ\80ή Ï\87Ï\81Ï\8eμαÏ\84οÏ\82 ÎµÏ\80ιÏ\80έδοÏ\85 Ï\83Ï\84οÏ\8dνÏ\84ιο</string>
 
-  <string id="13130">Î\9aενÏ\8c Ï\83ε Î¬Î»Î»ÎµÏ\82 Î±Ï\80εικονίÏ\83εις</string>
+  <string id="13130">Î\9aενÏ\8c Ï\83ε Î¬Î»Î»ÎµÏ\82 Î¿Î¸Ï\8cνες</string>
   <string id="13131">Ανενεργή</string>
-  <string id="13132">Î\9aενέÏ\82 Î±Ï\80εικονίÏ\83εις</string>
+  <string id="13132">Î\9aενέÏ\82 Î¿Î¸Ï\8cνες</string>
 
   <string id="13140">Έχουν ανιχνευτεί ενεργές συνδέσεις!</string>
-  <string id="13141">Î\95άν Ï\83Ï\85νεÏ\87ίÏ\83εÏ\84ε, Î´ÎµÎ½ Î¸Î± ÎµÎ¯Î½Î±Î¹ Î´Ï\85ναÏ\84Ï\8cÏ\82 Ï\80λέον Î¿ Î­Î»ÎµÎ³Ï\87οÏ\82 του XBMC.</string>
+  <string id="13141">Î\91ν Ï\83Ï\85νεÏ\87ίÏ\83εÏ\84ε, Î¼Ï\80οÏ\81εί Î½Î± Ï\87άÏ\83εÏ\84ε Ï\84ον Î­Î»ÎµÎ³Ï\87ο του XBMC.</string>
   <string id="13142">Να διακοπεί η λειτουργία του Απομακρυσμένου διακομιστή;</string>
 
-  <string id="13144">Î\91λλαγή ÎºÎ±Ï\84άÏ\83Ï\84αÏ\83ηÏ\82 Ï\83Ï\85Ï\83κεÏ\85ήÏ\82 (Apple Remote);</string>
-  <string id="13145">Εάν χρησιμοποιείτε τώρα τη συσκευή (Apple Remote) για να</string>
-  <string id="13146">ελέγξετε το XBMC, η αλλαγή της ρύθμισης αυτής θα επηρεάσει</string>
+  <string id="13144">Î\91λλαγή Î»ÎµÎ¹Ï\84οÏ\85Ï\81γίαÏ\82 Ï\83Ï\85Ï\83κεÏ\85ήÏ\82 Apple Remote;</string>
+  <string id="13145">Εάν χρησιμοποιείτε τώρα τη συσκευή Apple Remote για να</string>
+  <string id="13146">ελέγχετε το XBMC, η αλλαγή αυτής της ρύθμισης θα επηρεάσει</string>
   <string id="13147">την ικανότητα ελέγχου του. Θέλετε να συνεχίσετε;</string>
 
   <string id="13159">Μάσκα Υποδικτύου</string>
   <string id="13170">Ποτέ</string>
   <string id="13171">Αμέσως</string>
   <string id="13172">Μετά από %i δευτ.</string>
-  <string id="13173">Ημερομηνία εγκατάστασης</string>
-  <string id="13174">Πλήθος περιστροφών σε ισχύ</string>
+  <string id="13173">Ημερομηνία εγκατάστασης:</string>
+  <string id="13174">Πλήθος περιστροφών σε ισχύ:</string>
 
   <string id="13200">Προφίλ</string>
   <string id="13201">Διαγραφή προφίλ '%s';</string>
   <string id="13209">Διάρκεια κουδουνισμού (σε λεπτά)</string>
   <string id="13210">Εκκίνηση ξυπνητηριού σε %im</string>
   <string id="13211">Συναγερμός!</string>
-  <string id="13212">Ακυρώθηκε %im%is απέμειναν</string>
-  <string id="13213">%2.0fm</string>
-  <string id="13214">%2.0fs</string>
+  <string id="13212">Ακυρώθηκε με %im%is να απομένουν</string>
+  <string id="13213">%2.0fm</string> <!--minutes (left from countdown)-->
+  <string id="13214">%2.0fs</string> <!--seconds (left from countdown)-->
 
-  <string id="13249">Αναζήτηση υποτίτλων στα RARs</string>
+  <string id="13249">Αναζήτηση υποτίτλων σε RAR</string>
   <string id="13250">Αναζήτηση για υπότιτλο...</string>
   <string id="13251">Μετακίνηση αντικειμένου</string>
   <string id="13252">Μετακίνηση αντικειμένου εδώ</string>
   <string id="13253">Ακύρωση μετακίνησης</string>
 
-  <string id="13270">Υλικό</string>
-  <string id="13271">ΤαÏ\87Ï\8dÏ\84ηÏ\84α CPU</string>
+  <string id="13270">Υλικό:</string>
+  <string id="13271">ΧÏ\81ήÏ\83η CPU:</string>
 
-  <string id="13274">ΣÏ\85νδέθηκε, Î±Î»Î»Î¬ Î· Î´Î¹ÎµÏ\8dθÏ\85νÏ\83η DNS Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹ Î´Î¹Î±Î¸Î­Ï\83ιμη.</string>
+  <string id="13274">ΣÏ\85νδέθηκε, Î±Î»Î»Î¬ Î´ÎµÎ½ Ï\85Ï\80άÏ\81Ï\87ει Î´Î¹Î±Î¸Î­Ï\83ιμη DNS.</string>
   <string id="13275">Σκληρός δίσκος</string>
   <string id="13276">DVD-ROM</string>
   <string id="13277">Μέσα αποθήκευσης</string>
   <string id="13280">Βίντεο</string>
   <string id="13281">Υλικό</string>
 
-  <string id="13283">Λειτουργικό σύστημα</string>
-  <string id="13284">Ταχύτητα CPU</string>
+  <string id="13283">Λειτουργικό σύστημα:</string>
+  <string id="13284">Ταχύτητα CPU:</string>
 
   <string id="13286">Κωδικοποιητής βίντεο:</string>
-  <string id="13287">Ανάλυση οθόνης</string>
+  <string id="13287">Ανάλυση οθόνης:</string>
 
-  <string id="13292">Καλώδιο A/V</string>
+  <string id="13292">Καλώδιο A/V:</string>
 
-  <string id="13294">Περιοχή DVD</string>
-  <string id="13295">Internet</string>
+  <string id="13294">Περιοχή DVD:</string>
+  <string id="13295">Διαδίκτυο:</string>
   <string id="13296">Συνδέθηκε</string>
   <string id="13297">Δε συνδέθηκε. Ελέγξτε τις ρυθμίσεις δικτύου.</string>
 
-  <string id="13299">Î\98εÏ\81μοκÏ\81αÏ\83ία Ï\83Ï\84Ï\8cÏ\87οÏ\82</string>
+  <string id="13299">Î\95Ï\80ιθÏ\85μηÏ\84ή Î¸ÎµÏ\81μοκÏ\81αÏ\83ία</string>
   <string id="13300">Ταχύτητα ανεμιστήρα</string>
   <string id="13301">Αυτόματος έλεγχος θερμοκρασίας</string>
-  <string id="13302">Προτεραιότητα στην ταχύτητα του ανεμιστήρα</string>
+  <string id="13302">Παράκαμψη ταχύτητας ανεμιστήρα</string>
   <string id="13303">- Γραμματοσειρές</string>
   <string id="13304">Ενεργοποίηση αμφίδρομης κατεύθυνσης</string>
   <string id="13305">Εμφάνιση ροών τίτλων ειδήσεων (RSS)</string>
-  <string id="13306">Εμφάνιση περιεχομένων φακέλου</string>
-  <string id="13307">Πρότυπο ονομασίας κομματιού</string>
+  <string id="13306">Εμφάνιση περιεχομένων αρχικού φακέλου</string>
+  <string id="13307">Πρότυπο ονομασίας κομματιών</string>
   <string id="13308">Επιθυμείτε επανεκκίνηση του συστήματος</string>
   <string id="13309">και όχι μόνο του XBMC;</string>
   <string id="13310">Εφέ μεγέθυνσης</string>
   <string id="13312">Ελαχιστοποίηση μαύρης μπάρας</string>
   <string id="13313">Επανεκκίνηση</string>
   <string id="13314">Βαθμιαία εξασθένιση μεταξύ των τραγουδιών</string>
-  <string id="13315">Î\95Ï\80αναδημιοÏ\85Ï\81γία Î¼Î¹ÎºÏ\81ογÏ\81αÏ\86ίαÏ\82</string>
-  <string id="13316">Î\95Ï\80αναλαμβανÏ\8cμενη Î¼Î¹ÎºÏ\81ογÏ\81αÏ\86ία</string>
-  <string id="13317">Προβολή παρουσίασης</string>
-  <string id="13318">Î\95Ï\80αναλαμβανÏ\8cμενη Ï\80αÏ\81οÏ\85Ï\83ίαÏ\83η</string>
+  <string id="13315">Î\95Ï\80αναδημιοÏ\85Ï\81γία Î¼Î¹ÎºÏ\81ογÏ\81αÏ\86ιÏ\8eν</string>
+  <string id="13316">Î\9cικÏ\81ογÏ\81αÏ\86ίεÏ\82 ÎºÎ±Î¹ Ï\83ε Ï\85Ï\80οÏ\86ακέλοÏ\85Ï\82</string>
+  <string id="13317">Παρουσίαση διαφανειών</string>
+  <string id="13318">ΠαÏ\81οÏ\85Ï\83ίαÏ\83η Î´Î¹Î±Ï\86ανειÏ\8eν ÎºÎ±Î¹ Ï\84Ï\89ν Ï\85Ï\80οÏ\86ακέλÏ\89ν</string>
   <string id="13319">Τυχαία διάταξη</string>
   <string id="13320">Στερεοφωνικά</string>
   <string id="13321">Αριστερό μόνο</string>
-  <string id="13322">Î\94εξιÏ\8c μόνο</string>
+  <string id="13322">Î\94εξί μόνο</string>
   <string id="13323">Ενεργοποίηση υποστήριξης karaoke</string>
-  <string id="13324">Î\94ιαÏ\86άνεια Ï\83Ï\84ο Ï\85Ï\80Ï\8cβαθÏ\81Ï\8c</string>
-  <string id="13325">Î\94ιαÏ\86άνεια Ï\83ε Ï\80Ï\81Ï\8eÏ\84ο Ï\80λάνο</string>
+  <string id="13324">Î\94ιαÏ\86άνεια Ï\85Ï\80οβάθÏ\81οÏ\85</string>
+  <string id="13325">Î\94ιαÏ\86άνεια Ï\80Ï\81οÏ\83κήνιοÏ\85</string>
   <string id="13326">A/V καθυστέρηση</string>
   <string id="13327">Karaoke</string>
   <string id="13328">%s δεν βρέθηκε</string>
   <string id="13329">Σφάλμα κατά το άνοιγμα %s</string>
   <string id="13330">Αδυναμία φόρτωσης %s</string>
-  <string id="13331">Σφάλμα: Έλλειψη μνήμης.</string>
+  <string id="13331">Σφάλμα: Έλλειψη μνήμης</string>
   <string id="13332">Μετακίνηση πάνω</string>
   <string id="13333">Μετακίνηση κάτω</string>
   <string id="13334">Επεξεργασία ετικέτας</string>
   <string id="13342">Πορτοκαλί</string>
   <string id="13343">Κόκκινο</string>
   <string id="13344">Κύκλος</string>
-  <string id="13345">ΣβηÏ\83μένη Î· Î»Ï\85Ï\87νία κατά την αναπαραγωγή</string>
+  <string id="13345">Î\91Ï\80ενεÏ\81γοÏ\80οίηÏ\83η Î»Ï\85Ï\87νίαÏ\82 (LED) κατά την αναπαραγωγή</string>
   <string id="13346">Πληροφορίες ταινίας</string>
   <string id="13347">Κομμάτι σε αναμονή</string>
-  <string id="13348">Αναζήτηση IMDb...</string>
+  <string id="13348">Αναζήτηση στο IMDb...</string>
   <string id="13349">Έρευνα για νέο περιεχόμενο</string>
   <string id="13350">Τώρα εκτελείται...</string>
   <string id="13351">Πληροφορίες άλμπουμ</string>
   <string id="13352">Ανίχνευση αντικειμένου στη συλλογή</string>
   <string id="13353">Διακοπή αναζήτησης</string>
   <string id="13354">Μέθοδος απόδοσης</string>
-  <string id="13355">Χαμηλής ποιότητας (Pixel Shader)</string>
+  <string id="13355">Χαμηλής ποιότητας σκίαση pixel</string>
   <string id="13356">Επικαλύψεις υλικού</string>
-  <string id="13357">Υψηλής ποιότητας (Pixel Shader)</string>
+  <string id="13357">Υψηλής ποιότητας σκίαση pixel</string>
   <string id="13358">Αναπαραγωγή αντικειμένου</string>
   <string id="13359">Ορισμός μικρογραφίας καλλιτέχνη</string>
   <string id="13360">Αυτόματη δημιουργία μικρογραφιών</string>
   <string id="13377">Προεπιλεγμένη κατάσταση προβολής</string>
   <string id="13378">Προεπιλεγμένη φωτεινότητα</string>
   <string id="13379">Προεπιλεγμένη αντίθεση</string>
-  <string id="13380">Προεπιλεγμένος συντελεστής γάμα</string>
+  <string id="13380">ΠÏ\81οεÏ\80ιλεγμένοÏ\82 Ï\83Ï\85νÏ\84ελεÏ\83Ï\84ήÏ\82 Î³Î¬Î¼Î¼Î±</string>
   <string id="13381">Συνέχιση βίντεο</string>
   <string id="13382">Μάσκα φωνής - Θύρα 1</string>
   <string id="13383">Μάσκα φωνής - Θύρα 2</string>
   <string id="13384">Μάσκα φωνής - Θύρα 3</string>
   <string id="13385">Μάσκα φωνής - Θύρα 4</string>
-  <string id="13386">Î\91ναζήÏ\84ηÏ\83η Î²Î±Ï\83ιÏ\83μένη Ï\83Ï\84ην Ï\87Ï\81ήÏ\83η χρόνου</string>
+  <string id="13386">Î\91ναζήÏ\84ηÏ\83η Î²Î¬Ï\83ει χρόνου</string>
   <string id="13387">Πρότυπο ονομασίας κομματιού (δεξιά πλευρά)</string>
-  <string id="13388">ΠÏ\81οκαθοÏ\81ιÏ\83μένα</string>
-  <string id="13389">Δεν υπάρχουν διαθέσιμα προκαθορισμένα γι' αυτή την απεικόνιση</string>
-  <string id="13390">Δεν υπάρχουν διαθέσιμες ρυθμίσεις γι' αυτή την απεικόνιση</string>
+  <string id="13388">ΠÏ\81οκαθοÏ\81ιÏ\83μένο</string>
+  <string id="13389">Δεν υπάρχουν διαθέσιμα προκαθορισμένα&#10;γι' αυτή την οπτικοποίηση</string>
+  <string id="13390">Δεν υπάρχουν διαθέσιμες ρυθμίσεις&#10;γι' αυτή την οπτικοποίηση</string>
   <string id="13391">Εξαγωγή/Εισαγωγή</string>
-  <string id="13392">ΧÏ\81ήÏ\83η Î±Ï\80εικονίÏ\83εÏ\89ν ÎºÎ±Ï\84ά Ï\84ην Î±Î½Î±Ï\80αÏ\81αγÏ\89γή Î®Ï\87οÏ\85</string>
+  <string id="13392">ΧÏ\81ήÏ\83η Î¿Ï\80Ï\84ικοÏ\80οιήÏ\83εÏ\89ν ÎºÎ±Ï\84ά Ï\84ην Î±Î½Î±Ï\80αÏ\81αγÏ\89γή Î¼Î¿Ï\85Ï\83ικήÏ\82</string>
   <string id="13393">Υπολόγισε το μέγεθος</string>
   <string id="13394">Υπολογισμός μεγέθους φακέλου</string>
   <string id="13395">Ρυθμίσεις βίντεο</string>
   <string id="13396">Ρυθμίσεις ήχου και υποτίτλων</string>
   <string id="13397">Ενεργοποίηση υποτίτλων</string>
   <string id="13398">Συντομεύσεις</string>
-  <string id="13399">Î\91γνÏ\8cηÏ\83ε Ï\84ο Î¬Ï\81θÏ\81ο "The" ÎºÎ±Ï\84ά Ï\84ην Ï\84αξινÏ\8cμηÏ\83η</string>
-  <string id="13400">Î\92αθμιαία ÎµÎ¾Î±Ï\83θένιÏ\83η Î¼ÎµÏ\84αξÏ\8d Ï\84Ï\89ν Ï\84Ï\81αγοÏ\85διÏ\8eν Ï\84οÏ\85 Î¯Î´Î¹Î¿Ï\85 Î¬Î»Î¼Ï\80οÏ\85μ</string>
+  <string id="13399">Î\91γνÏ\8cηÏ\83ε Ï\84α Î¬Ï\81θÏ\81α ÎºÎ±Ï\84ά Ï\84ην Ï\84αξινÏ\8cμηÏ\83η (Ï\80\87. Ï\84ο "The")</string>
+  <string id="13400">Βαθμιαία εξασθένιση μεταξύ τραγουδιών του ίδιου άλμπουμ</string>
   <string id="13401">Αναζήτηση για %s</string>
   <string id="13402">Εμφάνιση της θέσης του κομματιού</string>
   <string id="13403">Απαλοιφή προεπιλογών</string>
   <string id="13404">Συνέχεια</string>
-  <string id="13405">Î\9cικÏ\81ογÏ\81αÏ\86ία</string>
+  <string id="13405">Î\9bήÏ\88η Î¼Î¹ÎºÏ\81ογÏ\81αÏ\86ίαÏ\82</string>
   <string id="13406">Πληροφορίες εικόνας</string>
   <string id="13407">%s προκαθορισμένα</string>
   <string id="13408">(Αξιολόγηση IMDb)</string>
   <string id="13411">Ελάχιστη ταχύτητα ανεμιστήρα</string>
   <string id="13412">Αναπαραγωγή από εδώ</string>
   <string id="13413">Λήψη</string>
-  <string id="13414">Î\95νÏ\83Ï\89μάÏ\84Ï\89Ï\83η ÎºÎ±Î»Î»Î¹Ï\84εÏ\87νÏ\8eν Ï\80οÏ\85 ÎµÎ¼Ï\86ανίζονÏ\84αι Î¼Ï\8cνο Ï\83Ï\84ιÏ\82 συνθέσεις</string>
+  <string id="13414">ΣÏ\85μÏ\80εÏ\81ίληÏ\88η ÎºÎ±Î»Î»Î¹Ï\84εÏ\87νÏ\8eν Ï\80οÏ\85 ÎµÎ¼Ï\86ανίζονÏ\84αι Î¼Ï\8cνο Ï\83ε συνθέσεις</string>
   <string id="13415">Μέθοδος απόδοσης</string>
   <string id="13416">Αυτόματη ανίχνευση</string>
-  <string id="13417">ΣÏ\84οιÏ\87ειÏ\8eδης (ARB)</string>
-  <string id="13418">Î\95ξειδικεÏ\85μένη (GLSL)</string>
+  <string id="13417">ΣÏ\84οιÏ\87ειÏ\8eδειÏ\82 Ï\83κιαÏ\83Ï\84ές (ARB)</string>
+  <string id="13418">ΠÏ\81οηγμένοι Ï\83κιαÏ\83Ï\84έÏ\82 (GLSL)</string>
   <string id="13419">Λογισμικό</string>
   <string id="13420">Ασφαλής κατάργηση</string>
   <string id="13421">VDPAU</string>
-  <string id="13422">Î\88ναÏ\81ξη Ï\80αÏ\81οÏ\85Ï\83ίαÏ\83ηÏ\82 Î´Î¹Î±Ï\86ανειÏ\8eν εδώ</string>
-  <string id="13423">Î\91Ï\80ομνημÏ\8cνεÏ\85Ï\83η Î±Ï\85Ï\84ήÏ\82 Ï\84ηÏ\82 Î´Î¹Î±Î´Ï\81ομήÏ\82</string>
-  <string id="13424">Χρήση των προσωρινά αποθηκευμένων αντικειμένων</string>
-  <string id="13425">Î\91Ï\80οδοÏ\87ή επιτάχυνσης υλικού (VDPAU)</string>
-  <string id="13426">Î\91Ï\80οδοÏ\87ή επιτάχυνσης υλικού (VAAPI)</string>
-  <string id="13427">Î\91Ï\80οδοÏ\87ή επιτάχυνσης υλικού (DXVA2)</string>
-  <string id="13428">Î\91Ï\80οδοÏ\87ή επιτάχυνσης υλικού (CrystalHD)</string>
-  <string id="13429">Î\91Ï\80οδοÏ\87ή επιτάχυνσης υλικού (VDADecoder)</string>
-  <string id="13430">Î\91Ï\80οδοÏ\87ή επιτάχυνσης υλικού (OpenMax)</string>
-  <string id="13431">Σκιάσεις εικονοστοιχείου</string>
+  <string id="13422">ΠαÏ\81οÏ\85Ï\83ίαÏ\83η Î´Î¹Î±Ï\86ανειÏ\8eν Î±Ï\80Ï\8c εδώ</string>
+  <string id="13423">Î\91Ï\80ομνημÏ\8cνεÏ\85Ï\83η Î³Î¹Î± Î±Ï\85Ï\84ή Ï\84η Î´Î¹Î±Î´Ï\81ομή</string>
+  <string id="13424">Χρήση αντικειμένων προσωρινής μνήμης pixel</string>
+  <string id="13425">Î\88γκÏ\81ιÏ\83η επιτάχυνσης υλικού (VDPAU)</string>
+  <string id="13426">Î\88γκÏ\81ιÏ\83η επιτάχυνσης υλικού (VAAPI)</string>
+  <string id="13427">Î\88γκÏ\81ιÏ\83η επιτάχυνσης υλικού (DXVA2)</string>
+  <string id="13428">Î\88γκÏ\81ιÏ\83η επιτάχυνσης υλικού (CrystalHD)</string>
+  <string id="13429">Î\88γκÏ\81ιÏ\83η επιτάχυνσης υλικού (VDADecoder)</string>
+  <string id="13430">Î\88γκÏ\81ιÏ\83η επιτάχυνσης υλικού (OpenMax)</string>
+  <string id="13431">Σκιάσεις Pixel</string>
   <string id="13432">Έγκριση επιτάχυνσης υλικού (VideoToolbox)</string>
 
   <string id="13500">Μέθοδος συγχρονισμού A/V</string>
   <string id="13507">Μεσαία</string>
   <string id="13508">Υψηλή</string>
   <string id="13509">Πραγματικά υψηλή (αργή!)</string>
-  <string id="13510">ΣÏ\85γÏ\87Ï\81ονιÏ\83μÏ\8cÏ\82 Î±Î½Î±Ï\80αÏ\81αγÏ\89γήÏ\82 Î®Ï\87οÏ\85 ÎºÎ±Ï\84ά Ï\84η Ï\80Ï\81οβολή</string>
+  <string id="13510">ΣÏ\85γÏ\87Ï\81ονιÏ\83μÏ\8cÏ\82 Î±Î½Î±Ï\80αÏ\81αγÏ\89γήÏ\82 Î®Ï\87οÏ\85 Î¼Îµ Î¿Î¸Ï\8cνη</string>
 
-  <string id="13550">Παύση κατά τη διάρκεια ανανέωσης του ρυθμού αλλαγής</string>
+  <string id="13550">Παύση κατά την αλλαγή του ρυθμού ανανέωσης</string>
   <string id="13551">Ανενεργό</string>
   <string id="13552">%.1f Δευτερόλεπτο</string>
   <string id="13553">%.1f Δευτερόλεπτα</string>
 
   <string id="13600">Apple Remote</string>
 
-  <string id="13602">Έγκριση έναρξης του XBMC μέσου απομακρυσμένου ελέγχου</string>
-  <string id="13603">Î\91κολοÏ\85θία Ï\87Ï\81Ï\8cνοÏ\85 ÎºÎ±Î¸Ï\85Ï\83Ï\84έÏ\81ηÏ\83ης</string>
+  <string id="13602">Έγκριση έναρξης του XBMC μέσου του χειριστηρίου</string>
+  <string id="13603">ΧÏ\81Ï\8cνοÏ\82 ÎºÎ±Î¸Ï\85Ï\83Ï\84έÏ\81ηÏ\83ηÏ\82 Î±ÎºÎ¿Î»Î¿Ï\85θίας</string>
 
   <string id="13610">Ανενεργή</string>
   <string id="13611">Τυπική</string>
   <string id="13612">Τηλεχειριστήριο γενικής χρήσης</string>
-  <string id="13613">Τηλεχειριστήριο γενικής χρήσης (Harmony)</string>
+  <string id="13613">Τηλεχειριστήριο Multi (Harmony)</string>
 
-  <string id="13620">Σφάλμα συσκευής (Apple Remote)</string>
-  <string id="13621">Αδυναμία υποστήριξης συσκευής (Apple Remote).</string>
+  <string id="13620">Σφάλμα συσκευής Apple Remote</string>
+  <string id="13621">Αδυναμία υποστήριξης συσκευής Apple Remote.</string>
 
   <string id="14000">Στοίβαγμα</string>
   <string id="14001">Σκόρπισμα</string>
   <string id="14007">Αποτυχία λήψης αρχείου λίστας αναπαραγωγής</string>
 
   <string id="14009">Κατάλογος παιχνιδιών</string>
-  <string id="14010">Αυτόματη εναλλαγή με βάση τις μικρογραφίες</string>
+  <string id="14010">Αυτόματη εναλλαγή σε μικρογραφίες βάσει</string>
   <string id="14011">Ενεργοποίηση αυτόματης εναλλαγής στην προβολή μικρογραφιών</string>
   <string id="14012">- Χρήση μεγάλων εικονιδίων</string>
-  <string id="14013">- Î\95ναλλαγή Î²Î¬Ï\83η</string>
+  <string id="14013">- Î\95ναλλαγή Î²Î¬Ï\83ει</string>
   <string id="14014">- Ποσοστό</string>
   <string id="14015">Καθόλου αρχεία και τουλάχιστον μία μικρογραφία</string>
-  <string id="14016">ΤοÏ\85λάÏ\87ιÏ\83Ï\84ον Î­Î½Î± Î±Ï\81Ï\87είο ÎºÎ±Î¹ Î¼Î¹α μικρογραφία</string>
+  <string id="14016">ΤοÏ\85λάÏ\87ιÏ\83Ï\84ον Î­Î½Î± Î±Ï\81Ï\87είο ÎºÎ±Î¹ Î¼Î¯α μικρογραφία</string>
   <string id="14017">Ποσοστό μικρογραφιών</string>
   <string id="14018">Επιλογές προβολής</string>
   <string id="14019">Αλλαγή κωδικού 1ης περιοχής</string>
   <string id="14021">Αλλαγή κωδικού 3ης περιοχής</string>
   <string id="14022">Συλλογή</string>
   <string id="14023">Χωρίς τηλεόραση</string>
-  <string id="14024">Εισαγωγή της κοντινότερης μεγάλης πόλης ή ταχυδρομικού κωδικού (US)</string>
+  <string id="14024">Εισαγωγή της κοντινότερης μεγάλης πόλης</string>
   <string id="14025">Συνολική λανθάνουσα μνήμη - Σκληρός δίσκος</string>
-  <string id="14026">Λανθάνουσα μνήμη βίντεο - DVDRom</string>
+  <string id="14026">Λανθάνουσα μνήμη βίντεο - DVD-ROM</string>
   <string id="14027">- Τοπικό δίκτυο</string>
-  <string id="14028">- Internet</string>
-  <string id="14030">Λανθάνουσα μνήμη ήχου - DVDRom</string>
+  <string id="14028">- Διαδίκτυο</string>
+  <string id="14030">Λανθάνουσα μνήμη ήχου - DVD-ROM</string>
   <string id="14031">- Τοπικό δίκτυο</string>
-  <string id="14032">- Internet</string>
-  <string id="14034">Λανθάνουσα μνήμη DVD - DVDRom</string>
+  <string id="14032">- Διαδίκτυο</string>
+  <string id="14034">Λανθάνουσα μνήμη DVD - DVD-ROM</string>
   <string id="14035">- Τοπικό δίκτυο</string>
   <string id="14036">Υπηρεσίες</string>
 
   <string id="14038">Οι ρυθμίσεις του δικτύου άλλαξαν</string>
   <string id="14039">Το XBMC πρέπει να επανεκκινηθεί για να αλλάξουν</string>
   <string id="14040">οι ρυθμίσεις δικτύου. Να γίνει επανεκκίνηση;</string>
-  <string id="14041">Σύνδεση Internet με περιορισμένο εύρος</string>
+  <string id="14041">Σύνδεση Διαδικτύου με περιορισμένο εύρος ζώνης</string>
 
   <string id="14043">- Τερματισμός κατά την αναπαραγωγή</string>
   <string id="14044">%i λεπτ.</string>
   <string id="14048">%i kbps</string>
   <string id="14049">%i kb</string>
   <string id="14050">%i.0 dB</string>
-  <string id="14051">Î\94ιαμÏ\8cÏ\81Ï\86Ï\89Ï\83η Ώρας</string>
-  <string id="14052">Î\94ιαμÏ\8cÏ\81Ï\86Ï\89Ï\83η Ημ/νίας</string>
+  <string id="14051">Î\9cοÏ\81Ï\86ή Ώρας</string>
+  <string id="14052">Î\9cοÏ\81Ï\86ή Ημ/νίας</string>
   <string id="14053">Φίλτρα γραφικού περιβάλλοντος (GUI)</string>
 
   <string id="14055">Σάρωση στο παρασκήνιο</string>
   <string id="14056">Διακοπή σάρωσης</string>
-  <string id="14057">Δεν είναι εφικτό κατά τη σάρωση πληροφοριών αρχείων</string>
+  <string id="14057">Δεν είναι εφικτό κατά τη σάρωση πληροφοριών πολυμέσων</string>
   <string id="14058">Εφέ Film Grain</string>
   <string id="14059">Έρευνα στους κοινόχρηστους πόρους για μικρογραφίες</string>
-  <string id="14060">Άγνωστος τύπος λανθάνουσας μνήμης - Internet</string>
+  <string id="14060">Άγνωστος τύπος λανθάνουσας μνήμης - Διαδίκτυο</string>
   <string id="14061">Αυτόματο/η</string>
   <string id="14062">Εισάγετε όνομα χρήστη για</string>
-  <string id="14063">Ημερομηνία &amp; Ώρα</string>
-  <string id="14064">Ορισμός ημερομηνίας</string>
+  <string id="14063">Ημερομηνία &amp; ώρα</string>
+  <string id="14064">Ορισμός ημ/νίας</string>
   <string id="14065">Ορισμός ώρας</string>
-  <string id="14066">Εισάγετε την ώρα σε ψηφιακή μορφή</string>
-  <string id="14067">Εισάγετε την ημ/νία στο ΗΗ/MM/ΕΤΟΣ</string>
+  <string id="14066">Εισάγετε την ώρα σε 24ωρη μορφή (ΩΩ:ΛΛ)</string>
+  <string id="14067">Εισάγετε την ημ/νία σε μορφή ΗΗ/MM/ΕΤΟΣ</string>
   <string id="14068">Εισάγετε την διεύθυνση ΙP</string>
   <string id="14069">Εφαρμογή αυτών των ρυθμίσεων τώρα;</string>
   <string id="14070">Εφαρμογή ρυθμίσεων τώρα</string>
-  <string id="14071">Επιτρεπτή η μετονομασία και η διαγραφή</string>
+  <string id="14071">Επιτρεπτή η μετονομασία και η διαγραφή αρχείων</string>
 
   <string id="14074">Ορισμός ζώνης ώρας</string>
   <string id="14075">Ενεργοποίηση θερινής ώρας</string>
   <string id="14082">Εμφάνιση πληροφοριών εικόνας (EXIF)</string>
   <string id="14083">Χρήση του μεγιστοποιημένου παραθύρου αντί της πλήρους οθόνης</string>
   <string id="14084">Επιλεγμένα τραγούδια στη λίστα αναμονής</string>
-  <string id="14085">Αυτόματη αναπαραγωγή CDs ήχου</string>
+  <string id="14085">Αυτόματη αναπαραγωγή CD ήχου</string>
   <string id="14086">Αναπαραγωγή</string>
-  <string id="14087">DVDs</string>
-  <string id="14088">Αυτόματη αναπαραγωγή DVDs βίντεο</string>
+  <string id="14087">DVD</string>
+  <string id="14088">Αυτόματη αναπαραγωγή DVD</string>
   <string id="14089">Χρήση γραμματοσειράς στους υπότιτλους</string>
   <string id="14090">Διεθνοποίηση</string>
   <string id="14091">Κωδικοποίηση χαρακτήρων</string>
-  <string id="14092">Î\91Ï\80οÏ\83Ï\86αλμάÏ\84Ï\89Ï\83η</string>
+  <string id="14092">Î\95νÏ\84οÏ\80ιÏ\83μÏ\8cÏ\82 Ï\83Ï\86αλμάÏ\84Ï\89ν</string>
   <string id="14093">Ασφάλεια</string>
   <string id="14094">Συσκευές εισόδου</string>
   <string id="14095">Εξοικονόμηση ενέργειας</string>
 
   <string id="15107">Aποθήκευση...</string>
   <string id="15108">Ήχοι πλοήγησης</string>
-  <string id="15109">ΠÏ\81οεÏ\80ιλεγμένο ÎºÎ­Î»Ï\85Ï\86ος</string>
+  <string id="15109">ΠÏ\81οεÏ\80ιλογή ÎºÎµÎ»Ï\8dÏ\86οÏ\85ς</string>
   <string id="15111">- Θέμα</string>
   <string id="15112">Προεπιλεγμένο Θέμα</string>
 
-  <string id="15200">Last.FM</string>
-  <string id="15201">Αποστολή τραγουδιών στο Last.FM</string>
-  <string id="15202">Όνομα χρήστη Last.FM</string>
-  <string id="15203">Κωδικός πρόσβασης Last.FM</string>
+  <string id="15200">Last.fm</string>
+  <string id="15201">Αποστολή τραγουδιών στο Last.fm</string>
+  <string id="15202">Όνομα χρήστη Last.fm</string>
+  <string id="15203">Κωδικός πρόσβασης Last.fm</string>
   <string id="15204">Αδύνατη η χειραψία: σε αδράνεια...</string>
-  <string id="15205">Παρακαλώ, αναβαθμίστε το XBMC</string>
-  <string id="15206">Απέτυχε η εξακρίβωση. Ελέγξτε το όνομα χρήστη και τον κωδικό πρόσβασης</string>
+  <string id="15205">Παρακαλώ αναβαθμίστε το XBMC</string>
+  <string id="15206">Απέτυχε η εξακρίβωση: Ελέγξτε το όνομα χρήστη και τον κωδικό πρόσβασης</string>
   <string id="15207">Συνδεμένο</string>
   <string id="15208">Αποσυνδεμένο</string>
-  <string id="15209">Î\91Ï\80οÏ\83Ï\84ολή Î´Î¹Î±Ï\83Ï\84ήμαÏ\84ος %i</string>
+  <string id="15209">Î\94ιάÏ\83Ï\84ημα Î±Ï\80οÏ\83Ï\84ολής %i</string>
   <string id="15210">%i τραγούδια στη λανθάνουσα μνήμη</string>
   <string id="15211">Αποστολή...</string>
   <string id="15212">Αποστολή σε %i δευτ.</string>
-  <string id="15213">Î\94οÏ\85λεÏ\8dει Ï\87Ï\81ηÏ\83ιμοÏ\80οιÏ\8eνÏ\84αÏ\82...</string>
+  <string id="15213">Î\86νοιγμα Î¼Îµ...</string>
   <string id="15214">Χρήση συγχρονισμού Smoothed A/V</string>
   <string id="15215">Απόκρυψη ονομάτων αρχείων στην προβολή μικρογραφιών</string>
-  <string id="15216">Î\95κÏ\84ελείÏ\84ε σε Party Mode</string>
-  <string id="15217">Î¥Ï\80οβολή τραγουδιών στο Libre.fm</string>
-  <string id="15218">Όνομα χρήστη (Libre.fm)</string>
-  <string id="15219">Κωδικός πρόσβασης (Libre.fm)</string>
+  <string id="15216">Î\95κÏ\84έλεÏ\83η σε Party Mode</string>
+  <string id="15217">Î\91Ï\80οÏ\83Ï\84ολή τραγουδιών στο Libre.fm</string>
+  <string id="15218">Όνομα χρήστη Libre.fm</string>
+  <string id="15219">Κωδικός πρόσβασης Libre.fm</string>
   <string id="15220">Libre.fm</string>
-  <string id="15221">Υποβολή αιτήματος τραγουδιού</string>
+  <string id="15221">Υποβολή τραγουδιού</string>
 
   <string id="15250">Αποστολή Last.fm radio στο Last.fm</string>
-  <string id="15251">Σύνδεση με Last.FM...</string>
+  <string id="15251">Σύνδεση με Last.fm...</string>
   <string id="15252">Επιλογή σταθμού...</string>
   <string id="15253">Αναζήτηση παρόμοιων καλλιτεχνών...</string>
   <string id="15254">Αναζήτηση παρόμοιων ετικετών...</string>
   <string id="15255">Το προφίλ σας (%name%)</string>
-  <string id="15256">Î\93ενικέÏ\82 κορυφαίες ετικέτες</string>
+  <string id="15256">Î\93ενικά κορυφαίες ετικέτες</string>
   <string id="15257">Κορυφαίοι καλλιτέχνες για την ετικέτα %name%</string>
   <string id="15258">Κορυφαία άλμπουμ για την ετικέτα %name%</string>
   <string id="15259">Κορυφαία κομμάτια για την ετικέτα %name%</string>
-  <string id="15260">Ακρόαση της ετικέτας %name% στο Last.FM radio</string>
+  <string id="15260">Ακρόαση της ετικέτας %name% στο Last.fm radio</string>
   <string id="15261">Παρόμοιοι καλλιτέχνες όπως ο %name%</string>
-  <string id="15262">%name% κορυφαία άλμπουμ</string>
-  <string id="15263">%name% κορυφαία κομμάτια</string>
-  <string id="15264">%name% κορυφαίες ετικέτες</string>
+  <string id="15262">Κορυφαία άλμπουμ %name%</string>
+  <string id="15263">Κορυφαία κομμάτια %name%</string>
+  <string id="15264">Κορυφαίες ετικέτες %name%</string>
   <string id="15265">Οι μεγαλύτεροι θαυμαστές του %name%</string>
-  <string id="15266">Ακρόαση θαυμαστών του %name% στο Last.FM radio</string>
-  <string id="15267">Ακρόαση παρόμοιων καλλιτεχνών με τον %name% στο Last.FM radio</string>
+  <string id="15266">Ακρόαση θαυμαστών του %name% στο Last.fm radio</string>
+  <string id="15267">Ακρόαση καλλιτεχνών παρόμοιων με τον %name% στο Last.fm radio</string>
   <string id="15268">Οι καλύτεροι καλλιτέχνες του χρήστη %name%</string>
   <string id="15269">Τα καλύτερα άλμπουμ του χρήστη %name%</string>
   <string id="15270">Τα καλύτερα κομμάτια του χρήστη %name%</string>
   <string id="15271">Φίλοι του χρήστη %name%</string>
   <string id="15272">Γείτονες του χρήστη %name%</string>
-  <string id="15273">Εβδομαδιαίο chart καλλιτέχνη του %name%</string>
-  <string id="15274">Εβδομαδιαίο chart άλμπουμ του %name%</string>
-  <string id="15275">Εβδομαδιαίο chart κομματιού του %name%</string>
-  <string id="15276">Ακρόαση των γειτόνων του  %name% στο Last.FM radio</string>
-  <string id="15277">Ακρόαση των προσωπικών του %name% στο Last.FM radio</string>
-  <string id="15278">Ακρόαση των  %name%'s mix Last.fm radio</string>
-  <string id="15279">Ανάκτηση λίστας από Last.FM...</string>
-  <string id="15280">Αδύνατη η ανάκτηση λίστας από Last.FM...</string>
-  <string id="15281">Εισάγετε ένα όνομα καλλιτέχνη</string>
-  <string id="15282">Î\95ιÏ\83άγεÏ\84ε Î¼Î¯Î± ÎµÏ\84ικέÏ\84α Î³Î¹Î± Î½Î± Î²Ï\81είÏ\84ε Ï\84α Ï\80αÏ\81Ï\8cμοια</string>
+  <string id="15273">Εβδομαδιαίο chart του καλλιτέχνη %name%</string>
+  <string id="15274">Εβδομαδιαίο chart του άλμπουμ %name%</string>
+  <string id="15275">Εβδομαδιαίο chart του κομματιού %name%</string>
+  <string id="15276">Ακρόαση του Last.fm radio των γειτόνων του %name%</string>
+  <string id="15277">Ακρόαση του προσωπικού Last.fm radio του %name%</string>
+  <string id="15278">Ακρόαση της μίξης Last.fm radio του %name%</string>
+  <string id="15279">Ανάκτηση λίστας από Last.fm...</string>
+  <string id="15280">Αδύνατη η ανάκτηση λίστας από Last.fm...</string>
+  <string id="15281">Εισάγετε ένα όνομα καλλιτέχνη για να βρείτε παρόμοια</string>
+  <string id="15282">Î\95ιÏ\83άγεÏ\84ε Î¼Î¯Î± ÎµÏ\84ικέÏ\84α Î³Î¹Î± Î½Î± Î²Ï\81είÏ\84ε Ï\80αÏ\81Ï\8cμοιεÏ\82</string>
   <string id="15283">Κομμάτια που ακούστηκαν πρόσφατα από τον %name%</string>
-  <string id="15284">Ακρόαση των προτιμήσεων του %name% στο Last.FM radio</string>
+  <string id="15284">Ακρόαση των προτιμήσεων του %name% στο Last.fm radio</string>
   <string id="15285">Κορυφαίες ετικέτες για τον χρήστη %name%</string>
 
-  <string id="15287">Να προστεθεί το παρόν κομμάτι στα  αγαπημένα σας;</string>
+  <string id="15287">Να προστεθεί το παρόν κομμάτι στα αγαπημένα σας;</string>
   <string id="15288">Να αποκλειστεί το παρόν κομμάτι;</string>
   <string id="15289">Προσθήκη στα αγαπημένα σας κομμάτια: '%s'.</string>
-  <string id="15290">Δεν προστέθηκε το '%s' στα Αγαπημένα σας.</string>
+  <string id="15290">Δεν μπορεί να προστεθεί το '%s' στα αγαπημένα σας.</string>
   <string id="15291">Αποκλεισμένα: '%s'.</string>
-  <string id="15292">Î\9dα Î¼Î·Î½ Î±Ï\80οκλειÏ\83Ï\84εί '%s'.</string>
+  <string id="15292">Î\94εν Î¼Ï\80οÏ\81εί Î½Î± Î±Ï\80οκλειÏ\83Ï\84εί Ï\84ο '%s'.</string>
   <string id="15293">Πρόσφατα αγαπημένα κομμάτια από %name%</string>
-  <string id="15294">ΠÏ\81Ï\8cÏ\83Ï\86αÏ\84εÏ\82 Î±Î½Î±Î³Î³ÎµÎ»Î¯ÎµÏ\82 από %name%</string>
-  <string id="15295">Î\91Ï\86αιÏ\81έθηκε από τα αγαπημένα σας</string>
-  <string id="15296">Î\91Ï\80οδεκÏ\84Ï\8c</string>
-  <string id="15297">Να αφαιρεθεί το παρόν κομμάτι από τα  αγαπημένα σας;</string>
-  <string id="15298">Î\9dα Î¼Î·Î½ Î±Ï\80οκλειÏ\83Ï\84εί Ï\84ο Ï\80αÏ\81Ï\8cν κομμάτι;</string>
+  <string id="15294">ΠÏ\81Ï\8cÏ\83Ï\86αÏ\84α Î±Ï\80οκλειÏ\83μένα ÎºÎ¿Î¼Î¼Î¬Ï\84ια από %name%</string>
+  <string id="15295">Î\91Ï\86αίÏ\81εÏ\83η από τα αγαπημένα σας</string>
+  <string id="15296">Î\86Ï\81Ï\83η Î±Ï\80οκλειÏ\83μοÏ\8d</string>
+  <string id="15297">Να αφαιρεθεί το παρόν κομμάτι από τα αγαπημένα σας;</string>
+  <string id="15298">Î\9dα Î±Ï\81θεί Î¿ Î±Ï\80οκλειÏ\83μÏ\8cÏ\82 Î³Î¹Î± Î±Ï\85Ï\84Ï\8c Ï\84ο κομμάτι;</string>
 
-  <string id="15300">H διαδρομή δεν βρέθηκε</string>
+  <string id="15300">Η διαδρομή δε βρέθηκε</string>
   <string id="15301">Απέτυχε η σύνδεση με τον διακομιστή δικτύου</string>
   <string id="15302">Δεν βρέθηκαν διακομιστές</string>
-  <string id="15303">Î\94εν Î²Ï\81έθηκαν Î¿Î¼Î¬Î´ÎµÏ\82 εργασίας</string>
+  <string id="15303">Î\94εν Î²Ï\81έθηκε Î· Î¿Î¼Î¬Î´Î± εργασίας</string>
 
   <string id="15310">Άνοιγμα πηγής multi-path</string>
   <string id="15311">Διαδρομή:</string>
 
   <string id="16000">Γενικά</string>
 
-  <string id="16002">Έρευνα στο Internet</string>
+  <string id="16002">Έρευνα στο Διαδίκτυο</string>
   <string id="16003">Αναπαραγωγή</string>
   <string id="16004">Αναπαραγωγή πολυμέσων από το δίσκο</string>
 
   <string id="16014">Εισάγετε όνομα φακέλου</string>
   <string id="16015">Εισάγετε κατάλογο</string>
   <string id="16016">Διαθέσιμες επιλογές: %A, %T, %N, %B, %D, %G, %Y, %F, %S</string>
-  <string id="16017">Εισαγωγή συμβολοσειράς αναζήτησης</string>
+  <string id="16017">Εισαγωγή κειμένου αναζήτησης</string>
   <string id="16018">Καμία</string>
   <string id="16019">Αυτόματη επιλογή</string>
   <string id="16020">Απόπλεξη</string>
-  <string id="16021">Επιλεκτική</string>
-  <string id="16022">Επιλεκτική (αντιστροφή)</string>
-  <string id="16023">Μέθοδος περιπλεγμένου χειρισμού</string>
+  <string id="16021">Bob</string>
+  <string id="16022">Bob (αντιστροφή)</string>
+  <string id="16023"></string>
   <string id="16024">Ακύρωση...</string>
   <string id="16025">Εισάγετε το όνομα του καλλιτέχνη</string>
   <string id="16026">Η αναπαραγωγή απέτυχε</string>
-  <string id="16027">Î\91Ï\80οÏ\84Ï\85Ï\87ία Î±Î½Î±Ï\80αÏ\81αγÏ\89γήÏ\82 ÎµÎ½Ï\8cÏ\82 Î® Ï\80εÏ\81ιÏ\83Ï\83Ï\8cÏ\84εÏ\81Ï\89ν Î±Î½Ï\84ικείμενων.</string>
+  <string id="16027">Î\91Ï\80οÏ\84Ï\85Ï\87ία Î±Î½Î±Ï\80αÏ\81αγÏ\89γήÏ\82 ÎµÎ½Ï\8cÏ\82 Î® Ï\80εÏ\81ιÏ\83Ï\83Ï\8cÏ\84εÏ\81Ï\89ν Î±Î½Ï\84ικειμένων.</string>
   <string id="16028">Εισαγωγή τιμής</string>
-  <string id="16029">Για περισσότερες λεπτομέρειες ελέγξτε το αρχείο συμβάντων</string>
-  <string id="16030">Το Party Mode ως μέθοδος απορρίφθηκε.</string>
-  <string id="16031">Î\94εν Ï\85Ï\80άÏ\81Ï\87οÏ\85ν Ï\84Ï\81αγοÏ\8dδια Ï\83Ï\84η Ï\83Ï\85λλογή Ï\80οÏ\85 Î½Î± Ï\84αιÏ\81ιάζοÏ\85ν.</string>
+  <string id="16029">Για λεπτομέρειες ελέγξτε το αρχείο καταγραφής.</string>
+  <string id="16030">Το Party Mode απορρίφθηκε.</string>
+  <string id="16031">Î\94εν Ï\85Ï\80άÏ\81Ï\87οÏ\85ν Ï\80αÏ\81Ï\8cμοια Ï\84Ï\81αγοÏ\8dδια Ï\83Ï\84η Ï\83Ï\85λλογή.</string>
   <string id="16032">Δεν είναι δυνατός ο συγχρονισμός με τη βάση δεδομένων.</string>
   <string id="16033">Απέτυχε το άνοιγμα της βάσης δεδομένων.</string>
   <string id="16034">Απέτυχε η λήψη τραγουδιών από τη βάση δεδομένων.</string>
-  <string id="16035">Λίστα αναπαραγωγής σε Party Μode</string>
+  <string id="16035">Λίστα αναπαραγωγής σε Party Mode</string>
   <string id="16036">Απόπλεξη (κατά το ήμισυ)</string>
-  <string id="16037">Απόπλεξη βίντεο</string>
+  <string id="16037">Απόπλεξη βίντεο (Deinterlace)</string>
   <string id="16038">Μέθοδος απόπλεξης</string>
   <string id="16039">Ανενεργή</string>
   <string id="16040">Αυτόματη</string>
 
   <string id="16300">Μέθοδος προσαρμογής ανάλυσης βίντεο</string>
   <string id="16301">Εγγύτερη προσέγγιση</string>
-  <string id="16302">Διγραμμική</string>
-  <string id="16303">Δικυβική</string>
+  <string id="16302">Bilinear</string>
+  <string id="16303">Bicubic</string>
   <string id="16304">Lanczos2</string>
   <string id="16305">Lanczos3</string>
   <string id="16306">Sinc8</string>
-  <string id="16307">Δικυβική (με λογισμικό)</string>
-  <string id="16308">Lanczos (με Î»Î¿Î³Î¹Ï\83μικÏ\8c)</string>
-  <string id="16309">Sinc (με Î»Î¿Î³Î¹Ï\83μικÏ\8c)</string>
+  <string id="16307">Bicubic (λογισμικό)</string>
+  <string id="16308">Lanczos (λογισμικό)</string>
+  <string id="16309">Sinc (λογισμικό)</string>
   <string id="16310">Χρονική</string>
   <string id="16311">Χρονική/Χωρική</string>
   <string id="16312">(VDPAU) Μείωση θορύβου</string>
   <string id="20000">Φάκελος αποθήκευσης μουσικής</string>
   <string id="20001">Χρήση εξωτερικού αναπαραγωγέα DVD</string>
   <string id="20002">Εξωτερικός αναπαραγωγέας DVD</string>
-  <string id="20003">Φάκελος εκπαιδευτών</string>
-  <string id="20004">Φάκελος στιγμιότυπου</string>
+  <string id="20003">Φάκελος trainer</string>
+  <string id="20004">Φάκελος στιγμιότυπων</string>
 
   <string id="20006">Φάκελος λίστας αναπαραγωγής</string>
   <string id="20007">Εγγραφές</string>
   <string id="20011">Λίστες αναπαραγωγής μουσικής</string>
   <string id="20012">Λίστες αναπαραγωγής βίντεο</string>
   <string id="20013">Να εκτελεστεί το παιχνίδι;</string>
-  <string id="20014">Ταξιν.: Λίστα αναπαραγωγής</string>
+  <string id="20014">Ταξ.: Λίστα αναπαραγωγής</string>
   <string id="20015">Απομακρυσμένη μικρογραφία</string>
   <string id="20016">Τρέχουσα μικρογραφία</string>
   <string id="20017">Τοπική μικρογραφία</string>
   <!-- string id 20022 will always be set to an empty string (LocalizeStrings.cpp)-->
   <string id="20022"></string>
   <string id="20023">Διένεξη</string>
-  <string id="20024">ΣάÏ\81Ï\89Ï\83η ÎºÎ±Î¹Î½Î¿Ï\8dÏ\81γιων</string>
+  <string id="20024">ΣάÏ\81Ï\89Ï\83η Î½Î­ων</string>
   <string id="20025">Σάρωση όλων</string>
   <string id="20026">Περιοχή</string>
 
   <!-- string id's 20027 thru 20034 are reserved for temperature strings (LocalizeStrings.cpp)-->
 
-  <string id="20037">Συνολικές</string>
-  <string id="20038">Î\9aλείδÏ\89μα Ï\84ηÏ\82 μουσικής</string>
-  <string id="20039">Î\9aλείδÏ\89μα Ï\84Ï\89ν βίντεο</string>
-  <string id="20040">Î\9aλείδÏ\89μα Ï\84Ï\89ν Ï\86Ï\89Ï\84ογÏ\81αÏ\86ιÏ\8eν</string>
-  <string id="20041">Κλείδωμα εφαρμογών και scripts windows</string>
+  <string id="20037">Συνοπτικά</string>
+  <string id="20038">Î\9aλείδÏ\89μα Ï\80αÏ\81αθÏ\8dÏ\81οÏ\85 μουσικής</string>
+  <string id="20039">Î\9aλείδÏ\89μα Ï\80αÏ\81αθÏ\8dÏ\81οÏ\85 βίντεο</string>
+  <string id="20040">Î\9aλείδÏ\89μα Ï\80αÏ\81αθÏ\8dÏ\81οÏ\85 ÎµÎ¹ÎºÏ\8cνÏ\89ν</string>
+  <string id="20041">Κλείδωμα παραθύρου εφαρμογών &amp; script</string>
   <string id="20042">Κλείδωμα της διαχείρισης αρχείων</string>
   <string id="20043">Κλείδωμα των ρυθμίσεων</string>
   <string id="20044">Νέα έναρξη</string>
   <string id="20045">Είσοδος στη γενική διαχείριση</string>
   <string id="20046">Έξοδος από τη γενική διαχείριση</string>
   <string id="20047">Δημιουργία προφίλ '%s';</string>
-  <string id="20048">Î\88ναÏ\81ξη Î¼Îµ ÎºÎ±Î¹Î½Î¿Ï\8dÏ\81γιες ρυθμίσεις</string>
+  <string id="20048">Î\88ναÏ\81ξη Î¼Îµ Î½Î­ες ρυθμίσεις</string>
   <string id="20049">Η καλύτερη δυνατή</string>
   <string id="20050">Αυτόματη εναλλαγή μεταξύ 16:9 και 4:3</string>
   <string id="20051">Μεταχείριση στοιβαγμένων αρχείων σαν ένα</string>
   <string id="20052">Προσοχή</string>
-  <string id="20053">Î\91Ï\81ιÏ\83Ï\84εÏ\81ή Î³ÎµÎ½Î¹ÎºÎ® διαχείριση</string>
-  <string id="20054">Î\9aαÏ\84αÏ\87Ï\89Ï\81ημένη Î³ÎµÎ½Î¹ÎºÎ® διαχείριση</string>
+  <string id="20053">Î\91Ï\80οÏ\87Ï\8eÏ\81ηÏ\83η Î±Ï\80Ï\8c Ï\84η Î³ÎµÎ½. διαχείριση</string>
+  <string id="20054">Î\95ιÏ\83αγÏ\89γή Ï\83Ï\84η Î³ÎµÎ½. διαχείριση</string>
   <string id="20055">Μικρογραφία Allmusic.com</string>
 
   <string id="20057">Απομάκρυνση μικρογραφίας</string>
-  <string id="20058">ΠÏ\81οÏ\83θέÏ\83Ï\84ε προφίλ...</string>
-  <string id="20059">Î\95Ï\81Ï\8eÏ\84ημα για όλα τα άλμπουμ</string>
+  <string id="20058">ΠÏ\81οÏ\83θήκη προφίλ...</string>
+  <string id="20059">Î\95Ï\8dÏ\81εÏ\83η Ï\80ληÏ\81οÏ\86οÏ\81ιÏ\8eν για όλα τα άλμπουμ</string>
   <string id="20060">Πληροφορίες πολυμέσων</string>
   <string id="20061">Ξεχωριστές</string>
-  <string id="20062">Î\9aοινÏ\8cÏ\87Ï\81ηÏ\83Ï\84α Î¼Îµ Ï\80Ï\81οεÏ\80ιλεγμένα</string>
-  <string id="20063">Î\9aοινÏ\8cÏ\87Ï\81ηÏ\83Ï\84α Î¼Îµ Ï\80Ï\81οεÏ\80ιλεγμένα (ανάγνωση μόνο)</string>
-  <string id="20064">Î\91νÏ\84ιγÏ\81αÏ\86ή Ï\80Ï\81οεÏ\80ιλεγμένÏ\89ν</string>
+  <string id="20062">Î\9aοινÏ\8cÏ\87Ï\81ηÏ\83Ï\84α Î¼Îµ Ï\80Ï\81οεÏ\80ιλογέÏ\82</string>
+  <string id="20063">Î\9aοινÏ\8cÏ\87Ï\81ηÏ\83Ï\84α Î¼Îµ Ï\80Ï\81οεÏ\80ιλογέÏ\82 (ανάγνωση μόνο)</string>
+  <string id="20064">Î\91νÏ\84ιγÏ\81αÏ\86ή Ï\80Ï\81οεÏ\80ιλογÏ\8eν</string>
   <string id="20065">Εικόνα προφίλ</string>
-  <string id="20066">Î\95Ï\80ιλογές κλειδώματος</string>
+  <string id="20066">ΠÏ\81οÏ\84ιμήÏ\83εις κλειδώματος</string>
   <string id="20067">Επεξεργασία προφίλ</string>
   <string id="20068">Κλείδωμα προφίλ</string>
   <string id="20069">Αδύνατη η δημιουργία φακέλου</string>
-  <string id="20070">Φάκελος προφίλ</string>
+  <string id="20070">Î\9aαÏ\84άλογος προφίλ</string>
   <string id="20071">Έναρξη με νέες πηγές πολυμέσων</string>
   <string id="20072">Σιγουρευτείτε ότι ο επιλεγμένος φάκελος μπορεί να εγγραφεί</string>
-  <string id="20073">και ότι το όνομα του είναι έγκυρο</string>
+  <string id="20073">και ότι το νέο όνομα είναι έγκυρο</string>
   <string id="20074">Αξιολόγηση MPAA</string>
   <string id="20075">Εισαγωγή κωδικού κεντρικού κλειδώματος</string>
   <string id="20076">Αίτημα για κωδικό κεντρικού κλειδώματος στην εκκίνηση</string>
   <string id="20077">Ρυθμίσεις κελύφους</string>
   <string id="20078">- δεν έχει οριστεί σύνδεση -</string>
-  <string id="20079">Ενεργοποίηση εφέ κίνησης κελύφους</string>
-  <string id="20080">Ανενεργές οι Ροές Τίτλων Ειδήσεων κατά την ακρόαση τραγουδιών</string>
+  <string id="20079">Ενεργοποίηση εφέ κίνησης</string>
+  <string id="20080">Απενεργοποίηση των Ροών Τίτλων Ειδήσεων (RSS) κατά την ακρόαση μουσικής</string>
   <string id="20081">Ενεργοποίηση πλήκτρων συντόμευσης</string>
   <string id="20082">Εμφάνιση των εφαρμογών στο κεντρικό μενού</string>
   <string id="20083">Εμφάνιση πληροφοριών για τη μουσική</string>
   <string id="20095">Εισάγετε κωδικό κλειδώματος προφίλ</string>
   <string id="20096">Οθόνη σύνδεσης</string>
   <string id="20097">Λήψη πληροφοριών άλμπουμ</string>
-  <string id="20098">Î\9bαμβάνει πληροφορίες για το άλμπουμ</string>
-  <string id="20099">Î\91δÏ\85ναμία ÎµÎ³Î³Ï\81αÏ\86ήÏ\82 Ï\84οÏ\85 CD Î® Ï\84οÏ\85 ÎºÎ¿Î¼Î¼Î±Ï\84ιοÏ\8d ÎºÎ±Ï\84ά Ï\84ην Î±Î½Î±Ï\80αÏ\81αγÏ\89γή Î´Î¯Ï\83κοÏ\85</string>
-  <string id="20100">Κεντρικό κλείδωμα και επιλογές</string>
-  <string id="20101">Î\95ιÏ\83αγÏ\89γή ÎºÏ\89δικοÏ\8d Î³Î¹Î± Ï\84ην ÎµÎ½ÎµÏ\81γοÏ\80οίηÏ\83η Ï\84ηÏ\82 Î³ÎµÎ½Î¹ÎºÎ®Ï\82 Î´Î¹Î±Ï\87είÏ\81ιÏ\83ηÏ\82</string>
-  <string id="20102">ή Î±Î½Ï\84ιγÏ\81αÏ\86ή Ï\84οÏ\85 ÎºÏ\89δικοÏ\8d Ï\8cÏ\80Ï\89Ï\82 Î±Ï\85Ï\84Ï\8cÏ\82 Î­Ï\87ει Ï\80Ï\81οκαθοÏ\81ιÏ\83Ï\84εί;</string>
+  <string id="20098">Î\9bαμβάνονÏ\84αι πληροφορίες για το άλμπουμ</string>
+  <string id="20099">Î\91δÏ\85ναμία Î±Î½Ï\84ιγÏ\81αÏ\86ήÏ\82 Ï\84οÏ\85 CD Î® Ï\84οÏ\85 ÎºÎ¿Î¼Î¼Î±Ï\84ιοÏ\8d ÎºÎ±Ï\84ά Ï\84ην Î±Î½Î±Ï\80αÏ\81αγÏ\89γή Ï\84οÏ\85 CD</string>
+  <string id="20100">Κωδικός κεντρικού κλειδώματος και επιλογές</string>
+  <string id="20101">Î\9f ÎºÏ\89δικÏ\8cÏ\82 ÎºÎµÎ½Ï\84Ï\81ικοÏ\8d ÎºÎ»ÎµÎ¹Î´Ï\8eμαÏ\84οÏ\82 Î½Î± ÎµÎ½ÎµÏ\81γοÏ\80οιεί Ï\80άνÏ\84α Ï\84η Î³ÎµÎ½. Î´Î¹Î±Ï\87είÏ\81ιÏ\83η</string>
+  <string id="20102">ή Î½Î± Î±Î½Ï\84ιγÏ\81άÏ\86εÏ\84αι Î¿ Ï\80Ï\81οκαθοÏ\81ιÏ\83μένοÏ\82 ÎºÏ\89δικÏ\8cÏ\82;</string>
   <string id="20103">Αποθήκευση αλλαγών στο προφίλ;</string>
   <string id="20104">Βρέθηκαν παλιές ρυθμίσεις.</string>
   <string id="20105">Θέλετε να τις χρησιμοποιήσετε;</string>
   <string id="20112">Τελευταία σύνδεση: %s</string>
   <string id="20113">Ποτέ δεν συνδέθηκε</string>
   <string id="20114">Προφίλ %i / %i</string>
-  <string id="20115">Î\8cνομα χρήστη / Επιλέξτε ένα προφίλ</string>
+  <string id="20115">ΣÏ\8dνδεÏ\83η χρήστη / Επιλέξτε ένα προφίλ</string>
   <string id="20116">Χρήση κλειδώματος στην οθόνη σύνδεσης</string>
   <string id="20117">Λάθος κωδικός κλειδώματος.</string>
-  <string id="20118">Απαιτεί να ενεργοποιήσετε το κεντρικό κλείδωμα</string>
-  <string id="20119">Θέλετε να το ρυθμίσετε τώρα;</string>
+  <string id="20118">Απαιτείται ορισμός του κεντρικού κλειδώματος.</string>
+  <string id="20119">Θέλετε να το ορίσετε τώρα;</string>
   <string id="20120">Φόρτωση πληροφοριών εφαρμογής</string>
   <string id="20121">Party on!</string>
   <string id="20122">Αληθές</string>
   <string id="20124">Γεμίζοντας τα ποτήρια</string>
   <string id="20125">Συνδεμένος σαν</string>
   <string id="20126">Αποσύνδεση</string>
-  <string id="20128">Πήγαινε Ï\83Ï\84ο root</string>
-  <string id="20129">Ύφανση</string>
-  <string id="20130">Ύφανση (αντιστροφή)</string>
-  <string id="20131">Συνδυασμός</string>
+  <string id="20128">Î\9cεÏ\84άβαÏ\83η Ï\83ε root</string>
+  <string id="20129">Weave</string>
+  <string id="20130">Weave (αντιστροφή)</string>
+  <string id="20131">Blend</string>
   <string id="20132">Επανεκκίνηση βίντεο</string>
   <string id="20133">Επεξεργασία τοποθεσίας δικτύου</string>
   <string id="20134">Απομάκρυνση τοποθεσίας δικτύου</string>
   <string id="20136">Μονάδα μνήμης</string>
   <string id="20137">Προσάρτηση μονάδας μνήμης</string>
   <string id="20138">Αδύνατη η προσάρτηση μονάδας μνήμης</string>
-  <string id="20139">Στη θύρα %i ,υποδοχή %i</string>
+  <string id="20139">Στη θύρα %iυποδοχή %i</string>
   <string id="20140">Κλείδωμα προφύλαξης οθόνης</string>
   <string id="20141">Ορισμός σε</string>
   <string id="20142">Όνομα χρήστη</string>
   <string id="20151">Ακύρωση χρονοδιακόπτη τερματισμού</string>
   <string id="20152">Κλείδωμα ρυθμίσεων για %s</string>
   <string id="20153">Αναζήτηση...</string>
-  <string id="20154">Συνολικές πληροφορίες</string>
+  <string id="20154">Συνοπτικές πληροφορίες</string>
   <string id="20155">Πληροφορίες αποθηκευτικού χώρου</string>
   <string id="20156">Πληροφορίες σκληρού δίσκου</string>
   <string id="20157">Πληροφορίες DVD-ROM</string>
   <string id="20161">Συνολικά</string>
   <string id="20162">Χρησιμοποιημένα</string>
   <string id="20163">από τα</string>
-  <string id="20164">Δεν υποστηρίζει κλείδωμα</string>
+  <string id="20164">Δεν υποστηρίζεται κλείδωμα</string>
   <string id="20165">Ξεκλείδωτος</string>
   <string id="20166">Κλειδωμένος</string>
   <string id="20167">Παγωμένος</string>
   <string id="20181">Διαγραφή</string>
   <string id="20182">Κενό</string>
   <string id="20183">Επαναφόρτωση κελύφους</string>
-  <string id="20184">ΠεÏ\81ιÏ\83Ï\84Ï\81οÏ\86ή ÎµÎ¹ÎºÏ\8cνÏ\89ν Ï\80οÏ\85 Ï\87Ï\81ηÏ\83ιμοÏ\80οιοÏ\8dν Ï\84ιÏ\82 Ï\80ληÏ\81οÏ\86οÏ\81ίεÏ\82 EXIF</string>
+  <string id="20184">Περιστροφή εικόνων που χρησιμοποιούν πληροφορίες EXIF</string>
   <string id="20185">Χρήση στυλ αφισών για τις τηλεοπτικές σειρές</string>
   <string id="20186">Απασχολημένο</string>
 
-  <string id="20189">Ενεργοποίηση αυτόματης κύλισης στην επισκόπηση πλοκής &amp; κριτικής</string>
+  <string id="20189">Ενεργοποίηση αυτόματης κύλισης για πλοκή &amp; κριτική</string>
   <string id="20190">Προσαρμογή</string>
-  <string id="20191">Ενεργοποίηση καταγραφής αποσφαλμάτωσης</string>
+  <string id="20191">Ενεργοποίηση καταγραφής σφαλμάτων (debug log)</string>
   <string id="20192">Λήψη πρόσθετων πληροφοριών κατά τις ενημερώσεις συλλογής</string>
   <string id="20193">Προκαθορισμένη υπηρεσία πληροφοριών άλμπουμ</string>
   <string id="20194">Προκαθορισμένη υπηρεσία πληροφοριών καλλιτέχνη</string>
-  <string id="20195">Αλλαγή καταγραφέα</string>
+  <string id="20195">Αλλαγή scraper</string>
   <string id="20196">Εξαγωγή μουσικής συλλογής</string>
   <string id="20197">Εισαγωγή μουσικής συλλογής</string>
   <string id="20198">Δεν βρέθηκε ο καλλιτέχνης!</string>
-  <string id="20199">Î\91Ï\80οÏ\84Ï\85Ï\87ία Î»Î®Ï\88ηÏ\82 Ï\80ληÏ\81οÏ\86οÏ\81ιÏ\8eν Î³Î¹Î± Ï\84ον ÎºÎ±Î»Î»Î¹Ï\84έÏ\87νη</string>
+  <string id="20199">Αποτυχία λήψης πληροφοριών καλλιτέχνη</string>
 
   <!-- string id's 20200 thru 20211 are reserved for speedstrings (LocalizeStrings.cpp)-->
 
   <string id="20304">Ροή τίτλων ειδήσεων (RSS)</string>
 
   <string id="20307">Δευτερεύον DNS</string>
-  <string id="20308">DHCP διακομιστή:</string>
+  <string id="20308">Διακομιστής DHCP:</string>
   <string id="20309">Δημιουργία νέου φακέλου</string>
-  <string id="20310">Σκίαση LCD κατά την αναπαραγωγή</string>
+  <string id="20310">Î\91μαÏ\8dÏ\81Ï\89ση LCD κατά την αναπαραγωγή</string>
   <string id="20311">Άγνωστο ή πάνω στην μητρική (προστατεύεται)</string>
-  <string id="20312">ΣκίαÏ\83η LCD Ï\83ε παύση</string>
+  <string id="20312">Î\91μαÏ\8dÏ\81Ï\89Ï\83η LCD Ï\83Ï\84ην παύση</string>
 
   <string id="20314">Βίντεο - Συλλογή</string>
 
-  <string id="20316">Ταξ. κατά: ID</string>
+  <string id="20316">Ταξ.: ID</string>
 
   <string id="20324">Αναπαραγωγή κομματιού...</string>
   <string id="20325">Επαναφορά βαθμονόμησης</string>
   <string id="20332">Χρήση φακέλων ή ονομάτων αρχείων στις αναζητήσεις;</string>
   <string id="20333">Ορισμός περιεχομένου</string>
   <string id="20334">Φάκελος</string>
-  <string id="20335">Î\9aαÏ\84Ï\8cÏ\80Ï\84εÏ\85Ï\83η ÎºÎ±Ï\84' ÎµÏ\80ανάληÏ\88η Ï\84οÏ\85 Ï\80εÏ\81ιεÏ\87ομένοÏ\85;</string>
+  <string id="20335">Î\88λεγÏ\87οÏ\82 Ï\80εÏ\81ιεÏ\87ομένοÏ\85 ÎºÎ±Î¹ Ï\84Ï\89ν Ï\85Ï\80οÏ\86ακέλÏ\89ν;</string>
   <string id="20336">Ξεκλείδωμα πηγών</string>
   <string id="20337">Ηθοποιός</string>
   <string id="20338">Ταινία</string>
   <string id="20339">Σκηνοθεσία</string>
-  <string id="20340">Θέλετε να απομακρύνετε όλα τα αντικείμενα που βρίσκονται</string>
-  <string id="20341">σ΄ αυτή την διαδρομή από τη συλλογή του XBMC;</string>
+  <string id="20340">Θέλετε να απομακρύνετε όλα τα αντικείμενα</string>
+  <string id="20341">αυτής της διαδρομής από τη συλλογή του XBMC;</string>
   <string id="20342">Ταινίες</string>
   <string id="20343">Τηλεοπτικές σειρές</string>
   <string id="20344">Αυτός ο φάκελος περιέχει</string>
   <string id="20345">Εκτέλεση αυτόματης σάρωσης</string>
-  <string id="20346">Σάρωση κατ' επανάληψη</string>
+  <string id="20346">Σάρωση και των υποφακέλων</string>
   <string id="20347">ως</string>
   <string id="20348">Σκηνοθέτες</string>
   <string id="20349">Δεν βρέθηκαν αρχεία βίντεο σε αυτή τη διαδρομή!</string>
   <string id="20376">Πρωτότυπος τίτλος</string>
   <string id="20377">Ανανέωση πληροφοριών τηλεοπτικής σειράς</string>
   <string id="20378">Ανανέωση πληροφοριών για όλα τα επεισόδια;</string>
-  <string id="20379">Ο επιλεγμένος φάκελος περιέχει μία ενιαία τηλεοπτική σειρά</string>
+  <string id="20379">Ο επιλεγμένος φάκελος περιέχει μόνο μία τηλεοπτική σειρά</string>
   <string id="20380">Εξαίρεση του επιλεγμένου φακέλου από τυχόν ελέγχους</string>
   <string id="20381">Ιδιαίτερα στοιχεία</string>
-  <string id="20382">Î\91Ï\85Ï\84Ï\8cμαÏ\84η Î±Ï\80Ï\8cÏ\83Ï\80αÏ\83η Î¼Î¹ÎºÏ\81ογÏ\81αÏ\86ιÏ\8eν ÎºÏ\8dκλοÏ\85</string>
-  <string id="20383">Î\9f Î\95Ï\80ιλεγμένοÏ\82 Ï\86άκελοÏ\82 Ï\80εÏ\81ιέÏ\87ει Î­Î½Î± ÎµÎ½Î¹Î±Î¯Î¿ βίντεο</string>
-  <string id="20384">Σύνδεσμος στην τηλεοπτική σειρά</string>
-  <string id="20385">Î\91Ï\86αίÏ\81εÏ\83η Ï\83Ï\85νδέÏ\83μοÏ\85 Î±Ï\80Ï\8c Ï\84ην Ï\84ηλεοÏ\80Ï\84ική Ï\83ειÏ\81ά</string>
+  <string id="20382">Î\91Ï\85Ï\84Ï\8cμαÏ\84η Î»Î®Ï\88η Î¼Î¹ÎºÏ\81ογÏ\81αÏ\86ιÏ\8eν ÎºÏ\8dκλÏ\89ν</string>
+  <string id="20383">Î\9f ÎµÏ\80ιλεγμένοÏ\82 Ï\86άκελοÏ\82 Ï\80εÏ\81ιέÏ\87ει Î¼Ï\8cνο Î­Î½Î± βίντεο</string>
+  <string id="20384">Σύνδεσμος σε τηλεοπτική σειρά</string>
+  <string id="20385">Αφαίρεση συνδέσμου από τηλεοπτική σειρά</string>
   <string id="20386">Πρόσφατα εισαχθείσες ταινίες</string>
   <string id="20387">Πρόσφατα εισαχθέντα επεισόδια</string>
   <string id="20388">Στούντιο</string>
   <string id="20391">Μουσικό βίντεο</string>
   <string id="20392">Αφαίρεση μουσικού βίντεο από τη συλλογή</string>
   <string id="20393">Πληροφορίες μουσικού βίντεο</string>
-  <string id="20394">Î\9bαμβάνονÏ\84αι Ï\80ληÏ\81οÏ\86οÏ\81ίεÏ\82 για το μουσικό βίντεο</string>
-  <string id="20395">ΣÏ\85Ï\81Ï\81αμμένα</string>
+  <string id="20394">ΦÏ\8cÏ\81Ï\84Ï\89Ï\83η Ï\80ληÏ\81οÏ\86οÏ\81ιÏ\8eν για το μουσικό βίντεο</string>
+  <string id="20395">Î\91νάμικÏ\84α</string>
   <string id="20396">Άλμπουμ καλλιτέχνη</string>
   <string id="20397">Άλμπουμ</string>
   <string id="20398">Αναπαραγωγή τραγουδιού</string>
   <string id="20399">Μουσικά βίντεο από άλμπουμ</string>
   <string id="20400">Μουσικά βίντεο ανά καλλιτέχνη</string>
   <string id="20401">Αναπαραγωγή μουσικού βίντεο</string>
-  <string id="20402">Λήψη μικρογραφιών ηθοποιού κατά τη προσθήκη στη συλλογή</string>
+  <string id="20402">Λήψη μικρογραφιών ηθοποιού κατά την προσθήκη στη συλλογή</string>
   <string id="20403">Ορισμός μικρογραφίας ηθοποιού</string>
 
   <string id="20405">Αφαίρεση σελιδοδείκτη επεισοδίου</string>
   <string id="20406">Ορισμός σελιδοδείκτη επεισοδίου</string>
-  <string id="20407">Ρυθμίσεις καταγραφέα</string>
+  <string id="20407">Ρυθμίσεις scraper</string>
   <string id="20408">Λήψη πληροφοριών για το μουσικό βίντεο</string>
   <string id="20409">Λήψη πληροφοριών για την τηλεοπτική σειρά</string>
   <string id="20410">Διαφημιστικό</string>
-  <string id="20411">Î\99Ï\83οÏ\80έδÏ\89Ï\83η</string>
-  <string id="20412">Î\99Ï\83οÏ\80έδÏ\89Ï\83η Ï\84ηλεοÏ\80Ï\84ικÏ\8eν Ï\83ειÏ\81Ï\8eν</string>
+  <string id="20411">Î\95νιαία Î»Î¯Ï\83Ï\84α (Flatten)</string>
+  <string id="20412">Î\95νιαία Î»Î¯Ï\83Ï\84α ÎµÏ\80ειÏ\83οδίÏ\89ν Ï\83ειÏ\81άÏ\82 (Flatten)</string>
   <string id="20413">Λήψη Fanart</string>
   <string id="20414">Προβολή Fanart στις συλλογές βίντεο και μουσικής</string>
   <string id="20415">Έλεγχος για νέα περιεχόμενα</string>
   <string id="20422">Πάντα</string>
   <string id="20423">Έχει διαφημιστικό</string>
   <string id="20424">Ψευδές</string>
-  <string id="20425">Παρουσίαση Fanart</string>
+  <string id="20425">Παρουσίαση διαφανειών Fanart</string>
   <string id="20426">Εξαγωγή σε ένα αρχείο ή σε πολλαπλά</string>
   <string id="20427">αρχεία ανά εγγραφή;</string>
   <string id="20428">Ένα αρχείο</string>
   <string id="20432">Εξαίρεση διαδρομής από τις ενημερώσεις συλλογής</string>
   <string id="20433">Εξαγωγή μικρογραφιών και πληροφοριών</string>
   <string id="20434">Ομάδες Ταινιών</string>
-  <string id="20435">Î\9fÏ\81ιÏ\83μÏ\8cÏ\82 Î¸Î­Ï\83ηÏ\82 Î¼Î¹ÎºÏ\81ογÏ\81αÏ\86ίαÏ\82 Ï\84αινίας</string>
-  <string id="20436">Î\95ξαγÏ\89γή Î¼Î¹ÎºÏ\81ογÏ\81αÏ\86ιÏ\8eν ÎºÎ±Î»Î»Î¹Ï\84έÏ\87νη;</string>
-  <string id="20437">Î\95Ï\80ιλεγμένο fanart</string>
+  <string id="20435">Î\9fÏ\81ιÏ\83μÏ\8cÏ\82 Î¼Î¹ÎºÏ\81ογÏ\81αÏ\86ίαÏ\82 Î¿Î¼Î¬Î´ας</string>
+  <string id="20436">Î\95ξαγÏ\89γή Î¼Î¹ÎºÏ\81ογÏ\81αÏ\86ιÏ\8eν Î·Î¸Î¿Ï\80οιοÏ\8d;</string>
+  <string id="20437">Î\95Ï\80ιλογή fanart</string>
   <string id="20438">Τοπικό fanart</string>
   <string id="20439">Χωρίς fanart</string>
   <string id="20440">Τρέχον fanart</string>
   <string id="20444">για όλα τα στοιχεία αυτής της διαδρομής;</string>
   <string id="20445">Fanart</string>
   <string id="20446">Βρέθηκαν τοπικά αποθηκευμένες πληροφορίες.</string>
-  <string id="20447">Να αγνοηθούν και να ανανεωθούν από το internet;</string>
+  <string id="20447">Να αγνοηθούν και να ανανεωθούν από το διαδίκτυο;</string>
   <string id="20448">Αδυναμία λήψης πληροφοριών</string>
   <string id="20449">Αδυναμία σύνδεσης με τον απομακρυσμένο διακομιστή</string>
   <string id="20450">Επιθυμείτε να συνεχίσετε την αναζήτηση;</string>
   <!-- up to 21355 is reserved for the TuxBox Client!! !-->
 
   <string id="21359">Προσθήκη κοινόχρηστου πολυμέσου...</string>
-  <string id="21360">Διαμοιρασμός κοινόχρηστων συλλογών μουσικής και βίντεο διαμέσου UPnP</string>
+  <string id="21360">Διαμοιρασμός συλλογών μουσικής και βίντεο μέσω UPnP</string>
 
   <string id="21364">Επεξεργασία κοινόχρηστων πολυμέσων</string>
   <string id="21365">Απομάκρυνση κοινόχρηστων πολυμέσων</string>
   <string id="21367">Ταινία &amp; εναλλακτικός φάκελος υποτίτλων</string>
   <string id="21368">Παράκαμψη γραμματοσειρών υποτίτλων ASS/SSA</string>
 
-  <string id="21369">Ενεργοποίηση ποντικιού</string>
-  <string id="21370">Î\95νεÏ\81γοÏ\80οίηÏ\83η Î®Ï\87Ï\89ν Ï\80λοήγηÏ\83ηÏ\82 ÎºÎ±Ï\84ά Ï\84ην ÎµÎºÏ\84έλεÏ\83η Ï\80ολÏ\85μέÏ\83Ï\89ν</string>
+  <string id="21369">Ενεργοποίηση ποντικιού και υποστήριξης Οθόνης Αφής</string>
+  <string id="21370">Î\95νεÏ\81γοÏ\80οίηÏ\83η Î®Ï\87Ï\89ν Ï\80λοήγηÏ\83ηÏ\82 ÎºÎ±Ï\84ά Ï\84ην Î±Î½Î±Ï\80αÏ\81αγÏ\89γή</string>
   <string id="21371">Μικρογραφία</string>
   <string id="21372">Περιοχή αναπαραγωγέα DVD</string>
   <string id="21373">Έξοδος βίντεο</string>
-  <string id="21374">Απεικόνιση οθόνης</string>
+  <string id="21374">Αναλογία οθόνης</string>
   <string id="21375">Κανονική</string>
   <string id="21376">Letterbox</string>
-  <string id="21377">Ευρεία προβολή</string>
+  <string id="21377">Ευρεία οθόνη</string>
   <string id="21378">Ενεργοποίηση 480p</string>
   <string id="21379">Ενεργοποίηση 720p</string>
   <string id="21380">Ενεργοποίηση 1080i</string>
   <string id="21386">Διαχείριση στάθμης θορύβου</string>
   <string id="21387">Θορυβώδες</string>
   <string id="21388">Αθόρυβο</string>
-  <string id="21389">Ενεργοποίηση προσαρμοσμένου υπόβαθρου</string>
+  <string id="21389">Ενεργοποίηση προσαρμοσμένου υποβάθρου</string>
   <string id="21390">Διαχείριση παροχής ενέργειας</string>
   <string id="21391">Υψηλή τροφοδοσία</string>
   <string id="21392">Χαμηλή τροφοδοσία</string>
   <string id="21393">Υψηλή αναμονή</string>
   <string id="21394">Χαμηλή αναμονή</string>
-  <string id="21395">Αδυναμία δημιουργίας προσωρινών αρχείων μεγαλύτερων των 4 gb</string>
+  <string id="21395">Αδυναμία δημιουργίας προσωρινών αρχείων μεγαλύτερων από 4GB</string>
   <string id="21396">Κεφάλαιο</string>
-  <string id="21397">Υψηλή ποιότητα (Pixel Shader V2)</string>
+  <string id="21397">Υψηλή ποιότητα (Σκίαση pixel v2)</string>
   <string id="21398">Ενεργοποίηση λίστας αναπαραγωγής κατά την εκκίνηση</string>
   <string id="21399">Ενεργοποίηση εφέ παλινδρομικής κίνησης</string>
   <string id="21400">περιέχει</string>
   <string id="21409">πριν</string>
   <string id="21410">στο τελευταίο</string>
   <string id="21411">όχι στο τελευταίο</string>
-  <string id="21412">Καταγραφείς</string>
-  <string id="21413">Προεπιλεγμένος καταγραφέας ταινίας</string>
-  <string id="21414">Προεπιλεγμένος καταγραφέας τηλεοπτικής σειράς</string>
-  <string id="21415">Προεπιλεγμένος καταγραφέας μουσικού βίντεο</string>
-  <string id="21416">Ενεργοποίηση επαναφοράς (βάση της γλώσσας του καταγραφέα)</string>
+  <string id="21412">Scraper</string>
+  <string id="21413">Προεπιλεγμένο scraper ταινιών</string>
+  <string id="21414">Προεπιλεγμένο scraper τηλεοπτικών σειρών</string>
+  <string id="21415">Προεπιλεγμένο scraper μουσικών βίντεο</string>
+  <string id="21416">Ενεργοποίηση επαναφοράς (βάση της γλώσσας του scraper)</string>
   <string id="21417">- Ρυθμίσεις</string>
   <string id="21418">Πολύγλωσσο</string>
-  <string id="21419">Δεν υπάρχει διαθέσιμος καταγραφέας</string>
-  <string id="21420">ΤιμέÏ\82 για αντιστοίχιση</string>
-  <string id="21421">Î\8cÏ\81οι έξυπνης λίστας αναπαραγωγής</string>
-  <string id="21422">Î\9aÏ\81ιÏ\84ήÏ\81ια Î±Î½Ï\84ιÏ\83Ï\84οίÏ\87ιÏ\83ηÏ\82 Î±Î½Ï\84ικειμένÏ\89ν</string>
-  <string id="21423">Νέοι κανόνες...</string>
-  <string id="21424">Î\91νÏ\84ικείμενα Î¼Îµ Ï\80ολλέÏ\82 Î±Î½Ï\84ιÏ\83Ï\84οιÏ\87ίεÏ\82</string>
-  <string id="21425">με όλους τους κανόνες</string>
-  <string id="21426">με Î­Î½Î±Î½ Î® Ï\80εÏ\81ιÏ\83Ï\83Ï\8cÏ\84εÏ\81οÏ\85Ï\82 ÎºÎ±Î½Ï\8cνεÏ\82</string>
+  <string id="21419">Δεν υπάρχει διαθέσιμο scraper</string>
+  <string id="21420">Τιμή για αντιστοίχιση</string>
+  <string id="21421">Î\9aανÏ\8cναÏ\82 έξυπνης λίστας αναπαραγωγής</string>
+  <string id="21422">Î\91νÏ\84ιÏ\83Ï\84οίÏ\87ιÏ\83η Î±Î½Ï\84ικειμένÏ\89ν Ï\8cÏ\84αν</string>
+  <string id="21423">Νέος κανόνας...</string>
+  <string id="21424">Τα Î±Î½Ï\84ικείμενα Ï\80Ï\81έÏ\80ει Î½Î± Ï\80ληÏ\81οÏ\8dν</string>
+  <string id="21425">όλους τους κανόνες</string>
+  <string id="21426">έναν ή περισσότερους κανόνες</string>
   <string id="21427">Αριθμητικό όριο</string>
   <string id="21428">Χωρίς περιορισμό</string>
-  <string id="21429">Συσχετιζόμενο στοιχείο</string>
+  <string id="21429">Σειρά κατά</string>
   <string id="21430">αύξουσα</string>
   <string id="21431">φθίνουσα</string>
   <string id="21432">Επεξεργασία έξυπνης λίστας αναπαραγωγής</string>
   <string id="21433">Όνομα λίστας αναπαραγωγής</string>
-  <string id="21434">Εύρεση αντιστοιχίας αντικειμένων</string>
+  <string id="21434">Εύρεση αντικειμένων για τα οποία</string>
   <string id="21435">Επεξεργασία</string>
   <string id="21436">%i αντικείμενα</string>
   <string id="21437">Νέα έξυπνη λίστα αναπαραγωγής...</string>
   <string id="21438">%c Δίσκος</string>
-  <string id="21439">Επεξεργασία όρων Party Mode</string>
+  <string id="21439">Επεξεργασία κανόνων Party Mode</string>
   <string id="21440">Αρχικός φάκελος</string>
-  <string id="21441">Πλήθος θεαμάτων</string>
+  <string id="21441">Πλήθος προβληθέντων</string>
   <string id="21442">Τίτλος επεισοδίου</string>
   <string id="21443">Ανάλυση βίντεο</string>
   <string id="21444">Κανάλια ήχου</string>
   <string id="21448">Γλώσσα υποτίτλων</string>
   <string id="21449">Το τηλεχειριστήριο στέλνει εντολές πληκτρολογίου</string>
   <string id="21450">- Επεξεργασία</string>
-  <string id="21451">Απαιτείται σύνδεση στο Internet.</string>
-  <string id="21452">Λήψη περισσότερων...</string>
+  <string id="21451">Απαιτείται σύνδεση στο Διαδίκτυο.</string>
+  <string id="21452">Λήψη Περισσότερων...</string>
   <string id="21453">Σύστημα αρχείων root</string>
   <string id="21454">Λανθάνουσα μνήμη πλήρης</string>
   <string id="21455">Η λανθάνουσα μνήμη γέμισε πριν φθάσει το απαιτούμενο μέγεθος για συνεχόμενη αναπαραγωγή</string>
 
-  <string id="21460">Θέση υπότιτλου</string>
+  <string id="21460">Θέση υποτίτλου</string>
   <string id="21461">Σταθερή</string>
   <string id="21462">Κάτω πλευρά του βίντεο</string>
   <string id="21463">Κάτω από το βίντεο</string>
   <string id="21801">Διαδρομή αρχείου</string>
   <string id="21802">Μέγεθος αρχείου</string>
   <string id="21803">Ημερομηνία αρχείου</string>
-  <string id="21804">Î\95Ï\85Ï\81εÏ\84ήÏ\81ιο διαφάνειας</string>
+  <string id="21804">Î\98έÏ\83η διαφάνειας</string>
   <string id="21805">Ανάλυση</string>
   <string id="21806">Σχόλιο</string>
-  <string id="21807">Î\91Ï\80Ï\8cδοÏ\83η</string>
+  <string id="21807">Î\88γÏ\87Ï\81Ï\89μη/Î\91Ï\83Ï\80Ï\81Ï\8cμαÏ\85Ï\81η</string>
   <string id="21808">Επεξεργασία JPEG</string>
 
-  <string id="21820">Ημερομηνία λήψης</string>
+  <string id="21820">Ημερομηνία/Ώρα</string>
   <string id="21821">Περιγραφή</string>
   <string id="21822">Κατασκευαστής κάμερας</string>
   <string id="21823">Μοντέλο κάμερας</string>
   <string id="21837">Ευαισθησία ISO</string>
   <string id="21838">Ψηφιακή μεγέθυνση</string>
   <string id="21839">Πλάτος CCD</string>
-  <string id="21840">GPS γεωγραφικό πλάτος</string>
-  <string id="21841">GPS γεωγραφικό μήκος</string>
+  <string id="21840">GPS γεωγρ. πλάτος</string>
+  <string id="21841">GPS γεωγρ. μήκος</string>
   <string id="21842">GPS υψόμετρο</string>
   <string id="21843">Προσανατολισμός</string>
 
   <string id="21862">Λεζάντα</string>
   <string id="21863">Δημιουργός</string>
   <string id="21864">Επικεφαλίδα</string>
-  <string id="21865">Î\95ξειδικεÏ\85μένες πληροφορίες</string>
+  <string id="21865">Î\95ιδικές πληροφορίες</string>
   <string id="21866">Κατηγορία</string>
   <string id="21867">Προέλευση</string>
   <string id="21868">Τίτλος</string>
   <string id="21871">Σημειώσεις πνευματικής ιδιοκτησίας</string>
   <string id="21872">Όνομα αντικειμένου</string>
   <string id="21873">Πόλη</string>
-  <string id="21874">Î\95Ï\80αÏ\81Ï\87εία</string>
+  <string id="21874">ΠολιÏ\84εία</string>
   <string id="21875">Χώρα</string>
   <string id="21876">Νομοθετικές πληροφορίες</string>
   <string id="21877">Ημερομηνία δημιουργίας</string>
   <string id="21878">Πνευματικά δικαιώματα</string>
   <string id="21879">Κωδικός χώρας</string>
   <string id="21880">Υπηρεσία πληροφόρησης</string>
-  <string id="21881">Έγκριση στους ελεγκτές UPnP να ελέγχουν το XBMC</string>
+  <string id="21881">Έγκριση ελέγχου του XBMC μέσω UPnP</string>
   <string id="21882">Απόπειρα αποφυγής οδηγιών πριν από το μενού DVD</string>
   <string id="21883">Αποθηκευμένη μουσική</string>
-  <string id="21884">Î\95Ï\81Ï\8eÏ\84ημα για όλους τους καλλιτέχνες</string>
+  <string id="21884">Î\95Ï\8dÏ\81εÏ\83η Ï\80ληÏ\81οÏ\86οÏ\81ιÏ\8eν για όλους τους καλλιτέχνες</string>
   <string id="21885">Λήψη πληροφοριών για το άλμπουμ</string>
   <string id="21886">Λήψη πληροφοριών για τον καλλιτέχνη</string>
   <string id="21887">Βιογραφικό</string>
   <string id="21890">Επιλογή καλλιτέxνη</string>
   <string id="21891">Πληροφορίες καλλιτέχνη</string>
   <string id="21892">Όργανα</string>
-  <string id="21893">Î\93έννηÏ\83η</string>
+  <string id="21893">Î\93εννήθηκε</string>
   <string id="21894">Δημιουργία</string>
   <string id="21895">Θεματολόγιο</string>
-  <string id="21896">Î\94ιάλÏ\85Ï\83η</string>
-  <string id="21897">Î\98άναÏ\84οÏ\82</string>
+  <string id="21896">Î\94ιαλÏ\8dθηκε</string>
+  <string id="21897">Πέθανε</string>
   <string id="21898">Έτη ενεργής σταδιοδρομίας</string>
   <string id="21899">Ετικέτα</string>
   <string id="21900">Γέννηση/Δημιουργία</string>
   <string id="22011">Θερμοκρασία CPU:</string>
   <string id="22012">Συνολική μνήμη</string>
   <string id="22013">Δεδομένα προφίλ</string>
-  <string id="22014">Χρήση 'Αμυδρού φωτός' κατά τη παύση της αναπαραγωγής βίντεο</string>
+  <string id="22014">Χρήση 'Αμυδρού φωτός' κατά την παύση αναπαραγωγής βίντεο</string>
   <string id="22015">Όλες οι εγγραφές</string>
   <string id="22016">Aνά τίτλο</string>
   <string id="22017">Ανά ομάδα</string>
   <string id="22018">Δικτυακά κανάλια</string>
   <string id="22019">Εγγραφές ανά τίτλο</string>
   <string id="22020">Οδηγός</string>
-  <string id="22021">Î\95Ï\80ιÏ\84Ï\81εÏ\80Ï\8cμενο Ï\83Ï\86άλμα Ï\83Ï\84ο Î»Ï\8cγο Î±Ï\80εικÏ\8cνιÏ\83ηÏ\82 Î³Î¹Î± Î½Î± ÎµÎ»Î±Ï\87ιÏ\83Ï\84οÏ\80οιηθοÏ\8dν Î¿Î¹ Î¼Î±Ï\8dÏ\81εÏ\82 Î¼Ï\80άÏ\81εÏ\82</string>
+  <string id="22021">ΣÏ\86άλμα Î±Î½Î±Î»Î¿Î³Î¯Î±Ï\82 Î¿Î¸Ï\8cνηÏ\82 Î³Î¹Î± Î¼ÎµÎ¯Ï\89Ï\83η Î¼Î±Ï\8dÏ\81Ï\89ν Î¼Ï\80αÏ\81Ï\8eν</string>
   <string id="22022">Εμφάνιση αρχείων βίντεο στις λίστες</string>
   <string id="22023">Κατασκευαστής DirectX:</string>
   <string id="22024">Έκδοση Direct3D:</string>
 
   <!-- strings 23100 thru 23150 reserved for external player -->
   <string id="23100">Ενεργός εξωτερικός αναπαραγωγέας</string>
-  <string id="23101">Πιέστε το 'Εντάξει' για να τερματίσετε τον αναπαραγωγέα</string>
+  <string id="23101">Πιέστε 'Επιλογή' για να τερματίσετε την αναπαραγωγή</string>
 
-  <string id="23104">Πιέστε το 'Εντάξει' όταν η αναπαραγωγή ολοκληρωθεί</string>
+  <string id="23104">Πιέστε 'Επιλογή' όταν η αναπαραγωγή ολοκληρωθεί</string>
 
   <!-- strings 24000 thru 24299 reserved for the Add-ons framework -->
   <string id="24000">Πρόσθετο</string>
   <string id="24007">Πληροφορίες ταινίας</string>
   <string id="24008">Προφύλαξη οθόνης</string>
   <string id="24009">Script</string>
-  <string id="24010">Î\91Ï\80εικÏ\8cνιση</string>
-  <string id="24011">ΦÏ\8dλαξη Ï\80Ï\81Ï\8cÏ\83θεÏ\84οÏ\85</string>
+  <string id="24010">Î\9fÏ\80Ï\84ικοÏ\80οίηση</string>
+  <string id="24011">Î\91Ï\80οθεÏ\84ήÏ\81ιο Ï\80Ï\81Ï\8cÏ\83θεÏ\84Ï\89ν</string>
   <string id="24012">Υπότιτλοι</string>
   <string id="24013">Στίχοι</string>
   <string id="24014">Πληροφορίες τηλεόρασης</string>
   <string id="24032">Όλα τα πρόσθετα</string>
   <string id="24033">Λήψη πρόσθετων</string>
   <string id="24034">Έλεγχος για ενημερώσεις</string>
-  <string id="24035">Î\91ναγκασμένη ανανέωση</string>
+  <string id="24035">Î\95ξαναγκασμένη ανανέωση</string>
   <string id="24036">Καταγραφή αλλαγών</string>
   <string id="24037">Κατάργηση εγκατάστασης</string>
   <string id="24038">Εγκατάσταση</string>
   <string id="24041">Εγκατάσταση από αρχείο zip</string>
   <string id="24042">Λήψη %i%%</string>
   <string id="24043">Διαθέσιμες ενημερώσεις</string>
-  <string id="24044">Î\94εν Ï\80ληÏ\81οÏ\8dνÏ\84αι Î¿Î¹ Î\95ξαρτήσεις</string>
-  <string id="24045">Î\97 Î\95Ï\80έκÏ\84αÏ\83η δεν έχει τη σωστή δομή</string>
-  <string id="24046">%s χρησιμοποιείται από την εγκατεστημένη(νες) Επέκταση(εις)</string>
-  <string id="24047">Î\91δÏ\85ναμία Î±Ï\80εγκαÏ\84άÏ\83Ï\84αÏ\83ηÏ\82 Î±Ï\85Ï\84ήÏ\82 Ï\84ηÏ\82 Î\95Ï\80έκÏ\84αÏ\83ηÏ\82</string>
+  <string id="24044">Î\94εν Ï\80ληÏ\81οÏ\8dνÏ\84αι Î¿Î¹ Îµξαρτήσεις</string>
+  <string id="24045">Το Î Ï\81Ï\8cÏ\83θεÏ\84ο δεν έχει τη σωστή δομή</string>
+  <string id="24046">Το %s χρησιμοποιείται από τα εγκατεστημένα Πρόσθετα</string>
+  <string id="24047">Î\91δÏ\85ναμία Î±Ï\80εγκαÏ\84άÏ\83Ï\84αÏ\83ηÏ\82 Î±Ï\85Ï\84οÏ\8d Ï\84οÏ\85 Î Ï\81Ï\8cÏ\83θεÏ\84οÏ\85</string>
   <string id="24048">Επαναφορά</string>
 
   <string id="24050">Διαθέσιμα πρόσθετα</string>
   <string id="25000">Ειδοποιήσεις</string>
 
   <!-- strings 29800 thru 29998 reserved strings used only in the default Project Mayhem III skin and not c++ code -->
-  <string id="29800">Λειτουργία συλλογής</string>
+  <string id="29800">Λειτουργία Συλλογής</string>
   <string id="29801">Διάταξη πληκτρολογίου QWERTY</string>
   <string id="29802">Σε λειτουργία η διέλευση ήχου</string>
 
   <string id="33001">Ποιότητα διαφημιστικού</string>
   <string id="33002">Ροή πολυμέσων</string>
   <string id="33003">Λήψη</string>
-  <string id="33004">Λήψη και εκτέλεση</string>
-  <string id="33005">Λήψη και αποθήκευση</string>
+  <string id="33004">Λήψη &amp; εκτέλεση</string>
+  <string id="33005">Λήψη &amp; αποθήκευση</string>
   <string id="33006">Σήμερα</string>
   <string id="33007">Αύριο</string>
   <string id="33008">Αποθήκευση</string>
   <string id="33013">Εκτεταμένος</string>
   <string id="33014">Ορισμός αναπαραγωγέα DVD αντί του κανονικού</string>
   <string id="33015">Επιβεβαίωση λήψης πριν την αναπαραγωγή του βίντεο</string>
-  <string id="33016">Clips</string>
-  <string id="33017">Î\95Ï\80ανεκκίνηÏ\83η plugin Î³Î¹Î± Ï\84ην ÎµÎ½ÎµÏ\81γοÏ\80οίηÏ\83η του</string>
-  <string id="33018">ΣήμεÏ\81α Ï\84ο Î²Ï\81άδÏ\85</string>
-  <string id="33019">Αύριο το βράδυ</string>
+  <string id="33016">Clip</string>
+  <string id="33017">Î\95Ï\80ανεκκίνηÏ\83η plugin Î³Î¹Î± Ï\84ην ÎµÎ½ÎµÏ\81γοÏ\80οίηÏ\83ή του</string>
+  <string id="33018">Î\91Ï\80Ï\8cÏ\88ε</string>
+  <string id="33019">Αύριο βράδυ</string>
   <string id="33020">Kατάσταση καιρού</string>
   <string id="33021">Υετός</string>
   <string id="33022">Βροχή</string>
   <string id="33023">Υγρασία</string>
   <string id="33024">Αίσθηση</string>
   <string id="33025">Παρατηρούμενη</string>
-  <string id="33026">Î\95κÏ\86Ï\85γή από το κανονικό</string>
+  <string id="33026">ΠαÏ\81έκκλιÏ\83η από το κανονικό</string>
   <string id="33027">Ανατολή ηλίου</string>
   <string id="33028">Δύση ηλίου</string>
   <string id="33029">Λεπτομέρειες</string>
-  <string id="33030">Î\95ξέλιξη</string>
+  <string id="33030">ΠÏ\81Ï\8cγνÏ\89Ï\83η</string>
   <string id="33031">Ροή εξώφυλλων</string>
   <string id="33032">Μετάφραση κειμένου</string>
   <string id="33033">Κατηγορία λίστας χαρτών %s</string>
-  <string id="33034">Τριήμερη</string>
-  <string id="33035">Χάρτες καιρού</string>
+  <string id="33034">36ωρο</string>
+  <string id="33035">Χάρτες</string>
   <string id="33036">Ωριαία</string>
   <string id="33037">Σαββατοκύριακο</string>
   <string id="33038">%sη ημέρα</string>
   <string id="33049">Προειδοποίηση</string>
   <string id="33050">Προειδοποιήσεις</string>
   <string id="33051">Επιλογή</string>
-  <string id="33052">ΠÏ\81Ï\8cγνÏ\89Ï\83η</string>
+  <string id="33052">Î\88λεγÏ\87οÏ\82</string>
   <string id="33053">Ρύθμιση</string>
-  <string id="33054">Î\9aÏ\8dκλοι</string>
+  <string id="33054">Î\95Ï\80οÏ\87έÏ\82</string>
   <string id="33055">Εκτέλεση</string>
   <string id="33056">Παρακολούθηση</string>
   <string id="33057">Ακρόαση</string>
   <string id="33072">Σημειώσεις έκδοσης</string>
   <string id="33073">Αλλαγές έκδοσης</string>
   <string id="33074">Για να εκτελεστεί η έκδοση %s απαιτείται</string>
-  <string id="33075">η %s Î±Î½Î±Î¸ÎµÏ\89Ï\81ημένη Î­ÎºÎ´Î¿Ï\83η Ï\84οÏ\85 XBMC Î® ÎºÎ±Î¹ Î½ÎµÏ\8eÏ\84εÏ\81η.</string>
-  <string id="33076">Παρακαλώ, αναβαθμίστε άμεσα το XBMC.</string>
+  <string id="33075">η %s αναθεωρημένη έκδοση του XBMC ή νεώτερη.</string>
+  <string id="33076">Παρακαλώ αναβαθμίστε το XBMC.</string>
   <string id="33077">Δεν βρέθηκαν δεδομένα!</string>
   <string id="33078">Επόμενη σελίδα</string>
   <string id="33079">Αγαπητό</string>
   <string id="33080">Απεχθές</string>
-  <string id="33081">Αυτό το αρχείο είναι στοιβαγμένο, επιλέξτε το μέρος αυτού που επιθυμείτε να αναπαραχθεί.</string>
+  <string id="33081">Αυτό το αρχείο είναι στοιβαγμένο, επιλέξτε από που να γίνει αναπαραγωγή.</string>
   <string id="33082">Διαδρομή για το script</string>
   <string id="33083">Ενεργοποίηση προσαρμοσμένου πλήκτρου script</string>
 
   <string id="33100">Αποτυχία εκκίνησης</string>
-  <string id="33101">Διακομιστής web</string>
+  <string id="33101">Διακομιστής ιστού</string>
   <string id="33102">Διακομιστής Συμβάντων</string>
   <string id="33103">Απομακρυσμένος Διακομιστής Επικοινωνίας</string>
 
   <string id="34301">Είναι εγκατεστημένη η Υπηρεσία Bonjour της Apple; Δείτε το αρχείο καταγραφής για περισσότερες πληροφορίες.</string>
   
   <string id="34400">Απόδοση Βίντεο</string>
-  <string id="34401">Αποτυχία αρχικοποίησης φίλτρων/scalers βίντεο, επαναφορά σε διγραμμική προσαρμογή ανάλυσης</string>
-  <string id="34402">Î\91Ï\80οÏ\84Ï\85Ï\87ία Î±Ï\81Ï\87ικοÏ\80οίηÏ\83ης της συσκευής ήχου</string>
+  <string id="34401">Αποτυχία χρήσης φίλτρων/scalers βίντεο, επαναφορά σε bilinear προσαρμογή ανάλυσης</string>
+  <string id="34402">Î\91Ï\80οÏ\84Ï\85Ï\87ία Î­Î½Î±Ï\81ξης της συσκευής ήχου</string>
   <string id="34403">Ελέγξτε τις ρυθμίσεις ήχου</string>
 
   <string id="35000">Περιφερειακά</string>
   <string id="35001">Γενική συσκευή HID</string>
   <string id="35002">Γενικός προσαρμογέας δικτύου</string>
   <string id="35003">Γενικός δίσκος</string>
-  <string id="35004">Δεν υπάρχουν διαθέσιμες ρυθμίσεις για αυτό το περιφερειακό.</string>
-  <string id="35005">Η νέα συσκευή έχει ρυθμιστεί</string>
-  <string id="35006">Î\97 Ï\83Ï\85Ï\83κεÏ\85ή Î­Ï\87ει Î±Ï\86αιÏ\81εθεί</string>
-  <string id="35007">Το Keymap να χρησιμοποιηθεί για τη συγκεκριμένη συσκευή</string>
+  <string id="35004">Δεν υπάρχουν διαθέσιμες ρυθμίσεις&#10;για αυτό το περιφερειακό.</string>
+  <string id="35005">Η νέα συσκευή ρυθμίστηκε</string>
+  <string id="35006">Î\97 Ï\83Ï\85Ï\83κεÏ\85ή Î±Ï\86αιÏ\81έθηκε</string>
+  <string id="35007">Keymap για χρήση με αυτή τη συσκευή</string>
   <string id="35008">Ενεργοποιημένο Keymap</string>
 
   <string id="35500">Τοποθεσία</string>
   <string id="36001">Pulse-Eight Nyxboard</string>
   <string id="36002">Μετάβαση στο πληκτρολόγιο εντολών</string>
   <string id="36003">Ενεργοποίηση διακόπτη εντολών</string>
-  <string id="36004">ΠαÏ\84ήÏ\83Ï\84ε Ï\84ο "user" Ï\89Ï\82 πλήκτρο εντολών</string>
+  <string id="36004">ΠιέÏ\83Ï\84ε Ï\84ο "user" πλήκτρο εντολών</string>
   <string id="36005">Ενεργοποίηση διακόπτη εντολών</string>
   <string id="36006">Αδυναμία εκκίνησης του προσαρμογέα</string>
-  <string id="36007">Î\95νεÏ\81γοÏ\80οιήÏ\83Ï\84ε Ï\84ην Ï\84ηλεÏ\8cÏ\81αÏ\83η κατά την εκκίνηση του XBMC</string>
+  <string id="36007">Î\95νεÏ\81γοÏ\80οίηÏ\83η Ï\84ηÏ\82 Ï\84ηλεÏ\8cÏ\81αÏ\83ηÏ\82 κατά την εκκίνηση του XBMC</string>
   <string id="36008">Απενεργοποίηση συσκευών κατά τη διακοπή λειτουργίας του XBMC</string>
-  <string id="36009">Î\92άλÏ\84ε Ï\83Ï\85Ï\83κεÏ\85έÏ\82 Ï\83ε ÎºÎ±Ï\84άÏ\83Ï\84αÏ\83η Î±Î½Î±Î¼Î¿Î½Î®Ï\82 ÎºÎ±Ï\84ά Ï\84ην ÎµÎ½ÎµÏ\81γοÏ\80οίηÏ\83η Ï\84ηÏ\82 Ï\80Ï\81οÏ\86Ï\8dλαξηÏ\82 οθόνης</string>
+  <string id="36009">ΣÏ\85Ï\83κεÏ\85έÏ\82 Ï\83ε ÎºÎ±Ï\84άÏ\83Ï\84αÏ\83η Î±Î½Î±Î¼Î¿Î½Î®Ï\82 ÎºÎ±Ï\84ά Ï\84ην Ï\80Ï\81οÏ\86Ï\8dλαξη οθόνης</string>
   <string id="36010"></string>
-  <string id="36011">Î\94εν Î®Ï\84αν Î´Ï\85ναÏ\84ή Î· Î±Î½Î¯Ï\87νεÏ\85Ï\83η Ï\84ηÏ\82 Î¸Ï\8dÏ\81αÏ\82 CEC. Ρυθμίστε την χειροκίνητα.</string>
-  <string id="36012">Î\94εν Î®Ï\84αν Î´Ï\85ναÏ\84ή Î· Î±Î½Î¯Ï\87νεÏ\85Ï\83η Ï\84οÏ\85 Ï\80Ï\81οÏ\83αÏ\81μογέα CEC.</string>
-  <string id="36013">Μη υποστηριζόμενη έκδοση διεπαφής libcec. %d είναι μεγαλύτερη από την έκδοση που το XBMC υποστηρίζει (%d)</string>
-  <string id="36014">Î\92άλÏ\84ε Î±Ï\85Ï\84Ï\8cν Ï\84ον Ï\85Ï\80ολογιÏ\83Ï\84ή Ï\83ε ÎºÎ±Ï\84άÏ\83Ï\84αÏ\83η Î±Î½Î±Î¼Î¿Î½Î®Ï\82 Ï\8cÏ\84αν Î· Ï\84ηλεÏ\8cÏ\81αÏ\83η ÎµÎ¯Î½Î±Î¹ Î±Ï\80ενεÏ\81γοÏ\80οιημένη</string>
+  <string id="36011">Î\94εν ÎµÎ½Ï\84οÏ\80ίÏ\83Ï\84ηκε Î· Î¸Ï\8dÏ\81α CEC. Ρυθμίστε την χειροκίνητα.</string>
+  <string id="36012">Î\94εν ÎµÎ½Ï\84οÏ\80ίÏ\83Ï\84ηκε Î¿ Ï\80Ï\81οÏ\83αÏ\81μογέαÏ\82 CEC.</string>
+  <string id="36013">Μη υποστηριζόμενη έκδοση libcec. Η %d είναι μεγαλύτερη από την έκδοση που το XBMC υποστηρίζει (%d)</string>
+  <string id="36014">Î\9f Ï\85Ï\80ολογιÏ\83Ï\84ήÏ\82 Ï\83ε ÎºÎ±Ï\84άÏ\83Ï\84αÏ\83η Î±Î½Î±Î¼Î¿Î½Î®Ï\82 Ï\8cÏ\84αν ÎºÎ»ÎµÎ¯Ï\83ει Î· Ï\84ηλεÏ\8cÏ\81αÏ\83η</string>
   <string id="36015">Αριθμός θύρας HDMI</string>
   <string id="36016">Συνδεδεμένη</string> <!-- max. 13 characters -->
-  <string id="36017">O προσαρμογέας εντοπίσθηκε, αλλά  η libcec δεν είναι διαθέσιμη</string>
-  <string id="36018">Χρήση της γλώσσας της τηλεόρασης</string>
+  <string id="36017">O προσαρμογέας εντοπίσθηκε, αλλά η libcec δεν είναι διαθέσιμη</string>
+  <string id="36018">Χρήση των ρυθμίσεων γλώσσας της τηλεόρασης</string>
 </strings>
index cee9ec5..e160608 100644 (file)
   </dvd>
 
   <regions>
-    <region locale="IL">
+    <region name="ISRAEL (12h)" locale="IL">
+      <dateshort>DD/MM/YYYY</dateshort>
+      <datelong>DDDD DD MMMM YYYY</datelong>
+      <time symbolAM="" symbolPM="">hh:mm:ss</time>
+      <tempunit>C</tempunit>
+      <speedunit>kmh</speedunit>
+    </region>
+
+    <region name="ISRAEL (24h)" locale="US">
       <dateshort>DD/MM/YYYY</dateshort>
       <datelong>DDDD DD MMMM YYYY</datelong>
       <time symbolAM="" symbolPM="">HH:mm:ss</time>
       <tempunit>C</tempunit>
       <speedunit>kmh</speedunit>
     </region>
+
   </regions>
 </language>
 
index ed47e18..ba60c85 100644 (file)
@@ -2,8 +2,8 @@
 <!--Language file translated with Team XBMC Translator-->
 <!--Translator: Idan Bushari-->
 <!--Email: bushari2003@hotmail.com-->
-<!--Date of translation: 01/25/2012-->
-<!--Based on English 3978ce61ee897fab5daf83c345f3a8183aae0b22 (26.01.2012)-->
+<!--Date of translation: 02/20/2012-->
+<!--Based on English 0ee1ef09238e4d913cf6c47fa18138c3654cd33e (08.02.2012)-->
 <strings>
   <string id="0">תוכנות</string>
   <string id="1">תמונות</string>
   <string id="10019">הגדרות - מראה</string>
   <string id="10020">סקריפטים</string>
   <string id="10021">דפדפן אינטרנט</string>
+  <string id="10025">וידאו</string>
   <string id="10028">וידאו/רשימת ניגון</string>
+  <string id="10029">מסך כניסה</string>
   <string id="10034">הגדרות - פרופילים</string>
+  <string id="10040">דפדפן הרחבות</string>
   <string id="10100">דיאלוג לא/כן</string>
   <string id="10101">דיאלוג התקדמות</string>
   <string id="10210">מחפש כתוביות...</string>
   <string id="20042">נעל מנהל קבצים</string>
   <string id="20043">נעל הגדרות</string>
   <string id="20044">התחל מחדש</string>
-  <string id="20045">×\94×\99×\9bנס ×\9c×\9eצ×\91 ×\9e×\95×\9e×\97×\94</string>
-  <string id="20046">צ×\90 ×\9e×\9eצ×\91 ×\9e×\95×\9e×\97×\94</string>
+  <string id="20045">×\94×\99×\9bנס ×\9c×\9eצ×\91 ×¨×\90ש×\99</string>
+  <string id="20046">צ×\90 ×\9e×\9eצ×\91 ×¨×\90ש×\99</string>
   <string id="20047">צור פרופיל '%s' ?</string>
   <string id="20048">התחל עם הגדרות חדשות</string>
   <string id="20049">הזמין הטוב ביותר</string>
   <string id="20050">החלף אוטומטית בין 16x9 ו 4x3</string>
   <string id="20051">התייחס לערימת קבצים כקובץ אחד</string>
   <string id="20052">זהירות</string>
-  <string id="20053">×¢×\96×\91 ×\9eצ×\91 ×\9e×\95×\9e×\97×\94</string>
-  <string id="20054">× ×\9bנס ×\9c×\9eצ×\91 ×\9e×\95×\9e×\97×\94</string>
+  <string id="20053">×¢×\96×\91 ×\9eצ×\91 ×¨×\90ש×\99</string>
+  <string id="20054">× ×\9bנס ×\9c×\9eצ×\91 ×¨×\90ש×\99</string>
   <string id="20055">תמונה ממוזערת Allmusic.com</string>
   <string id="20057">הסר תמונה ממוזערת</string>
   <string id="20058">הוסף פרופיל...</string>
   <string id="20098">משיג פרטים עבור האלבום</string>
   <string id="20099">לא יכול להעתיק דיסק או רצועה בזמן ניגון מהדיסק</string>
   <string id="20100">קוד נעילה ראשי והגדרות</string>
-  <string id="20101">×\94×\96נת ×§×\95×\93 × ×¢×\99×\9c×\94 ×¨×\90ש×\99 ×ª×\9e×\99×\93 ×\9e×\90פשרת ×\9eצ×\91 ×\9e×\95×\9e×\97×\94</string>
+  <string id="20101">×\94×\96נת ×§×\95×\93 × ×¢×\99×\9c×\94 ×¨×\90ש×\99 ×ª×\9e×\99×\93 ×\9e×\90פשרת ×\9eצ×\91 ×¨×\90ש×\99</string>
   <string id="20102">או העתק מברירת מחדל?</string>
   <string id="20103">שמור שינויים לפרופיל?</string>
   <string id="20104">הגדרות ישנות נמצאו</string>
   <string id="20326">זה יאפס את ערכי הכיול ל %s</string>
   <string id="20327">לערכי ברירת המחדל שלו</string>
   <string id="20328">עיין לנתיב יעד</string>
+  <string id="20329">סרטים נמצאים בתיקיות נפרדות עם כותרת הסרט</string>
   <string id="20330">השתמש בשמות תיקיות לחיפוש</string>
   <string id="20331">קובץ</string>
   <string id="20332">השתמש בשמות תיקיה או קובץ בחיפוש?</string>
   <string id="20432">אל תכלול נתיב זה בעידכוני ספריה</string>
   <string id="20433">חלץ תמונות ממוזערות ופרטי וידאו</string>
   <string id="20434">מארזים</string>
-  <string id="20435">ק×\91×¢ ×ª×\9e×\95× ×\95ת ממוזערת למארז סרטים</string>
+  <string id="20435">ק×\91×¢ ×ª×\9e×\95× ×\94 ממוזערת למארז סרטים</string>
   <string id="20436">לייצא תמונות ממוזערות לשחקנים</string>
   <string id="20437">בחר פאנארט</string>
   <string id="20438">פאנארט מקומי</string>
index 4702678..6d3f8b5 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <!--Translator: Bence Nádas and Attila Jakosa with a help of Zsolt Malecz-->
 <!--Email: attila.jakosa@gmail.com-->
-<!--Based on English 98d103ae66a1e81e379e65dd131341cd119cfcf2 (21.01.2012)-->
+<!--Based on English 0ee1ef09238e4d913cf6c47fa18138c3654cd33e (08.02.2012)-->
 <strings>
   <string id="0">Programok</string>
   <string id="1">Képek</string>
   <string id="10020">Programok</string>
   <string id="10021">Internet böngésző</string>
 
+  <string id="10025">Videók</string>
+
   <string id="10028">Videók/lejátszáslista</string>
+  <string id="10029">Bejelentkezési képernyő</string>
   <string id="10034">Beállítások - Profilok</string>
+  <string id="10040">Kiegészítő böngésző</string>
 
   <string id="10100">Igen/nem párbeszédpanel</string>
   <string id="10101">Folyamatjelző párbeszédpanel</string>
   <string id="20326">Kalibrációs értékek törlése %s számára</string>
   <string id="20327">az alapértelmezett értékekere.</string>
   <string id="20328">Tallózás</string>
-
+  <string id="20329">A filmcímnek megfelelő találatok külön mappákban találhatók</string>
   <string id="20330">Használja a mappanevet a keresésekhez</string>
   <string id="20331">Fájl</string>
   <string id="20332">Mappa- vagy fájlnevek használata kereséskor?</string>
   <string id="20416">Első adás</string>
   <string id="20417">Írta</string>
   <string id="20418"></string>
-  <string id="20419">Metaadatok mutatása a fájlnézetben</string>
+  <string id="20419">Fájlnevek helyett a médiatár címek mutatása</string>
 
   <string id="20420">Soha</string>
   <string id="20421">Csak, ha egy évad van</string>
   <string id="20455">Hallgató</string>
   <string id="20456">Filmgyűjtemény fanart beállítása</string>
   <string id="20457">Filmgyűjtemény</string>
+  <string id="20458">Filmek csoportosítása készletekbe</string>
   <!-- 21329-ig videó-adatbázisra fenntartva  !! !-->
 
   <string id="21330">Rejtett fájlok és mappák megjelenítése</string>
index 641804d..7c1c4e3 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!--Translator: Succo, updated by Gulp-->
+<!--Translator: Succo, updated by Gulp and Liltee89-->
 <!--Email: succo69@libero.it, http://forum.xbmc.org/member.php?u=42290-->
 <!--Based on English 5c8c939de7422db2427f37d5c26036138a9fe04e (03.02.2012)-->
 <strings>
   <string id="382">Sparsi</string>
   <string id="383">Vento</string>
   <string id="384">Forte</string>
-  <string id="385">Bello</string>
-  <string id="386">Chiaro</string>
+  <string id="385">Sereno</string>
+  <string id="386">Limpido</string>
   <string id="387">Nuvoloso</string>
   <string id="388">Anticipati</string>
   <string id="389">Rovescio</string>
   <string id="390">Turbini</string>
-  <string id="391">Bassa</string>
+  <string id="391">Minima</string>
   <string id="392">Media</string>
-  <string id="393">Alta</string>
+  <string id="393">Massima</string>
   <string id="394">Nebbia</string>
-  <string id="395">Coperto</string>
+  <string id="395">Foschia</string>
   <string id="396">Seleziona località</string>
   <string id="397">Aggiornamento</string>
   <string id="398">Misura di temperatura</string>
   <string id="405">P. di rugiada</string>
   <string id="406">Umidità</string>
 
-  <string id="409">Predefinitio</string>
+  <string id="409">Predefinito</string>
   <string id="410">Accesso a servizio meteo</string>
   <string id="411">Aggiorno le previsioni meteo per:</string>
   <string id="412">Impossibile aggiornare le informazioni meteo</string>
   <string id="496">Calibrazione</string>
   <string id="497">Mostra le estensioni dei file</string>
   <string id="498">Ordina per: Tipo</string>
-  <string id="499">Impossibile collegarsi a servizio di ricerca online</string>
+  <string id="499">Impossibile collegarsi al servizio di ricerca online</string>
   <string id="500">Impossibile scaricare le informazioni sull'album</string>
   <string id="501">Ricerca nome album in corso...</string>
   <string id="502">Aperto</string>
   <string id="518">Avvia</string>
   <string id="519">Avvia in...</string>
 
-  <string id="521">Compilations</string>
+  <string id="521">Compilation</string>
   <string id="522">Rimuovi sorgente</string>
   <string id="523">Cambia media</string>
   <string id="524">Seleziona playlist</string>
   <string id="641">Livello PreAmp - file "Replay gained"</string>
   <string id="642">Livello PreAmp - file "non Replay gained"</string>
   <string id="643">Evita clipping nei file "Replay gained"</string>
-  <string id="644">Taglia barre nere</string>
-  <string id="645">Devo scomprimere un file grande. Continuare?</string>
+  <string id="644">Taglia bande nere</string>
+  <string id="645">Devo scompattare un file grande. Continuare?</string>
   <string id="646">Elimina dall'archivio</string>
   <string id="647">Esporta l'archivio video</string>
   <string id="648">Importa l'archivio video</string>
   <string id="794">Permetti a programmi esterni di controllare XBMC</string>
   <string id="795">Ritardo ripetizione iniziale (ms)</string>
   <string id="796">Ritardo ripetizione continuo (ms)</string>
-  <string id="797">Numero massimo di clients</string>
+  <string id="797">Numero massimo di client</string>
   <string id="798">Accesso a Internet</string>
 
   <string id="850">Inserito un numero di porta non valido</string>
   <string id="1251">Autorilevamento sistema</string>
   <string id="1252">Nick name</string>
 
-  <string id="1254">Richiedi di connetersi</string>
+  <string id="1254">Richiedi di connettersi</string>
   <string id="1255">Invia user e password FTP</string>
   <string id="1256">Intervallo ping</string>
   <string id="1257">Vuoi connetterti al sistema rilevato?</string>
   <string id="1271">Nome periferica</string>
   <string id="1272">- Proteggi con password</string>
 
-  <string id="1300">Dispositipo audio personalizzato</string>
+  <string id="1300">Dispositivo audio personalizzato</string>
   <string id="1301">Dispositivo passthrough personalizzato</string>
 
   <string id="1396">Mutevole</string>
   <string id="12368">Inserire un master code valido</string>
   <string id="12373">Impostazioni &amp; file</string>
   <string id="12376">Imposta come default per tutti i filmati</string>
-  <string id="12377">Questo resetterà i valori salvati in precendeza</string>
+  <string id="12377">Questo resetterà i valori salvati in precedenza</string>
   <string id="12378">Tempo di visualizzazione di ogni immagine</string>
   <string id="12379">Usa gli effetti pan e zoom</string>
 
   <string id="13171">Immediatamente</string>
   <string id="13172">Dopo %i secondi</string>
   <string id="13173">Data installazione hard disk:</string>
-  <string id="13174">Conteggio spegnimenti HDD:</string>
+  <string id="13174">Conteggio spegnimento HDD:</string>
 
   <string id="13200">Profili</string>
   <string id="13201">Cancella profilo '%i'?</string>
   <string id="13206">Sovrascrivi</string>
 
   <string id="13208">Allarme sveglia</string>
-  <string id="13209">Intervallo allarme sveglia (in minutes)</string>
+  <string id="13209">Intervallo allarme sveglia (in minuti)</string>
   <string id="13210">Partito, allarme tra %im</string>
   <string id="13211">Allarme!</string>
   <string id="13212">Annullato con ancora %im%is</string>
   <string id="13214">%2.0fs</string> <!--seconds (left from countdown)-->
 
   <string id="13249">Cerca sottotili nei file RAR</string>
-  <string id="13250">Mostra sottotili...</string>
+  <string id="13250">Mostra sottotitoli...</string>
   <string id="13251">Sposta l'elemento</string>
   <string id="13252">Sposta l'elemento qui</string>
   <string id="13253">Annulla spostamento</string>
   <string id="13274">Connesso, ma non c'è nessun DNS disponibile.</string>
   <string id="13275">Hard Disk</string>
   <string id="13276">DVD-ROM</string>
-  <string id="13277">Disp.di memorizz.</string>
+  <string id="13277">Disp. di memoriz.</string>
   <string id="13278">Default</string>
   <string id="13279">Rete</string>
   <string id="13280">Video</string>
   <string id="13309">invece di XBMC?</string>
   <string id="13310">Effetto zoom</string>
   <string id="13311">Effetto spostamento</string>
-  <string id="13312">Riduzione barra nera</string>
+  <string id="13312">Riduzione banda nera</string>
   <string id="13313">Riavvia</string>
   <string id="13314">Dissolvenza tra le tracce</string>
   <string id="13315">Ricrea le icone</string>
   <string id="14013">- Vista ad icone per</string>
   <string id="14014">- Percentuale</string>
   <string id="14015">Nessun file ed almeno una icona</string>
-  <string id="14016">Almeno un file ed una Icona</string>
+  <string id="14016">Almeno un file ed una icona</string>
   <string id="14017">Percentuale di icone</string>
   <string id="14018">Opzioni di visione</string>
   <string id="14019">Nome o codice città 1</string>
 
   <string id="14055">Usa scansione in background</string>
   <string id="14056">Ferma scansione</string>
-  <string id="14057">Non si può durante la scansione informazioni media</string>
+  <string id="14057">Non si possono ottenere informazioni durante la scansione</string>
   <string id="14058">Effetto film sgranato</string>
   <string id="14059">Cerca le icone nelle condivisioni remote</string>
   <string id="14060">Cache di tipo sconosciuto - Internet</string>
   <string id="15202">Nome utente Last.fm</string>
   <string id="15203">Password Last.fm</string>
   <string id="15204">Inoperabile: disattivo...</string>
-  <string id="15205">Pregasi aggiornare XBMC</string>
+  <string id="15205">Per favore aggiornare XBMC</string>
   <string id="15206">Non autorizzato: controlla nome utente e password</string>
   <string id="15207">Connesso</string>
   <string id="15208">Non connesso</string>
   <string id="15212">Inviato in %i secondi</string>
   <string id="15213">Riproduci con...</string>
   <string id="15214">Perfeziona sincronizzazione A/V</string>
-  <string id="15215">Nascondi nomi dei files in vista ad icone</string>
+  <string id="15215">Nascondi i nomi dei file in vista ad icone</string>
   <string id="15216">Esegui in modalità party</string>
   <string id="15217">Invia le canzoni a Libre.fm</string>
   <string id="15218">Nome utente di Libre.fm</string>
   <string id="15278">Ascolta le Last.fm radio canzoni preferite di %name%</string>
   <string id="15279">Ricezione lista da Last.fm...</string>
   <string id="15280">Impossibile ricevere la lista da Last.fm...</string>
-  <string id="15281">Inserire il nome di un artista per trovarne i relazionati</string>
+  <string id="15281">Inserire il nome di un artista per trovarne i correlati</string>
   <string id="15282">Inserire il nome di un etichetta per trovarne di simili</string>
-  <string id="15283">Traccce recentemente ascoltate da %name%</string>
+  <string id="15283">Tracce recentemente ascoltate da %name%</string>
   <string id="15284">Ascolta le %name%'s raccomandazioni Last.fm radio</string>
   <string id="15285">Etichette preferite per l'utente %name%</string>
 
   <string id="20003">Cartella dei trainer</string>
   <string id="20004">Cartella per gli screenshot</string>
 
-  <string id="20006">Cartella playlists</string>
+  <string id="20006">Cartella playlist</string>
   <string id="20007">Registrazioni</string>
-  <string id="20008">Screenshots</string>
+  <string id="20008">Screenshot</string>
   <string id="20009">Usa XBMC</string>
 
-  <string id="20011">Playlists musica</string>
-  <string id="20012">Playlists video</string>
+  <string id="20011">Playlist musica</string>
+  <string id="20012">Playlist video</string>
   <string id="20013">Vuoi lanciare il gioco?</string>
   <string id="20014">Ordina per: Playlist</string>
   <string id="20015">Icona remota</string>
 
   <!-- string id's 20200 thru 20211 are reserved for speedstrings (LocalizeStrings.cpp)-->
 
-  <string id="20250">Party attivo! (videos)</string>
-  <string id="20251">Mixando bevande (videos)</string>
-  <string id="20252">Riempiendo bicchieri (videos)</string>
+  <string id="20250">Party attivo! (video)</string>
+  <string id="20251">Mixando bevande (video)</string>
+  <string id="20252">Riempiendo bicchieri (video)</string>
   <string id="20253">WebDAV server (HTTP)</string>
   <string id="20254">WebDAV server (HTTPS)</string>
   <string id="20255">Primo login, edita il tuo profilo</string>
   <string id="20326">Questo resetterà il valore di calibrazione per %s</string>
   <string id="20327">al suo valore originale.</string>
   <string id="20328">Cerca la destinazione</string>
-  <string id="20329">I film sono in cartelle separate che riportano il titolo del film</string>
+  <string id="20329">I film sono in cartelle separate rinominate con il titolo del film</string>
   <string id="20330">Usa i nomi delle cartelle per le ricerche</string>
   <string id="20331">File</string>
-  <string id="20332">Uso i nomi dei files o delle cartelle per le ricerche?</string>
+  <string id="20332">Uso i nomi dei file o delle cartelle per le ricerche?</string>
   <string id="20333">Imposta il contenuto</string>
   <string id="20334">Cartella</string>
   <string id="20335">Cerco il contenuto in modo ricorsivo?</string>
   <string id="20385">Rimuovi collegamento a serie TV</string>
   <string id="20386">Film aggiunti di recente</string>
   <string id="20387">Episodi aggiunti di recente</string>
-  <string id="20388">Studios</string>
+  <string id="20388">Studio</string>
   <string id="20389">Video musicali</string>
   <string id="20390">Video musicali recenti</string>
   <string id="20391">Video musicale</string>
   <string id="20393">Informazioni video musicale</string>
   <string id="20394">Caricamento informazioni video musicale</string>
   <string id="20395">Mixed</string>
-  <string id="20396">Vai a albums per artista</string>
+  <string id="20396">Vai a album per artista</string>
   <string id="20397">Vai a album</string>
   <string id="20398">Riproduci brano</string>
   <string id="20399">Vai a video musicali dall'album</string>
   <string id="20415">Scansione nuovo contenuto</string>
   <string id="20416">Prima visione</string>
   <string id="20417">Scrittore</string>
-  <string id="20418">Pulisci i nomi dei files e delle cartelle</string>
-  <string id="20419">Sostituisci i nomi dei files con i titoli presenti nella libreria</string>
+  <string id="20418">Pulisci i nomi dei file e delle cartelle</string>
+  <string id="20419">Mostra i metadati nella vista file</string>
 
   <string id="20420">Mai</string>
   <string id="20421">Se solo una stagione</string>
   <string id="20454">In Ascolto</string>
   <string id="20455">In Ascolto</string>
   <string id="20456">Imposta l'immagine fanart per un set di filmati</string>
-  <string id="20457">Set di film</string>
-  <string id="20458">Raggruppa i film in set</string>
+  <string id="20457">imposta filmato</string>
+  <string id="20458">Raggruppa film in antologie</string>
   <!-- up to 21329 is reserved for the video db !! !-->
 
   <string id="21330">Mostra i files e le cartelle nascoste</string>
   <string id="21423">Nuova regola...</string>
   <string id="21424">Gli elementi devono combaciare</string>
   <string id="21425">tutte le regole</string>
-  <string id="21426">ona o più delle regole</string>
+  <string id="21426">una o più delle regole</string>
   <string id="21427">Limita a</string>
   <string id="21428">Nessun limite</string>
   <string id="21429">Ordina per</string>
-  <string id="21430">ascendente</string>
-  <string id="21431">discendente</string>
+  <string id="21430">crescente</string>
+  <string id="21431">descrescente</string>
   <string id="21432">Modifica smart playlist</string>
   <string id="21433">Nome della playlist</string>
   <string id="21434">Trova gli elementi che combaciano</string>
   <string id="24028">Weather.com (standard)</string>
   <string id="24030">Questo Add-on non può essere configurato</string>
   <string id="24031">Errore nel caricamento delle impostazioni</string>
-  <string id="24032">Tutti gli add-ons</string>
-  <string id="24033">Scarica add-ons</string>
+  <string id="24032">Tutti gli add-on</string>
+  <string id="24033">Scarica add-on</string>
   <string id="24034">Controlla Aggiornamenti</string>
   <string id="24035">Forza refresh</string>
   <string id="24036">Change log</string>
   <string id="24037">Disinstalla</string>
   <string id="24038">Installa</string>
-  <string id="24039">Add-ons disabilitato</string>
+  <string id="24039">Add-on disabilitato</string>
   <string id="24040">(Resetta le impostazioni attuali)</string>
   <string id="24041">Installa da un file zip</string>
   <string id="24042">Scaricando %i%%</string>
   <string id="24047">Questo add-on non può essere rimosso</string>
   <string id="24048">Regredire versione</string>
 
-  <string id="24050">Add-ons disponibili</string>
+  <string id="24050">Add-on disponibili</string>
   <string id="24051">Versione:</string>
   <string id="24052">Informazioni</string>
   <string id="24053">Licenza:</string>
   <string id="24064">Abilita Add-on</string>
   <string id="24065">Add-on Aggiornato</string>
   <string id="24066">Cancella il download dell'Add-on?</string>
-  <string id="24067">Download dell'Add-ons in corso</string>
+  <string id="24067">Download dell'Add-on in corso</string>
   <string id="24068">Aggiornamento disponibile</string>
   <string id="24069">Aggiorna</string>
 
   <string id="24090">Blocca il manager degli Add-on</string>
 
   <string id="24094">(currente)</string>
-  <string id="24095">(blacklisted)</string>
+  <string id="24095">(in blacklist)</string>
   <string id="24096">Questo Add-on è segnalato non funzionante nel repository.</string>
   <string id="24097">Vuoi disabilitarlo nel tuo sistema?</string>
   <string id="24098">Non funzionante</string>
index a69dd93..3a6044a 100644 (file)
   <string id="852">유효한 포트 범위는 1024-65535 입니다</string>
 
   <string id="998">음악 파일 위치 추가...</string>
-  <string id="999">비디오 파일 위치 추가...</string>
+  <string id="999">비디오 추가...</string>
   <string id="1000">- 미리보기</string>
   <string id="1001">연결할수 없음</string>
   <string id="1002">XBMC가 네트워크에 연결할수 없습니다.</string>
   <string id="10019">설정 - 모양새</string>
   <string id="10020">스크립트</string>
   <string id="10021">웹 브라우저</string>
-
+  <string id="10025">비디오</string>
   <string id="10028">비디오/재생목록</string>
+  <string id="10029">로그인 화면</string>
   <string id="10034">설정 - 프로파일</string>
+  <string id="10040">애드온 탐색기</string>
 
   <string id="10100">예/아니오 대화창</string>
   <string id="10101">진행 대화창</string>
   <string id="13409">인기 250</string>
   <string id="13410">Last.fm 에 채널을 맞춤</string>
   <string id="13411">최소 팬 속도</string>
-  <string id="13412">Play from here</string>
+  <string id="13412">이 항목부터 재생</string>
   <string id="13413">다운로드</string>
   <string id="13414">컴필레이션에만 있는 아티스트 포함</string>
   <string id="13415">렌더링 방식</string>
   <string id="20326">기본값으로 %s 조정값를</string>
   <string id="20327">초기화하게 됩니다.</string>
   <string id="20328">대상 찾기</string>
-
+  <string id="20329">영화 파일들이 영화 제목과 같은 개별 폴더에 저장됨</string>
   <string id="20330">검색에 폴더 이름 사용</string>
   <string id="20331">파일</string>
   <string id="20332">검색에 파일이나 폴더 이름을 사용 하시겠습니까?</string>
   <string id="20416">초연</string>
   <string id="20417">각본</string>
   <string id="20418">파일 및 폴더 이름 정리</string>
-  <string id="20419">파일 보기에서 미디어정보 보기</string>
+  <string id="20419">파일명을 라이브러리 제목으로 표시</string>
 
   <string id="20420">안함</string>
   <string id="20421">한 시즌 일때만</string>
   <string id="20455">청취자</string>
   <string id="20456">시리즈 영화 팬아트 설정</string>
   <string id="20457">시리즈 영화</string>
+  <string id="20458">시리즈 영화 묶기</string>
   <!-- up to 21329 is reserved for the video db !! !-->
 
   <string id="21330">숨김 파일 및 디렉토리 보이기</string>
   <string id="21451">인터넷 연결이 필요함.</string>
   <string id="21452">더 가져오기...</string>
   <string id="21453">루트 파일시스템</string>
+  <string id="21454">캐시 가득참</string>
+  <string id="21455">연속 재생에 필요한 양에 도달하기 전에 캐시가 채워짐</string>
 
   <string id="21460">자막 위치</string>
   <string id="21461">고정</string>
   <string id="24041">압축 파일에서 설치</string>
   <string id="24042">%i%% 다운로드중</string>
   <string id="24043">사용가능한 업데이트</string>
-  <string id="24044">Dependencies not met</string>
+  <string id="24044">설치 요구조건을 충족하지 않습니다</string>
   <string id="24045">애드온의 구조가 바르지 않습니다</string>
   <string id="24046">%s 을 설치된 애드온이 사용합니다.</string>
   <string id="24047">이 추가기능은 제거할 수 없습니다</string>
   <string id="33102">이벤트 서버</string>
   <string id="33103">원격 커뮤니케이션 서버</string>
 
+  <string id="33200">새 연결 검색됨</string>
+
   <!-- translators: no need to add these to your language files -->
   <string id="34000">Lame</string>
   <string id="34001">Vorbis</string>
   <string id="34201">재생할 다음 항목이 없습니다</string>
   <string id="34202">재생할 이전 항목이 없습니다</string>
 
+  <string id="34300">제로컨프 시작 실패</string>
+  <string id="34301">애플 봉주르 서비스가 설치되어 있습니까? 자세한 정보는 로그를 확인하세요.</string>
+  
+  <string id="34400">비디오 렌더링</string>
+  <string id="34401">비디오 필터/스케일러 초기화 실패. 이중선형 스케일링으로 변경합니다</string>
+  <string id="34402">오디오 장치 초기화 실패</string>
+  <string id="34403">오디오 설정을 확인하세요</string>
+
   <string id="35000">주변장치</string>
 
   <string id="35001">Generic HID 장치</string>
   <string id="36002">키보드 사이드 명령으로 전환</string>
   <string id="36003">리모콘 사이드 명령으로 전환</string>
   <string id="36004">"user" 버튼 명령 누르기</string>
-  <string id="36005">Enable switch side commands</string>
+  <string id="36005">스위치 사이드 명령 사용</string>
   <string id="36006">어댑터를 열 수 없습니다</string>
   <string id="36007">XBMC 시작시 TV 켜기</string>
   <string id="36008">XBMC 종료시 장치 전원 끄기</string>
index ab1a878..46bfca0 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <!--Translator: Artūras Griškonis (ArtX38)-->
 <!--Email: info@xbmc.lt-->
-<!--Date of translation: 21/01/2012-->
-<!--Based on english strings version 98d103ae66a1e81e379e65dd131341cd119cfcf2-->
+<!--Date of translation: 02/03/2012-->
+<!--Based on english strings version 4a0e4931310c8957d73ffec0cf6fdfa9292bb8d4 (08.02.2012)-->
 <strings>
   <string id="0">Programos</string>
   <string id="1">Foto</string>
   <string id="164">Grotuve nėra disko</string>
   <string id="165">Diskas grotuve</string>
   <string id="166">Viršeliai</string>
-  <string id="167">Įjungti FTP serverį</string>
-  <string id="168">Įjungti laiko sinhronizavimą internetu</string>
+
   <string id="169">Ekrano rezoliucija</string>
   <string id="170">Nustatyti ekrano atnaujinimo dažnį</string>
-  <string id="171">Išdidinti nuo 4:3 iki 16:9</string>
 
   <string id="172">Išleidimo data</string>
   <string id="173">Rodyti formatą 4:3 kaip</string>
   <string id="205">Balsų:</string>
   <string id="206">Artistai</string>
   <string id="207">Siužetas</string>
-  <string id="208">Atkurti</string>
+  <string id="208">Atkūrti</string>
   <string id="209">Sekantis</string>
   <string id="210">Ankstesnis</string>
   <string id="213">Kalibravimo sąsaja...</string>
   <string id="283">Paieškos rezultatai</string>
   <string id="284">Nieko nerasta</string>
 
-  <string id="286">Baigiamoji doroklė</string>
   <string id="287">Subtitrai</string>
   <string id="288">Šriftas</string>
   <string id="289">- Dydis</string>
   <string id="304">Kalba</string>
   <string id="305">Įjungta</string>
   <string id="306">Ne-formatas</string>
-  <string id="307">- automatinis baigiamasis apdorojimas</string>
-  <string id="308">- vertikalus Deblocking-filtras</string>
-  <string id="309">- horizontalus Deblocking-filtras</string>
-  <string id="310">- Autoryškumas/Kontrastas</string>
-  <string id="311">- Atspindžių slopinimas</string>
+
   <string id="312">(0=auto)</string>
   <string id="313">Duomenų bazės valymas</string>
   <string id="314">Paruošimas...</string>
   <string id="431">Nėra talpyklos</string>
   <string id="432">Pašalinti filmą iš bibliotekos</string>
   <string id="433">Ar tikrai ištrinti '%s'?</string>
-  <string id="434">C %s į %i %s</string> <!--From <wind dir.> at <speed> <unit>-->
+  <string id="434"> %s į %i %s</string> <!--From <wind dir.> at <speed> <unit>-->
 
-  <string id="437">Išimti diską</string>
+  <string id="437">Keičiamasis diskas</string>
   <string id="438">Failo atidarymas</string>
   <string id="439">Buferizacija</string>
   <string id="440">HDD diskas</string>
   <string id="448">LCD ekranas</string>
   <string id="449">Įjungta</string>
   <string id="450">Ženklų kiekis eilėje</string>
-  <string id="451">Eilutė 1 adresas</string>
-  <string id="452">Eilutė 2 adresas</string>
-  <string id="453">Eilutė 3 adresas</string>
-  <string id="454">Eilutė 4 adresas</string>
+  <string id="451">1 eilutė adresas</string>
+  <string id="452">2 eilutė adresas</string>
+  <string id="453">3 eilutė adresas</string>
+  <string id="454">4 eilutė adresas</string>
   <string id="455">Adresų eilių skaičius</string>
   <string id="456">Režimas</string>
   <string id="457">Pakeisti išvaizdą</string>
   <string id="471">МOD-čipas</string>
   <string id="474">Išjungta</string>
   <string id="475">Tiktai muzika</string>
-  <string id="476">Muzika &amp; Video</string>
+  <string id="476">Muzika ir Video</string>
   <string id="477">Nepavyko įkelti į grojaraštį</string>
   <string id="478">Erano meniu (OSD)</string>
   <string id="479">Kalba ir vaizdas</string>
   <string id="665">Suspaudimo laipsnis</string>
 
   <string id="700">Bibliotekos išvalymas</string>
-  <string id="701">Senų dainų valymas iš bibliotekos</string>
+  <string id="701">Senų dainų šalinimas iš bibliotekos</string>
   <string id="702">Šis aplankas buvo patikrintas seniau</string>
   <string id="705">Tinklas</string>
-  <string id="706">HTTP-proxy serverio adresas</string>
+  <string id="706">- Serveris</string>
 
   <string id="708">Naudoti HTTP-proxy serverį</string>
 
 
   <string id="715">- Paskyrimas</string>
   <string id="716">Automatiškai (DHCP)</string>
-  <string id="717">Rankiniu būdu (Static)</string>
-  <string id="718">Pagal nutylėjimą (iš Dashboard)</string>
+  <string id="717">Manualas (Static)</string>
+
   <string id="719">- IP adresas</string>
   <string id="720">- Tinklo kaukė</string>
   <string id="721">- Numatytas šliuzas</string>
   <string id="722">- ADNS serveris</string>
-  <string id="723">Išsaugoti &amp; paleisti</string>
+  <string id="723">Išsaugoti ir paleisti</string>
   <string id="724">Neteisingas adresas. Turėtų būti AAA.BBB.CCC.DDD</string>
   <string id="725">skaičiai nuo 0 iki 255.</string>
   <string id="726">Pakeitimai neišsaugoti. Vistiek tęsti?</string>
   <string id="727">Interneto serveris</string>
   <string id="728">FTP serveris</string>
-  <string id="729">Laikas pagal internetą</string>
+
   <string id="730">Interneto serverio portas</string>
-  <string id="731">Laiko serverio adresas</string>
-  <string id="732">Išsaugoti &amp; pritaikyti</string>
+
+  <string id="732">Išsaugoti ir pritaikyti</string>
   <string id="733">Prieigos slaptažodis prie interneto serverio</string>
   <string id="734">Be slaptažodžio</string>
   <string id="735">- Simbolių parinkimas</string>
   <string id="1212">Video</string>
   <string id="1213">Foto</string>
   <string id="1214">Failai</string>
-  <string id="1215">Muzika &amp; video</string>
-  <string id="1216">Muzika &amp; foto</string>
-  <string id="1217">Muzika &amp; failai</string>
-  <string id="1218">Video &amp; foto</string>
-  <string id="1219">Video &amp; failai</string>
-  <string id="1220">Foto &amp; failai</string>
-  <string id="1221">Muzika, video &amp; failai</string>
-  <string id="1222">Muzika, video, foto &amp; failai</string>
+  <string id="1215">Muzika ir video</string>
+  <string id="1216">Muzika ir foto</string>
+  <string id="1217">Muzika ir failai</string>
+  <string id="1218">Video ir foto</string>
+  <string id="1219">Video ir failai</string>
+  <string id="1220">Foto ir failai</string>
+  <string id="1221">Muzika, video ir failai</string>
+  <string id="1222">Muzika, video, foto ir failai</string>
   <string id="1223">Atjungta</string>
-  <string id="1226">Failai, muzika &amp; video</string>
-  <string id="1227">Failai, foto &amp; muzika</string>
-  <string id="1228">Failai, foto &amp; video</string>
-  <string id="1229">Muzika &amp; programos</string>
-  <string id="1230">Video &amp; programos</string>
-  <string id="1231">Foto &amp; programos</string>
-  <string id="1232">Muzika, video, foto &amp; programos</string>
-  <string id="1233">Programos, video &amp; muzika</string>
-  <string id="1234">Programos, foto &amp; muzika</string>
-  <string id="1235">Programos, foto &amp; video</string>
-
-  <string id="1245">FTP vartotojo vardas</string>
-  <string id="1246">FTP vartotojo slaptažodis</string>
-  <string id="1247">Slaptažodis išsaugotas</string>
+  <string id="1226">Failai, muzika ir video</string>
+  <string id="1227">Failai, foto ir muzika</string>
+  <string id="1228">Failai, foto ir video</string>
+  <string id="1229">Muzika ir programos</string>
+  <string id="1230">Video ir programos</string>
+  <string id="1231">Foto ir programos</string>
+  <string id="1232">Muzika, video, foto ir programos</string>
+  <string id="1233">Programos, video ir muzika</string>
+  <string id="1234">Programos, foto ir muzika</string>
+  <string id="1235">Programos, foto ir video</string>
 
   <string id="1250">Auto nustatymas</string>
   <string id="1251">Auto nustatymas sistemai</string>
   <string id="10021">Interneto Naršyklė</string>
 
   <string id="10028">Video/Grojaraštis</string>
+  <string id="10029">Prisijungimo langas</string>
   <string id="10034">Nustatymai - Profilis</string>
+  <string id="10040">Priedų naršyklė</string>
 
   <string id="10100">Dialogas 'Taip/Ne'</string>
   <string id="10101">Dialogas Vykdymas</string>
 
   <string id="12021">Pradėti nuo pradžios</string>
   <string id="12022">Tęsti nuo %s</string>
-  <string id="12023">Patikrinti esamą instruktciją...</string>
 
   <string id="12310">0</string>
   <string id="12311">1</string>
   <string id="13210">Paleistas, suveiks %im</string>
   <string id="13211">PRIMINIMAS!</string>
   <string id="13212">Atšaukiama %im%is iki suveikimo</string>
-  <string id="13213">%2.fm</string> <!--minutes (left from countdown)-->
-  <string id="13214">%2.fs</string> <!--seconds (left from countdown)-->
+  <string id="13213">%2.0fm</string> <!--minutes (left from countdown)-->
+  <string id="13214">%2.0fs</string> <!--seconds (left from countdown)-->
 
   <string id="13249">Ieškoti subtitrų RARe</string>
   <string id="13250">Nurodykite subtitrus...</string>
   <string id="13355">Žemos kokybės Pixel Shader</string>
   <string id="13356">Aparatūros derinimas</string>
   <string id="13357">Aukštos kokybės Pixel Shader</string>
-  <string id="13358">Atkurti objektą</string>
+  <string id="13358">Atkūrti objektą</string>
   <string id="13359">Įdiegti atlikėjo eskizą</string>
   <string id="13360">Kurti eskizus</string>
   <string id="13361">Įjungti mikrofoną</string>
   <string id="13431">Pikseliniai šešėliai</string>
   <string id="13432">Leisti aparatūros spartinimą (VideoToolbox)</string>
 
-  <string id="13500">Sinchronizacijos metodas A/V</string>
-  <string id="13501">pagal dažnį garsas</string>
-  <string id="13502">pagal dažnį video (praleisti/dubliuoti garsą)</string>
-  <string id="13503">pagal dažnį video (konvertuoti garsą)</string>
+  <string id="13500">Sinchr. metodas A/V</string>
+  <string id="13501">Audio laikrodis</string>
+  <string id="13502">Video laikrodis (Drop/Dupe audio)</string>
+  <string id="13503">Video laikrodis (Resample audio)</string>
   <string id="13504">Maksimalus konvertavimo dydis (%)</string>
   <string id="13505">Konvertavimo kokybė</string>
   <string id="13506">Žema</string>
   <string id="14006">Klaida įkeliant sąrašo srautą</string>
   <string id="14007">Klaida įkeliant bibliotekos failą</string>
 
-  <string id="14009">Papkė su žaidimais</string>
+  <string id="14009">Žaidimų direktorija</string>
   <string id="14010">Vaizdo auto perjungimas į eskizus po</string>
   <string id="14011">Įjungti auto perjungimas į eskizus</string>
-  <string id="14012">- naudoti didelius ženkliukus</string>
+  <string id="14012">- Naudoti didelius ženkliukus</string>
   <string id="14013">- Perjungi po</string>
-  <string id="14014">- procentinių santykių</string>
-  <string id="14015">nėra failų ir nors vienas eskizas</string>
-  <string id="14016">nors vienas failas ir eskizas</string>
-  <string id="14017">procentinių santykių eskizų</string>
+  <string id="14014">- Procentinių santykių</string>
+  <string id="14015">Nėra failų ir nors vienas eskizas</string>
+  <string id="14016">Nors vienas failas ir eskizas</string>
+  <string id="14017">Procentinių santykių eskizų</string>
   <string id="14018">Peržiūros nustatymai</string>
   <string id="14019">1-as miestas</string>
   <string id="14020">2-as miestas</string>
   <string id="14060">Nežinomas talpyklos podėlis - Internetas</string>
   <string id="14061">Auto</string>
   <string id="14062">Įveskite vartotojo vardą</string>
-  <string id="14063">Data &amp; laikas</string>
+  <string id="14063">Data ir laikas</string>
   <string id="14064">Nustatyti datą</string>
   <string id="14065">Nustatyti laiką</string>
   <string id="14066">Įveskite laiką 24 valandų HH:MM</string>
   <string id="15283">Pastaruoju metu klausomos dainos %name%'</string>
   <string id="15284">Klausyti(is) rekomenduojamų %name%' Last.fm</string>
   <string id="15285">Top žymos %name%</string>
-  <string id="15286">Klausyti(is) iš grojaraščio %name%' Last.fm</string>
+
   <string id="15287">Ar norite pridėti šį takelį į savo mėgstami kūriniai?</string>
   <string id="15288">Norite užrakinti šį takelį?</string>
   <string id="15289">Pridėta prie Jūsų mėgstami kūriniai: '%s'.</string>
   <string id="16027">Per daug klaidų iš eilės</string>
   <string id="16028">Įveskite reikšmę</string>
   <string id="16029">Patikrinkite žurnalo bylą išsamiai informacijai</string>
-  <string id="16030">'Vakarėlis' atšauktas.</string>
+  <string id="16030">'Party' atšauktas.</string>
   <string id="16031">Nėra atitinkamų dainų bibliotekoje.</string>
   <string id="16032">Nepavyko inicijuoti duomenų bazės.</string>
   <string id="16033">Nepavyko atidaryti duomenų bazės.</string>
   <string id="16034">Nepavyko gauti dainų iš duomenų bazės.</string>
-  <string id="16035">Grojaraštis 'Vakarėlis'</string>
+  <string id="16035">Grojaraštis 'Party'</string>
   <string id="16036">De-interlace (Half)</string>
   <string id="16037">Deinterlace video</string>
   <string id="16038">Deinterlace method</string>
   <string id="16321">DXVA Best</string>
   <string id="16322">Spline36</string>
   <string id="16323">Spline36 optimizuotas(i)</string>
-  <string id="16324">Programinė įranga Blend</string>
+  <string id="16324">Programinė Blend</string>
 
   <string id="16400">Vaizdo pertvarkymas</string>
-  <string id="16401">Atjungta</string>
-  <string id="16402">Įjungti SD turinį</string>
-  <string id="16403">Visada įjungta</string>
 
   <string id="17500">Ekranas miego režime</string>
 
   <string id="20038">Blokuoti 'Muzika'</string>
   <string id="20039">Blokuoti 'Video'</string>
   <string id="20040">Blokuoti 'Foto'</string>
-  <string id="20041">Blokuoti 'Programos' &amp; 'Skriptai'</string>
+  <string id="20041">Blokuoti 'Programos' ir 'Skriptai'</string>
   <string id="20042">Blokuoti 'Failų tvarkyklė'</string>
   <string id="20043">Blokuoti 'Nustatymai'</string>
   <string id="20044">Švari paleistis</string>
   <string id="20185">Naudoti afišos vaizdą serialams</string>
   <string id="20186">Prašome palaukti</string>
 
-  <string id="20189">Įjungti automatinį slinktį, siužetams &amp; peržiūroms</string>
+  <string id="20189">Įjungti automatinį slinktį, siužetams ir peržiūroms</string>
   <string id="20190">Papildomai</string>
   <string id="20191">Įjungti žurnalo derinimą</string>
   <string id="20192">Ieškoti albumo info dedant į biblioteką</string>
   <string id="20326">Tai atstatys kalibravimą %s</string>
   <string id="20327">pagal numatytąją reikšmę</string>
   <string id="20328">Nurodykite tikslą</string>
-
+  <string id="20329">Filmai atskiruose aplankuose, kurie atitinka filmo pavadinimą</string>
   <string id="20330">Naudokite aplankų pavadinimus ieškant</string>
   <string id="20331">Failo</string>
   <string id="20332">Naudoti failų ar aplankų vardus ieškant?</string>
   <string id="20455">Klausytojų</string>
   <string id="20456">Nustatyti rodomo filmo Fanart</string>
   <string id="20457">Filmų rinkinys</string>
+  <string id="20458">Grupiniai filmų rinkiniai</string>
   <!-- up to 21329 is reserved for the video db !! !-->
 
   <string id="21330">Rodyti paslėptus failus ir aplankus</string>
   <string id="21364">Pakeisti media resursai</string>
   <string id="21365">Pašalinti media resursai</string>
   <string id="21366">Ypatingas aplankas subtitrams</string>
-  <string id="21367">Aplankas filmams &amp; alternatyviems subtitrams</string>
+  <string id="21367">Aplankas filmams ir alternatyviems subtitrams</string>
   <string id="21368">Nepaisyti ASS/SSA subtitrų šriftų</string>
 
   <string id="21369">Įjungti pelę ir Touch Screen palaikymą</string>
   <string id="21436">%i objektą(-us,ai)</string>
   <string id="21437">Naujas išmoningas grojaraštis...</string>
   <string id="21438">%c Diskas</string>
-  <string id="21439">Keisti režimo taisykles 'Vakarėlis'</string>
+  <string id="21439">Keisti režimo taisykles 'Party'</string>
   <string id="21440">Namų papkė</string>
   <string id="21441">Peržiūros kiekis</string>
   <string id="21442">Epizodo pavadinimas</string>
   <string id="33001">Treilerio kokybė</string>
   <string id="33002">Srautas</string>
   <string id="33003">Atsisiųsti</string>
-  <string id="33004">Atsisiųsti &amp; groti</string>
-  <string id="33005">Atsisiųsti &amp; išsaugoti</string>
+  <string id="33004">Atsisiųsti ir groti</string>
+  <string id="33005">Atsisiųsti ir išsaugoti</string>
   <string id="33006">Šiandien</string>
   <string id="33007">Rytoj</string>
   <string id="33008">Išsaugojimas</string>
   <string id="33059">Pritaikykite</string>
   <string id="33060">Energija</string>
   <string id="33061">Meniu</string>
-  <string id="33062">Atkurti</string>
+  <string id="33062">Atkūrti</string>
   <string id="33063">Nustatymai</string>
   <string id="33065">Redaktorius</string>
   <string id="33066">Apie Jūsų</string>
   <string id="33102">Serverio įvykis</string>
   <string id="33103">Nuotolinio ryšio serveris</string>
 
+  <string id="33200">Aptiktas Naujas Pajungimas</string>
+
   <!-- translators: no need to add these to your language files -->
   <string id="34000">Lame</string>
   <string id="34001">Vorbis</string>
   <string id="34110">7.1</string>
   <!-- 34112-34200 reserved for future use -->
 
-  <string id="33200">Aptiktas Naujas Pajungimas</string>
   <string id="34201">Nerasta kito failo grojimui</string>
   <string id="34202">Nerasta ankstesnio failo grojimui</string>
 
   <string id="34403">Patikrinkite savo garso nustatymus</string>
 
   <string id="35000">Periferija</string>
+
   <string id="35001">Bendras HID prietaisas</string>
   <string id="35002">Bendras tinklo adapteris</string>
   <string id="35003">Bendras diskas</string>
   <string id="36013">Nepalaikomas 'libec' sąsajos versija.%d atsisiuskite naujesnę  XBMC versiją (%d)</string>
   <string id="36014">Kompiuterį budėjimo režimu, kai televizorius yra išjungtas</string>
   <string id="36015">HDMI prievado numeris</string>
-  <string id="36016">Sujungtas</string>
+  <string id="36016">Sujungtas</string> <!-- max. 13 characters -->
   <string id="36017">Adapteris rastas, bet Libcec nėra</string>
   <string id="36018">Naudokite TV kalbos nustatymus</string>
-</strings>
+</strings>
\ No newline at end of file
index d5bd082..ac07e8e 100644 (file)
@@ -2,7 +2,7 @@
 <!--Language file translated with Team XBMC Translator-->
 <!--Translator: Rafał Wójcik-->
 <!--Email: rafal.wojcik@gmail.com-->
-<!--Date of translation: 02/14/2012-->
+<!--Date of translation: 02/21/2012-->
 <!--$Revision$-->
 <strings>
   <string id="0">Programy</string>
   <string id="10019">Ustawienia - Wygląd</string>
   <string id="10020">Skrypty</string>
   <string id="10021">Przeglądarka</string>
+  <string id="10025">Pliki wideo</string>
   <string id="10028">Wideo/Playlista</string>
+  <string id="10029">Ekran logowania</string>
   <string id="10034">Ustawienia - Profile</string>
+  <string id="10040">Przeglądarka wtyczek</string>
   <string id="10100">Dialog Tak/Nie</string>
   <string id="10101">Okno postępu</string>
   <string id="10210">Szukam napisów...</string>
   <string id="20256">Klient HTS Tvheadend</string>
   <string id="20257">Klient VDR Streamdev</string>
   <string id="20258">Klient MythTV</string>
+  <string id="20259">System plików NFS</string>
+  <string id="20260">SSH/SFTP</string>
+  <string id="20261">Protokół AFP</string>
   <string id="20300">Katalog serwera web (HTTP)</string>
   <string id="20301">Katalog serwera web (HTTPS)</string>
   <string id="20302">Nie powiódł się zapis do folderu:</string>
   <string id="24041">Instaluj z pliku zip</string>
   <string id="24042">Pobieram %i%%</string>
   <string id="24043">Dostępne aktualizacje</string>
+  <string id="24044">Zależności nie są spełnione</string>
   <string id="24045">Wtyczka nie ma właściwej struktury</string>
   <string id="24046">%s jest używany przez następujące zainstalowane wtyczki</string>
   <string id="24047">Ta wtyczka nie może zostać usunięta</string>
index 3aabdf4..d8ec842 100644 (file)
@@ -2,10 +2,10 @@
 <!--Language file translated with Team XBMC Translator[wm] -->
 <!--Translator: Fabiano Santiago (fabianosan), bugre (wm) -->
 <!--Email: fabianosan@hotmail.com, wxxx333-nospam-at-gmail.com -->
-<!--Updated on 15/02/2012 by wcampos -->
+<!--Updated on 28/02/2012 by wcampos -->
 <!--Updated on 28/08/2011 by fabianosan -->
 <!--Updated on 15/11/2010 by bugre -->
-<!--Based on English 5c8c939de7422db2427f37d5c26036138a9fe04e (03.02.2012)-->
+<!--Based on English 4a0e4931310c8957d73ffec0cf6fdfa9292bb8d4 (08.02.2012)-->
 <strings>
   <string id="0">Programas</string>
   <string id="1">Imagens</string>
   <string id="221">Rede não está conectada</string>
   <string id="222">Cancelar</string>
   <string id="224">Velocidade</string>
+  <string id="225">Deslocamento Vertical</string>
   <string id="226">Padrões de teste....</string>
   <string id="227">Procurar CDs de áudio na Internet</string>
   <string id="228">Misturar lista de reprodução ao carregar</string>
   <string id="1257">Gostaria de conectar ao sistema auto detectado?</string>
 
   <string id="1260">Anunciar estes serviços para outros sistemas via Zeroconf</string>
-  <string id="1270">Permitir ao XBMC receber contéudo AirPlay</string>
+  <string id="1270">Permitir ao XBMC receber contdo AirPlay</string>
   <string id="1271">Nome Equipamento</string>
   <string id="1272">- Usar senha para proteção</string>
 
   <string id="10021">Navegador Web</string>
 
   <string id="10028">Vídeos/lista de reprodução</string>
+  <string id="10029">Tela de Login</string>
+  
   <string id="10034">Configurações - Perfil</string>
+  
+  <string id="10040">Addon-Navegador</string>
 
   <string id="10100">Janela sim/não</string>
   <string id="10101">Janela de progresso</string>
index dd534fe..0ea741f 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!-- Translated by Daniel Alămiță, based on english revision 35193 -->
+<!-- Translated by Daniel Alămiță, based on english revision 0ee1ef0923 -->
 <strings>
   <string id="0">Programe</string>
   <string id="1">Imagini</string>
   <string id="164">Niciun disc</string>
   <string id="165">Disc prezent</string>
   <string id="166">Costum</string>
-  <string id="167"></string>
-  <string id="168"></string>
+
   <string id="169">Rezoluție</string>
   <string id="170">Ajustează rată reîmprospătare ecran pentru potrivire cu video</string>
-  <string id="171"></string>
 
   <string id="172">Dată de lansare</string>
   <string id="173">Afișează filmele 4:3 ca</string>
   <string id="221">Nu există conectare la rețea</string>
   <string id="222">Renunță</string>
   <string id="224">Viteză</string>
-
+  <string id="225">Deplasare verticală</string>
   <string id="226">Modele de testare...</string>
   <string id="227">Caută nume piste CD audio pe freedb.org</string>
   <string id="228">Amestecă lista de redare la încărcare</string>
   <string id="242">În fereastră</string>
   <string id="243">Rată de reîmprospătare</string>
   <string id="244">Ecran complet</string>
-  <string id="245">Dimensionare: (%i,%i)->(%i,%i) (zoom x%2.2f) AR:%2.2f:1 (pixeli: %2.2f:1)</string>
+  <string id="245">Dimensionare: (%i,%i)->(%i,%i) (zoom x%2.2f) AR:%2.2f:1 (pixeli: %2.2f:1) (DeplasareV: %2.2f)</string>
 
   <string id="247">Scripturi</string>
   <string id="248">Limbă</string>
   <string id="251">Selectează dosarul destinație</string>
   <string id="252">Scoate stereo în toate difuzoarele</string>
   <string id="253">Număr de canale</string>
-  <string id="254">- Receptor capabil de DTS</string>
+  <string id="254">- Receptor capabil DTS</string>
   <string id="255">CDDB</string>
   <string id="256">Culegere informații CD</string>
   <string id="257">Eroare</string>
   <string id="282">S-au găsit %i elemente</string>
   <string id="283">Rezultate căutare</string>
   <string id="284">Nu s-au găsit rezultate.</string>
-  <string id="286"></string>
+
   <string id="287">Subtitrări</string>
   <string id="288">Font</string>
   <string id="289">- Dimensiune</string>
   <string id="304">Limbă</string>
   <string id="305">Activat</string>
   <string id="306">Non-intercalat</string>
-  <string id="307"></string>
-  <string id="308"></string>
-  <string id="309"></string>
-  <string id="310"></string>
-  <string id="311"></string>
+
   <string id="312">(0=automat)</string>
   <string id="313">Curățare bază de date</string>
   <string id="314">Pregătire...</string>
   <string id="404">Vânt</string>
   <string id="405">Punct de rouă</string>
   <string id="406">Umiditate</string>
-  <string id="407"></string>
-  <string id="408"></string>
+
   <string id="409">Implicit</string>
   <string id="410">Se accesează serviciul de prognoză</string>
   <string id="411">Se obține prognoza pentru:</string>
   <string id="426">Nu s-au găsit informații CD</string>
   <string id="427">Disc</string>
   <string id="428">Inserați CD-ul/DVD-ul corect</string>
-  <string id="429">Inserați următorul CD/DVD</string>
+  <string id="429">Inserați următorul disc:</string>
   <string id="430">Sortează după: DVD#</string>
   <string id="431">Fără cache</string>
   <string id="432">Eliminare film din mediatecă</string>
   <string id="517">Albume redate recent</string>
   <string id="518">Lansează</string>
   <string id="519">Lansează în...</string>
-  <string id="520"></string>
+
   <string id="521">Compilații</string>
   <string id="522">Elimină sursa</string>
   <string id="523">Schimbă media</string>
   <string id="573">Cale</string>
   <string id="574">Țară</string>
   <string id="575">În progres</string>
+  <string id="576">Număr redări</string>
 
   <string id="580">Direcție de sortare</string>
   <string id="581">Metodă de sortare</string>
   <string id="715">- Atribuire</string>
   <string id="716">Automat (DHCP)</string>
   <string id="717">Manual (static)</string>
-  <string id="718"></string>
+
   <string id="719">- Adresă IP</string>
   <string id="720">- Mască de rețea</string>
   <string id="721">- Gateway implicit</string>
   <string id="726">Modificările nu au fost salvate. Continuați fără a le salva?</string>
   <string id="727">Server Web</string>
   <string id="728">Server FTP</string>
-  <string id="729"></string>
+
   <string id="730">- Port</string>
-  <string id="731"></string>
+
   <string id="732">Salvează și aplică</string>
   <string id="733">- Parolă</string>
   <string id="734">Nicio parolă</string>
   <!-- strings 768 and 769 reserved for more subtitle colors -->
 
   <string id="770">Eroare %i: partajarea nu este disponibilă</string>
-  <string id="771"></string>
+
   <string id="772">Ieșire audio</string>
   <string id="773">Salt</string>
   <string id="774">Dosar prezentare diapozitive</string>
   <string id="851">Interval valid de porturi este 1-65535</string>
   <string id="852">Interval valid de porturi este 1024-65535</string>
 
+  <string id="998">Adaugă muzică...</string>
+  <string id="999">Adaugă filme...</string>
   <string id="1000">- Previzualizare</string>
   <string id="1001">Imposibil de conectat</string>
   <string id="1002">XBMC nu s-a putut conecta la locația rețelei.</string>
   <string id="1030">Alegere imagine</string>
   <string id="1031">Alegere dosar de imagini</string>
   <string id="1032">Adaugă locație rețea...</string>
-  <string id="1033">Caută fișier</string>
+  <string id="1033">Căutare fișier</string>
   <string id="1034">Submeniu</string>
   <string id="1035">Activează butoane submeniu</string>
   <string id="1036">Favorite</string>
   <string id="1051">Introduceți adresă web</string>
 
   <string id="1200">Client SMB</string>
-  <string id="1202">Workgroup</string>
+  <string id="1202">Grup de lucru</string>
   <string id="1203">Nume utilizator implicit</string>
   <string id="1204">Parolă implicită</string>
 
   <string id="1234">Programe, imagini și muzică</string>
   <string id="1235">Programe, imagini și video</string>
 
-  <string id="1245"></string>
-  <string id="1246"></string>
-  <string id="1247"></string>
-
   <string id="1250">Detectare automată</string>
   <string id="1251">Detectează automat sistemul</string>
   <string id="1252">Pseudonim</string>
   <string id="1257">Doriți să vă conectați cu sistemul detectat automat?</string>
 
   <string id="1260">Anunță aceste servicii către celelalte sisteme prin Zeroconf</string>
+  <string id="1270">Permite XBMC să primească conținut AirPlay</string>
+  <string id="1271">Nume dispozitiv</string>
+  <string id="1272">- Folosește protecție prin parolă</string>
 
   <string id="1300">Dispozitiv audio specific</string>
   <string id="1301">Dispozitiv de traversare specific</string>
 
   <string id="2100">Scriptul a eșuat! : %s</string>
   <string id="2101">Este necesară o versiune mai nouă - Vedeți istoric modificări</string>
-  <string id="2102"></string>
-  <string id="2103"></string>
 
-  <string id="4501">Activează LCD/VFD</string>
+  <string id="4501">Activează LCD / VFD</string>
 
   <string id="10000">Acasă</string>
   <string id="10001">Programe</string>
   <string id="10019">Setări - Aspect</string>
   <string id="10020">Scripturi</string>
   <string id="10021">Navigator web</string>
-
+  <string id="10025">Filme</string>
   <string id="10028">Filme/Listă de redare</string>
+  <string id="10029">Ecran de autentificare</string>
   <string id="10034">Setări - Profile</string>
+  <string id="10040">Navigator de suplimente</string>
 
   <string id="10100">Dialog Da/Nu</string>
   <string id="10101">Dialog de progres</string>
   <string id="12009">Se reface indexul...</string>
   <string id="12010">Revino la fereastra de muzică</string>
   <string id="12011">Revino la fereastra de filme</string>
-  <string id="12012"></string>
-  <string id="12013"></string>
-  <string id="12014"></string>
-  <string id="12015"></string>
-  <string id="12016"></string>
-  <string id="12017"></string>
-  <string id="12018"></string>
-  <string id="12019"></string>
-  <string id="12020"></string>
+
   <string id="12021">Pornește de la început</string>
   <string id="12022">Reia de la %s</string>
-  <string id="12023"></string>
 
   <string id="12310">0</string>
   <string id="12311">1</string>
   <string id="12377">Vor fi resetate toate valorile salvate anterior.</string>
   <string id="12378">Durată de afișare pentru fiecare imagine</string>
   <string id="12379">Folosește efecte de mișcare și mărire</string>
-  <string id="12380"></string>
-  <string id="12381"></string>
-  <string id="12382"></string>
+
   <string id="12383">Ceas 12 ore</string>
   <string id="12384">Ceas 24 ore</string>
   <string id="12385">Zi/Lună</string>
   <string id="12392">ore</string>
   <string id="12393">zile</string>
   <string id="12394">Timp total de funcționare</string>
+  <string id="12395">Nivel baterie</string>
 
   <string id="12600">Meteo</string>
 
   <string id="13003">- Întârziere</string>
   <string id="13004">- Durată minimă fișier</string>
   <string id="13005">Închidere</string>
-  <string id="13006"></string>
-  <string id="13007"></string>
+
   <string id="13008">Tip de închidere</string>
   <string id="13009">Ieșire</string>
   <string id="13010">Hibernare</string>
 
   <string id="13100">Filtru pâlpâire</string>
   <string id="13101">Permite driverului să aleagă (necesită repornire)</string>
+
   <string id="13105">Sincronizare verticală goală</string>
   <string id="13106">Dezactivat</string>
   <string id="13107">Activată în timpul redării video</string>
   <string id="13146">XBMC, modificând această setare vă poate afecta abilitatea</string>
   <string id="13147">de a continua să îl controlați. Doriți să continuați?</string>
 
-  <string id="13150"></string>
-  <string id="13151"></string>
-  <string id="13152"></string>
-  <string id="13153"></string>
-  <string id="13154"></string>
-  <string id="13155"></string>
-  <string id="13156"></string>
-  <string id="13157"></string>
-  <string id="13158"></string>
-  <string id="13159">Mască subrețea</string>
+  <string id="13159">Mască de rețea</string>
   <string id="13160">Gateway</string>
   <string id="13161">DNS primar</string>
   <string id="13162">Inițializarea a eșuat</string>
 
-  <string id="13163"></string>
-  <string id="13164"></string>
-  <string id="13165"></string>
-  <string id="13166"></string>
-  <string id="13167"></string>
-  <string id="13168"></string>
-  <string id="13169"></string>
-
-
   <string id="13170">Niciodată</string>
   <string id="13171">Imediat</string>
   <string id="13172">După %i secunde</string>
 
   <string id="13200">Profile</string>
   <string id="13201">Ștergeți profilul '%s'?</string>
+  
   <string id="13204">Ultimul profil încărcat:</string>
   <string id="13205">Necunoscut</string>
   <string id="13206">Suprascrie</string>
+
   <string id="13208">Ceas alarmă</string>
   <string id="13209">Interval ceas alarmă (în minute)</string>
   <string id="13210">Pornit, alarmă în %i minute</string>
 
   <string id="13283">Sistem de operare:</string>
   <string id="13284">Viteză CPU:</string>
-  <string id="13285"></string>
+
   <string id="13286">Codor video:</string>
   <string id="13287">Rezoluție ecran:</string>
-  <string id="13288"></string>
-  <string id="13289"></string>
-  <string id="13290"></string>
-  <string id="13291"></string>
+
   <string id="13292">Cablu A/V:</string>
-  <string id="13293"></string>
+
   <string id="13294">Regiune DVD:</string>
   <string id="13295">Internet:</string>
   <string id="13296">conectat</string>
   <string id="13297">Neconectat. Verificați setările rețelei.</string>
-  <string id="13298"></string>
+
   <string id="13299">Temperatură țintă</string>
   <string id="13300">Viteză ventilator</string>
   <string id="13301">Control temperatură automat</string>
   <string id="13334">Modifică eticheta</string>
   <string id="13335">Setează ca implicit</string>
   <string id="13336">Elimină buton</string>
-  <string id="13338"></string>
-  <string id="13339"></string>
+
   <string id="13340">Lasă-l așa</string>
   <string id="13341">Verde</string>
   <string id="13342">Portocaliu</string>
   <string id="13359">Setează poză artist</string>
   <string id="13360">Generează miniaturi automat</string>
   <string id="13361">Activează voce</string>
+
   <string id="13375">Activează dispozitiv</string>
   <string id="13376">Volum</string>
   <string id="13377">Mod de vizualizare implicit</string>
   <string id="13409">Top 250</string>
   <string id="13410">Prinde radio Last.fm</string>
   <string id="13411">Viteză minimă ventilator</string>
-
+  <string id="13412">Redă începând de aici</string>
   <string id="13413">Se descarcă</string>
   <string id="13414">Include artiști care apar doar pe compilații</string>
   <string id="13415">Metodă de redare</string>
   <string id="13429">Permite accelerare hardware (VDADecoder)</string>
   <string id="13430">Permite accelerare hardware (OpenMax)</string>
   <string id="13431">Pixel shaders</string>
+  <string id="13432">Permite accelerare hardware (VideoToolbox)</string>
 
   <string id="13500">Metodă sincronizare A/V</string>
   <string id="13501">ceas audio</string>
   <string id="14038">Setările de rețea au fost schimbate</string>
   <string id="14039">XBMC trebuie repornit pentru a putea modifica</string>
   <string id="14040">setăriile rețelei.  Doriți să reporniți XBMC acum?</string>
-  <string id="14041"></string>
+  <string id="14041">Limitare bandă conexiune Internet</string>
 
   <string id="14043">- Oprire în timpul redării</string>
   <string id="14044">%i min</string>
   <string id="15275">Grafic piste săptămânal pentru %name%</string>
   <string id="15276">Ascultă radio Last.fm al veciniilor lui %name%</string>
   <string id="15277">Ascultă radio personal Last.fm al lui %name%'s</string>
-  <string id="15278">Ascultă radio Last.fm piste plăcute de %name%</string>
+  <string id="15278">Ascultă radio Last.fm mix %name%</string>
   <string id="15279">Se obține lista de la Last.fm...</string>
   <string id="15280">Nu se poate obține lista de la Last.fm...</string>
   <string id="15281">Introduceți un nume de artist pentru a găsii artiști similari</string>
   <string id="15283">Piese ascultate recent de %name%</string>
   <string id="15284">Ascultă recomandăriile lui %name% pe radio Last.fm</string>
   <string id="15285">Top etichete pentru utilizator %name%</string>
-  <string id="15286">Ascultă lista de redare a lui %name% pe radio Last.fm</string>
+
   <string id="15287">Doriți să adăugați piesa curentă la piesele îndrăgite?</string>
   <string id="15288">Doriți să blocați piesa curentă?</string>
   <string id="15289">Adaugată la piesele îndrăgite: '%s'.</string>
   <string id="16020">De-întrețesere</string>
   <string id="16021">Bob</string>
   <string id="16022">Bob (inversat)</string>
-  <string id="16023">Tratare video întrețesut</string>
+  <string id="16023"></string>
   <string id="16024">Renunțare...</string>
   <string id="16025">Introduceți nume artist</string>
   <string id="16026">Redarea a eșuat</string>
   <string id="16033">Baza de date nu poate fi deschisă.</string>
   <string id="16034">Nu pot fi preluate cântece din baza de date.</string>
   <string id="16035">Listă de redare mod petrecere</string>
-
+  <string id="16036">Deîntrețesere (jumătate)</string>
+  <string id="16037">Deîntrețesere video</string>
+  <string id="16038">Metodă de deîntrețesere</string>
+  <string id="16039">Oprită</string>
+  <string id="16040">Automat</string>
+  <string id="16041">Pornită</string>
+  
   <string id="16100">Toate filmele</string>
   <string id="16101">neprivite</string>
   <string id="16102">privite</string>
   <string id="16103">Marchează ca privit</string>
   <string id="16104">Marchează ca neprivit</string>
-  <string id="16105">Modifică titlul</string>
-  <string id="16106"></string>
-  <string id="16107"></string>
-  <string id="16108"></string>
-  <string id="16109"></string>
-  <string id="16110"></string>
+  <string id="16105">Modifică numele</string>
 
   <string id="16200">Operațiunea a fost anulată</string>
   <string id="16201">Copierea a eșuat</string>
   <string id="16309">Sinc (software)</string>
   <string id="16310">Temporal</string>
   <string id="16311">Temporal/Spațial</string>
-  <string id="16312">(VDPAU)Reducere zgomot</string>
-  <string id="16313">(VDPAU)Claritate</string>
+  <string id="16312">(VDPAU) Reducere zgomot</string>
+  <string id="16313">(VDPAU) Claritate</string>
   <string id="16314">Inverse Telecine</string>
-  <string id="16315">Lanczos3 optimized</string>
+  <string id="16315">Lanczos3 optimizat</string>
   <string id="16316">Automat</string>
   <string id="16317">Temporal (jumătate)</string>
   <string id="16318">Temporal/Spațial (jumătate)</string>
   <string id="16319">DXVA</string>
-
+  <string id="16320">DXVA Bob</string>
+  <string id="16321">DXVA maxim</string>
+  <string id="16322">Spline36</string>
+  <string id="16323">Spline36 optimizat</string>
+  <string id="16324">Software Blend</string>
+  
   <string id="16400">Post-procesare video</string>
-  <string id="16401">Dezactivată</string>
-  <string id="16402">Activată pentru conținut SD</string>
-  <string id="16403">Activată întotdeauna</string>
 
   <string id="17500">Timp de așteptare repaus ecran</string>
 
   <string id="20141">Setează</string>
   <string id="20142">Nume utilizator</string>
   <string id="20143">Introduceți parola pentru</string>
-  <string id="20144">Cronometru de închidere</string>
-  <string id="20145">Interval de închidere&#10;(în minute)</string>
-  <string id="20146">Pornit, închidere în %i minute</string>
+  <string id="20144">Planificare închidere</string>
+  <string id="20145">Planificare închidere&#10;(în minute)</string>
+  <string id="20146">Pornită, închidere în %i minute</string>
   <string id="20147">Închidere în 30 de minute</string>
   <string id="20148">Închidere în 60 de minute</string>
   <string id="20149">Închidere în 120 de minute</string>
-  <string id="20150">Cronometru personalizat de închidere</string>
-  <string id="20151">Renunțare la cronomentru de închidere</string>
+  <string id="20150">Planificare închidere</string>
+  <string id="20151">Renunță la plan. închidere</string>
   <string id="20152">Blochează preferințele pentru %s</string>
   <string id="20153">Alege...</string>
   <string id="20154">Rezumat informații</string>
   <string id="20184">Rotește imaginile folosind informațiile EXIF</string>
   <string id="20185">Folosește stiluri vizualizare afiș pentru serialele TV</string>
   <string id="20186">Vă rugăm așteptați</string>
-  <string id="20187"></string>
-  <string id="20188"></string>
+
   <string id="20189">Activează derulare automată pentru intrigă și recenzie</string>
   <string id="20190">Particularizat</string>
   <string id="20191">Activează jurnalizare depanare</string>
   <string id="20256">Client HTS Tvheadend</string>
   <string id="20257">Client VDR Streamdev</string>
   <string id="20258">Client MythTV</string>
+  <string id="20259">Network Filesystem (NFS)</string>
+  <string id="20260">Secure Shell (SSH/SFTP)</string>
+  <string id="20261">Apple Filing Protocol (AFP)</string>
 
   <string id="20300">Director server Web (HTTP)</string>
   <string id="20301">Director server Web (HTTPS)</string>
   <string id="20303">Doriți să săriți și să continuați?</string>
   <string id="20304">Flux RSS</string>
 
-  <string id="20306"></string>
   <string id="20307">DNS secundar</string>
   <string id="20308">Server DHCP:</string>
   <string id="20309">Creează dosar nou</string>
   <string id="20310">Întunecă LCD la redare</string>
   <string id="20311">Necunoscut sau integrat (protejat)</string>
   <string id="20312">Întunecă LCD în pauză</string>
-  <string id="20313"></string>
+
   <string id="20314">Mediatecă video</string>
-  <string id="20315"></string>
+
   <string id="20316">Sort. după: ID</string>
-  <string id="20317"></string>
-  <string id="20318"></string>
-  <string id="20319"></string>
-  <string id="20320"></string>
-  <string id="20321"></string>
-  <string id="20322"></string>
-  <string id="20323"></string>
+
   <string id="20324">Redă parte...</string>
   <string id="20325">Resetare calibrare</string>
   <string id="20326">Vor fi resetate valorile de calibrare pentru %s</string>
   <string id="20327">către valorile implicite.</string>
   <string id="20328">Alege destinație</string>
-
+  <string id="20329">Filmele sunt în dosare separate care se potrivesc cu numele filmului</string>
   <string id="20330">Folosește nume dosare la căutări</string>
   <string id="20331">Fișier</string>
   <string id="20332">Folosește nume fișier sau nume dosar la căutări?</string>
   <string id="20373">Sezon</string>
   <string id="20374">Descărcare informații filme</string>
   <string id="20375">Eliminare atribuire conținut</string>
-  <string id="20376">Titlu original</string>
+  <string id="20376">Nume original</string>
   <string id="20377">Actualizare informații serial</string>
   <string id="20378">Actualizați informațiile pentru toate episoadele?</string>
   <string id="20379">Dosarul selectat conține un singur serial</string>
   <string id="20407">Setări scraper</string>
   <string id="20408">Descărcare informații videoclipuri</string>
   <string id="20409">Descărcare informații serial</string>
-  <string id="20410">Trailer</string>
+  <string id="20410">Secvențe</string>
   <string id="20411">Netezește</string>
   <string id="20412">Netezește seriale</string>
-  <string id="20413">Obține Fanart</string>
-  <string id="20414">Arată Fanart în mediateciile de filme și muzică</string>
+  <string id="20413">Obține fundal</string>
+  <string id="20414">Arată fundale în mediateciile de filme și muzică</string>
   <string id="20415">Se scanează pentru conținut nou</string>
   <string id="20416">Prima difuzare</string>
   <string id="20417">Scenarist</string>
-  <string id="20418">Curăță numele fișierelor și al dosarelor</string>
+  <string id="20418"></string>
+  <string id="20419">Înlocuiește numele fișierelor cu titlurile din mediatecă</string>
 
   <string id="20420">niciodată</string>
   <string id="20421">doar dacă este un singur sezon</string>
   <string id="20453">episoade</string>
   <string id="20454">Ascultător</string>
   <string id="20455">Ascultători</string>
+  <string id="20456">Alege fundal set de filme</string>
+  <string id="20457">Set de filme</string>
+  <string id="20458">Grupează filmele în seturi</string>
   <!-- up to 21329 is reserved for the video db !! !-->
 
   <string id="21330">Arată dosarele și fișierele ascunse</string>
   <string id="21365">Elimină partajare media</string>
   <string id="21366">Dosar de subtitrări</string>
   <string id="21367">Director de film și subtitrare alternativă</string>
+  <string id="21368">Ignoră fonturi subtitrări ASS/SSA</string>
 
-  <string id="21369">Activare mouse</string>
+  <string id="21369">Activează suport mouse și ecran sensibil la atingere</string>
   <string id="21370">Emite sunete de navigare în timpul redării media</string>
   <string id="21371">Miniaturi</string>
   <string id="21372">Regiune forțată lector DVD</string>
   <string id="21451">Este necesară o conexiune la Internet.</string>
   <string id="21452">Obține mai multe...</string>
   <string id="21453">Sistem de fișiere rădăcină</string>
+  <string id="21454">Cache plin</string>
+  <string id="21455">Cache împlinit înainte de a ajunge la nivelul necesar pentru redare continuă</string>
+  
+  <string id="21460">Locație subtitrare</string>
+  <string id="21461">Fixă</string>
+  <string id="21462">Jos pe video</string>
+  <string id="21463">Jos sub video</string>
+  <string id="21464">Sus pe video</string>
+  <string id="21465">Sus peste video</string>
 
   <string id="21800">Nume fișier</string>
   <string id="21801">Cale fișier</string>
   <string id="24015">Informații videoclipuri</string>
   <string id="24016">Informații albume</string>
   <string id="24017">Informații artiști</string>
+  <string id="24018">Servicii</string>
 
   <string id="24020">Configurează</string>
   <string id="24021">Dezactivează</string>
   <string id="24041">Instalare din fișier zip</string>
   <string id="24042">Se descarcă %i%%</string>
   <string id="24043">Actualizări disponibile</string>
+  <string id="24044">Dependențele nu au fost îndeplinite</string>
+  <string id="24045">Suplimentul nu are structura corectă</string>
+  <string id="24046">%s este folosit de următoarele suplimente instalate</string>
+  <string id="24047">Acest supliment nu poate fi dezinstalat</string>
+  <string id="24048">Revino</string>
 
   <string id="24050">Suplimente disponibile</string>
   <string id="24051">Versiune:</string>
   <string id="24073">Imposibil de conectat</string>
   <string id="24074">Trebuie să fie repornit</string>
   <string id="24075">Dezactivează</string>
+  <string id="24076">Supliment necesar</string>
   <string id="24080">Încercați reconectarea?</string>
   <string id="24089">Reporniri supliment</string>
   <string id="24090">Blochează gestionarul de suplimente</string>
 
-  <string id="24091"></string>
-  <string id="24092"></string>
-  <string id="24093"></string>
-  <string id="24094"></string>
-  <string id="24095"></string>
-
+  <string id="24094">(curent)</string>
+  <string id="24095">(pe lista neagră)</string>
   <string id="24096">Suplimentul a fost marcat ca defect în depozit.</string>
   <string id="24097">Doriți să îl dezactivați pe sistemul dumneavoastră?</string>
   <string id="24098">Defect</string>
   <string id="24099">Doriți să folosiți acest costum?</string>
+  <string id="24100">Pentru aceasta trebuie să descărcați un supliment:</string>
+  <string id="24101">Doriți să descărcați acest supliment?</string>
   <string id="25000">Notificări</string>
 
   <!-- strings 29800 thru 29998 reserved strings used only in the default Project Mayhem III skin and not c++ code -->
   <string id="29801">Tastatură QWERTY</string>
   <string id="29802">Traversare Audio în folosință</string>
 
-  <string id="29999"></string>
-
   <!-- strings 30000 thru 30999 reserved for plugins and plugin settings -->
   <!-- strings 31000 thru 31999 reserved for skins -->
   <!-- strings 32000 thru 32999 reserved for scripts -->
   <!-- strings 33000 thru 33999 reserved for common strings used in addons -->
-  <string id="33001">Calitate trailer</string>
+  <string id="33001">Calitate secvențe</string>
   <string id="33002">Flux</string>
   <string id="33003">Descarcă</string>
   <string id="33004">Descarcă și redă</string>
   <string id="33082">Cale către script</string>
   <string id="33083">Activează buton personalizat script</string>
 
+  <string id="33100">Nu poate fi pornit</string>
+  <string id="33101">Server web</string>
+  <string id="33102">Server evenimente</string>
+  <string id="33103">Server comunicare la distanță</string>
+  
+  <string id="33200">Conexiune nouă detectată</string>
+
   <!-- translators: no need to add these to your language files -->
   <string id="34000">Lame</string>
   <string id="34001">Vorbis</string>
   <string id="34110">7.1</string>
   <!-- 34112-34200 reserved for future use -->
 
+  <string id="34201">Următorul element de redat nu poate fi găsit</string>
+  <string id="34202">Elementul anterior de redat nu poate fi găsit</string>
+  
+  <string id="34300">Zeroconf nu poate fi pornit</string>
+  <string id="34301">Serviciul Bonjour de la Apple este instalat? Vedeți jurnalul pentru mai multe informații.</string>
+  
+  <string id="34400">Randare video</string>
+  <string id="34401">Filtre/scalori video nu pot fi inițializați, revenim la scalare bilineară</string>
+  <string id="34402">Dispozitivul audio nu poate fi inițializat</string>
+  <string id="34403">Verificați setările audio</string>
+
+  <string id="35000">Periferice</string>
+
+  <string id="35001">Dispozitiv HID generic</string>
+  <string id="35002">Adaptor de rețea generic</string>
+  <string id="35003">Disc generic</string>
+  <string id="35004">Nu există setări disponibile&#10;pentru acest periferic.</string>
+  <string id="35005">Dispozitiv nou configurat</string>
+  <string id="35006">Dispozitiv eliminat</string>
+  <string id="35007">Hartă de taste de folosit pentru acest dispozitiv</string>
+  <string id="35008">Hartă de taste activată</string>
+
+  <string id="35500">Locație</string>
+  <string id="35501">Clasă</string>
+  <string id="35502">Nume</string>
+  <string id="35503">Furnizor</string>
+  <string id="35504">ID produs</string>
+  
+  <string id="36000">Adaptor Pulse-Eight CEC</string>
+  <string id="36001">Pulse-Eight Nyxboard</string>
+  <string id="36002">Comandă de comutare la parte tastatură</string>
+  <string id="36003">Comandă de comutare la parte telecomandă</string>
+  <string id="36004">Comandă apasă buton „utilizator”</string>
+  <string id="36005">Activează comenzi de schimbare a părții</string>
+  <string id="36006">Adapotorul nu poate fi deschis</string>
+  <string id="36007">Aprinde televizorul atunci când XBMC este pornit</string>
+  <string id="36008">Oprește dispozitivele atunci când XBMC este oprit</string>
+  <string id="36009">Pune dispozitivele în modul repaus când protector ecran este activat</string>
+  <string id="36010"></string>
+  <string id="36011">Portul CEC nu poate fi detectat. Setați-l manual.</string>
+  <string id="36012">Adaptorul CEC nu poate fi detectat.</string>
+  <string id="36013">Versiune interfață libcec nesuportată. %d este mai mare decât versiunea pe care XBMC o suportă (%d)</string>
+  <string id="36014">Pune acest calculator în repaus când televizorul este oprit</string>
+  <string id="36015">Număr port HDMI</string>
+  <string id="36016">Conectat</string> <!-- max. 13 characters -->
+  <string id="36017">Adaptor găsit, dar librăria libcec nu este disponibilă</string>
+  <string id="36018">Folosește setările de limbă ale televizorului</string>
 </strings>
index 883e2ef..8f8d425 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <!--Translator: Tadej Novak-->
 <!--Email: tadej@tano.si-->
-<!--Date of translation: 20/11/2011-->
+<!--Date of translation: 18/02/2012-->
 <!--$Revision$-->
 <strings>
   <string id="0">Programi</string>
   <string id="10020">Skripte</string>
   <string id="10021">Spletni brskalnik</string>
 
+  <string id="10025">Videi</string>
   <string id="10028">Video/Predvajalni seznam</string>
+  <string id="10029">Prijavno okno</string>
   <string id="10034">Nastavitve - Profili</string>
+  <string id="10040">Brskalnik dodatkov</string>
 
   <string id="10100">Da/Ne dialog</string>
   <string id="10101">Dialog napredka</string>
   <string id="20327">na privzete vrednosti.</string>
   <string id="20328">Prebrskaj za ciljem</string>
 
+  <string id="20329">Filmi so v ločenih mapah, ki se ujemajo z naslovom filma</string>
   <string id="20330">Uporabi imena map za poizvedbe</string>
   <string id="20331">Datoteka</string>
   <string id="20332">Uporabi ime datoteke ali mape v poizvedbah?</string>
   <string id="20416">Prvič na sporedu</string>
   <string id="20417">Scenarist</string>
   <string id="20418"></string>
-  <string id="20419">Prikaži podrobnosti v pogledu datotek</string>
+  <string id="20419">Zamenjaj imena datotek z naslovi v knjižnici</string>
 
   <string id="20420">Nikoli</string>
   <string id="20421">Če vsebuje le eno sezono</string>
   <string id="20455">Listeners</string>
   <string id="20456">Nastavi ozadje filmske zbirke</string>
   <string id="20457">Filmska zbirka</string>
+  <string id="20458">Združi filme v zbirke</string>
   <!-- up to 21329 is reserved for the video db !! !-->
 
   <string id="21330">Prikaži skrite datoteke in mape</string>
   <string id="21451">Potrebna je internetna povezava.</string>
   <string id="21452">Prenesi več...</string>
   <string id="21453">Korenski datotečni sistem</string>
+  <string id="21454">Začasni pomnilnik poln</string>
+  <string id="21455">Začasni pomnilnik se je zapolnil, preden je bila dosežen nivo za tekoče predvajanje</string>
 
   <string id="21460">Položaj podnapisov</string>
   <string id="21461">Fiksno</string>
   <string id="33102">Strežnik dogodkov</string>
   <string id="33103">Strežnik oddaljene komunikacije</string>
 
+  <string id="33200">Zaznana nova povezava</string>
+
   <!-- translators: no need to add these to your language files -->
   <string id="34000">Lame</string>
   <string id="34001">Vorbis</string>
index 0753c5e..61204e2 100644 (file)
@@ -7,8 +7,8 @@
 <!--Date of translation: 22/04/2011-->
 <!--Translator: Özgür BASKIN (queeup)-->
 <!--Email: ozgur.baskin@gmail.com-->
-<!--Date of translation: 21/01/2012-->
-<!--Based on English strings commit e9bcfd0779 -->
+<!--Date of translation: 27/02/2012-->
+<!--Based on English strings commit 0ee1ef0923 -->
 <strings>
   <string id="0">Programlar</string>
   <string id="1">Resimler</string>
   <string id="596">Tekrar: Birini</string>
   <string id="597">Tekrar: Hepsini</string>
 
-  <string id="600">Ses CD'sini Aktar</string>
+  <string id="600">Ses CD'sinden kopyala</string>
   <string id="601">Orta</string>
   <string id="602">Standart</string>
   <string id="603">Extreme</string>
   <string id="605">Kopyalanıyor...</string>
 
   <string id="607">Nereye:</string>
-  <string id="608">CD veya parça aktarılamıyor</string>
-  <string id="609">CDDA Aktarma Yolu ayarlanmamış</string>
-  <string id="610">Parçayı aktar</string>
+  <string id="608">CD veya parça kopyalanamıyor</string>
+  <string id="609">CDDA kopyalama yolu ayarlanmamış</string>
+  <string id="610">Parçayı kopyala</string>
   <string id="611">Numara gir</string>
   <string id="612">Bits/Sample</string>
   <string id="613">Sample Frequency</string>
   <string id="10019">Ayarlar - Görünüm</string>
   <string id="10020">Betikler</string>
   <string id="10021">Web Tarayıcısı</string>
-
+  <string id="10025">Videolar</string>
   <string id="10028">Videolar/Çalma Listesi</string>
+  <string id="10029">Giriş ekranı</string>
   <string id="10034">Ayarlar - Profiller</string>
+  <string id="10040">Eklenti tarayıcısı</string>
 
   <string id="10100">Evet/Hayır iletişim kutusu</string>
   <string id="10101">İlerleme iletişim kutusu</string>
   <string id="12340">Yeni parolayı girin</string>
   <string id="12341">Yeni parolayı tekrar girin</string>
   <string id="12342">Yanlış parola,</string>
-  <string id="12343"> deneme hakkı kaldı </string>
+  <string id="12343">deneme hakkı kaldı </string>
   <string id="12344">Girilen parola aynı değil.</string>
   <string id="12345">Giriş reddedildi</string>
   <string id="12346">Parola deneme hakkı tükendi.</string>
   <string id="13171">Hemen</string>
   <string id="13172">%i saniye sonra</string>
   <string id="13173">HDD yükleme tarihi:</string>
-  <string id="13174">HDD power cycle count:</string>
+  <string id="13174">HDD güç döngüsü sayısı:</string>
 
   <string id="13200">Profiller</string>
   <string id="13201">'%s' profili silinsin mi?</string>
   <string id="13302">Fan hızı ayarı</string>
   <string id="13303">- Yazı tipleri</string>
   <string id="13304">Enable flipping bi-directional strings</string>
-  <string id="13305">RSS haber beslemelerini göster</string>
+  <string id="13305">RSS haber akışlarını göster</string>
   <string id="13306">Geri gitme simgesini göster</string>
   <string id="13307">Parça isim kalıbı</string>
   <string id="13308">XBMC'yi yeniden başlatmak yerine sistemi</string>
   <string id="20301">Web sunucu dizini (HTTPS)</string>
   <string id="20302">Klasöre yazılamıyor:</string>
   <string id="20303">Bu adımı atlayıp devam etme istiyor musunuz?</string>
-  <string id="20304">RSS Beslemesi</string>
+  <string id="20304">RSS Akışı</string>
 
   <string id="20307">İkincil DNS</string>
   <string id="20308">DHCP sunucusu:</string>
   <string id="20326">Bu %s için olan ayarlama değerlerini</string>
   <string id="20327">varsayılana sıfırlayacak.</string>
   <string id="20328">Hedefe gözat</string>
-
+  <string id="20329">Filmler ayrı klasörlerde film başlığı ile eşleşecek şekilde bulunuyor</string>
   <string id="20330">Arama için klasör adlarını kullan</string>
   <string id="20331">Dosya</string>
   <string id="20332">Aramalarda dosya veya klasör adları kullanılsın mı?</string>
   <string id="20455">Dinleyiciler</string>
   <string id="20456">Set movieset fanart</string>
   <string id="20457">Movie set</string>
+  <string id="20458">Group movies in sets</string>
   <!-- up to 21329 is reserved for the video db !! !-->
 
   <string id="21330">Gizli dosya ve dizinleri göster</string>
   <string id="21448">Altyazı dili</string>
   <string id="21449">Remote control sends keyboard presses</string>
   <string id="21450">- Düzenle</string>
-  <string id="21451">Internet bağlantısı gereklidir.</string>
+  <string id="21451">İnternet bağlantısı gereklidir.</string>
   <string id="21452">Daha Fazla...</string>
   <string id="21453">Kök dosya sistemi</string>
   <string id="21454">Önbellek dolu</string>
index a688909..e48fa0a 100644 (file)
 
 #define _stdfunction 
 
-#ifdef _APPLE
-  #ifndef BIG_ENDIAN
-    #define BIG_ENDIAN
-  #endif
-  #ifdef LITTLE_ENDIAN
-    #undef LITTLE_ENDIAN
-  #endif
-#endif
-
 #if defined(__sparc) || defined(sparc) || defined(__hpux)
   #ifndef BIG_ENDIAN
      #define BIG_ENDIAN
diff --git a/lib/boost/uuid/sha1.hpp b/lib/boost/uuid/sha1.hpp
new file mode 100644 (file)
index 0000000..f160e3f
--- /dev/null
@@ -0,0 +1,208 @@
+// boost/uuid/sha1.hpp header file  ----------------------------------------------//
+
+// Copyright 2007 Andy Tompkins.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Revision History
+//  29 May 2007 - Initial Revision
+//  25 Feb 2008 - moved to namespace boost::uuids::detail
+
+// This is a byte oriented implementation
+// Note: this implementation does not handle message longer than
+//       2^32 bytes.
+
+#ifndef BOOST_UUID_SHA1_H
+#define BOOST_UUID_SHA1_H
+
+#include <boost/static_assert.hpp>
+#include <cstddef>
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std {
+    using ::size_t;
+} // namespace std
+#endif
+
+namespace boost {
+namespace uuids {
+namespace detail {
+
+BOOST_STATIC_ASSERT(sizeof(unsigned char)*8 == 8);
+BOOST_STATIC_ASSERT(sizeof(unsigned int)*8 == 32);
+
+inline unsigned int left_rotate(unsigned int x, std::size_t n)
+{
+    return (x<<n) ^ (x>> (32-n));
+}
+
+class sha1
+{
+public:
+    typedef unsigned int(&digest_type)[5];
+public:
+    sha1();
+
+    void reset();
+
+    void process_byte(unsigned char byte);
+    void process_block(void const* bytes_begin, void const* bytes_end);
+    void process_bytes(void const* buffer, std::size_t byte_count);
+
+    void get_digest(digest_type digest);
+
+private:
+    void process_block();
+
+private:
+    unsigned int h_[5];
+
+    unsigned char block_[64];
+
+    std::size_t block_byte_index_;
+    std::size_t byte_count_;
+};
+
+inline sha1::sha1()
+{
+    reset();
+}
+
+inline void sha1::reset()
+{
+    h_[0] = 0x67452301;
+    h_[1] = 0xEFCDAB89;
+    h_[2] = 0x98BADCFE;
+    h_[3] = 0x10325476;
+    h_[4] = 0xC3D2E1F0;
+
+    block_byte_index_ = 0;
+    byte_count_ = 0;
+}
+
+inline void sha1::process_byte(unsigned char byte)
+{
+    block_[block_byte_index_++] = byte;
+    ++byte_count_;
+    if (block_byte_index_ == 64) {
+        block_byte_index_ = 0;
+        process_block();
+    }
+}
+
+inline void sha1::process_block(void const* bytes_begin, void const* bytes_end)
+{
+    unsigned char const* begin = static_cast<unsigned char const*>(bytes_begin);
+    unsigned char const* end = static_cast<unsigned char const*>(bytes_end);
+    for(; begin != end; ++begin) {
+        process_byte(*begin);
+    }
+}
+
+inline void sha1::process_bytes(void const* buffer, std::size_t byte_count)
+{
+    unsigned char const* b = static_cast<unsigned char const*>(buffer);
+    process_block(b, b+byte_count);
+}
+
+inline void sha1::process_block()
+{
+    unsigned int w[80];
+    for (std::size_t i=0; i<16; ++i) {
+        w[i]  = (block_[i*4 + 0] << 24);
+        w[i] |= (block_[i*4 + 1] << 16);
+        w[i] |= (block_[i*4 + 2] << 8);
+        w[i] |= (block_[i*4 + 3]);
+    }
+    for (std::size_t i=16; i<80; ++i) {
+        w[i] = left_rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1);
+    }
+
+    unsigned int a = h_[0];
+    unsigned int b = h_[1];
+    unsigned int c = h_[2];
+    unsigned int d = h_[3];
+    unsigned int e = h_[4];
+
+    for (std::size_t i=0; i<80; ++i) {
+        unsigned int f;
+        unsigned int k;
+
+        if (i<20) {
+            f = (b & c) | (~b & d);
+            k = 0x5A827999;
+        } else if (i<40) {
+            f = b ^ c ^ d;
+            k = 0x6ED9EBA1;
+        } else if (i<60) {
+            f = (b & c) | (b & d) | (c & d);
+            k = 0x8F1BBCDC;
+        } else {
+            f = b ^ c ^ d;
+            k = 0xCA62C1D6;
+        }
+
+        unsigned temp = left_rotate(a, 5) + f + e + k + w[i];
+        e = d;
+        d = c;
+        c = left_rotate(b, 30);
+        b = a;
+        a = temp;
+    }
+
+    h_[0] += a;
+    h_[1] += b;
+    h_[2] += c;
+    h_[3] += d;
+    h_[4] += e;
+}
+
+inline void sha1::get_digest(digest_type digest)
+{
+    std::size_t bit_count = byte_count_*8;
+
+    // append the bit '1' to the message
+    process_byte(0x80);
+
+    // append k bits '0', where k is the minimum number >= 0
+    // such that the resulting message length is congruent to 56 (mod 64)
+    // check if there is enough space for padding and bit_count
+    if (block_byte_index_ > 56) {
+        // finish this block
+        while (block_byte_index_ != 0) {
+            process_byte(0);
+        }
+
+        // one more block
+        while (block_byte_index_ < 56) {
+            process_byte(0);
+        }
+    } else {
+        while (block_byte_index_ < 56) {
+            process_byte(0);
+        }
+    }
+
+    // append length of message (before pre-processing) 
+    // as a 64-bit big-endian integer
+    process_byte(0);
+    process_byte(0);
+    process_byte(0);
+    process_byte(0);
+    process_byte( static_cast<unsigned char>((bit_count>>24) & 0xFF));
+    process_byte( static_cast<unsigned char>((bit_count>>16) & 0xFF));
+    process_byte( static_cast<unsigned char>((bit_count>>8 ) & 0xFF));
+    process_byte( static_cast<unsigned char>((bit_count)     & 0xFF));
+
+    // get final digest
+    digest[0] = h_[0];
+    digest[1] = h_[1];
+    digest[2] = h_[2];
+    digest[3] = h_[3];
+    digest[4] = h_[4];
+}
+
+}}} // namespace boost::uuids::detail
+
+#endif
\ No newline at end of file
index f718269..adadeea 100644 (file)
 void CxImagePNG::ima_png_error(png_struct *png_ptr, char *message)
 {
        strcpy(info.szLastError,message);
+#ifdef USE_NEW_LIBPNG_API
+       longjmp(png_jmpbuf(png_ptr), 1);
+#else
        longjmp(png_ptr->jmpbuf, 1);
+#endif
 }
 ////////////////////////////////////////////////////////////////////////////////
 #if CXIMAGE_SUPPORT_DECODE
@@ -62,7 +66,11 @@ bool CxImagePNG::Decode(CxFile *hFile)
     /* Set error handling if you are using the setjmp/longjmp method (this is
     * the normal method of doing things with libpng).  REQUIRED unless you
     * set up your own error handlers in the png_create_read_struct() earlier. */
+#ifdef USE_NEW_LIBPNG_API
+       if (setjmp(png_jmpbuf(png_ptr))) {
+#else
        if (setjmp(png_ptr->jmpbuf)) {
+#endif
                /* Free all of the memory associated with the png_ptr and info_ptr */
                delete [] row_pointers;
                png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
@@ -76,16 +84,34 @@ bool CxImagePNG::Decode(CxFile *hFile)
        /* read the file information */
        png_read_info(png_ptr, info_ptr);
 
+#ifdef USE_NEW_LIBPNG_API
+       png_uint_32 _width,_height;
+       int _bit_depth,_color_type,_interlace_type,_compression_type,_filter_type;
+       png_get_IHDR(png_ptr,info_ptr,&_width,&_height,&_bit_depth,&_color_type,
+               &_interlace_type,&_compression_type,&_filter_type);
+
+       if (info.nEscape == -1){
+               head.biWidth = _width;
+               head.biHeight= _height;
+               info.dwType = CXIMAGE_FORMAT_PNG;
+               longjmp(png_jmpbuf(png_ptr), 1);
+       }
+#else
        if (info.nEscape == -1){
                head.biWidth = info_ptr->width;
                head.biHeight= info_ptr->height;
                info.dwType = CXIMAGE_FORMAT_PNG;
                longjmp(png_ptr->jmpbuf, 1);
        }
+#endif
 
        /* calculate new number of channels */
        int channels=0;
+#ifdef USE_NEW_LIBPNG_API
+       switch(_color_type){
+#else
        switch(info_ptr->color_type){
+#endif
        case PNG_COLOR_TYPE_GRAY:
        case PNG_COLOR_TYPE_PALETTE:
                channels = 1;
@@ -101,20 +127,49 @@ bool CxImagePNG::Decode(CxFile *hFile)
                break;
        default:
                strcpy(info.szLastError,"unknown PNG color type");
+#ifdef USE_NEW_LIBPNG_API
+               longjmp(png_jmpbuf(png_ptr), 1);
+#else
                longjmp(png_ptr->jmpbuf, 1);
+#endif
        }
 
        //find the right pixel depth used for cximage
+#ifdef USE_NEW_LIBPNG_API
+       int pixel_depth = _bit_depth * png_get_channels(png_ptr,info_ptr);
+#else
        int pixel_depth = info_ptr->pixel_depth;
+#endif
        if (channels == 1 && pixel_depth>8) pixel_depth=8;
        if (channels == 2) pixel_depth=8;
        if (channels >= 3) pixel_depth=24;
 
+#ifdef USE_NEW_LIBPNG_API
+       if (!Create(_width, _height, pixel_depth, CXIMAGE_FORMAT_PNG)){
+               longjmp(png_jmpbuf(png_ptr), 1);
+#else
        if (!Create(info_ptr->width, info_ptr->height, pixel_depth, CXIMAGE_FORMAT_PNG)){
                longjmp(png_ptr->jmpbuf, 1);
+#endif
        }
 
        /* get metrics */
+#ifdef USE_NEW_LIBPNG_API
+       png_uint_32 _x_pixels_per_unit,_y_pixels_per_unit;
+       int _phys_unit_type;
+       png_get_pHYs(png_ptr,info_ptr,&_x_pixels_per_unit,&_y_pixels_per_unit,&_phys_unit_type);
+       switch (_phys_unit_type)
+       {
+       case PNG_RESOLUTION_UNKNOWN:
+               SetXDPI(_x_pixels_per_unit);
+               SetYDPI(_y_pixels_per_unit);
+               break;
+       case PNG_RESOLUTION_METER:
+               SetXDPI((long)floor(_x_pixels_per_unit * 254.0 / 10000.0 + 0.5));
+               SetYDPI((long)floor(_y_pixels_per_unit * 254.0 / 10000.0 + 0.5));
+               break;
+       }
+#else
        switch (info_ptr->phys_unit_type)
        {
        case PNG_RESOLUTION_UNKNOWN:
@@ -126,46 +181,94 @@ bool CxImagePNG::Decode(CxFile *hFile)
                SetYDPI((long)floor(info_ptr->y_pixels_per_unit * 254.0 / 10000.0 + 0.5));
                break;
        }
+#endif
 
+#ifdef USE_NEW_LIBPNG_API
+       int _num_palette;
+       png_colorp _palette;
+       png_uint_32 _palette_ret;
+       _palette_ret = png_get_PLTE(png_ptr,info_ptr,&_palette,&_num_palette);
+       if (_palette_ret && _num_palette>0){
+               SetPalette((rgb_color*)_palette,_num_palette);
+               SetClrImportant(_num_palette);
+       } else if (_bit_depth ==2) { //<DP> needed for 2 bpp grayscale PNGs
+#else
        if (info_ptr->num_palette>0){
                SetPalette((rgb_color*)info_ptr->palette,info_ptr->num_palette);
                SetClrImportant(info_ptr->num_palette);
        } else if (info_ptr->bit_depth ==2) { //<DP> needed for 2 bpp grayscale PNGs
+#endif
                SetPaletteColor(0,0,0,0);
                SetPaletteColor(1,85,85,85);
                SetPaletteColor(2,170,170,170);
                SetPaletteColor(3,255,255,255);
        } else SetGrayPalette(); //<DP> needed for grayscale PNGs
        
+#ifdef USE_NEW_LIBPNG_API
+       int nshift = max(0,(_bit_depth>>3)-1)<<3;
+#else
        int nshift = max(0,(info_ptr->bit_depth>>3)-1)<<3;
+#endif
 
+#ifdef USE_NEW_LIBPNG_API
+       png_bytep _trans_alpha;
+       int _num_trans;
+       png_color_16p _trans_color;
+       png_uint_32 _trans_ret;
+       _trans_ret = png_get_tRNS(png_ptr,info_ptr,&_trans_alpha,&_num_trans,&_trans_color);
+       if (_trans_ret && _num_trans!=0){ //palette transparency
+               if (_num_trans==1){
+                       if (_color_type == PNG_COLOR_TYPE_PALETTE){
+#else
        if (info_ptr->num_trans!=0){ //palette transparency
                if (info_ptr->num_trans==1){
                        if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE){
+#endif
+#ifdef USE_NEW_LIBPNG_API
+                               info.nBkgndIndex = _trans_color->index;
+#else
 #if PNG_LIBPNG_VER > 10399
                                info.nBkgndIndex = info_ptr->trans_color.index;
 #else
                                info.nBkgndIndex = info_ptr->trans_values.index;
 #endif
+#endif
                        } else{
+#ifdef USE_NEW_LIBPNG_API
+                               info.nBkgndIndex = _trans_color->gray>>nshift;
+#else
 #if PNG_LIBPNG_VER > 10399
                                info.nBkgndIndex = info_ptr->trans_color.gray>>nshift;
 #else
                                info.nBkgndIndex = info_ptr->trans_values.gray>>nshift;
 #endif
+#endif
                        }
                }
+#ifdef USE_NEW_LIBPNG_API
+               if (_num_trans>1 && _trans_alpha!=NULL){
+#else
                if (info_ptr->num_trans>1){
+#endif
                        RGBQUAD* pal=GetPalette();
                        if (pal){
                                DWORD ip;
+#ifdef USE_NEW_LIBPNG_API
+                               for (ip=0;ip<min(head.biClrUsed,(unsigned long)_num_trans);ip++)
+                                       pal[ip].rgbReserved=_trans_alpha[ip];
+#else
                                for (ip=0;ip<min(head.biClrUsed,(unsigned long)info_ptr->num_trans);ip++)
 #if PNG_LIBPNG_VER > 10399
                                        pal[ip].rgbReserved=info_ptr->trans_alpha[ip];
 #else
                                        pal[ip].rgbReserved=info_ptr->trans[ip];
 #endif
+#endif
+#ifdef USE_NEW_LIBPNG_API
+                               for (ip=_num_trans;ip<head.biClrUsed;ip++){
+#else
                                for (ip=info_ptr->num_trans;ip<head.biClrUsed;ip++){
+#endif
                                        pal[ip].rgbReserved=255;
                                }
                                info.bAlphaPaletteEnabled=true;
@@ -178,6 +281,11 @@ bool CxImagePNG::Decode(CxFile *hFile)
                int num_trans;
                png_color_16 *image_background;
                if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &image_background)){
+#ifdef USE_NEW_LIBPNG_API
+                       info.nBkgndColor.rgbRed   = (BYTE)(_trans_color->red>>nshift);
+                       info.nBkgndColor.rgbGreen = (BYTE)(_trans_color->green>>nshift);
+                       info.nBkgndColor.rgbBlue  = (BYTE)(_trans_color->blue>>nshift);
+#else
 #if PNG_LIBPNG_VER > 10399
                        info.nBkgndColor.rgbRed   = (BYTE)(info_ptr->trans_color.red>>nshift);
                        info.nBkgndColor.rgbGreen = (BYTE)(info_ptr->trans_color.green>>nshift);
@@ -187,6 +295,7 @@ bool CxImagePNG::Decode(CxFile *hFile)
                        info.nBkgndColor.rgbGreen = (BYTE)(info_ptr->trans_values.green>>nshift);
                        info.nBkgndColor.rgbBlue  = (BYTE)(info_ptr->trans_values.blue>>nshift);
 #endif
+#endif
                        info.nBkgndColor.rgbReserved = 0;
                        info.nBkgndIndex = 0;
                }
@@ -202,15 +311,27 @@ bool CxImagePNG::Decode(CxFile *hFile)
        }
 
        // <vho> - flip the RGB pixels to BGR (or RGBA to BGRA)
+#ifdef USE_NEW_LIBPNG_API
+       if (_color_type & PNG_COLOR_MASK_COLOR){
+#else
        if (info_ptr->color_type & PNG_COLOR_MASK_COLOR){
+#endif
                png_set_bgr(png_ptr);
        }
 
        // <vho> - handle cancel
+#ifdef USE_NEW_LIBPNG_API
+       if (info.nEscape) longjmp(png_jmpbuf(png_ptr), 1);
+#else
        if (info.nEscape) longjmp(png_ptr->jmpbuf, 1);
+#endif
 
        // row_bytes is the width x number of channels x (bit-depth / 8)
+#ifdef USE_NEW_LIBPNG_API
+       row_pointers = new BYTE[png_get_rowbytes(png_ptr,info_ptr) + 8];
+#else
        row_pointers = new BYTE[info_ptr->rowbytes + 8];
+#endif
 
        // turn on interlace handling
        int number_passes = png_set_interlace_handling(png_ptr);
@@ -221,8 +342,16 @@ bool CxImagePNG::Decode(CxFile *hFile)
                SetCodecOption(0);
        }
 
+#ifdef USE_NEW_LIBPNG_API
+       int chan_offset = _bit_depth >> 3;
+#else
        int chan_offset = info_ptr->bit_depth >> 3;
+#endif
+#ifdef USE_NEW_LIBPNG_API
+       int pixel_offset = (_bit_depth * png_get_channels(png_ptr,info_ptr)) >> 3;
+#else
        int pixel_offset = info_ptr->pixel_depth >> 3;
+#endif
 
        for (int pass=0; pass < number_passes; pass++) {
                iter.Upset();
@@ -230,7 +359,11 @@ bool CxImagePNG::Decode(CxFile *hFile)
                do      {
 
                        // <vho> - handle cancel
+#ifdef USE_NEW_LIBPNG_API
+                       if (info.nEscape) longjmp(png_jmpbuf(png_ptr), 1);
+#else
                        if (info.nEscape) longjmp(png_ptr->jmpbuf, 1);
+#endif
 
 #if CXIMAGE_SUPPORT_ALPHA      // <vho>
                        if (AlphaIsValid()) {
@@ -241,7 +374,11 @@ bool CxImagePNG::Decode(CxFile *hFile)
                                BYTE* prow= iter.GetRow(ay);
 
                                //recover data from previous scan
+#ifdef USE_NEW_LIBPNG_API
+                               if (_interlace_type && pass>0 && pass!=7){
+#else
                                if (info_ptr->interlace_type && pass>0 && pass!=7){
+#endif
                                        for(ax=0;ax<head.biWidth;ax++){
                                                long px = ax * pixel_offset;
                                                if (channels == 2){
@@ -278,10 +415,17 @@ bool CxImagePNG::Decode(CxFile *hFile)
 #endif // CXIMAGE_SUPPORT_ALPHA                // vho
                        {
                                //recover data from previous scan
+#ifdef USE_NEW_LIBPNG_API
+                               if (_interlace_type && pass>0){
+                                       iter.GetRow(row_pointers, png_get_rowbytes(png_ptr,info_ptr));
+                                       //re-expand buffer for images with bit depth > 8
+                                       if (_bit_depth > 8){
+#else
                                if (info_ptr->interlace_type && pass>0){
                                        iter.GetRow(row_pointers, info_ptr->rowbytes);
                                        //re-expand buffer for images with bit depth > 8
                                        if (info_ptr->bit_depth > 8){
+#endif
                                                for(long ax=(head.biWidth*channels-1);ax>=0;ax--)
                                                        row_pointers[ax*chan_offset] = row_pointers[ax];
                                        }
@@ -291,15 +435,27 @@ bool CxImagePNG::Decode(CxFile *hFile)
                                png_read_row(png_ptr, row_pointers, NULL);
 
                                //shrink 16 bit depth images down to 8 bits
+#ifdef USE_NEW_LIBPNG_API
+                               if (_bit_depth > 8){
+#else
                                if (info_ptr->bit_depth > 8){
+#endif
                                        for(long ax=0;ax<(head.biWidth*channels);ax++)
                                                row_pointers[ax] = row_pointers[ax*chan_offset];
                                }
 
                                //copy the pixels
+#ifdef USE_NEW_LIBPNG_API
+                               iter.SetRow(row_pointers, png_get_rowbytes(png_ptr,info_ptr));
+#else
                                iter.SetRow(row_pointers, info_ptr->rowbytes);
+#endif
                                //<DP> expand 2 bpp images only in the last pass
+#ifdef USE_NEW_LIBPNG_API
+                               if (_bit_depth==2 && pass==(number_passes-1))
+#else
                                if (info_ptr->bit_depth==2 && pass==(number_passes-1))
+#endif
                                        expand2to4bpp(iter.GetRow());
 
                                //go on
@@ -361,9 +517,13 @@ bool CxImagePNG::Encode(CxFile *hFile)
    /* Set error handling.  REQUIRED if you aren't supplying your own
     * error hadnling functions in the png_create_write_struct() call.
     */
+#ifdef USE_NEW_LIBPNG_API
+       if (setjmp(png_jmpbuf(png_ptr))){
+#else
        if (setjmp(png_ptr->jmpbuf)){
                /* If we get here, we had a problem reading the file */
                if (info_ptr->palette) free(info_ptr->palette);
+#endif
                png_destroy_write_struct(&png_ptr,  (png_infopp)&info_ptr);
                cx_throw("Error saving PNG file");
        }
@@ -372,9 +532,23 @@ bool CxImagePNG::Encode(CxFile *hFile)
        //png_init_io(png_ptr, hFile);
 
        // use custom I/O functions
-    png_set_write_fn(png_ptr,hFile,/*(png_rw_ptr)*/user_write_data,/*(png_flush_ptr)*/user_flush_data);
+       png_set_write_fn(png_ptr,hFile,/*(png_rw_ptr)*/user_write_data,/*(png_flush_ptr)*/user_flush_data);
 
        /* set the file information here */
+#ifdef USE_NEW_LIBPNG_API
+       /* use variables to hold the values so it isnt necessary to png_get them later */
+       png_uint_32 _width,_height;
+       int _bit_depth,_color_type,_interlace_type,_compression_type,_filter_type;
+       png_byte _channels,_pixel_depth;
+
+       _width = GetWidth();
+       _height = GetHeight();
+       _pixel_depth = (BYTE)GetBpp();
+       _channels = (GetBpp()>8) ? (BYTE)3: (BYTE)1;
+       _bit_depth = (BYTE)(GetBpp()/_channels);
+       _compression_type = PNG_COMPRESSION_TYPE_DEFAULT;
+       _filter_type = PNG_FILTER_TYPE_DEFAULT;
+#else
        info_ptr->width = GetWidth();
        info_ptr->height = GetHeight();
        info_ptr->pixel_depth = (BYTE)GetBpp();
@@ -382,13 +556,22 @@ bool CxImagePNG::Encode(CxFile *hFile)
        info_ptr->bit_depth = (BYTE)(GetBpp()/info_ptr->channels);
        info_ptr->compression_type = info_ptr->filter_type = 0;
        info_ptr->valid = 0;
+#endif
 
        switch(GetCodecOption(CXIMAGE_FORMAT_PNG)){
        case 1:
+#ifdef USE_NEW_LIBPNG_API
+               _interlace_type = PNG_INTERLACE_ADAM7;
+#else
                info_ptr->interlace_type = PNG_INTERLACE_ADAM7;
+#endif
                break;
        default:
+#ifdef USE_NEW_LIBPNG_API
+               _interlace_type = PNG_INTERLACE_NONE;
+#else
                info_ptr->interlace_type = PNG_INTERLACE_NONE;
+#endif
        }
 
        /* set compression level */
@@ -398,19 +581,38 @@ bool CxImagePNG::Encode(CxFile *hFile)
 
        if (GetNumColors()){
                if (bGrayScale){
+#ifdef USE_NEW_LIBPNG_API
+                       _color_type = PNG_COLOR_TYPE_GRAY;
+#else
                        info_ptr->color_type = PNG_COLOR_TYPE_GRAY;
+#endif
                } else {
+#ifdef USE_NEW_LIBPNG_API
+                       _color_type = PNG_COLOR_TYPE_PALETTE;
+#else
                        info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+#endif
                }
        } else {
+#ifdef USE_NEW_LIBPNG_API
+               _color_type = PNG_COLOR_TYPE_RGB;
+#else
                info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+#endif
        }
 #if CXIMAGE_SUPPORT_ALPHA
        if (AlphaIsValid()){
+#ifdef USE_NEW_LIBPNG_API
+               _color_type |= PNG_COLOR_MASK_ALPHA;
+               _channels++;
+               _bit_depth = 8;
+               _pixel_depth += 8;
+#else
                info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
                info_ptr->channels++;
                info_ptr->bit_depth = 8;
                info_ptr->pixel_depth += 8;
+#endif
        }
 #endif
 
@@ -427,14 +629,30 @@ bool CxImagePNG::Encode(CxFile *hFile)
        /* set metrics */
        png_set_pHYs(png_ptr, info_ptr, head.biXPelsPerMeter, head.biYPelsPerMeter, PNG_RESOLUTION_METER);
 
+#ifdef USE_NEW_LIBPNG_API
+       png_set_IHDR(png_ptr,info_ptr,_width,_height,_bit_depth,_color_type,_interlace_type,
+               _compression_type,_filter_type);
+#else
        png_set_IHDR(png_ptr, info_ptr, info_ptr->width, info_ptr->height, info_ptr->bit_depth,
                                info_ptr->color_type, info_ptr->interlace_type,
                                PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+#endif
 
        //<DP> simple transparency
        if (info.nBkgndIndex >= 0){
+#if PNG_LIBPNG_VER <= 10499
                info_ptr->num_trans = 1;
                info_ptr->valid |= PNG_INFO_tRNS;
+#endif
+#ifdef USE_NEW_LIBPNG_API
+               png_color_16 _trans_color;
+               _trans_color.index = (BYTE)info.nBkgndIndex;
+               _trans_color.red   = tc.rgbRed;
+               _trans_color.green = tc.rgbGreen;
+               _trans_color.blue  = tc.rgbBlue;
+               _trans_color.gray  = _trans_color.index;
+               png_set_tRNS(png_ptr,info_ptr,(png_bytep)trans,1,&_trans_color);
+#else
 #if PNG_LIBPNG_VER > 10399
                info_ptr->trans_alpha = trans;
                info_ptr->trans_color.index = (BYTE)info.nBkgndIndex;
@@ -450,6 +668,7 @@ bool CxImagePNG::Encode(CxFile *hFile)
                info_ptr->trans_values.blue  = tc.rgbBlue;
                info_ptr->trans_values.gray  = info_ptr->trans_values.index;
 #endif
+#endif
 
                // the transparency indexes start from 0 for non grayscale palette
                if (!bGrayScale && head.biClrUsed && info.nBkgndIndex)
@@ -457,10 +676,16 @@ bool CxImagePNG::Encode(CxFile *hFile)
        }
 
        /* set the palette if there is one */
+#ifdef USE_NEW_LIBPNG_API
+       png_colorp _palette = NULL;
+       if (GetPalette()){
+               /* png_set_PLTE() will be called once the palette is ready */
+#else
        if (GetPalette()){
                if (!bGrayScale){
                        info_ptr->valid |= PNG_INFO_PLTE;
                }
+#endif
 
                int nc = GetClrImportant();
                if (nc==0) nc = GetNumColors();
@@ -468,20 +693,34 @@ bool CxImagePNG::Encode(CxFile *hFile)
                if (info.bAlphaPaletteEnabled){
                        for(WORD ip=0; ip<nc;ip++)
                                trans[ip]=GetPaletteColor((BYTE)ip).rgbReserved;
+#if PNG_LIBPNG_VER <= 10499
                        info_ptr->num_trans = (WORD)nc;
                        info_ptr->valid |= PNG_INFO_tRNS;
+#endif
+#ifdef USE_NEW_LIBPNG_API
+                       png_set_tRNS(png_ptr,info_ptr,(png_bytep)trans,nc,NULL);
+#else
 #if PNG_LIBPNG_VER > 10399
                        info_ptr->trans_alpha = trans;
 #else
                        info_ptr->trans = trans;
 #endif
+#endif
                }
 
                // copy the palette colors
+#ifdef USE_NEW_LIBPNG_API
+               _palette = new png_color[nc];
+               for (int i=0; i<nc; i++)
+                       GetPaletteColor(i, &_palette[i].red, &_palette[i].green, &_palette[i].blue);
+
+               png_set_PLTE(png_ptr,info_ptr,_palette,nc);
+#else
                info_ptr->palette = new png_color[nc];
                info_ptr->num_palette = (png_uint_16) nc;
                for (int i=0; i<nc; i++)
                        GetPaletteColor(i, &info_ptr->palette[i].red, &info_ptr->palette[i].green, &info_ptr->palette[i].blue);
+#endif
        }  
 
 #if CXIMAGE_SUPPORT_ALPHA      // <vho>
@@ -495,8 +734,12 @@ bool CxImagePNG::Encode(CxFile *hFile)
        }       }       }
 #endif // CXIMAGE_SUPPORT_ALPHA        // <vho>
 
+#ifdef USE_NEW_LIBPNG_API
+       int row_size = max(info.dwEffWidth, (_width * _channels * _bit_depth / 8));
+#else
        int row_size = max(info.dwEffWidth, info_ptr->width*info_ptr->channels*(info_ptr->bit_depth/8));
        info_ptr->rowbytes = row_size;
+#endif
        BYTE *row_pointers = new BYTE[row_size];
 
        /* write the file information */
@@ -514,7 +757,11 @@ bool CxImagePNG::Encode(CxFile *hFile)
                        if (AlphaIsValid()){
                                for (long ax=head.biWidth-1; ax>=0;ax--){
                                        c = BlindGetPixelColor(ax,ay);
+#ifdef USE_NEW_LIBPNG_API
+                                       int px = ax * _channels;
+#else
                                        int px = ax * info_ptr->channels;
+#endif
                                        if (!bGrayScale){
                                                row_pointers[px++]=c.rgbRed;
                                                row_pointers[px++]=c.rgbGreen;
@@ -529,7 +776,11 @@ bool CxImagePNG::Encode(CxFile *hFile)
 #endif //CXIMAGE_SUPPORT_ALPHA // <vho>
                        {
                                iter.GetRow(row_pointers, row_size);
+#ifdef USE_NEW_LIBPNG_API
+                               if (_color_type == PNG_COLOR_TYPE_RGB) //HACK BY OP
+#else
                                if (info_ptr->color_type == PNG_COLOR_TYPE_RGB) //HACK BY OP
+#endif
                                        RGBtoBGR(row_pointers, row_size);
                                png_write_row(png_ptr, row_pointers);
                        }
@@ -546,9 +797,14 @@ bool CxImagePNG::Encode(CxFile *hFile)
        png_write_end(png_ptr, info_ptr);
 
        /* if you malloced the palette, free it here */
+#ifdef USE_NEW_LIBPNG_API
+       if (_palette){
+               delete [] (_palette);
+#else
        if (info_ptr->palette){
                delete [] (info_ptr->palette);
                info_ptr->palette = NULL;
+#endif
        }
 
        /* clean up after the write, and free any memory allocated */
index db41935..7d1611b 100644 (file)
@@ -30,6 +30,10 @@ extern "C" {
 #endif
 }
 
+#if PNG_LIBPNG_VER > 10499
+  #define USE_NEW_LIBPNG_API
+#endif
+
 class CxImagePNG: public CxImage
 {
 public:
@@ -69,8 +73,13 @@ protected:
 
     static void PNGAPI user_error_fn(png_structp png_ptr,png_const_charp error_msg)
        {
+#ifdef USE_NEW_LIBPNG_API
+               strncpy((char*)png_get_error_ptr(png_ptr),error_msg,255);
+               longjmp(png_jmpbuf(png_ptr), 1);
+#else
                strncpy((char*)png_ptr->error_ptr,error_msg,255);
                longjmp(png_ptr->jmpbuf, 1);
+#endif
        }
 };
 
index d8ceca1..f5af44e 100644 (file)
@@ -398,7 +398,7 @@ static av_noinline void OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst,
             "2:                         \n\t"\
             \
             : "+a"(src), "+c"(dst)\
-            : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "g"(h)\
+            : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "rm"(h)\
             : "memory"\
         );\
         src += 4-(h+5)*srcStride;\
@@ -446,7 +446,7 @@ static av_always_inline void OPNAME ## h264_qpel8or16_hv1_lowpass_ ## MMX(int16_
             QPEL_H264HV(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, 15*48)\
             "2:                     \n\t"\
             : "+a"(src)\
-            : "c"(tmp), "S"((x86_reg)srcStride), "g"(size)\
+            : "c"(tmp), "S"((x86_reg)srcStride), "rm"(size)\
             : "memory"\
             );\
         tmp += 4;\
@@ -823,7 +823,7 @@ static av_noinline void OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst,
         "2:                          \n\t"\
         \
         : "+a"(src), "+c"(dst)\
-        : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "g"(h)\
+        : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "rm"(h)\
         : XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3", \
                        "%xmm4", "%xmm5", "%xmm6", "%xmm7",)\
           "memory"\
@@ -878,7 +878,7 @@ static av_always_inline void put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp, u
             QPEL_H264HV_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, 15*48)
             "2:                         \n\t"
             : "+a"(src)
-            : "c"(tmp), "S"((x86_reg)srcStride), "g"(size)
+            : "c"(tmp), "S"((x86_reg)srcStride), "rm"(size)
             : XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3",
                            "%xmm4", "%xmm5", "%xmm6", "%xmm7",)
               "memory"
index da91600..1ed8807 100644 (file)
@@ -56,42 +56,42 @@ typedef struct {
     AVFilterBufferRef *out;
     void (*filter_line)(uint8_t *dst,
                         uint8_t *prev, uint8_t *cur, uint8_t *next,
-                        int w, int refs, int parity, int mode);
+                        int w, int prefs, int mrefs, int parity, int mode);
 } YADIFContext;
 
 static void filter_line_c(uint8_t *dst,
                           uint8_t *prev, uint8_t *cur, uint8_t *next,
-                          int w, int refs, int parity, int mode)
+                          int w, int prefs, int mrefs, int parity, int mode)
 {
     int x;
     uint8_t *prev2 = parity ? prev : cur ;
     uint8_t *next2 = parity ? cur  : next;
     for (x = 0;  x < w; x++) {
-        int c = cur[-refs];
+        int c = cur[mrefs];
         int d = (prev2[0] + next2[0])>>1;
-        int e = cur[+refs];
+        int e = cur[prefs];
         int temporal_diff0 = FFABS(prev2[0] - next2[0]);
-        int temporal_diff1 =(FFABS(prev[-refs] - c) + FFABS(prev[+refs] - e) )>>1;
-        int temporal_diff2 =(FFABS(next[-refs] - c) + FFABS(next[+refs] - e) )>>1;
+        int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e) )>>1;
+        int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1;
         int diff = FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
         int spatial_pred = (c+e)>>1;
-        int spatial_score = FFABS(cur[-refs-1] - cur[+refs-1]) + FFABS(c-e)
-                          + FFABS(cur[-refs+1] - cur[+refs+1]) - 1;
+        int spatial_score = FFABS(cur[mrefs-1] - cur[prefs-1]) + FFABS(c-e)
+                          + FFABS(cur[mrefs+1] - cur[prefs+1]) - 1;
 
 #define CHECK(j)\
-    {   int score = FFABS(cur[-refs-1+j] - cur[+refs-1-j])\
-                  + FFABS(cur[-refs  +j] - cur[+refs  -j])\
-                  + FFABS(cur[-refs+1+j] - cur[+refs+1-j]);\
+    {   int score = FFABS(cur[mrefs-1+j] - cur[prefs-1-j])\
+                  + FFABS(cur[mrefs  +j] - cur[prefs  -j])\
+                  + FFABS(cur[mrefs+1+j] - cur[prefs+1-j]);\
         if (score < spatial_score) {\
             spatial_score= score;\
-            spatial_pred= (cur[-refs  +j] + cur[+refs  -j])>>1;\
+            spatial_pred= (cur[mrefs  +j] + cur[prefs  -j])>>1;\
 
         CHECK(-1) CHECK(-2) }} }}
         CHECK( 1) CHECK( 2) }} }}
 
         if (mode < 2) {
-            int b = (prev2[-2*refs] + next2[-2*refs])>>1;
-            int f = (prev2[+2*refs] + next2[+2*refs])>>1;
+            int b = (prev2[2*mrefs] + next2[2*mrefs])>>1;
+            int f = (prev2[2*prefs] + next2[2*prefs])>>1;
 #if 0
             int a = cur[-3*refs];
             int g = cur[+3*refs];
@@ -139,7 +139,8 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic,
                 uint8_t *cur  = &yadif->cur ->data[i][y*refs];
                 uint8_t *next = &yadif->next->data[i][y*refs];
                 uint8_t *dst  = &dstpic->data[i][y*dstpic->linesize[i]];
-                yadif->filter_line(dst, prev, cur, next, w, refs, parity ^ tff, yadif->mode);
+                int     mode  = y==1 || y+2==h ? 2 : yadif->mode;
+                yadif->filter_line(dst, prev, cur, next, w, y+1<h ? refs : -refs, y ? -refs : refs, parity ^ tff, mode);
             } else {
                 memcpy(&dstpic->data[i][y*dstpic->linesize[i]],
                        &yadif->cur->data[i][y*refs], w);
index 3e520cb..50ea843 100644 (file)
 
 void RENAME(ff_yadif_filter_line)(uint8_t *dst,
                                   uint8_t *prev, uint8_t *cur, uint8_t *next,
-                                  int w, int refs, int parity, int mode)
+                                  int w, int prefs, int mrefs, int parity, int mode)
 {
     DECLARE_ALIGNED(16, uint8_t, tmp0[16]);
     DECLARE_ALIGNED(16, uint8_t, tmp1[16]);
@@ -226,8 +226,8 @@ void RENAME(ff_yadif_filter_line)(uint8_t *dst,
             :[prev] "r"(prev),\
              [cur]  "r"(cur),\
              [next] "r"(next),\
-             [prefs]"r"((x86_reg)refs),\
-             [mrefs]"r"((x86_reg)-refs),\
+             [prefs]"r"((x86_reg)prefs),\
+             [mrefs]"r"((x86_reg)mrefs),\
              [mode] "g"(mode)\
         );\
         __asm__ volatile(MOV" "MM"1, %0" :"=m"(*dst));\
index 072812c..ff574da 100644 (file)
 
 void ff_yadif_filter_line_mmx(uint8_t *dst,
                               uint8_t *prev, uint8_t *cur, uint8_t *next,
-                              int w, int refs, int parity, int mode);
+                              int w, int prefs, int mrefs, int parity, int mode);
 
 void ff_yadif_filter_line_sse2(uint8_t *dst,
                                uint8_t *prev, uint8_t *cur, uint8_t *next,
-                               int w, int refs, int parity, int mode);
+                               int w, int prefs, int mrefs, int parity, int mode);
 
 void ff_yadif_filter_line_ssse3(uint8_t *dst,
                                 uint8_t *prev, uint8_t *cur, uint8_t *next,
-                                int w, int refs, int parity, int mode);
+                                int w, int prefs, int mrefs, int parity, int mode);
 
 #endif /* AVFILTER_YADIF_H */
index 14b96d4..70489e8 100644 (file)
@@ -1066,19 +1066,21 @@ static void matroska_convert_tags(AVFormatContext *s)
         if (tags[i].target.attachuid) {
             MatroskaAttachement *attachment = matroska->attachments.elem;
             for (j=0; j<matroska->attachments.nb_elem; j++)
-                if (attachment[j].uid == tags[i].target.attachuid)
+                if (attachment[j].uid == tags[i].target.attachuid
+                    && attachment[j].stream)
                     matroska_convert_tag(s, &tags[i].tag,
                                          &attachment[j].stream->metadata, NULL);
         } else if (tags[i].target.chapteruid) {
             MatroskaChapter *chapter = matroska->chapters.elem;
             for (j=0; j<matroska->chapters.nb_elem; j++)
-                if (chapter[j].uid == tags[i].target.chapteruid)
+                if (chapter[j].uid == tags[i].target.chapteruid
+                    && chapter[j].chapter)
                     matroska_convert_tag(s, &tags[i].tag,
                                          &chapter[j].chapter->metadata, NULL);
         } else if (tags[i].target.trackuid) {
             MatroskaTrack *track = matroska->tracks.elem;
             for (j=0; j<matroska->tracks.nb_elem; j++)
-                if (track[j].uid == tags[i].target.trackuid)
+                if (track[j].uid == tags[i].target.trackuid && track[j].stream)
                     matroska_convert_tag(s, &tags[i].tag,
                                          &track[j].stream->metadata, NULL);
         } else {
diff --git a/lib/ffmpeg/patches/0062-fixed-crash-in-ffmpeg-matroskadec-with-some-files-fi.patch b/lib/ffmpeg/patches/0062-fixed-crash-in-ffmpeg-matroskadec-with-some-files-fi.patch
new file mode 100644 (file)
index 0000000..00260c7
--- /dev/null
@@ -0,0 +1,50 @@
+From e138f82d2b066a47262ce0f06df106665761ac43 Mon Sep 17 00:00:00 2001
+From: Anssi Hannula <anssi@xbmc.org>
+Date: Wed, 7 Mar 2012 15:08:41 +0200
+Subject: [PATCH] fixed: crash in ffmpeg matroskadec with some files (fixes
+ #12741)
+
+Backport 2851b1f6566580485dceb67cbb6b93f64ee9a9bd from upstream FFmpeg,
+it fixes a rare matroskadec crash:
+
+matroskadec: check that pointers were initialized before accessing them
+
+fix ticket #14
+
+Signed-off-by: Aurelien Jacobs <aurel@gnuage.org>
+---
+ lib/ffmpeg/libavformat/matroskadec.c |    8 +++++---
+ 1 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/lib/ffmpeg/libavformat/matroskadec.c b/lib/ffmpeg/libavformat/matroskadec.c
+index 14b96d4..70489e8 100644
+--- a/lib/ffmpeg/libavformat/matroskadec.c
++++ b/lib/ffmpeg/libavformat/matroskadec.c
+@@ -1066,19 +1066,21 @@ static void matroska_convert_tags(AVFormatContext *s)
+         if (tags[i].target.attachuid) {
+             MatroskaAttachement *attachment = matroska->attachments.elem;
+             for (j=0; j<matroska->attachments.nb_elem; j++)
+-                if (attachment[j].uid == tags[i].target.attachuid)
++                if (attachment[j].uid == tags[i].target.attachuid
++                    && attachment[j].stream)
+                     matroska_convert_tag(s, &tags[i].tag,
+                                          &attachment[j].stream->metadata, NULL);
+         } else if (tags[i].target.chapteruid) {
+             MatroskaChapter *chapter = matroska->chapters.elem;
+             for (j=0; j<matroska->chapters.nb_elem; j++)
+-                if (chapter[j].uid == tags[i].target.chapteruid)
++                if (chapter[j].uid == tags[i].target.chapteruid
++                    && chapter[j].chapter)
+                     matroska_convert_tag(s, &tags[i].tag,
+                                          &chapter[j].chapter->metadata, NULL);
+         } else if (tags[i].target.trackuid) {
+             MatroskaTrack *track = matroska->tracks.elem;
+             for (j=0; j<matroska->tracks.nb_elem; j++)
+-                if (track[j].uid == tags[i].target.trackuid)
++                if (track[j].uid == tags[i].target.trackuid && track[j].stream)
+                     matroska_convert_tag(s, &tags[i].tag,
+                                          &track[j].stream->metadata, NULL);
+         } else {
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0063-fixed-playing-mpegts-over-rtsp-caused-ffmpeg-to-read.patch b/lib/ffmpeg/patches/0063-fixed-playing-mpegts-over-rtsp-caused-ffmpeg-to-read.patch
new file mode 100644 (file)
index 0000000..4b50b5e
--- /dev/null
@@ -0,0 +1,29 @@
+From 8ec66e240fe0a9f672d7ff1932022f22f8332ffb Mon Sep 17 00:00:00 2001
+From: Joakim Plate <elupus@xbmc.org>
+Date: Mon, 7 Mar 2011 22:53:30 +0100
+Subject: [PATCH] fixed: playing mpegts over rtsp caused ffmpeg to read
+ uninitialized stack values
+
+This is an amendment to cdfab91b9c4b7ed2560071f5630567db174d6084 the memleak
+fix for mpegts. It's questionable if that change is needed. Since
+the main issue it was for has been fixed correctly. However it
+doesn't hurt to avoid potential memleaks this way.
+---
+ lib/ffmpeg/libavformat/mpegts.c |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/lib/ffmpeg/libavformat/mpegts.c b/lib/ffmpeg/libavformat/mpegts.c
+index 9c25e37..2dbd07e 100644
+--- a/lib/ffmpeg/libavformat/mpegts.c
++++ b/lib/ffmpeg/libavformat/mpegts.c
+@@ -1879,6 +1879,7 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
+     len1 = len;
+     ts->pkt = pkt;
++    ts->pkt->data = NULL;
+     ts->stop_parse = 0;
+     for(;;) {
+         if (ts->stop_parse>0)
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0064-ffmpeg-add-missing-check-for-NULL-pointer.patch b/lib/ffmpeg/patches/0064-ffmpeg-add-missing-check-for-NULL-pointer.patch
new file mode 100644 (file)
index 0000000..a1ff8e2
--- /dev/null
@@ -0,0 +1,28 @@
+From 54fd0c0596e8bd47adb9ac325ddb93d99647fe83 Mon Sep 17 00:00:00 2001
+From: Marcel Groothuis <margro.xbmc@gmail.com>
+Date: Sat, 12 Mar 2011 23:02:06 +0100
+Subject: [PATCH] ffmpeg: add missing check for NULL pointer Extends commit
+ 8ec66e240fe0a9f672d7ff1932022f22f8332ffb (fixed: playing
+ mpegts over rtsp caused ffmpeg to read uninitialized stack
+ values)
+
+---
+ lib/ffmpeg/libavformat/utils.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/lib/ffmpeg/libavformat/utils.c b/lib/ffmpeg/libavformat/utils.c
+index bee0475..d3c11e2 100644
+--- a/lib/ffmpeg/libavformat/utils.c
++++ b/lib/ffmpeg/libavformat/utils.c
+@@ -1092,7 +1092,7 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
+                     av_add_index_entry(st, pkt->pos, pkt->dts, 0, 0, AVINDEX_KEYFRAME);
+                 }
+                 break;
+-            } else if (st->cur_len > 0 && st->discard < AVDISCARD_ALL) {
++            } else if (st->cur_len > 0 && st->cur_ptr && st->discard < AVDISCARD_ALL) {
+                 len = av_parser_parse2(st->parser, st->codec, &pkt->data, &pkt->size,
+                                        st->cur_ptr, st->cur_len,
+                                        st->cur_pkt.pts, st->cur_pkt.dts,
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0065-changed-allow-yadif-deinterlacer-to-enable-and-disab.patch b/lib/ffmpeg/patches/0065-changed-allow-yadif-deinterlacer-to-enable-and-disab.patch
new file mode 100644 (file)
index 0000000..30b27f4
--- /dev/null
@@ -0,0 +1,106 @@
+From c174f74181bcfa169aa8284f9524cd9db0f4cdda Mon Sep 17 00:00:00 2001
+From: elupus <elupus@xbmc.org>
+Date: Fri, 24 Jun 2011 01:23:48 +0200
+Subject: [PATCH] changed: allow yadif deinterlacer to enable and disable
+ based on input interlaced flag
+
+---
+ lib/ffmpeg/libavfilter/vf_yadif.c                  |   34 ++++++++++++++++++--
+ .../DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp        |    4 ++
+ 2 files changed, 35 insertions(+), 3 deletions(-)
+
+diff --git a/lib/ffmpeg/libavfilter/vf_yadif.c b/lib/ffmpeg/libavfilter/vf_yadif.c
+index bd0a9de..28b1d3e 100644
+--- a/lib/ffmpeg/libavfilter/vf_yadif.c
++++ b/lib/ffmpeg/libavfilter/vf_yadif.c
+@@ -43,6 +43,13 @@ typedef struct {
+     int parity;
+     int frame_pending;
++    int skip;
++
++    /**
++     *  0: deinterlace all frames
++     *  1: only deinterlace frames marked as interlaced
++     */
++    int auto_enable;
+     AVFilterBufferRef *cur;
+     AVFilterBufferRef *next;
+@@ -212,10 +219,21 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+     yadif->prev = yadif->cur;
+     yadif->cur  = yadif->next;
+     yadif->next = picref;
++    yadif->skip = 0;
+     if (!yadif->cur)
+         return;
++    if (yadif->auto_enable && !yadif->cur->video->interlaced) {
++        yadif->out  = yadif->cur;
++        avfilter_unref_buffer(yadif->prev);
++        yadif->cur  = NULL;
++        yadif->prev = NULL;
++        yadif->skip = 1;
++        avfilter_start_frame(ctx->outputs[0], yadif->out);
++        return;
++    }
++
+     if (!yadif->prev)
+         yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);
+@@ -232,6 +250,12 @@ static void end_frame(AVFilterLink *link)
+     AVFilterContext *ctx = link->dst;
+     YADIFContext *yadif = ctx->priv;
++    if (yadif->skip) {
++        avfilter_draw_slice(ctx->outputs[0], 0, link->h, 1);
++        avfilter_end_frame(ctx->outputs[0]);
++        return;
++    }
++
+     if (!yadif->out)
+         return;
+@@ -253,7 +277,7 @@ static int request_frame(AVFilterLink *link)
+         if ((ret = avfilter_request_frame(link->src->inputs[0])))
+             return ret;
+-    } while (!yadif->cur);
++    } while (!yadif->out);
+     return 0;
+ }
+@@ -275,6 +299,9 @@ static int poll_frame(AVFilterLink *link)
+     }
+     assert(yadif->next);
++    if (yadif->skip)
++        return val;
++
+     return val * ((yadif->mode&1)+1);
+ }
+@@ -307,8 +334,9 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+     yadif->mode = 0;
+     yadif->parity = -1;
++    yadif->auto_enable = 0;
+-    if (args) sscanf(args, "%d:%d", &yadif->mode, &yadif->parity);
++    if (args) sscanf(args, "%d:%d:%d", &yadif->mode, &yadif->parity, &yadif->auto_enable);
+     yadif->filter_line = filter_line_c;
+     if (HAVE_SSSE3 && cpu_flags & AV_CPU_FLAG_SSSE3)
+@@ -318,7 +346,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+     else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX)
+         yadif->filter_line = ff_yadif_filter_line_mmx;
+-    av_log(ctx, AV_LOG_INFO, "mode:%d parity:%d\n", yadif->mode, yadif->parity);
++    av_log(ctx, AV_LOG_INFO, "mode:%d parity:%d auto_enable:%d\n", yadif->mode, yadif->parity, yadif->auto_enable);
+     return 0;
+ }
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0066-changed-updated-yadif-patch-to-same-as-will-be-appli.patch b/lib/ffmpeg/patches/0066-changed-updated-yadif-patch-to-same-as-will-be-appli.patch
new file mode 100644 (file)
index 0000000..e5c3113
--- /dev/null
@@ -0,0 +1,82 @@
+From 91efb0af6f80d82b104a810a1ccdc0ae6702d022 Mon Sep 17 00:00:00 2001
+From: elupus <elupus@xbmc.org>
+Date: Sun, 3 Jul 2011 17:06:42 +0200
+Subject: [PATCH] changed: updated yadif patch to same as will be applied
+ upstream
+
+---
+ lib/ffmpeg/libavfilter/vf_yadif.c |   18 +++++++-----------
+ 1 files changed, 7 insertions(+), 11 deletions(-)
+
+diff --git a/lib/ffmpeg/libavfilter/vf_yadif.c b/lib/ffmpeg/libavfilter/vf_yadif.c
+index 28b1d3e..d7bed90 100644
+--- a/lib/ffmpeg/libavfilter/vf_yadif.c
++++ b/lib/ffmpeg/libavfilter/vf_yadif.c
+@@ -43,7 +43,6 @@ typedef struct {
+     int parity;
+     int frame_pending;
+-    int skip;
+     /**
+      *  0: deinterlace all frames
+@@ -219,17 +218,14 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+     yadif->prev = yadif->cur;
+     yadif->cur  = yadif->next;
+     yadif->next = picref;
+-    yadif->skip = 0;
+     if (!yadif->cur)
+         return;
+     if (yadif->auto_enable && !yadif->cur->video->interlaced) {
+-        yadif->out  = yadif->cur;
++        yadif->out  = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);
+         avfilter_unref_buffer(yadif->prev);
+-        yadif->cur  = NULL;
+         yadif->prev = NULL;
+-        yadif->skip = 1;
+         avfilter_start_frame(ctx->outputs[0], yadif->out);
+         return;
+     }
+@@ -250,15 +246,15 @@ static void end_frame(AVFilterLink *link)
+     AVFilterContext *ctx = link->dst;
+     YADIFContext *yadif = ctx->priv;
+-    if (yadif->skip) {
++    if (!yadif->out)
++        return;
++
++    if (yadif->auto_enable && !yadif->cur->video->interlaced) {
+         avfilter_draw_slice(ctx->outputs[0], 0, link->h, 1);
+         avfilter_end_frame(ctx->outputs[0]);
+         return;
+     }
+-    if (!yadif->out)
+-        return;
+-
+     return_frame(ctx, 0);
+ }
+@@ -277,7 +273,7 @@ static int request_frame(AVFilterLink *link)
+         if ((ret = avfilter_request_frame(link->src->inputs[0])))
+             return ret;
+-    } while (!yadif->out);
++    } while (!yadif->cur);
+     return 0;
+ }
+@@ -299,7 +295,7 @@ static int poll_frame(AVFilterLink *link)
+     }
+     assert(yadif->next);
+-    if (yadif->skip)
++    if (yadif->auto_enable && yadif->next && !yadif->next->video->interlaced)
+         return val;
+     return val * ((yadif->mode&1)+1);
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0067-changed-updated-dxva-zigzag-workaround-for-ATI-based.patch b/lib/ffmpeg/patches/0067-changed-updated-dxva-zigzag-workaround-for-ATI-based.patch
new file mode 100644 (file)
index 0000000..8854f7a
--- /dev/null
@@ -0,0 +1,92 @@
+From 321c5e668f2c213a33cef6c7c9fe11ee2850665f Mon Sep 17 00:00:00 2001
+From: elupus <elupus@xbmc.org>
+Date: Tue, 5 Jul 2011 00:14:52 +0200
+Subject: [PATCH] changed: updated dxva zigzag workaround for ATI based on
+ comments on xbmc.org and ffmpeg.org
+
+---
+ lib/ffmpeg/libavcodec/avcodec.h               |    1 -
+ lib/ffmpeg/libavcodec/dxva2.h                 |    2 ++
+ lib/ffmpeg/libavcodec/dxva2_h264.c            |   23 +++++++++++++----------
+ xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp |   14 +++-----------
+ 4 files changed, 18 insertions(+), 22 deletions(-)
+
+diff --git a/lib/ffmpeg/libavcodec/avcodec.h b/lib/ffmpeg/libavcodec/avcodec.h
+index cb96c6f..4745980 100644
+--- a/lib/ffmpeg/libavcodec/avcodec.h
++++ b/lib/ffmpeg/libavcodec/avcodec.h
+@@ -1429,7 +1429,6 @@ typedef struct AVCodecContext {
+ #define FF_BUG_DC_CLIP          4096
+ #define FF_BUG_MS               8192 ///< Work around various bugs in Microsoft's broken decoders.
+ #define FF_BUG_TRUNCATED       16384
+-#define FF_BUG_DXVA2_SCALING_LIST_ZIGZAG 32768 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards
+ //#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%.
+     /**
+diff --git a/lib/ffmpeg/libavcodec/dxva2.h b/lib/ffmpeg/libavcodec/dxva2.h
+index 5c5fe21..6eb494b 100644
+--- a/lib/ffmpeg/libavcodec/dxva2.h
++++ b/lib/ffmpeg/libavcodec/dxva2.h
+@@ -27,6 +27,8 @@
+ #include <dxva2api.h>
++#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards
++
+ /**
+  * This structure is used to provides the necessary configurations and data
+  * to the DXVA2 FFmpeg HWAccel implementation.
+diff --git a/lib/ffmpeg/libavcodec/dxva2_h264.c b/lib/ffmpeg/libavcodec/dxva2_h264.c
+index 7b81c8e..4e3370c 100644
+--- a/lib/ffmpeg/libavcodec/dxva2_h264.c
++++ b/lib/ffmpeg/libavcodec/dxva2_h264.c
+@@ -113,6 +113,9 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
+     pp->bit_depth_luma_minus8         = h->sps.bit_depth_luma - 8;
+     pp->bit_depth_chroma_minus8       = h->sps.bit_depth_chroma - 8;
++    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG)
++        pp->Reserved16Bits            = 0;
++    else
+     pp->Reserved16Bits                = 3; /* FIXME is there a way to detect the right mode ? */
+     pp->StatusReportFeedbackNumber    = 1 + ctx->report_id++;
+     pp->CurrFieldOrderCnt[0] = 0;
+@@ -150,18 +153,18 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
+     //pp->SliceGroupMap[810];               /* XXX not implemented by FFmpeg */
+ }
+-static void fill_scaling_lists(AVCodecContext *avctx, const H264Context *h, DXVA_Qmatrix_H264 *qm)
++static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm)
+ {
+     unsigned i, j;
+     memset(qm, 0, sizeof(*qm));
+-    if (avctx->workaround_bugs & FF_BUG_DXVA2_SCALING_LIST_ZIGZAG) {  // For old UVD/UVD+ ATI cards
+-    for (i = 0; i < 6; i++)
+-        for (j = 0; j < 16; j++)
+-            qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][j];
+-
+-    for (i = 0; i < 2; i++)
+-        for (j = 0; j < 64; j++)
+-            qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][j];
++    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) {
++        for (i = 0; i < 6; i++)
++            for (j = 0; j < 16; j++)
++                qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][j];
++
++        for (i = 0; i < 2; i++)
++            for (j = 0; j < 64; j++)
++                qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][j];
+     } else {
+     for (i = 0; i < 6; i++)
+         for (j = 0; j < 16; j++)
+@@ -380,7 +383,7 @@ static int start_frame(AVCodecContext *avctx,
+     fill_picture_parameters(ctx, h, &ctx_pic->pp);
+     /* Fill up DXVA_Qmatrix_H264 */
+-    fill_scaling_lists(avctx, h, &ctx_pic->qm);
++    fill_scaling_lists(ctx, h, &ctx_pic->qm);
+     ctx_pic->slice_count    = 0;
+     ctx_pic->bitstream_size = 0;
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0068-fixed-yadif-should-copy-frame-properties-of-second-f.patch b/lib/ffmpeg/patches/0068-fixed-yadif-should-copy-frame-properties-of-second-f.patch
new file mode 100644 (file)
index 0000000..a5b3a7c
--- /dev/null
@@ -0,0 +1,31 @@
+From 793f3e0bfcaadaccd0b5db2a37a60da42a6b207e Mon Sep 17 00:00:00 2001
+From: elupus <elupus@xbmc.org>
+Date: Thu, 14 Jul 2011 22:07:22 +0200
+Subject: [PATCH] fixed: yadif should copy frame properties of second frame as
+ well
+
+---
+ lib/ffmpeg/libavfilter/vf_yadif.c |    5 ++++-
+ 1 files changed, 4 insertions(+), 1 deletions(-)
+
+diff --git a/lib/ffmpeg/libavfilter/vf_yadif.c b/lib/ffmpeg/libavfilter/vf_yadif.c
+index d7bed90..da91600 100644
+--- a/lib/ffmpeg/libavfilter/vf_yadif.c
++++ b/lib/ffmpeg/libavfilter/vf_yadif.c
+@@ -182,9 +182,12 @@ static void return_frame(AVFilterContext *ctx, int is_second)
+         tff = yadif->parity^1;
+     }
+-    if (is_second)
++    if (is_second) {
+         yadif->out = avfilter_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE |
+                                                AV_PERM_REUSE, link->w, link->h);
++        avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);
++        yadif->out->video->interlaced = 0;
++    }
+     filter(ctx, yadif->out, tff ^ !is_second, tff);
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0069-ffmpeg-silence-compiler-warnings.patch b/lib/ffmpeg/patches/0069-ffmpeg-silence-compiler-warnings.patch
new file mode 100644 (file)
index 0000000..1ee77d7
--- /dev/null
@@ -0,0 +1,24 @@
+From 5542a0c7e68d123b86f168ace00f7320b294fc39 Mon Sep 17 00:00:00 2001
+From: davilla <davilla@4pi.com>
+Date: Wed, 7 Sep 2011 00:14:34 -0400
+Subject: [PATCH] [ffmpeg] silence compiler warnings
+
+---
+ lib/ffmpeg/libavfilter/avfilter.h |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/lib/ffmpeg/libavfilter/avfilter.h b/lib/ffmpeg/libavfilter/avfilter.h
+index ad8b1e5..daf43dc 100644
+--- a/lib/ffmpeg/libavfilter/avfilter.h
++++ b/lib/ffmpeg/libavfilter/avfilter.h
+@@ -159,6 +159,7 @@ static inline void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilt
+     switch (src->type) {
+     case AVMEDIA_TYPE_VIDEO: *dst->video = *src->video; break;
+     case AVMEDIA_TYPE_AUDIO: *dst->audio = *src->audio; break;
++    default: break;
+     }
+ }
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0070-matroskadec-use-correct-compression-parameters-for-c.patch b/lib/ffmpeg/patches/0070-matroskadec-use-correct-compression-parameters-for-c.patch
new file mode 100644 (file)
index 0000000..6042ffa
--- /dev/null
@@ -0,0 +1,33 @@
+From 8efe4d01dcd2f89ad012b8f1dd71192e09fa3e82 Mon Sep 17 00:00:00 2001
+From: CrystalP <CrystalP@xbmc.org>
+Date: Sun, 16 Oct 2011 03:16:26 -0400
+Subject: [PATCH] matroskadec: use correct compression parameters for current
+ track CodecPrivate
+
+backport of ffmpeg dc6c36ce46d4c4d7cb63503afc2ee44f00bf3725 on 2011-08-17
+
+fixes a bitmap sub color problem exposed by mkclean --optimize foo.mkv.
+The compressed private data could not be extracted, resulting in a bad color
+palette and wrong colors on screen.
+
+problem described in forum thread http://forum.xbmc.org/showthread.php?t=108942
+---
+ lib/ffmpeg/libavformat/matroskadec.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/lib/ffmpeg/libavformat/matroskadec.c b/lib/ffmpeg/libavformat/matroskadec.c
+index 1a87f4a..14b96d4 100644
+--- a/lib/ffmpeg/libavformat/matroskadec.c
++++ b/lib/ffmpeg/libavformat/matroskadec.c
+@@ -1220,7 +1220,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
+     for (i=0; i < matroska->tracks.nb_elem; i++) {
+         MatroskaTrack *track = &tracks[i];
+         enum CodecID codec_id = CODEC_ID_NONE;
+-        EbmlList *encodings_list = &tracks->encodings;
++        EbmlList *encodings_list = &track->encodings;
+         MatroskaTrackEncoding *encodings = encodings_list->elem;
+         uint8_t *extradata = NULL;
+         int extradata_size = 0;
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0071-fixed-Typo.patch b/lib/ffmpeg/patches/0071-fixed-Typo.patch
new file mode 100644 (file)
index 0000000..dcb5eda
--- /dev/null
@@ -0,0 +1,25 @@
+From dc0509f7a6341a72ca4399fee37e30c91fddc222 Mon Sep 17 00:00:00 2001
+From: arnova <nospam@void.org>
+Date: Tue, 8 Nov 2011 08:35:59 +0100
+Subject: [PATCH] fixed: Typo
+
+---
+ lib/ffmpeg/libavformat/mmsh.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/lib/ffmpeg/libavformat/mmsh.c b/lib/ffmpeg/libavformat/mmsh.c
+index 3ae886f..cc6efa3 100644
+--- a/lib/ffmpeg/libavformat/mmsh.c
++++ b/lib/ffmpeg/libavformat/mmsh.c
+@@ -284,7 +284,7 @@ static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int tim
+                    CLIENTGUID
+                    "Pragma: stream-switch-count=%d\r\n"
+                    "Pragma: stream-switch-entry=%s\r\n"
+-                   "Pragma: no-cache,rate)1.000000,stream-time=%u"
++                   "Pragma: no-cache,rate=1.000000,stream-time=%u"
+                    "Connection: Close\r\n\r\n",
+                    host, port, mmsh->request_seq++, mms->stream_num, stream_selection, timestamp);
+     av_freep(&stream_selection);
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0072-h264-Use-mismatching-frame-numbers-in-fields-to-sync.patch b/lib/ffmpeg/patches/0072-h264-Use-mismatching-frame-numbers-in-fields-to-sync.patch
new file mode 100644 (file)
index 0000000..a05dfff
--- /dev/null
@@ -0,0 +1,33 @@
+From 2ac62404c2f833d5aa64947819538ac354966ef0 Mon Sep 17 00:00:00 2001
+From: Michael Niedermayer <michaelni@gmx.at>
+Date: Sat, 12 Nov 2011 21:10:15 +0100
+Subject: [PATCH] h264: Use mismatching frame numbers in fields to synchronize
+ the first/second field state independant of them being
+ reference or not. Fixes Ticket354
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ lib/ffmpeg/libavcodec/h264.c |    6 ++----
+ 1 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/lib/ffmpeg/libavcodec/h264.c b/lib/ffmpeg/libavcodec/h264.c
+index 47b0073..87ec292 100644
+--- a/lib/ffmpeg/libavcodec/h264.c
++++ b/lib/ffmpeg/libavcodec/h264.c
+@@ -1936,11 +1936,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
+                 s0->first_field = FIELD_PICTURE;
+             } else {
+-                if (h->nal_ref_idc &&
+-                        s0->current_picture_ptr->reference &&
+-                        s0->current_picture_ptr->frame_num != h->frame_num) {
++                if (s0->current_picture_ptr->frame_num != h->frame_num) {
+                     /*
+-                     * This and previous field were reference, but had
++                     * This and previous field had
+                      * different frame_nums. Consider this field first in
+                      * pair. Throw away previous field except for reference
+                      * purposes.
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0073-Don-t-fill-in-frame-gaps-with-copied-refs-after-flus.patch b/lib/ffmpeg/patches/0073-Don-t-fill-in-frame-gaps-with-copied-refs-after-flus.patch
new file mode 100644 (file)
index 0000000..d919336
--- /dev/null
@@ -0,0 +1,36 @@
+From 46d99a89aa16db1981441bf7103a30e7d28e5e26 Mon Sep 17 00:00:00 2001
+From: Joakim Plate <elupus@ecce.se>
+Date: Fri, 18 Nov 2011 20:36:13 +0100
+Subject: [PATCH] Don't fill in frame gaps with copied refs after flush
+
+The filled in refs cause corruptions in the video frame
+for a long time after it should have recovered.
+---
+ lib/ffmpeg/libavcodec/h264.c |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/ffmpeg/libavcodec/h264.c b/lib/ffmpeg/libavcodec/h264.c
+index 87ec292..0e002ce 100644
+--- a/lib/ffmpeg/libavcodec/h264.c
++++ b/lib/ffmpeg/libavcodec/h264.c
+@@ -1464,7 +1464,7 @@ static void implicit_weight_table(H264Context *h, int field){
+  */
+ static void idr(H264Context *h){
+     ff_h264_remove_all_refs(h);
+-    h->prev_frame_num= 0;
++    h->prev_frame_num= -1;
+     h->prev_frame_num_offset= 0;
+     h->prev_poc_msb=
+     h->prev_poc_lsb= 0;
+@@ -1892,7 +1892,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
+     h->mb_field_decoding_flag= s->picture_structure != PICT_FRAME;
+     if(h0->current_slice == 0){
+-        while(h->frame_num !=  h->prev_frame_num &&
++        while(h->frame_num !=  h->prev_frame_num && h->prev_frame_num >= 0 &&
+               h->frame_num != (h->prev_frame_num+1)%(1<<h->sps.log2_max_frame_num)){
+             Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
+             av_log(h->s.avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n", h->frame_num, h->prev_frame_num);
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0074-vaapi-do-not-assert-on-value-read-from-input-bitstre.patch b/lib/ffmpeg/patches/0074-vaapi-do-not-assert-on-value-read-from-input-bitstre.patch
new file mode 100644 (file)
index 0000000..d7b2285
--- /dev/null
@@ -0,0 +1,41 @@
+From 425b9a373384813d2fe513d42b1d585ecbea6ca5 Mon Sep 17 00:00:00 2001
+From: Diego Biurrun <diego@biurrun.de>
+Date: Fri, 15 Jul 2011 01:06:16 +0200
+Subject: [PATCH] vaapi: do not assert on value read from input bitstream
+
+User-provided data should never trigger an assert; return error instead.
+Also fix an instance of get_bits where get_bits_long should have been used.
+
+This eliminates the following warning:
+libavcodec/vaapi_mpeg2.c:112:14: warning: variable 'start_code' set but not used
+
+Signed-off-by: elupus <elupus@xbmc.org>
+---
+ lib/ffmpeg/libavcodec/vaapi_mpeg2.c |    6 +++---
+ 1 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/lib/ffmpeg/libavcodec/vaapi_mpeg2.c b/lib/ffmpeg/libavcodec/vaapi_mpeg2.c
+index 17d82b7..8d456ba 100644
+--- a/lib/ffmpeg/libavcodec/vaapi_mpeg2.c
++++ b/lib/ffmpeg/libavcodec/vaapi_mpeg2.c
+@@ -109,14 +109,14 @@ static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer
+     MpegEncContext * const s = avctx->priv_data;
+     VASliceParameterBufferMPEG2 *slice_param;
+     GetBitContext gb;
+-    uint32_t start_code, quantiser_scale_code, intra_slice_flag, macroblock_offset;
++    uint32_t quantiser_scale_code, intra_slice_flag, macroblock_offset;
+     av_dlog(avctx, "vaapi_mpeg2_decode_slice(): buffer %p, size %d\n", buffer, size);
+     /* Determine macroblock_offset */
+     init_get_bits(&gb, buffer, 8 * size);
+-    start_code = get_bits(&gb, 32);
+-    assert((start_code & 0xffffff00) == 0x00000100);
++    if (get_bits_long(&gb, 32) >> 8 != 1) /* start code */
++        return AVERROR_INVALIDDATA;
+     quantiser_scale_code = get_bits(&gb, 5);
+     intra_slice_flag = get_bits1(&gb);
+     if (intra_slice_flag) {
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0075-fixed-playback-from-mmst-urls-would-halt-after-some-.patch b/lib/ffmpeg/patches/0075-fixed-playback-from-mmst-urls-would-halt-after-some-.patch
new file mode 100644 (file)
index 0000000..cd5412b
--- /dev/null
@@ -0,0 +1,30 @@
+From 919a875b4bc4ea2a8ddc0aab98ea74c6475f9525 Mon Sep 17 00:00:00 2001
+From: spiff <spiff@xbmc.org>
+Date: Tue, 17 Jan 2012 22:47:36 +0100
+Subject: [PATCH] fixed: playback from mmst:// urls would halt after some
+ time.
+
+this backports upstream 275189a2bd71cf49d66374c44d3de2262d323460
+
+thanks to johoja for doing the ground work
+---
+ lib/ffmpeg/libavformat/mmst.c |    3 +--
+ 1 files changed, 1 insertions(+), 2 deletions(-)
+
+diff --git a/lib/ffmpeg/libavformat/mmst.c b/lib/ffmpeg/libavformat/mmst.c
+index 8464d3b..385f017 100644
+--- a/lib/ffmpeg/libavformat/mmst.c
++++ b/lib/ffmpeg/libavformat/mmst.c
+@@ -290,8 +290,7 @@ static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
+                 return read_result < 0 ? read_result : AVERROR_IO;
+             }
+             packet_type= AV_RL16(mms->in_buffer+36);
+-            hr = AV_RL32(mms->in_buffer + 40);
+-            if (hr) {
++            if (read_result >= 44 && (hr = AV_RL32(mms->in_buffer + 40))) {
+                 av_log(NULL, AV_LOG_ERROR,
+                        "Server sent an error status code: 0x%08x\n", hr);
+                 return AVERROR_UNKNOWN;
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0076-Fix-dvb-subtitle-decoding-when-display-segment-is-mi.patch b/lib/ffmpeg/patches/0076-Fix-dvb-subtitle-decoding-when-display-segment-is-mi.patch
new file mode 100644 (file)
index 0000000..dbeca1a
--- /dev/null
@@ -0,0 +1,63 @@
+From 6373f33e5b12eb06e37d670c9bba4e7041cded79 Mon Sep 17 00:00:00 2001
+From: Paul Kendall <paul@kcbbs.gen.nz>
+Date: Sun, 29 Jan 2012 14:50:19 +0100
+Subject: [PATCH] Fix dvb subtitle decoding when display segment is missing.
+
+closes ticket #8504
+---
+ lib/ffmpeg/libavcodec/dvbsubdec.c |   10 ++++++++++
+ 1 files changed, 10 insertions(+), 0 deletions(-)
+
+diff --git a/lib/ffmpeg/libavcodec/dvbsubdec.c b/lib/ffmpeg/libavcodec/dvbsubdec.c
+index 7c37915..e8ef8ce 100644
+--- a/lib/ffmpeg/libavcodec/dvbsubdec.c
++++ b/lib/ffmpeg/libavcodec/dvbsubdec.c
+@@ -1409,6 +1409,7 @@ static int dvbsub_decode(AVCodecContext *avctx,
+     int segment_type;
+     int page_id;
+     int segment_length;
++    int got_segment = 0;
+ #ifdef DEBUG_PACKET_CONTENTS
+     int i;
+@@ -1445,21 +1446,26 @@ static int dvbsub_decode(AVCodecContext *avctx,
+             switch (segment_type) {
+             case DVBSUB_PAGE_SEGMENT:
+                 dvbsub_parse_page_segment(avctx, p, segment_length);
++                got_segment |= 1;
+                 break;
+             case DVBSUB_REGION_SEGMENT:
+                 dvbsub_parse_region_segment(avctx, p, segment_length);
++                got_segment |= 2;
+                 break;
+             case DVBSUB_CLUT_SEGMENT:
+                 dvbsub_parse_clut_segment(avctx, p, segment_length);
++                got_segment |= 4;
+                 break;
+             case DVBSUB_OBJECT_SEGMENT:
+                 dvbsub_parse_object_segment(avctx, p, segment_length);
++                got_segment |= 8;
+                 break;
+             case DVBSUB_DISPLAYDEFINITION_SEGMENT:
+                 dvbsub_parse_display_definition_segment(avctx, p, segment_length);
+                 break;
+             case DVBSUB_DISPLAY_SEGMENT:
+                 *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub);
++                got_segment |= 16;
+                 break;
+             default:
+                 av_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
+@@ -1470,6 +1476,10 @@ static int dvbsub_decode(AVCodecContext *avctx,
+         p += segment_length;
+     }
++    // Some streams do not send a display segment but if we have all the other
++    // segments then we need no further data.
++    if (got_segment == 15 && sub)
++        *data_size = dvbsub_display_end_segment(avctx, p, 0, sub);
+     if (p != p_end) {
+         av_dlog(avctx, "Junk at end of packet\n");
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0077-Change-yadif-to-not-use-out-of-picture-lines.-Fixes-.patch b/lib/ffmpeg/patches/0077-Change-yadif-to-not-use-out-of-picture-lines.-Fixes-.patch
new file mode 100644 (file)
index 0000000..d7d4ec9
--- /dev/null
@@ -0,0 +1,133 @@
+From 42bedafe92b2921ec63024a825d4297ba39888e9 Mon Sep 17 00:00:00 2001
+From: Michael Niedermayer <michaelni@gmx.at>
+Date: Fri, 18 Feb 2011 19:10:33 +0100
+Subject: [PATCH] Change yadif to not use out of picture lines. Fixes
+ issue2272.
+
+Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
+---
+ lib/ffmpeg/libavfilter/vf_yadif.c           |   31 ++++++++++++++-------------
+ lib/ffmpeg/libavfilter/x86/yadif_template.c |    6 ++--
+ lib/ffmpeg/libavfilter/yadif.h              |    6 ++--
+ 3 files changed, 22 insertions(+), 21 deletions(-)
+
+diff --git a/lib/ffmpeg/libavfilter/vf_yadif.c b/lib/ffmpeg/libavfilter/vf_yadif.c
+index da91600..1ed8807 100644
+--- a/lib/ffmpeg/libavfilter/vf_yadif.c
++++ b/lib/ffmpeg/libavfilter/vf_yadif.c
+@@ -56,42 +56,42 @@ typedef struct {
+     AVFilterBufferRef *out;
+     void (*filter_line)(uint8_t *dst,
+                         uint8_t *prev, uint8_t *cur, uint8_t *next,
+-                        int w, int refs, int parity, int mode);
++                        int w, int prefs, int mrefs, int parity, int mode);
+ } YADIFContext;
+ static void filter_line_c(uint8_t *dst,
+                           uint8_t *prev, uint8_t *cur, uint8_t *next,
+-                          int w, int refs, int parity, int mode)
++                          int w, int prefs, int mrefs, int parity, int mode)
+ {
+     int x;
+     uint8_t *prev2 = parity ? prev : cur ;
+     uint8_t *next2 = parity ? cur  : next;
+     for (x = 0;  x < w; x++) {
+-        int c = cur[-refs];
++        int c = cur[mrefs];
+         int d = (prev2[0] + next2[0])>>1;
+-        int e = cur[+refs];
++        int e = cur[prefs];
+         int temporal_diff0 = FFABS(prev2[0] - next2[0]);
+-        int temporal_diff1 =(FFABS(prev[-refs] - c) + FFABS(prev[+refs] - e) )>>1;
+-        int temporal_diff2 =(FFABS(next[-refs] - c) + FFABS(next[+refs] - e) )>>1;
++        int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e) )>>1;
++        int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1;
+         int diff = FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
+         int spatial_pred = (c+e)>>1;
+-        int spatial_score = FFABS(cur[-refs-1] - cur[+refs-1]) + FFABS(c-e)
+-                          + FFABS(cur[-refs+1] - cur[+refs+1]) - 1;
++        int spatial_score = FFABS(cur[mrefs-1] - cur[prefs-1]) + FFABS(c-e)
++                          + FFABS(cur[mrefs+1] - cur[prefs+1]) - 1;
+ #define CHECK(j)\
+-    {   int score = FFABS(cur[-refs-1+j] - cur[+refs-1-j])\
+-                  + FFABS(cur[-refs  +j] - cur[+refs  -j])\
+-                  + FFABS(cur[-refs+1+j] - cur[+refs+1-j]);\
++    {   int score = FFABS(cur[mrefs-1+j] - cur[prefs-1-j])\
++                  + FFABS(cur[mrefs  +j] - cur[prefs  -j])\
++                  + FFABS(cur[mrefs+1+j] - cur[prefs+1-j]);\
+         if (score < spatial_score) {\
+             spatial_score= score;\
+-            spatial_pred= (cur[-refs  +j] + cur[+refs  -j])>>1;\
++            spatial_pred= (cur[mrefs  +j] + cur[prefs  -j])>>1;\
+         CHECK(-1) CHECK(-2) }} }}
+         CHECK( 1) CHECK( 2) }} }}
+         if (mode < 2) {
+-            int b = (prev2[-2*refs] + next2[-2*refs])>>1;
+-            int f = (prev2[+2*refs] + next2[+2*refs])>>1;
++            int b = (prev2[2*mrefs] + next2[2*mrefs])>>1;
++            int f = (prev2[2*prefs] + next2[2*prefs])>>1;
+ #if 0
+             int a = cur[-3*refs];
+             int g = cur[+3*refs];
+@@ -139,7 +139,8 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic,
+                 uint8_t *cur  = &yadif->cur ->data[i][y*refs];
+                 uint8_t *next = &yadif->next->data[i][y*refs];
+                 uint8_t *dst  = &dstpic->data[i][y*dstpic->linesize[i]];
+-                yadif->filter_line(dst, prev, cur, next, w, refs, parity ^ tff, yadif->mode);
++                int     mode  = y==1 || y+2==h ? 2 : yadif->mode;
++                yadif->filter_line(dst, prev, cur, next, w, y+1<h ? refs : -refs, y ? -refs : refs, parity ^ tff, mode);
+             } else {
+                 memcpy(&dstpic->data[i][y*dstpic->linesize[i]],
+                        &yadif->cur->data[i][y*refs], w);
+diff --git a/lib/ffmpeg/libavfilter/x86/yadif_template.c b/lib/ffmpeg/libavfilter/x86/yadif_template.c
+index 3e520cb..50ea843 100644
+--- a/lib/ffmpeg/libavfilter/x86/yadif_template.c
++++ b/lib/ffmpeg/libavfilter/x86/yadif_template.c
+@@ -105,7 +105,7 @@
+ void RENAME(ff_yadif_filter_line)(uint8_t *dst,
+                                   uint8_t *prev, uint8_t *cur, uint8_t *next,
+-                                  int w, int refs, int parity, int mode)
++                                  int w, int prefs, int mrefs, int parity, int mode)
+ {
+     DECLARE_ALIGNED(16, uint8_t, tmp0[16]);
+     DECLARE_ALIGNED(16, uint8_t, tmp1[16]);
+@@ -226,8 +226,8 @@ void RENAME(ff_yadif_filter_line)(uint8_t *dst,
+             :[prev] "r"(prev),\
+              [cur]  "r"(cur),\
+              [next] "r"(next),\
+-             [prefs]"r"((x86_reg)refs),\
+-             [mrefs]"r"((x86_reg)-refs),\
++             [prefs]"r"((x86_reg)prefs),\
++             [mrefs]"r"((x86_reg)mrefs),\
+              [mode] "g"(mode)\
+         );\
+         __asm__ volatile(MOV" "MM"1, %0" :"=m"(*dst));\
+diff --git a/lib/ffmpeg/libavfilter/yadif.h b/lib/ffmpeg/libavfilter/yadif.h
+index 072812c..ff574da 100644
+--- a/lib/ffmpeg/libavfilter/yadif.h
++++ b/lib/ffmpeg/libavfilter/yadif.h
+@@ -23,14 +23,14 @@
+ void ff_yadif_filter_line_mmx(uint8_t *dst,
+                               uint8_t *prev, uint8_t *cur, uint8_t *next,
+-                              int w, int refs, int parity, int mode);
++                              int w, int prefs, int mrefs, int parity, int mode);
+ void ff_yadif_filter_line_sse2(uint8_t *dst,
+                                uint8_t *prev, uint8_t *cur, uint8_t *next,
+-                               int w, int refs, int parity, int mode);
++                               int w, int prefs, int mrefs, int parity, int mode);
+ void ff_yadif_filter_line_ssse3(uint8_t *dst,
+                                 uint8_t *prev, uint8_t *cur, uint8_t *next,
+-                                int w, int refs, int parity, int mode);
++                                int w, int prefs, int mrefs, int parity, int mode);
+ #endif /* AVFILTER_YADIF_H */
+-- 
+1.7.7.2
+
diff --git a/lib/ffmpeg/patches/0078-fixed-ffmpeg-build-with-gcc-4.7-on-x86.patch b/lib/ffmpeg/patches/0078-fixed-ffmpeg-build-with-gcc-4.7-on-x86.patch
new file mode 100644 (file)
index 0000000..6fe3958
--- /dev/null
@@ -0,0 +1,68 @@
+From 400b84bb8d3d2a9c202fa3da4fb01279230a87ce Mon Sep 17 00:00:00 2001
+From: Anssi Hannula <anssi@xbmc.org>
+Date: Wed, 7 Mar 2012 23:08:54 +0200
+Subject: [PATCH] fixed: ffmpeg build with gcc 4.7 on x86
+
+Backport da4c7cce2100a4e4f9276b4f17e260be47b53f41 from FFmpeg git:
+
+> From: Mans Rullgard <mans@mansr.com>
+> Date: Tue, 26 Jul 2011 11:23:43 +0000 (+0100)
+>
+> x86: fix build with gcc 4.7
+>
+> The upcoming gcc 4.7 has more advanced constant propagation
+> resulting some inline asm operands becoming constants and thus
+> emitted as literals, sometimes in contexts where this results
+> in invalid instructions.
+>
+> This patch changes the constraints of the relevant operands
+> to "rm" thus forcing a valid type.  While obviously suboptimal,
+> this is what older gcc versions already did, and there is no
+> change to the code generated with these.
+---
+ lib/ffmpeg/libavcodec/x86/h264_qpel_mmx.c |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/lib/ffmpeg/libavcodec/x86/h264_qpel_mmx.c b/lib/ffmpeg/libavcodec/x86/h264_qpel_mmx.c
+index d8ceca1..f5af44e 100644
+--- a/lib/ffmpeg/libavcodec/x86/h264_qpel_mmx.c
++++ b/lib/ffmpeg/libavcodec/x86/h264_qpel_mmx.c
+@@ -398,7 +398,7 @@ static av_noinline void OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst,
+             "2:                         \n\t"\
+             \
+             : "+a"(src), "+c"(dst)\
+-            : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "g"(h)\
++            : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "rm"(h)\
+             : "memory"\
+         );\
+         src += 4-(h+5)*srcStride;\
+@@ -446,7 +446,7 @@ static av_always_inline void OPNAME ## h264_qpel8or16_hv1_lowpass_ ## MMX(int16_
+             QPEL_H264HV(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, 15*48)\
+             "2:                     \n\t"\
+             : "+a"(src)\
+-            : "c"(tmp), "S"((x86_reg)srcStride), "g"(size)\
++            : "c"(tmp), "S"((x86_reg)srcStride), "rm"(size)\
+             : "memory"\
+             );\
+         tmp += 4;\
+@@ -823,7 +823,7 @@ static av_noinline void OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst,
+         "2:                          \n\t"\
+         \
+         : "+a"(src), "+c"(dst)\
+-        : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "g"(h)\
++        : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "rm"(h)\
+         : XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3", \
+                        "%xmm4", "%xmm5", "%xmm6", "%xmm7",)\
+           "memory"\
+@@ -878,7 +878,7 @@ static av_always_inline void put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp, u
+             QPEL_H264HV_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, 15*48)
+             "2:                         \n\t"
+             : "+a"(src)
+-            : "c"(tmp), "S"((x86_reg)srcStride), "g"(size)
++            : "c"(tmp), "S"((x86_reg)srcStride), "rm"(size)
+             : XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3",
+                            "%xmm4", "%xmm5", "%xmm6", "%xmm7",)
+               "memory"
+-- 
+1.7.7.2
+
index 66cbef8..de56f9f 100644 (file)
@@ -240,8 +240,43 @@ PLT_Service::SetSCPDXML(const char* scpd)
                 PLT_XmlHelper::GetChildText(allowedValueRange, "maximum", max);
                 PLT_XmlHelper::GetChildText(allowedValueRange, "step", step);
 
-                if (min.GetLength() == 0 || max.GetLength() == 0) {
-                    NPT_CHECK_LABEL_SEVERE(NPT_ERROR_INVALID_SYNTAX, failure);
+                // these are required but try to be nice
+                // in case bad devices provide nothing
+                if (min.GetLength() == 0) {
+                    if (variable->m_DataType == "ui1" ||
+                        variable->m_DataType == "ui2" ||
+                        variable->m_DataType == "ui4") {
+                        min = NPT_String::FromInteger(0);
+                    } else if (variable->m_DataType == "i1") {
+                        min = NPT_String::FromInteger(-128);
+                    } else if (variable->m_DataType == "i2") {
+                        min = NPT_String::FromInteger(-32768);
+                    } else if (variable->m_DataType == "i4" ||
+                               variable->m_DataType == "int") {
+                        min = NPT_String::FromInteger(-2147483647 - 1);
+                    } else {
+                        NPT_LOG_SEVERE_1("Invalid variable data type %s", variable->m_DataType.GetChars());
+                        NPT_CHECK_LABEL_SEVERE(NPT_ERROR_INVALID_SYNTAX, failure);
+                    }
+                }
+                if (max.GetLength() == 0) {
+                    if (variable->m_DataType == "ui1") {
+                        max = NPT_String::FromInteger(0xff);
+                    } else if (variable->m_DataType == "ui2") {
+                        max = NPT_String::FromInteger(0xffff);
+                    } else if (variable->m_DataType == "ui4") {
+                        max = NPT_String::FromInteger(0xffffffff);
+                    } else if (variable->m_DataType == "i1") {
+                        max = NPT_String::FromInteger(0x7f);
+                    } else if (variable->m_DataType == "i2") {
+                        max = NPT_String::FromInteger(0x7fff);
+                    } else if (variable->m_DataType == "i4" ||
+                               variable->m_DataType == "int") {
+                        max = NPT_String::FromInteger(0x7fffffff);
+                    } else {
+                        NPT_LOG_SEVERE_1("Invalid variable data type %s", variable->m_DataType.GetChars());
+                        NPT_CHECK_LABEL_SEVERE(NPT_ERROR_INVALID_SYNTAX, failure);
+                    }
                 }
 
                 variable->m_AllowedValueRange = new NPT_AllowedValueRange;
@@ -706,7 +741,7 @@ PLT_Service::UpdateLastChange(NPT_List<PLT_StateVariable*>& vars)
         return NPT_SUCCESS;
     }
 
-    NPT_XmlElementNode* top = new NPT_XmlElementNode("Event");
+    NPT_Reference<NPT_XmlElementNode> top(new NPT_XmlElementNode("Event"));
     NPT_CHECK_SEVERE(top->SetNamespaceUri("", m_LastChangeNamespace));
 
     NPT_XmlElementNode* instance = new NPT_XmlElementNode("InstanceID");
@@ -719,7 +754,6 @@ PLT_Service::UpdateLastChange(NPT_List<PLT_StateVariable*>& vars)
     // serialize node
     NPT_String value;
     NPT_CHECK_SEVERE(PLT_XmlHelper::Serialize(*top, value, false));
-    delete top;
 
     // set the state change direcly instead of calling SetValue
     // to avoid recursive lock, instead add var to publish here directly
index 52089c7..7758427 100644 (file)
@@ -51,9 +51,7 @@ is_id3v1 (ape_file * fp)
 {
     int n=0;
     char buf[16];
-    size_t savedFilePosition;
     
-    savedFilePosition = ape_ftell(fp);
     ape_fseek (fp, 0, SEEK_END);
     do {
         n++;
@@ -63,8 +61,7 @@ is_id3v1 (ape_file * fp)
         if (memcmp (buf, "APETAGEX",8) == 0) /*APE.TAG.EX*/
         break;
     } while (memcmp (buf+3, "TAG", 3) == 0);
-    
-    ape_fseek (fp, savedFilePosition, SEEK_SET);
+
     return (n-1)*128;
 }
 
@@ -83,7 +80,6 @@ is_id3v2 (ape_file * fp)
     size_t savedFilePosition;
     long id3v2size=0;
         
-    savedFilePosition = ape_ftell (fp);
     ape_fseek (fp, 0, SEEK_SET);
     do {    
         memset (buf, 0, sizeof (buf));
@@ -97,7 +93,6 @@ is_id3v2 (ape_file * fp)
         ((long) (buf[7]) << 14) | ((long) (buf[6]) << 21));
     } while(memcmp (buf, "ID3", 3) == 0);
     
-    ape_fseek (fp, savedFilePosition, SEEK_SET);
     return (int) id3v2size;
 }
 
@@ -112,19 +107,14 @@ int
 is_ape_ver (ape_file * fp)
 {
     char unsigned buf[32];
-    size_t savedFilePosition;
-        
-    savedFilePosition = ape_ftell (fp);
     memset (buf, 0, sizeof (buf));
         
     ape_fseek (fp, (is_id3v1 (fp) ? -32 - 128 : -32), SEEK_END);
     ape_fread (&buf, 1, sizeof (buf), fp);
     if (memcmp (buf, "APETAGEX", 8) != 0) {
-        ape_fseek (fp, savedFilePosition, SEEK_SET);
         return 0;
     }
         
-    ape_fseek (fp, savedFilePosition, SEEK_SET);
     return (int) is_tag_ape2long (buf + 8);
 }
 
@@ -140,19 +130,14 @@ int
 is_ape (ape_file * fp)
 {
     char unsigned buf[32];
-    size_t savedFilePosition;
-        
-    savedFilePosition = ape_ftell(fp);
     memset (buf, 0, sizeof (buf));
         
     ape_fseek (fp, (is_id3v1 (fp) ? -32 - 128 : -32), SEEK_END);
     ape_fread (&buf, 1, sizeof (buf), fp);
     if (memcmp (buf, "APETAGEX", 8) != 0) {
-        ape_fseek (fp, savedFilePosition, SEEK_SET);
         return 0;
     }
         
-    ape_fseek (fp, savedFilePosition, SEEK_SET);
     /* WARNING! macabra code */
     return (int) (is_tag_ape2long (buf + 8 + 4) +
         ( 
index a1c05e1..ef31e60 100644 (file)
@@ -1,7 +1,22 @@
-libass (0.9.13)
- * Fix critical problem with the outline preprocessor, fixes crash with
-   FreeType 2.4.6
- * Various small bugfixes, merged from master
+libass (0.10.0)
+ * Bidirectional layout and Arabic shaping via FriBidi (GC #13)
+ * OpenType shaping via HarfBuzz-ng (GC #13)
+ * Add API for shaper configuration
+ * Add support for `Language' Script Info property, this can be used for
+   hinting the text language
+ * Vertical layout improvements
+   * Use `vert' and `vkna' OpenType features for vertical glyph variants
+   * Position rotated glyphs onto baseline
+ * Parse font encoding property for base text direction hinting
+ * Refactor cache system
+ * Use generic outlines in place of FreeType glyphs
+ * Direct outline bitmap rendering
+ * Fix whitespace trimming (GC #35)
+ * Do not render border if there's no shadow or glyph (GC #29)
+ * Adjust spacing after a italic to non-italic style change (GC #37)
+ * Fix fade timing
+ * Fix x positioning with borders (GC #27)
+ * Build system tweaks
 
 libass (0.9.12)
  * Switch to permissive (ISC) license
index 7f5bfa4..35548c6 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT(libass, 0.9.13)
+AC_INIT(libass, 0.10.0)
 AM_INIT_AUTOMAKE
 AC_CONFIG_MACRO_DIR([m4])
 # Disable C++/Fortran checks
@@ -40,6 +40,8 @@ AC_ARG_ENABLE([enca], AS_HELP_STRING([--disable-enca],
     [disable enca (charset autodetect) support @<:@default=check@:>@]))
 AC_ARG_ENABLE([fontconfig], AS_HELP_STRING([--disable-fontconfig],
     [disable fontconfig support @<:@default=enabled@:>@]))
+AC_ARG_ENABLE([harfbuzz], AS_HELP_STRING([--disable-harfbuzz],
+    [disable HarfBuzz support @<:@default=check@:>@]))
 
 PKG_CHECK_MODULES([FREETYPE], freetype2 >= 9.10.3, [
     CFLAGS="$CFLAGS $FREETYPE_CFLAGS"
@@ -47,6 +49,12 @@ PKG_CHECK_MODULES([FREETYPE], freetype2 >= 9.10.3, [
     AC_DEFINE(CONFIG_FREETYPE, 1, [found freetype2 via pkg-config])
     ])
 
+PKG_CHECK_MODULES([FRIBIDI], fribidi >= 0.19.0, [
+    CFLAGS="$CFLAGS $FRIBIDI_CFLAGS"
+    LIBS="$LIBS $FRIBIDI_LIBS"
+    AC_DEFINE(CONFIG_FRIBIDI, 1, [found fribidi via pkg-config])
+    ])
+
 if test x$enable_fontconfig != xno; then
 PKG_CHECK_MODULES([FONTCONFIG], fontconfig >= 2.4.2, [
     CFLAGS="$CFLAGS $FONTCONFIG_CFLAGS"
@@ -56,6 +64,15 @@ PKG_CHECK_MODULES([FONTCONFIG], fontconfig >= 2.4.2, [
     ])
 fi
 
+if test x$enable_harfbuzz != xno; then
+PKG_CHECK_MODULES([HARFBUZZ], harfbuzz >= 0.7.0, [
+    CFLAGS="$CFLAGS $HARFBUZZ_CFLAGS"
+    LIBS="$LIBS $HARFBUZZ_LIBS"
+    AC_DEFINE(CONFIG_HARFBUZZ, 1, [found harfbuzz-ng via pkg-config])
+       harfbuzz=true
+    ], [harfbuzz=false])
+fi
+
 if test x$enable_enca != xno; then
 PKG_CHECK_MODULES([ENCA], enca, [
     CFLAGS="$CFLAGS $ENCA_CFLAGS"
@@ -69,22 +86,30 @@ libpng=false
 if test x$enable_test = xyes; then
 PKG_CHECK_MODULES([LIBPNG], libpng >= 1.2.0, [
     CFLAGS="$CFLAGS $LIBPNG_CFLAGS"
-    LIBS="$LIBS $LIBPNG_LIBS"
     AC_DEFINE(CONFIG_LIBPNG, 1, [found libpng via pkg-config])
     libpng=true])
 fi
 
 AM_CONDITIONAL([HAVE_LIBPNG], [test x$libpng = xtrue])
 
-# Add dependent libraries to pkg-config for static linking
-PKG_REQUIRES="freetype2 >= 9.6.3"
+# add libraries/packages to pkg-config for static linking
+pkg_libs="-lm"
+pkg_requires="freetype2 >= 9.6.3"
+pkg_requires="fribidi >= 0.19.0, ${pkg_requires}"
 if test x$enca = xtrue; then
-    PKG_REQUIRES="enca, ${PKG_REQUIRES}"
+    pkg_requires="enca, ${pkg_requires}"
 fi
 if test x$fontconfig = xtrue; then
-    PKG_REQUIRES="fontconfig >= 2.2.0, ${PKG_REQUIRES}"
+    pkg_requires="fontconfig >= 2.2.0, ${pkg_requires}"
+fi
+if test x$harfbuzz = xtrue; then
+    pkg_requires="harfbuzz >= 0.7.0, ${pkg_requires}"
 fi
-AC_SUBST([PKG_REQUIRES])
+
+AC_SUBST([PKG_LIBS_DEFAULT], [$(test x$enable_shared = xno && echo ${pkg_libs})])
+AC_SUBST([PKG_REQUIRES_DEFAULT], [$(test x$enable_shared = xno && echo ${pkg_requires})])
+AC_SUBST([PKG_LIBS_PRIVATE], [$(test x$enable_shared = xno || echo ${pkg_libs})])
+AC_SUBST([PKG_REQUIRES_PRIVATE], [$(test x$enable_shared = xno || echo ${pkg_requires})])
 
 # Setup output beautifier.
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
index 137aac9..e087835 100644 (file)
@@ -6,7 +6,8 @@ includedir=@includedir@
 Name: libass
 Description: LibASS is an SSA/ASS subtitles rendering library
 Version: @PACKAGE_VERSION@
-Requires.private: @PKG_REQUIRES@
-Libs: -L${libdir} -lass
-Libs.private: -lm
+Requires: @PKG_REQUIRES_DEFAULT@
+Requires.private: @PKG_REQUIRES_PRIVATE@
+Libs: -L${libdir} -lass @PKG_LIBS_DEFAULT@
+Libs.private: @PKG_LIBS_PRIVATE@
 Cflags: -I${includedir}
index 375f8e6..142de68 100644 (file)
@@ -10,7 +10,8 @@ libass_la_SOURCES = ass.c ass_cache.c ass_font.c ass_fontconfig.c ass_render.c \
                     ass_cache.h ass_fontconfig.h ass_font.h ass.h \
                     ass_library.h ass_types.h ass_utils.h ass_drawing.c \
                     ass_drawing.h ass_cache_template.h ass_render.h \
-                    ass_parse.c ass_parse.h ass_render_api.c ass_strtod.c
+                    ass_parse.c ass_parse.h ass_render_api.c ass_shaper.c \
+                    ass_shaper.h ass_strtod.c
 libass_la_LDFLAGS = -version-info $(LIBASS_LT_CURRENT):$(LIBASS_LT_REVISION):$(LIBASS_LT_AGE)
 libass_la_LDFLAGS += -export-symbols $(srcdir)/libass.sym
 
index 0b3bc4c..66868f2 100644 (file)
@@ -30,6 +30,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <inttypes.h>
+#include <ctype.h>
 
 #ifdef CONFIG_ICONV
 #include <iconv.h>
@@ -42,6 +43,7 @@
 #ifdef _WIN32
 #pragma comment(lib, "libiconv.lib")
 #pragma comment(lib, "freetype246MT.lib")
+#pragma comment(lib, "libfribidi.lib")
 #endif
 
 #define ass_atof(STR) (ass_strtod((STR),NULL))
@@ -76,6 +78,7 @@ void ass_free_track(ASS_Track *track)
     }
     free(track->style_format);
     free(track->event_format);
+    free(track->Language);
     if (track->styles) {
         for (i = 0; i < track->n_styles; ++i)
             ass_free_style(track, i);
@@ -602,6 +605,12 @@ static int process_info_line(ASS_Track *track, char *str)
         track->ScaledBorderAndShadow = parse_bool(str + 22);
     } else if (!strncmp(str, "Kerning:", 8)) {
         track->Kerning = parse_bool(str + 8);
+    } else if (!strncmp(str, "Language:", 9)) {
+        char *p = str + 9;
+        while (*p && isspace(*p)) p++;
+        track->Language = malloc(3);
+        strncpy(track->Language, p, 2);
+        track->Language[2] = 0;
     }
     return 0;
 }
@@ -1276,3 +1285,36 @@ ASS_Track *ass_new_track(ASS_Library *library)
     track->parser_priv = calloc(1, sizeof(ASS_ParserPriv));
     return track;
 }
+
+/**
+ * \brief Prepare track for rendering
+ */
+void ass_lazy_track_init(ASS_Library *lib, ASS_Track *track)
+{
+    if (track->PlayResX && track->PlayResY)
+        return;
+    if (!track->PlayResX && !track->PlayResY) {
+        ass_msg(lib, MSGL_WARN,
+               "Neither PlayResX nor PlayResY defined. Assuming 384x288");
+        track->PlayResX = 384;
+        track->PlayResY = 288;
+    } else {
+        if (!track->PlayResY && track->PlayResX == 1280) {
+            track->PlayResY = 1024;
+            ass_msg(lib, MSGL_WARN,
+                   "PlayResY undefined, setting to %d", track->PlayResY);
+        } else if (!track->PlayResY) {
+            track->PlayResY = track->PlayResX * 3 / 4;
+            ass_msg(lib, MSGL_WARN,
+                   "PlayResY undefined, setting to %d", track->PlayResY);
+        } else if (!track->PlayResX && track->PlayResY == 1024) {
+            track->PlayResX = 1280;
+            ass_msg(lib, MSGL_WARN,
+                   "PlayResX undefined, setting to %d", track->PlayResX);
+        } else if (!track->PlayResX) {
+            track->PlayResX = track->PlayResY * 4 / 3;
+            ass_msg(lib, MSGL_WARN,
+                   "PlayResX undefined, setting to %d", track->PlayResX);
+        }
+    }
+}
index caf09cf..5aef92e 100644 (file)
@@ -23,7 +23,7 @@
 #include <stdarg.h>
 #include "ass_types.h"
 
-#define LIBASS_VERSION 0x00913000
+#define LIBASS_VERSION 0x01000000
 
 /*
  * A linked list of images produced by an ass renderer.
@@ -61,6 +61,19 @@ typedef enum {
 } ASS_Hinting;
 
 /**
+ * \brief Text shaping levels.
+ *
+ * SIMPLE is a fast, font-agnostic shaper that can do only substitutions.
+ * COMPLEX is a slower shaper using OpenType for substitutions and positioning.
+ *
+ * libass uses the best shaper available by default.
+ */
+typedef enum {
+    ASS_SHAPING_SIMPLE = 0,
+    ASS_SHAPING_COMPLEX
+} ASS_ShapingLevel;
+
+/**
  * \brief Initialize the library.
  * \return library handle or NULL if failed
  */
@@ -147,6 +160,13 @@ void ass_renderer_done(ASS_Renderer *priv);
 void ass_set_frame_size(ASS_Renderer *priv, int w, int h);
 
 /**
+ * \brief Set shaping level. This is merely a hint, the renderer will use
+ * whatever is available if the request cannot be fulfilled.
+ * \param level shaping level
+ */
+void ass_set_shaper(ASS_Renderer *priv, ASS_ShapingLevel level);
+
+/**
  * \brief Set frame margins.  These values may be negative if pan-and-scan
  * is used.
  * \param priv renderer handle
index d546f59..6afe05d 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
+ * Copyright (C) 2011 Grigori Goronzy <greg@chown.ath.cx>
  *
  * This file is part of libass.
  *
@@ -22,6 +23,7 @@
 #include <assert.h>
 #include <ft2build.h>
 #include FT_GLYPH_H
+#include FT_OUTLINE_H
 
 #include "ass_utils.h"
 #include "ass_bitmap.h"
@@ -133,10 +135,12 @@ void ass_synth_done(ASS_SynthPriv *priv)
 static Bitmap *alloc_bitmap(int w, int h)
 {
     Bitmap *bm;
+    unsigned s = w; // XXX: alignment
     bm = malloc(sizeof(Bitmap));
-    bm->buffer = calloc(w, h);
+    bm->buffer = calloc(s, h);
     bm->w = w;
     bm->h = h;
+    bm->stride = s;
     bm->left = bm->top = 0;
     return bm;
 }
@@ -153,70 +157,57 @@ static Bitmap *copy_bitmap(const Bitmap *src)
     Bitmap *dst = alloc_bitmap(src->w, src->h);
     dst->left = src->left;
     dst->top = src->top;
-    memcpy(dst->buffer, src->buffer, src->w * src->h);
+    memcpy(dst->buffer, src->buffer, src->stride * src->h);
     return dst;
 }
 
-int check_glyph_area(ASS_Library *library, FT_Glyph glyph)
+Bitmap *outline_to_bitmap(ASS_Library *library, FT_Library ftlib,
+                          FT_Outline *outline, int bord)
 {
-    FT_BBox bbox;
-    long long dx, dy;
-    FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox);
-    dx = bbox.xMax - bbox.xMin;
-    dy = bbox.yMax - bbox.yMin;
-    if (dx * dy > 8000000) {
-        ass_msg(library, MSGL_WARN, "Glyph bounding box too large: %dx%dpx",
-               (int) dx, (int) dy);
-        return 1;
-    } else
-        return 0;
-}
-
-static Bitmap *glyph_to_bitmap_internal(ASS_Library *library,
-                                          FT_Glyph glyph, int bord)
-{
-    FT_BitmapGlyph bg;
-    FT_Bitmap *bit;
     Bitmap *bm;
     int w, h;
-    unsigned char *src;
-    unsigned char *dst;
-    int i;
     int error;
-
-    if (check_glyph_area(library, glyph))
-        return 0;
-    error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 0);
-    if (error) {
-        ass_msg(library, MSGL_WARN, "FT_Glyph_To_Bitmap error %d",
-               error);
-        return 0;
-    }
-
-    bg = (FT_BitmapGlyph) glyph;
-    bit = &(bg->bitmap);
-    if (bit->pixel_mode != FT_PIXEL_MODE_GRAY) {
-        ass_msg(library, MSGL_WARN, "Unsupported pixel mode: %d",
-               (int) (bit->pixel_mode));
-        FT_Done_Glyph(glyph);
-        return 0;
+    FT_BBox bbox;
+    FT_Bitmap bitmap;
+
+    FT_Outline_Get_CBox(outline, &bbox);
+    // move glyph to origin (0, 0)
+    bbox.xMin &= ~63;
+    bbox.yMin &= ~63;
+    FT_Outline_Translate(outline, -bbox.xMin, -bbox.yMin);
+    // bitmap size
+    bbox.xMax = (bbox.xMax + 63) & ~63;
+    bbox.yMax = (bbox.yMax + 63) & ~63;
+    w = (bbox.xMax - bbox.xMin) >> 6;
+    h = (bbox.yMax - bbox.yMin) >> 6;
+    // pen offset
+    bbox.xMin >>= 6;
+    bbox.yMax >>= 6;
+
+    if (w * h > 8000000) {
+        ass_msg(library, MSGL_WARN, "Glyph bounding box too large: %dx%dpx",
+                w, h);
+        return NULL;
     }
 
-    w = bit->width;
-    h = bit->rows;
+    // allocate and set up bitmap
     bm = alloc_bitmap(w + 2 * bord, h + 2 * bord);
-    bm->left = bg->left - bord;
-    bm->top = -bg->top - bord;
-
-    src = bit->buffer;
-    dst = bm->buffer + bord + bm->w * bord;
-    for (i = 0; i < h; ++i) {
-        memcpy(dst, src, w);
-        src += bit->pitch;
-        dst += bm->w;
+    bm->left = bbox.xMin - bord;
+    bm->top = -bbox.yMax - bord;
+    bitmap.width = w;
+    bitmap.rows = h;
+    bitmap.pitch = bm->stride;
+    bitmap.buffer = bm->buffer + bord + bm->stride * bord;
+    bitmap.num_grays = 256;
+    bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
+
+    // render into target bitmap
+    if ((error = FT_Outline_Get_Bitmap(ftlib, outline, &bitmap))) {
+        ass_msg(library, MSGL_WARN, "Failed to rasterize glyph: %d\n", error);
+        ass_free_bitmap(bm);
+        return NULL;
     }
 
-    FT_Done_Glyph(glyph);
     return bm;
 }
 
@@ -232,16 +223,16 @@ static void fix_outline(Bitmap *bm_g, Bitmap *bm_o)
     const int l = bm_o->left > bm_g->left ? bm_o->left : bm_g->left;
     const int t = bm_o->top > bm_g->top ? bm_o->top : bm_g->top;
     const int r =
-        bm_o->left + bm_o->w <
-        bm_g->left + bm_g->w ? bm_o->left + bm_o->w : bm_g->left + bm_g->w;
+        bm_o->left + bm_o->stride <
+        bm_g->left + bm_g->stride ? bm_o->left + bm_o->stride : bm_g->left + bm_g->stride;
     const int b =
         bm_o->top + bm_o->h <
         bm_g->top + bm_g->h ? bm_o->top + bm_o->h : bm_g->top + bm_g->h;
 
     unsigned char *g =
-        bm_g->buffer + (t - bm_g->top) * bm_g->w + (l - bm_g->left);
+        bm_g->buffer + (t - bm_g->top) * bm_g->stride + (l - bm_g->left);
     unsigned char *o =
-        bm_o->buffer + (t - bm_o->top) * bm_o->w + (l - bm_o->left);
+        bm_o->buffer + (t - bm_o->top) * bm_o->stride + (l - bm_o->left);
 
     for (y = 0; y < b - t; ++y) {
         for (x = 0; x < r - l; ++x) {
@@ -250,8 +241,8 @@ static void fix_outline(Bitmap *bm_g, Bitmap *bm_o)
             c_o = o[x];
             o[x] = (c_o > c_g) ? c_o - (c_g / 2) : 0;
         }
-        g += bm_g->w;
-        o += bm_o->w;
+        g += bm_g->stride;
+        o += bm_o->stride;
     }
 }
 
@@ -259,27 +250,30 @@ static void fix_outline(Bitmap *bm_g, Bitmap *bm_o)
  * \brief Shift a bitmap by the fraction of a pixel in x and y direction
  * expressed in 26.6 fixed point
  */
-static void shift_bitmap(unsigned char *buf, int w, int h, int shift_x,
-                         int shift_y)
+static void shift_bitmap(Bitmap *bm, int shift_x, int shift_y)
 {
     int x, y, b;
+    int w = bm->w;
+    int h = bm->h;
+    int s = bm->stride;
+    unsigned char *buf = bm->buffer;
 
     // Shift in x direction
     if (shift_x > 0) {
         for (y = 0; y < h; y++) {
             for (x = w - 1; x > 0; x--) {
-                b = (buf[x + y * w - 1] * shift_x) >> 6;
-                buf[x + y * w - 1] -= b;
-                buf[x + y * w] += b;
+                b = (buf[x + y * s - 1] * shift_x) >> 6;
+                buf[x + y * s - 1] -= b;
+                buf[x + y * s] += b;
             }
         }
     } else if (shift_x < 0) {
         shift_x = -shift_x;
         for (y = 0; y < h; y++) {
             for (x = 0; x < w - 1; x++) {
-                b = (buf[x + y * w + 1] * shift_x) >> 6;
-                buf[x + y * w + 1] -= b;
-                buf[x + y * w] += b;
+                b = (buf[x + y * s + 1] * shift_x) >> 6;
+                buf[x + y * s + 1] -= b;
+                buf[x + y * s] += b;
             }
         }
     }
@@ -288,18 +282,18 @@ static void shift_bitmap(unsigned char *buf, int w, int h, int shift_x,
     if (shift_y > 0) {
         for (x = 0; x < w; x++) {
             for (y = h - 1; y > 0; y--) {
-                b = (buf[x + (y - 1) * w] * shift_y) >> 6;
-                buf[x + (y - 1) * w] -= b;
-                buf[x + y * w] += b;
+                b = (buf[x + (y - 1) * s] * shift_y) >> 6;
+                buf[x + (y - 1) * s] -= b;
+                buf[x + y * s] += b;
             }
         }
     } else if (shift_y < 0) {
         shift_y = -shift_y;
         for (x = 0; x < w; x++) {
             for (y = 0; y < h - 1; y++) {
-                b = (buf[x + (y + 1) * w] * shift_y) >> 6;
-                buf[x + (y + 1) * w] -= b;
-                buf[x + y * w] += b;
+                b = (buf[x + (y + 1) * s] * shift_y) >> 6;
+                buf[x + (y + 1) * s] -= b;
+                buf[x + y * s] += b;
             }
         }
     }
@@ -430,16 +424,20 @@ static void ass_gauss_blur(unsigned char *buffer, unsigned short *tmp2,
  * \brief Blur with [[1,2,1]. [2,4,2], [1,2,1]] kernel
  * This blur is the same as the one employed by vsfilter.
  */
-static void be_blur(unsigned char *buf, int w, int h)
+static void be_blur(Bitmap *bm)
 {
+    int w = bm->w;
+    int h = bm->h;
+    int s = bm->stride;
+    unsigned char *buf = bm->buffer;
     unsigned int x, y;
     unsigned int old_sum, new_sum;
 
     for (y = 0; y < h; y++) {
-        old_sum = 2 * buf[y * w];
+        old_sum = 2 * buf[y * s];
         for (x = 0; x < w - 1; x++) {
-            new_sum = buf[y * w + x] + buf[y * w + x + 1];
-            buf[y * w + x] = (old_sum + new_sum) >> 2;
+            new_sum = buf[y * s + x] + buf[y * s + x + 1];
+            buf[y * s + x] = (old_sum + new_sum) >> 2;
             old_sum = new_sum;
         }
     }
@@ -447,18 +445,18 @@ static void be_blur(unsigned char *buf, int w, int h)
     for (x = 0; x < w; x++) {
         old_sum = 2 * buf[x];
         for (y = 0; y < h - 1; y++) {
-            new_sum = buf[y * w + x] + buf[(y + 1) * w + x];
-            buf[y * w + x] = (old_sum + new_sum) >> 2;
+            new_sum = buf[y * s + x] + buf[(y + 1) * s + x];
+            buf[y * s + x] = (old_sum + new_sum) >> 2;
             old_sum = new_sum;
         }
     }
 }
 
-int glyph_to_bitmap(ASS_Library *library, ASS_SynthPriv *priv_blur,
-                    FT_Glyph glyph, FT_Glyph outline_glyph,
-                    Bitmap **bm_g, Bitmap **bm_o, Bitmap **bm_s,
-                    int be, double blur_radius, FT_Vector shadow_offset,
-                    int border_style)
+int outline_to_bitmap3(ASS_Library *library, ASS_SynthPriv *priv_blur,
+                       FT_Library ftlib, FT_Outline *outline, FT_Outline *border,
+                       Bitmap **bm_g, Bitmap **bm_o, Bitmap **bm_s,
+                       int be, double blur_radius, FT_Vector shadow_offset,
+                       int border_style)
 {
     int bord, bbord, gbord;
     blur_radius *= 2;
@@ -472,13 +470,13 @@ int glyph_to_bitmap(ASS_Library *library, ASS_SynthPriv *priv_blur,
 
     *bm_g = *bm_o = *bm_s = 0;
 
-    if (glyph)
-        *bm_g = glyph_to_bitmap_internal(library, glyph, bord);
+    if (outline)
+        *bm_g = outline_to_bitmap(library, ftlib, outline, bord);
     if (!*bm_g)
         return 1;
 
-    if (outline_glyph) {
-        *bm_o = glyph_to_bitmap_internal(library, outline_glyph, bord);
+    if (border) {
+        *bm_o = outline_to_bitmap(library, ftlib, border, bord);
         if (!*bm_o) {
             return 1;
         }
@@ -487,9 +485,9 @@ int glyph_to_bitmap(ASS_Library *library, ASS_SynthPriv *priv_blur,
     // Apply box blur (multiple passes, if requested)
     while (be--) {
         if (*bm_o)
-            be_blur((*bm_o)->buffer, (*bm_o)->w, (*bm_o)->h);
+            be_blur(*bm_o);
         else
-            be_blur((*bm_g)->buffer, (*bm_g)->w, (*bm_g)->h);
+            be_blur(*bm_g);
     }
 
     // Apply gaussian blur
@@ -501,12 +499,12 @@ int glyph_to_bitmap(ASS_Library *library, ASS_SynthPriv *priv_blur,
         generate_tables(priv_blur, blur_radius);
         if (*bm_o)
             ass_gauss_blur((*bm_o)->buffer, priv_blur->tmp,
-                           (*bm_o)->w, (*bm_o)->h, (*bm_o)->w,
+                           (*bm_o)->w, (*bm_o)->h, (*bm_o)->stride,
                            (int *) priv_blur->gt2, priv_blur->g_r,
                            priv_blur->g_w);
         else
             ass_gauss_blur((*bm_g)->buffer, priv_blur->tmp,
-                           (*bm_g)->w, (*bm_g)->h, (*bm_g)->w,
+                           (*bm_g)->w, (*bm_g)->h, (*bm_g)->stride,
                            (int *) priv_blur->gt2, priv_blur->g_r,
                            priv_blur->g_w);
     }
@@ -522,8 +520,7 @@ int glyph_to_bitmap(ASS_Library *library, ASS_SynthPriv *priv_blur,
 
     assert(bm_s);
 
-    shift_bitmap((*bm_s)->buffer, (*bm_s)->w,(*bm_s)->h,
-                 shadow_offset.x, shadow_offset.y);
+    shift_bitmap(*bm_s, shadow_offset.x, shadow_offset.y);
 
     return 0;
 }
index 287b638..2a46aec 100644 (file)
@@ -32,9 +32,12 @@ void ass_synth_done(ASS_SynthPriv *priv);
 typedef struct {
     int left, top;
     int w, h;                   // width, height
+    int stride;
     unsigned char *buffer;      // w x h buffer
 } Bitmap;
 
+Bitmap *outline_to_bitmap(ASS_Library *library, FT_Library ftlib,
+                          FT_Outline *outline, int bord);
 /**
  * \brief perform glyph rendering
  * \param glyph original glyph
@@ -44,13 +47,12 @@ typedef struct {
  * \param bm_g out: pointer to the bitmap of glyph shadow is returned here
  * \param be 1 = produces blurred bitmaps, 0 = normal bitmaps
  */
-int glyph_to_bitmap(ASS_Library *library, ASS_SynthPriv *priv_blur,
-                    FT_Glyph glyph, FT_Glyph outline_glyph,
-                    Bitmap **bm_g, Bitmap **bm_o, Bitmap **bm_s,
-                    int be, double blur_radius, FT_Vector shadow_offset,
-                    int border_style);
+int outline_to_bitmap3(ASS_Library *library, ASS_SynthPriv *priv_blur,
+                       FT_Library ftlib, FT_Outline *outline, FT_Outline *border,
+                       Bitmap **bm_g, Bitmap **bm_o, Bitmap **bm_s,
+                       int be, double blur_radius, FT_Vector shadow_offset,
+                       int border_style);
 
 void ass_free_bitmap(Bitmap *bm);
-int check_glyph_area(ASS_Library *library, FT_Glyph glyph);
 
 #endif                          /* LIBASS_BITMAP_H */
index 46c2478..91801a0 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
+ * Copyright (C) 2011 Grigori Goronzy <greg@chown.ath.cx>
  *
  * This file is part of libass.
  *
 
 #include <inttypes.h>
 #include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_GLYPH_H
-
+#include FT_OUTLINE_H
 #include <assert.h>
 
 #include "ass_utils.h"
-#include "ass.h"
-#include "ass_fontconfig.h"
 #include "ass_font.h"
-#include "ass_bitmap.h"
 #include "ass_cache.h"
 
-static unsigned hashmap_hash(void *buf, size_t len)
-{
-    return fnv_32a_buf(buf, len, FNV1_32A_INIT);
-}
-
-static int hashmap_key_compare(void *a, void *b, size_t size)
-{
-    return memcmp(a, b, size) == 0;
-}
-
-static void hashmap_item_dtor(void *key, size_t key_size, void *value,
-                              size_t value_size)
-{
-    free(key);
-    free(value);
-}
-
-Hashmap *hashmap_init(ASS_Library *library, size_t key_size,
-                      size_t value_size, int nbuckets,
-                      HashmapItemDtor item_dtor,
-                      HashmapKeyCompare key_compare,
-                      HashmapHash hash)
-{
-    Hashmap *map = calloc(1, sizeof(Hashmap));
-    map->library = library;
-    map->nbuckets = nbuckets;
-    map->key_size = key_size;
-    map->value_size = value_size;
-    map->root = calloc(nbuckets, sizeof(hashmap_item_p));
-    map->item_dtor = item_dtor ? item_dtor : hashmap_item_dtor;
-    map->key_compare = key_compare ? key_compare : hashmap_key_compare;
-    map->hash = hash ? hash : hashmap_hash;
-    return map;
-}
-
-void hashmap_done(Hashmap *map)
-{
-    int i;
-    // print stats
-    if (map->count > 0 || map->hit_count + map->miss_count > 0)
-        ass_msg(map->library, MSGL_V,
-               "cache statistics: \n  total accesses: %d\n  hits: %d\n  "
-               "misses: %d\n  object count: %d",
-               map->hit_count + map->miss_count, map->hit_count,
-               map->miss_count, map->count);
-
-    for (i = 0; i < map->nbuckets; ++i) {
-        HashmapItem *item = map->root[i];
-        while (item) {
-            HashmapItem *next = item->next;
-            map->item_dtor(item->key, map->key_size, item->value,
-                           map->value_size);
-            free(item);
-            item = next;
-        }
-    }
-    free(map->root);
-    free(map);
-}
-
-// does nothing if key already exists
-void *hashmap_insert(Hashmap *map, void *key, void *value)
-{
-    unsigned hash = map->hash(key, map->key_size);
-    HashmapItem **next = map->root + (hash % map->nbuckets);
-    while (*next) {
-        if (map->key_compare(key, (*next)->key, map->key_size))
-            return (*next)->value;
-        next = &((*next)->next);
-        assert(next);
-    }
-    (*next) = malloc(sizeof(HashmapItem));
-    (*next)->key = malloc(map->key_size);
-    (*next)->value = malloc(map->value_size);
-    memcpy((*next)->key, key, map->key_size);
-    memcpy((*next)->value, value, map->value_size);
-    (*next)->next = 0;
-
-    map->count++;
-    return (*next)->value;
-}
-
-void *hashmap_find(Hashmap *map, void *key)
-{
-    unsigned hash = map->hash(key, map->key_size);
-    HashmapItem *item = map->root[hash % map->nbuckets];
-    while (item) {
-        if (map->key_compare(key, item->key, map->key_size)) {
-            map->hit_count++;
-            return item->value;
-        }
-        item = item->next;
-    }
-    map->miss_count++;
-    return 0;
-}
+// type-specific functions
+// create hash/compare functions for bitmap, outline and composite cache
+#define CREATE_HASH_FUNCTIONS
+#include "ass_cache_template.h"
+#define CREATE_COMPARISON_FUNCTIONS
+#include "ass_cache_template.h"
 
-//---------------------------------
 // font cache
-
-static unsigned font_desc_hash(void *buf, size_t len)
+static unsigned font_hash(void *buf, size_t len)
 {
     ASS_FontDesc *desc = buf;
     unsigned hval;
     hval = fnv_32a_str(desc->family, FNV1_32A_INIT);
     hval = fnv_32a_buf(&desc->bold, sizeof(desc->bold), hval);
     hval = fnv_32a_buf(&desc->italic, sizeof(desc->italic), hval);
+    hval = fnv_32a_buf(&desc->treat_family_as_pattern,
+            sizeof(desc->treat_family_as_pattern), hval);
+    hval = fnv_32a_buf(&desc->vertical, sizeof(desc->vertical), hval);
     return hval;
 }
 
-static int font_compare(void *key1, void *key2, size_t key_size)
+static unsigned font_compare(void *key1, void *key2, size_t key_size)
 {
     ASS_FontDesc *a = key1;
     ASS_FontDesc *b = key2;
@@ -159,227 +66,287 @@ static int font_compare(void *key1, void *key2, size_t key_size)
     return 1;
 }
 
-static void font_hash_dtor(void *key, size_t key_size, void *value,
-                           size_t value_size)
+static void font_destruct(void *key, void *value)
 {
     ass_font_free(value);
     free(key);
 }
 
-ASS_Font *ass_font_cache_find(Hashmap *font_cache,
-                              ASS_FontDesc *desc)
-{
-    return hashmap_find(font_cache, desc);
-}
-
-/**
- * \brief Add a face struct to cache.
- * \param font font struct
-*/
-void *ass_font_cache_add(Hashmap *font_cache, ASS_Font *font)
-{
-    return hashmap_insert(font_cache, &(font->desc), font);
-}
-
-Hashmap *ass_font_cache_init(ASS_Library *library)
-{
-    Hashmap *font_cache;
-    font_cache = hashmap_init(library, sizeof(ASS_FontDesc),
-                              sizeof(ASS_Font),
-                              1000,
-                              font_hash_dtor, font_compare, font_desc_hash);
-    return font_cache;
-}
-
-void ass_font_cache_done(Hashmap *font_cache)
-{
-    hashmap_done(font_cache);
-}
-
-
-// Create hash/compare functions for bitmap and glyph
-#define CREATE_HASH_FUNCTIONS
-#include "ass_cache_template.h"
-#define CREATE_COMPARISON_FUNCTIONS
-#include "ass_cache_template.h"
-
-//---------------------------------
 // bitmap cache
-
-static void bitmap_hash_dtor(void *key, size_t key_size, void *value,
-                             size_t value_size)
+static void bitmap_destruct(void *key, void *value)
 {
     BitmapHashValue *v = value;
+    BitmapHashKey *k = key;
     if (v->bm)
         ass_free_bitmap(v->bm);
     if (v->bm_o)
         ass_free_bitmap(v->bm_o);
     if (v->bm_s)
         ass_free_bitmap(v->bm_s);
+    if (k->type == BITMAP_CLIP)
+        free(k->u.clip.text);
     free(key);
     free(value);
 }
 
-void *cache_add_bitmap(Hashmap *bitmap_cache, BitmapHashKey *key,
-                       BitmapHashValue *val)
+static size_t bitmap_size(void *value, size_t value_size)
 {
-    // Note: this is only an approximation
+    BitmapHashValue *val = value;
     if (val->bm_o)
-        bitmap_cache->cache_size += val->bm_o->w * val->bm_o->h * 3;
+        return val->bm_o->w * val->bm_o->h * 3;
     else if (val->bm)
-        bitmap_cache->cache_size += val->bm->w * val->bm->h * 3;
-
-    return hashmap_insert(bitmap_cache, key, val);
+        return val->bm->w * val->bm->h * 3;
+    return 0;
 }
 
-/**
- * \brief Get a bitmap from bitmap cache.
- * \param key hash key
- * \return requested hash val or 0 if not found
-*/
-BitmapHashValue *cache_find_bitmap(Hashmap *bitmap_cache,
-                                   BitmapHashKey *key)
+static unsigned bitmap_hash(void *key, size_t key_size)
 {
-    return hashmap_find(bitmap_cache, key);
+    BitmapHashKey *k = key;
+    switch (k->type) {
+        case BITMAP_OUTLINE: return outline_bitmap_hash(&k->u, key_size);
+        case BITMAP_CLIP: return clip_bitmap_hash(&k->u, key_size);
+        default: return 0;
+    }
 }
 
-Hashmap *ass_bitmap_cache_init(ASS_Library *library)
+static unsigned bitmap_compare (void *a, void *b, size_t key_size)
 {
-    Hashmap *bitmap_cache;
-    bitmap_cache = hashmap_init(library,
-                                sizeof(BitmapHashKey),
-                                sizeof(BitmapHashValue),
-                                0xFFFF + 13,
-                                bitmap_hash_dtor, bitmap_compare,
-                                bitmap_hash);
-    return bitmap_cache;
+    BitmapHashKey *ak = a;
+    BitmapHashKey *bk = b;
+    if (ak->type != bk->type) return 0;
+    switch (ak->type) {
+        case BITMAP_OUTLINE: return outline_bitmap_compare(&ak->u, &bk->u, key_size);
+        case BITMAP_CLIP: return clip_bitmap_compare(&ak->u, &bk->u, key_size);
+        default: return 0;
+    }
 }
 
-void ass_bitmap_cache_done(Hashmap *bitmap_cache)
+// composite cache
+static void composite_destruct(void *key, void *value)
 {
-    hashmap_done(bitmap_cache);
+    CompositeHashValue *v = value;
+    free(v->a);
+    free(v->b);
+    free(key);
+    free(value);
 }
 
-Hashmap *ass_bitmap_cache_reset(Hashmap *bitmap_cache)
-{
-    ASS_Library *lib = bitmap_cache->library;
+// outline cache
 
-    ass_bitmap_cache_done(bitmap_cache);
-    return ass_bitmap_cache_init(lib);
+static unsigned outline_hash(void *key, size_t key_size)
+{
+    OutlineHashKey *k = key;
+    switch (k->type) {
+        case OUTLINE_GLYPH: return glyph_hash(&k->u, key_size);
+        case OUTLINE_DRAWING: return drawing_hash(&k->u, key_size);
+        default: return 0;
+    }
 }
 
-//---------------------------------
-// glyph cache
+static unsigned outline_compare(void *a, void *b, size_t key_size)
+{
+    OutlineHashKey *ak = a;
+    OutlineHashKey *bk = b;
+    if (ak->type != bk->type) return 0;
+    switch (ak->type) {
+        case OUTLINE_GLYPH: return glyph_compare(&ak->u, &bk->u, key_size);
+        case OUTLINE_DRAWING: return drawing_compare(&ak->u, &bk->u, key_size);
+        default: return 0;
+    }
+}
 
-static void glyph_hash_dtor(void *key, size_t key_size, void *value,
-                            size_t value_size)
+static void outline_destruct(void *key, void *value)
 {
-    GlyphHashValue *v = value;
-    if (v->glyph)
-        FT_Done_Glyph(v->glyph);
-    if (v->outline_glyph)
-        FT_Done_Glyph(v->outline_glyph);
+    OutlineHashValue *v = value;
+    OutlineHashKey *k = key;
+    if (v->outline)
+        outline_free(v->lib, v->outline);
+    if (v->border)
+        outline_free(v->lib, v->border);
+    if (k->type == OUTLINE_DRAWING)
+        free(k->u.drawing.text);
     free(key);
     free(value);
 }
 
-void *cache_add_glyph(Hashmap *glyph_cache, GlyphHashKey *key,
-                      GlyphHashValue *val)
-{
-       if (val->glyph && val->glyph->format == FT_GLYPH_FORMAT_BITMAP) {
-               FT_Bitmap *bitmap = &((FT_BitmapGlyph) val->glyph)->bitmap;
-               glyph_cache->cache_size += bitmap->rows * bitmap->pitch;
-       }
 
-    return hashmap_insert(glyph_cache, key, val);
+
+// Cache data
+typedef struct cache_item {
+    void *key;
+    void *value;
+    struct cache_item *next;
+} CacheItem;
+
+struct cache {
+    unsigned buckets;
+    CacheItem **map;
+
+    HashFunction hash_func;
+    ItemSize size_func;
+    HashCompare compare_func;
+    CacheItemDestructor destruct_func;
+    size_t key_size;
+    size_t value_size;
+
+    size_t cache_size;
+    unsigned hits;
+    unsigned misses;
+    unsigned items;
+};
+
+// Hash for a simple (single value or array) type
+static unsigned hash_simple(void *key, size_t key_size)
+{
+    return fnv_32a_buf(key, key_size, FNV1_32A_INIT);
 }
 
-/**
- * \brief Get a glyph from glyph cache.
- * \param key hash key
- * \return requested hash val or 0 if not found
-*/
-GlyphHashValue *cache_find_glyph(Hashmap *glyph_cache,
-                                 GlyphHashKey *key)
+// Comparison of a simple type
+static unsigned compare_simple(void *a, void *b, size_t key_size)
 {
-    return hashmap_find(glyph_cache, key);
+    return memcmp(a, b, key_size) == 0;
 }
 
-Hashmap *ass_glyph_cache_init(ASS_Library *library)
+// Default destructor
+static void destruct_simple(void *key, void *value)
 {
-    Hashmap *glyph_cache;
-    glyph_cache = hashmap_init(library, sizeof(GlyphHashKey),
-                               sizeof(GlyphHashValue),
-                               0xFFFF + 13,
-                               glyph_hash_dtor, glyph_compare, glyph_hash);
-    return glyph_cache;
+    free(key);
+    free(value);
 }
 
-void ass_glyph_cache_done(Hashmap *glyph_cache)
+
+// Create a cache with type-specific hash/compare/destruct/size functions
+Cache *ass_cache_create(HashFunction hash_func, HashCompare compare_func,
+                        CacheItemDestructor destruct_func, ItemSize size_func,
+                        size_t key_size, size_t value_size)
 {
-    hashmap_done(glyph_cache);
+    Cache *cache = calloc(1, sizeof(*cache));
+    cache->buckets = 0xFFFF;
+    cache->hash_func = hash_simple;
+    cache->compare_func = compare_simple;
+    cache->destruct_func = destruct_simple;
+    cache->size_func = size_func;
+    if (hash_func)
+        cache->hash_func = hash_func;
+    if (compare_func)
+        cache->compare_func = compare_func;
+    if (destruct_func)
+        cache->destruct_func = destruct_func;
+    cache->key_size = key_size;
+    cache->value_size = value_size;
+    cache->map = calloc(cache->buckets, sizeof(CacheItem *));
+
+    return cache;
 }
 
-Hashmap *ass_glyph_cache_reset(Hashmap *glyph_cache)
+void *ass_cache_put(Cache *cache, void *key, void *value)
 {
-    ASS_Library *lib = glyph_cache->library;
+    unsigned bucket = cache->hash_func(key, cache->key_size) % cache->buckets;
+    CacheItem **item = &cache->map[bucket];
+    while (*item)
+        item = &(*item)->next;
+    (*item) = calloc(1, sizeof(CacheItem));
+    (*item)->key = malloc(cache->key_size);
+    (*item)->value = malloc(cache->value_size);
+    memcpy((*item)->key, key, cache->key_size);
+    memcpy((*item)->value, value, cache->value_size);
+
+    cache->items++;
+    if (cache->size_func)
+        cache->cache_size += cache->size_func(value, cache->value_size);
+    else
+        cache->cache_size++;
 
-    ass_glyph_cache_done(glyph_cache);
-    return ass_glyph_cache_init(lib);
+    return (*item)->value;
 }
 
+void *ass_cache_get(Cache *cache, void *key)
+{
+    unsigned bucket = cache->hash_func(key, cache->key_size) % cache->buckets;
+    CacheItem *item = cache->map[bucket];
+    while (item) {
+        if (cache->compare_func(key, item->key, cache->key_size)) {
+            cache->hits++;
+            return item->value;
+        }
+        item = item->next;
+    }
+    cache->misses++;
+    return NULL;
+}
 
-//---------------------------------
-// composite cache
+int ass_cache_empty(Cache *cache, size_t max_size)
+{
+    int i;
+
+    if (cache->cache_size < max_size)
+        return 0;
 
-static void composite_hash_dtor(void *key, size_t key_size, void *value,
-                                size_t value_size)
+    for (i = 0; i < cache->buckets; i++) {
+        CacheItem *item = cache->map[i];
+        while (item) {
+            CacheItem *next = item->next;
+            cache->destruct_func(item->key, item->value);
+            free(item);
+            item = next;
+        }
+        cache->map[i] = NULL;
+    }
+
+    cache->items = cache->hits = cache->misses = cache->cache_size = 0;
+
+    return 1;
+}
+
+void ass_cache_stats(Cache *cache, size_t *size, unsigned *hits,
+                     unsigned *misses, unsigned *count)
 {
-    CompositeHashValue *v = value;
-    free(v->a);
-    free(v->b);
-    free(key);
-    free(value);
+    if (size)
+        *size = cache->cache_size;
+    if (hits)
+        *hits = cache->hits;
+    if (misses)
+        *misses = cache->misses;
+    if (count)
+        *count = cache->items;
 }
 
-void *cache_add_composite(Hashmap *composite_cache,
-                          CompositeHashKey *key,
-                          CompositeHashValue *val)
+void ass_cache_done(Cache *cache)
 {
-    return hashmap_insert(composite_cache, key, val);
+    ass_cache_empty(cache, 0);
+    free(cache->map);
+    free(cache);
 }
 
-/**
- * \brief Get a composite bitmap from composite cache.
- * \param key hash key
- * \return requested hash val or 0 if not found
-*/
-CompositeHashValue *cache_find_composite(Hashmap *composite_cache,
-                                         CompositeHashKey *key)
+// Type-specific creation function
+Cache *ass_font_cache_create(void)
 {
-    return hashmap_find(composite_cache, key);
+    return ass_cache_create(font_hash, font_compare, font_destruct,
+            (ItemSize)NULL, sizeof(ASS_FontDesc), sizeof(ASS_Font));
 }
 
-Hashmap *ass_composite_cache_init(ASS_Library *library)
+Cache *ass_outline_cache_create(void)
 {
-    Hashmap *composite_cache;
-    composite_cache = hashmap_init(library, sizeof(CompositeHashKey),
-                                   sizeof(CompositeHashValue),
-                                   0xFFFF + 13,
-                                   composite_hash_dtor, composite_compare,
-                                   composite_hash);
-    return composite_cache;
+    return ass_cache_create(outline_hash, outline_compare, outline_destruct,
+            NULL, sizeof(OutlineHashKey), sizeof(OutlineHashValue));
 }
 
-void ass_composite_cache_done(Hashmap *composite_cache)
+Cache *ass_glyph_metrics_cache_create(void)
 {
-    hashmap_done(composite_cache);
+    return ass_cache_create(glyph_metrics_hash, glyph_metrics_compare, NULL,
+            (ItemSize) NULL, sizeof(GlyphMetricsHashKey),
+            sizeof(GlyphMetricsHashValue));
 }
 
-Hashmap *ass_composite_cache_reset(Hashmap *composite_cache)
+Cache *ass_bitmap_cache_create(void)
 {
-    ASS_Library *lib = composite_cache->library;
+    return ass_cache_create(bitmap_hash, bitmap_compare, bitmap_destruct,
+            bitmap_size, sizeof(BitmapHashKey), sizeof(BitmapHashValue));
+}
 
-    ass_composite_cache_done(composite_cache);
-    return ass_composite_cache_init(lib);
+Cache *ass_composite_cache_create(void)
+{
+    return ass_cache_create(composite_hash, composite_compare,
+            composite_destruct, (ItemSize)NULL, sizeof(CompositeHashKey),
+            sizeof(CompositeHashValue));
 }
index 472bf35..7375f04 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
+ * Copyright (C) 2011 Grigori Goronzy <greg@chown.ath.cx>
  *
  * This file is part of libass.
  *
 #include "ass_font.h"
 #include "ass_bitmap.h"
 
-typedef void (*HashmapItemDtor) (void *key, size_t key_size,
-                                 void *value, size_t value_size);
-typedef int (*HashmapKeyCompare) (void *key1, void *key2,
-                                  size_t key_size);
-typedef unsigned (*HashmapHash) (void *key, size_t key_size);
+typedef struct cache Cache;
 
-typedef struct hashmap_item {
-    void *key;
-    void *value;
-    struct hashmap_item *next;
-} HashmapItem;
-typedef HashmapItem *hashmap_item_p;
-
-typedef struct {
-    int nbuckets;
-    size_t key_size, value_size;
-    hashmap_item_p *root;
-    HashmapItemDtor item_dtor;      // a destructor for hashmap key/value pairs
-    HashmapKeyCompare key_compare;
-    HashmapHash hash;
-    size_t cache_size;
-    // stats
-    int hit_count;
-    int miss_count;
-    int count;
-    ASS_Library *library;
-} Hashmap;
-
-Hashmap *hashmap_init(ASS_Library *library, size_t key_size,
-                      size_t value_size, int nbuckets,
-                      HashmapItemDtor item_dtor,
-                      HashmapKeyCompare key_compare,
-                      HashmapHash hash);
-void hashmap_done(Hashmap *map);
-void *hashmap_insert(Hashmap *map, void *key, void *value);
-void *hashmap_find(Hashmap *map, void *key);
-
-Hashmap *ass_font_cache_init(ASS_Library *library);
-ASS_Font *ass_font_cache_find(Hashmap *, ASS_FontDesc *desc);
-void *ass_font_cache_add(Hashmap *, ASS_Font *font);
-void ass_font_cache_done(Hashmap *);
-
-// Create definitions for bitmap_hash_key and glyph_hash_key
-#define CREATE_STRUCT_DEFINITIONS
-#include "ass_cache_template.h"
+// cache values
 
 typedef struct {
     Bitmap *bm;               // the actual bitmaps
@@ -75,43 +34,71 @@ typedef struct {
     Bitmap *bm_s;
 } BitmapHashValue;
 
-Hashmap *ass_bitmap_cache_init(ASS_Library *library);
-void *cache_add_bitmap(Hashmap *, BitmapHashKey *key,
-                       BitmapHashValue *val);
-BitmapHashValue *cache_find_bitmap(Hashmap *bitmap_cache,
-                                   BitmapHashKey *key);
-Hashmap *ass_bitmap_cache_reset(Hashmap *bitmap_cache);
-void ass_bitmap_cache_done(Hashmap *bitmap_cache);
-
-
 typedef struct {
     unsigned char *a;
     unsigned char *b;
 } CompositeHashValue;
 
-Hashmap *ass_composite_cache_init(ASS_Library *library);
-void *cache_add_composite(Hashmap *, CompositeHashKey *key,
-                          CompositeHashValue *val);
-CompositeHashValue *cache_find_composite(Hashmap *composite_cache,
-                                         CompositeHashKey *key);
-Hashmap *ass_composite_cache_reset(Hashmap *composite_cache);
-void ass_composite_cache_done(Hashmap *composite_cache);
-
-
 typedef struct {
-    FT_Glyph glyph;
-    FT_Glyph outline_glyph;
+    FT_Library lib;
+    FT_Outline *outline;
+    FT_Outline *border;
     FT_BBox bbox_scaled;        // bbox after scaling, but before rotation
-    FT_Vector advance;          // 26.6, advance distance to the next bitmap in line
-    int asc, desc;              // ascender/descender of a drawing
-} GlyphHashValue;
+    FT_Vector advance;          // 26.6, advance distance to the next outline in line
+    int asc, desc;              // ascender/descender
+} OutlineHashValue;
+
+typedef struct {
+    FT_Glyph_Metrics metrics;
+} GlyphMetricsHashValue;
+
+// Create definitions for bitmap, outline and composite hash keys
+#define CREATE_STRUCT_DEFINITIONS
+#include "ass_cache_template.h"
 
-Hashmap *ass_glyph_cache_init(ASS_Library *library);
-void *cache_add_glyph(Hashmap *, GlyphHashKey *key,
-                      GlyphHashValue *val);
-GlyphHashValue *cache_find_glyph(Hashmap *glyph_cache,
-                                 GlyphHashKey *key);
-Hashmap *ass_glyph_cache_reset(Hashmap *glyph_cache);
-void ass_glyph_cache_done(Hashmap *glyph_cache);
+// Type-specific function pointers
+typedef unsigned(*HashFunction)(void *key, size_t key_size);
+typedef size_t(*ItemSize)(void *value, size_t value_size);
+typedef unsigned(*HashCompare)(void *a, void *b, size_t key_size);
+typedef void(*CacheItemDestructor)(void *key, void *value);
+
+// cache hash keys
+
+typedef struct outline_hash_key {
+    enum {
+        OUTLINE_GLYPH,
+        OUTLINE_DRAWING,
+    } type;
+    union {
+        GlyphHashKey glyph;
+        DrawingHashKey drawing;
+    } u;
+} OutlineHashKey;
+
+typedef struct bitmap_hash_key {
+    enum {
+        BITMAP_OUTLINE,
+        BITMAP_CLIP,
+    } type;
+    union {
+        OutlineBitmapHashKey outline;
+        ClipMaskHashKey clip;
+    } u;
+} BitmapHashKey;
+
+Cache *ass_cache_create(HashFunction hash_func, HashCompare compare_func,
+                        CacheItemDestructor destruct_func, ItemSize size_func,
+                        size_t key_size, size_t value_size);
+void *ass_cache_put(Cache *cache, void *key, void *value);
+void *ass_cache_get(Cache *cache, void *key);
+int ass_cache_empty(Cache *cache, size_t max_size);
+void ass_cache_stats(Cache *cache, size_t *size, unsigned *hits,
+                     unsigned *misses, unsigned *count);
+void ass_cache_done(Cache *cache);
+Cache *ass_font_cache_create(void);
+Cache *ass_outline_cache_create(void);
+Cache *ass_glyph_metrics_cache_create(void);
+Cache *ass_bitmap_cache_create(void);
+Cache *ass_composite_cache_create(void);
 
 #endif                          /* LIBASS_CACHE_H */
index f335c6b..f9aab77 100644 (file)
@@ -4,6 +4,8 @@
     typedef struct structname {
 #define GENERIC(type, member) \
         type member;
+#define STRING(member) \
+        char *member;
 #define FTVECTOR(member) \
         FT_Vector member;
 #define BITMAPHASHKEY(member) \
 #elif defined(CREATE_COMPARISON_FUNCTIONS)
 #undef CREATE_COMPARISON_FUNCTIONS
 #define START(funcname, structname) \
-    static int funcname##_compare(void *key1, void *key2, size_t key_size) \
+    static unsigned funcname##_compare(void *key1, void *key2, size_t key_size) \
     { \
         struct structname *a = key1; \
         struct structname *b = key2; \
         return // conditions follow
 #define GENERIC(type, member) \
             a->member == b->member &&
+#define STRING(member) \
+            strcmp(a->member, b->member) == 0 &&
 #define FTVECTOR(member) \
             a->member.x == b->member.x && a->member.y == b->member.y &&
 #define BITMAPHASHKEY(member) \
@@ -38,6 +42,8 @@
         unsigned hval = FNV1_32A_INIT;
 #define GENERIC(type, member) \
         hval = fnv_32a_buf(&p->member, sizeof(p->member), hval);
+#define STRING(member) \
+        hval = fnv_32a_str(p->member, hval);
 #define FTVECTOR(member) GENERIC(, member.x); GENERIC(, member.y);
 #define BITMAPHASHKEY(member) { \
         unsigned temp = bitmap_hash(&p->member, sizeof(p->member)); \
 
 
 
-// describes a bitmap; bitmaps with equivalents structs are considered identical
-START(bitmap, bitmap_hash_key)
-    GENERIC(char, bitmap) // bool : true = bitmap, false = outline
-    GENERIC(ASS_Font *, font)
-    GENERIC(double, size) // font size
-    GENERIC(uint32_t, ch) // character code
-    FTVECTOR(outline) // border width, 16.16 fixed point value
-    GENERIC(int, bold)
-    GENERIC(int, italic)
+// describes an outline bitmap
+START(outline_bitmap, outline_bitmap_hash_key)
+    GENERIC(OutlineHashValue *, outline)
     GENERIC(char, be) // blur edges
     GENERIC(double, blur) // gaussian blur
-    GENERIC(unsigned, scale_x) // 16.16
-    GENERIC(unsigned, scale_y) // 16.16
     GENERIC(int, frx) // signed 16.16
     GENERIC(int, fry) // signed 16.16
     GENERIC(int, frz) // signed 16.16
@@ -78,26 +76,49 @@ START(bitmap, bitmap_hash_key)
     GENERIC(int, shift_y)
     FTVECTOR(advance) // subpixel shift vector
     FTVECTOR(shadow_offset) // shadow subpixel shift
-    GENERIC(unsigned, drawing_hash) // hashcode of a drawing
-    GENERIC(unsigned, flags)    // glyph decoration
-    GENERIC(unsigned, border_style)
-END(BitmapHashKey)
+END(OutlineBitmapHashKey)
+
+// describe a clip mask bitmap
+START(clip_bitmap, clip_bitmap_hash_key)
+    STRING(text)
+END(ClipMaskHashKey)
 
 // describes an outline glyph
 START(glyph, glyph_hash_key)
     GENERIC(ASS_Font *, font)
     GENERIC(double, size) // font size
-    GENERIC(uint32_t, ch) // character code
+    GENERIC(int, face_index)
+    GENERIC(int, glyph_index)
     GENERIC(int, bold)
     GENERIC(int, italic)
     GENERIC(unsigned, scale_x) // 16.16
     GENERIC(unsigned, scale_y) // 16.16
     FTVECTOR(outline) // border width, 16.16
-    GENERIC(unsigned, drawing_hash) // hashcode of a drawing
     GENERIC(unsigned, flags)    // glyph decoration flags
     GENERIC(unsigned, border_style)
 END(GlyphHashKey)
 
+START(glyph_metrics, glyph_metrics_hash_key)
+    GENERIC(ASS_Font *, font)
+    GENERIC(double, size)
+    GENERIC(int, face_index)
+    GENERIC(int, glyph_index)
+    GENERIC(unsigned, scale_x)
+    GENERIC(unsigned, scale_y)
+END(GlyphMetricsHashKey)
+
+// describes an outline drawing
+START(drawing, drawing_hash_key)
+    GENERIC(unsigned, scale_x)
+    GENERIC(unsigned, scale_y)
+    GENERIC(int, pbo)
+    FTVECTOR(outline)
+    GENERIC(unsigned, border_style)
+    GENERIC(int, scale)
+    GENERIC(unsigned, hash)
+    STRING(text)
+END(DrawingHashKey)
+
 // Cache for composited bitmaps
 START(composite, composite_hash_key)
     GENERIC(int, aw)
@@ -117,6 +138,7 @@ END(CompositeHashKey)
 
 #undef START
 #undef GENERIC
+#undef STRING
 #undef FTVECTOR
 #undef BITMAPHASHKEY
 #undef END
index 37bb59a..764e6f6 100644 (file)
  */
 
 #include <ft2build.h>
-#include FT_GLYPH_H
 #include FT_OUTLINE_H
 #include FT_BBOX_H
 #include <math.h>
 
 #include "ass_utils.h"
-#include "ass_font.h"
 #include "ass_drawing.h"
 
 #define CURVE_ACCURACY 64.0
 #define GLYPH_INITIAL_CONTOURS 5
 
 /*
- * \brief Get and prepare a FreeType glyph
- */
-static void drawing_make_glyph(ASS_Drawing *drawing, void *fontconfig_priv,
-                               ASS_Font *font)
-{
-    FT_OutlineGlyph glyph;
-
-    // This is hacky...
-    glyph = (FT_OutlineGlyph) ass_font_get_glyph(fontconfig_priv, font,
-                                                 (uint32_t) ' ', 0, 0);
-    if (glyph) {
-        FT_Outline_Done(drawing->ftlibrary, &glyph->outline);
-        FT_Outline_New(drawing->ftlibrary, GLYPH_INITIAL_POINTS,
-                       GLYPH_INITIAL_CONTOURS, &glyph->outline);
-
-        glyph->outline.n_contours = 0;
-        glyph->outline.n_points = 0;
-        glyph->root.advance.x = glyph->root.advance.y = 0;
-    }
-    drawing->glyph = glyph;
-}
-
-/*
  * \brief Add a single point to a contour.
  */
 static inline void drawing_add_point(ASS_Drawing *drawing,
                                      FT_Vector *point)
 {
-    FT_Outline *ol = &drawing->glyph->outline;
+    FT_Outline *ol = &drawing->outline;
 
     if (ol->n_points >= drawing->max_points) {
         drawing->max_points *= 2;
@@ -75,11 +50,11 @@ static inline void drawing_add_point(ASS_Drawing *drawing,
 }
 
 /*
- * \brief Close a contour and check glyph size overflow.
+ * \brief Close a contour and check outline size overflow.
  */
 static inline void drawing_close_shape(ASS_Drawing *drawing)
 {
-    FT_Outline *ol = &drawing->glyph->outline;
+    FT_Outline *ol = &drawing->outline;
 
     if (ol->n_contours >= drawing->max_contours) {
         drawing->max_contours *= 2;
@@ -107,13 +82,13 @@ static void drawing_prepare(ASS_Drawing *drawing)
 
 /*
  * \brief Finish a drawing.  This only sets the horizontal advance according
- * to the glyph's bbox at the moment.
+ * to the outline's bbox at the moment.
  */
 static void drawing_finish(ASS_Drawing *drawing, int raw_mode)
 {
     int i, offset;
     FT_BBox bbox = drawing->cbox;
-    FT_Outline *ol = &drawing->glyph->outline;
+    FT_Outline *ol = &drawing->outline;
 
     // Close the last contour
     drawing_close_shape(drawing);
@@ -126,7 +101,7 @@ static void drawing_finish(ASS_Drawing *drawing, int raw_mode)
     if (raw_mode)
         return;
 
-    drawing->glyph->root.advance.x = d6_to_d16(bbox.xMax - bbox.xMin);
+    drawing->advance.x = bbox.xMax - bbox.xMin;
 
     drawing->desc = double_to_d6(-drawing->pbo * drawing->scale_y);
     drawing->asc = bbox.yMax - bbox.yMin + drawing->desc;
@@ -356,8 +331,7 @@ static void drawing_evaluate_curve(ASS_Drawing *drawing,
 /*
  * \brief Create and initialize a new drawing and return it
  */
-ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font,
-                             FT_Library lib)
+ASS_Drawing *ass_drawing_new(ASS_Library *lib, FT_Library ftlib)
 {
     ASS_Drawing *drawing;
 
@@ -366,17 +340,18 @@ ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font,
     drawing->size = DRAWING_INITIAL_SIZE;
     drawing->cbox.xMin = drawing->cbox.yMin = INT_MAX;
     drawing->cbox.xMax = drawing->cbox.yMax = INT_MIN;
-    drawing->fontconfig_priv = fontconfig_priv;
-    drawing->font = font;
-    drawing->ftlibrary = lib;
-    if (font)
-        drawing->library = font->library;
-
+    drawing->ftlibrary = ftlib;
+    drawing->library   = lib;
     drawing->scale_x = 1.;
     drawing->scale_y = 1.;
     drawing->max_contours = GLYPH_INITIAL_CONTOURS;
     drawing->max_points = GLYPH_INITIAL_POINTS;
 
+    FT_Outline_New(drawing->ftlibrary, GLYPH_INITIAL_POINTS,
+            GLYPH_INITIAL_CONTOURS, &drawing->outline);
+    drawing->outline.n_contours = 0;
+    drawing->outline.n_points = 0;
+
     return drawing;
 }
 
@@ -387,6 +362,7 @@ void ass_drawing_free(ASS_Drawing* drawing)
 {
     if (drawing) {
         free(drawing->text);
+        FT_Outline_Done(drawing->ftlibrary, &drawing->outline);
     }
     free(drawing);
 }
@@ -417,17 +393,12 @@ void ass_drawing_hash(ASS_Drawing* drawing)
 /*
  * \brief Convert token list to outline.  Calls the line and curve evaluators.
  */
-FT_OutlineGlyph *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode)
+FT_Outline *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode)
 {
     int started = 0;
     ASS_DrawingToken *token;
     FT_Vector pen = {0, 0};
 
-    if (drawing->font)
-        drawing_make_glyph(drawing, drawing->fontconfig_priv, drawing->font);
-    if (!drawing->glyph)
-        return NULL;
-
     drawing->tokens = drawing_tokenize(drawing->text);
     drawing_prepare(drawing);
 
@@ -487,5 +458,5 @@ FT_OutlineGlyph *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode)
 
     drawing_finish(drawing, raw_mode);
     drawing_free_tokens(drawing->tokens);
-    return &drawing->glyph;
+    return &drawing->outline;
 }
index f677fcd..b17d7e3 100644 (file)
@@ -20,7 +20,7 @@
 #define LIBASS_DRAWING_H
 
 #include <ft2build.h>
-#include FT_GLYPH_H
+#include FT_OUTLINE_H
 
 #include "ass.h"
 
@@ -53,13 +53,12 @@ typedef struct {
     double scale_y;     // FontScaleY
     int asc;            // ascender
     int desc;           // descender
-    FT_OutlineGlyph glyph;  // the "fake" glyph created for later rendering
+    FT_Outline outline; // target outline
+    FT_Vector advance;  // advance (from cbox)
     int hash;           // hash value (for caching)
 
     // private
     FT_Library ftlibrary;   // needed for font ops
-    ASS_Font *font;         // dito
-    void *fontconfig_priv;  // dito
     ASS_Library *library;
     int size;           // current buffer size
     ASS_DrawingToken *tokens;    // tokenized drawing
@@ -70,11 +69,10 @@ typedef struct {
     FT_BBox cbox;   // bounding box, or let's say... VSFilter's idea of it
 } ASS_Drawing;
 
-ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font,
-                             FT_Library lib);
+ASS_Drawing *ass_drawing_new(ASS_Library *lib, FT_Library ftlib);
 void ass_drawing_free(ASS_Drawing* drawing);
 void ass_drawing_add_char(ASS_Drawing* drawing, char symbol);
 void ass_drawing_hash(ASS_Drawing* drawing);
-FT_OutlineGlyph *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode);
+FT_Outline *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode);
 
 #endif /* LIBASS_DRAWING_H */
index f7ceea3..4b6a71b 100644 (file)
 #include "ass.h"
 #include "ass_library.h"
 #include "ass_font.h"
-#include "ass_bitmap.h"
-#include "ass_cache.h"
 #include "ass_fontconfig.h"
 #include "ass_utils.h"
-
-#define VERTICAL_LOWER_BOUND 0x02f1
+#include "ass_shaper.h"
 
 /**
  * Select a good charmap, prefer Microsoft Unicode charmaps.
@@ -93,8 +90,6 @@ static int find_font(ASS_Library *library, char *name)
     return -1;
 }
 
-static void face_set_size(FT_Face face, double size);
-
 static void buggy_font_workaround(FT_Face face)
 {
     // Some fonts have zero Ascender/Descender fields in 'hhea' table.
@@ -163,7 +158,7 @@ static int add_face(void *fc_priv, ASS_Font *font, uint32_t ch)
     buggy_font_workaround(face);
 
     font->faces[font->n_faces++] = face;
-    face_set_size(face, font->size);
+    ass_face_set_size(face, font->size);
     free(path);
     return font->n_faces - 1;
 }
@@ -171,7 +166,7 @@ static int add_face(void *fc_priv, ASS_Font *font, uint32_t ch)
 /**
  * \brief Create a new ASS_Font according to "desc" argument
  */
-ASS_Font *ass_font_new(void *font_cache, ASS_Library *library,
+ASS_Font *ass_font_new(Cache *font_cache, ASS_Library *library,
                        FT_Library ftlibrary, void *fc_priv,
                        ASS_FontDesc *desc)
 {
@@ -179,12 +174,13 @@ ASS_Font *ass_font_new(void *font_cache, ASS_Library *library,
     ASS_Font *fontp;
     ASS_Font font;
 
-    fontp = ass_font_cache_find((Hashmap *) font_cache, desc);
+    fontp = ass_cache_get(font_cache, desc);
     if (fontp)
         return fontp;
 
     font.library = library;
     font.ftlibrary = ftlibrary;
+    font.shaper_priv = NULL;
     font.n_faces = 0;
     font.desc.family = strdup(desc->family);
     font.desc.treat_family_as_pattern = desc->treat_family_as_pattern;
@@ -201,7 +197,7 @@ ASS_Font *ass_font_new(void *font_cache, ASS_Library *library,
         free(font.desc.family);
         return 0;
     } else
-        return ass_font_cache_add((Hashmap *) font_cache, &font);
+        return ass_cache_put(font_cache, &font.desc, &font);
 }
 
 /**
@@ -218,7 +214,7 @@ void ass_font_set_transform(ASS_Font *font, double scale_x,
     }
 }
 
-static void face_set_size(FT_Face face, double size)
+void ass_face_set_size(FT_Face face, double size)
 {
     TT_HoriHeader *hori = FT_Get_Sfnt_Table(face, ft_sfnt_hhea);
     TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
@@ -253,7 +249,7 @@ void ass_font_set_size(ASS_Font *font, double size)
     if (font->size != size) {
         font->size = size;
         for (i = 0; i < font->n_faces; ++i)
-            face_set_size(font->faces[i], size);
+            ass_face_set_size(font->faces[i], size);
     }
 }
 
@@ -278,9 +274,6 @@ void ass_font_get_asc_desc(ASS_Font *font, uint32_t ch, int *asc,
                 *asc = FT_MulFix(face->ascender, y_scale);
                 *desc = FT_MulFix(-face->descender, y_scale);
             }
-            if (font->desc.vertical && ch >= VERTICAL_LOWER_BOUND) {
-                *asc = FT_MulFix(face->max_advance_width, y_scale);
-            }
             return;
         }
     }
@@ -309,11 +302,11 @@ static int ass_strike_outline_glyph(FT_Face face, ASS_Font *font,
 
     // Grow outline
     i = (under ? 4 : 0) + (through ? 4 : 0);
-    ol->points = realloc(ol->points, sizeof(FT_Vector) *
+    ol->points = (FT_Vector *) realloc(ol->points, sizeof(FT_Vector) *
                          (ol->n_points + i));
-    ol->tags = realloc(ol->tags, ol->n_points + i);
+    ol->tags = (char *) realloc(ol->tags, ol->n_points + i);
     i = !!under + !!through;
-    ol->contours = realloc(ol->contours, sizeof(short) *
+    ol->contours = (short *) realloc(ol->contours, sizeof(short) *
                            (ol->n_contours + i));
 
     // If the bearing is negative, the glyph starts left of the current
@@ -395,6 +388,25 @@ static int ass_strike_outline_glyph(FT_Face face, ASS_Font *font,
     return 0;
 }
 
+void outline_copy(FT_Library lib, FT_Outline *source, FT_Outline **dest)
+{
+    if (source == NULL) {
+        *dest = NULL;
+        return;
+    }
+    *dest = calloc(1, sizeof(**dest));
+
+    FT_Outline_New(lib, source->n_points, source->n_contours, *dest);
+    FT_Outline_Copy(source, *dest);
+}
+
+void outline_free(FT_Library lib, FT_Outline *outline)
+{
+    if (outline)
+        FT_Outline_Done(lib, outline);
+    free(outline);
+}
+
 /**
  * Slightly embold a glyph without touching its metrics
  */
@@ -412,35 +424,43 @@ static void ass_glyph_embolden(FT_GlyphSlot slot)
 }
 
 /**
- * \brief Get a glyph
- * \param ch character code
- **/
-FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
-                            uint32_t ch, ASS_Hinting hinting, int deco)
+ * \brief Get glyph and face index
+ * Finds a face that has the requested codepoint and returns both face
+ * and glyph index.
+ */
+int ass_font_get_index(void *fcpriv, ASS_Font *font, uint32_t symbol,
+                       int *face_index, int *glyph_index)
 {
-    int error;
     int index = 0;
     int i;
-    FT_Glyph glyph;
     FT_Face face = 0;
-    int flags = 0;
-    int vertical = font->desc.vertical;
-    FT_Matrix scale;
-    FT_Outline *outl;
 
-    if (ch < 0x20)
+    *glyph_index = 0;
+
+    if (symbol < 0x20) {
+        *face_index = 0;
         return 0;
+    }
     // Handle NBSP like a regular space when rendering the glyph
-    if (ch == 0xa0)
-        ch = ' ';
-    if (font->n_faces == 0)
+    if (symbol == 0xa0)
+        symbol = ' ';
+    if (font->n_faces == 0) {
+        *face_index = 0;
         return 0;
+    }
 
-    for (i = 0; i < font->n_faces; ++i) {
+    // try with the requested face
+    if (*face_index < font->n_faces) {
+        face = font->faces[*face_index];
+        index = FT_Get_Char_Index(face, symbol);
+    }
+
+    // not found in requested face, try all others
+    for (i = 0; i < font->n_faces && index == 0; ++i) {
         face = font->faces[i];
-        index = FT_Get_Char_Index(face, ch);
+        index = FT_Get_Char_Index(face, symbol);
         if (index)
-            break;
+            *face_index = i;
     }
 
 #ifdef CONFIG_FONTCONFIG
@@ -448,30 +468,52 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
         int face_idx;
         ass_msg(font->library, MSGL_INFO,
                 "Glyph 0x%X not found, selecting one more "
-                "font for (%s, %d, %d)", ch, font->desc.family,
+                "font for (%s, %d, %d)", symbol, font->desc.family,
                 font->desc.bold, font->desc.italic);
-        face_idx = add_face(fontconfig_priv, font, ch);
+        face_idx = *face_index = add_face(fcpriv, font, symbol);
         if (face_idx >= 0) {
             face = font->faces[face_idx];
-            index = FT_Get_Char_Index(face, ch);
+            index = FT_Get_Char_Index(face, symbol);
             if (index == 0 && face->num_charmaps > 0) {
                 int i;
                 ass_msg(font->library, MSGL_WARN,
-                    "Glyph 0x%X not found, broken font? Trying all charmaps", ch);
+                    "Glyph 0x%X not found, broken font? Trying all charmaps", symbol);
                 for (i = 0; i < face->num_charmaps; i++) {
                     FT_Set_Charmap(face, face->charmaps[i]);
-                    if ((index = FT_Get_Char_Index(face, ch)) != 0) break;
+                    if ((index = FT_Get_Char_Index(face, symbol)) != 0) break;
                 }
             }
             if (index == 0) {
                 ass_msg(font->library, MSGL_ERR,
                         "Glyph 0x%X not found in font for (%s, %d, %d)",
-                        ch, font->desc.family, font->desc.bold,
+                        symbol, font->desc.family, font->desc.bold,
                         font->desc.italic);
             }
         }
     }
 #endif
+    // FIXME: make sure we have a valid face_index. this is a HACK.
+    *face_index  = FFMAX(*face_index, 0);
+    *glyph_index = index;
+
+    return 1;
+}
+
+/**
+ * \brief Get a glyph
+ * \param ch character code
+ **/
+FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
+                            uint32_t ch, int face_index, int index,
+                            ASS_Hinting hinting, int deco)
+{
+    int error;
+    FT_Glyph glyph;
+    FT_Matrix scale;
+    FT_Outline *outl = NULL;
+    FT_Face face = font->faces[face_index];
+    int flags = 0;
+    int vertical = font->desc.vertical;
 
     flags = FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
             | FT_LOAD_IGNORE_TRANSFORM;
@@ -514,10 +556,16 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
     // Rotate glyph, if needed
     if (vertical && ch >= VERTICAL_LOWER_BOUND) {
         FT_Matrix m = { 0, double_to_d16(-1.0), double_to_d16(1.0), 0 };
+        TT_OS2 *os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+        int desc = 0;
+
+        if (os2)
+            desc = FT_MulFix(os2->sTypoDescender, face->size->metrics.y_scale);
+
+        FT_Outline_Translate(&((FT_OutlineGlyph) glyph)->outline, 0, -desc);
         FT_Outline_Transform(&((FT_OutlineGlyph) glyph)->outline, &m);
         FT_Outline_Translate(&((FT_OutlineGlyph) glyph)->outline,
-                             face->glyph->metrics.vertAdvance,
-                             0);
+                             face->glyph->metrics.vertAdvance, desc);
         glyph->advance.x = face->glyph->linearVertAdvance;
     }
 
@@ -525,7 +573,7 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
     scale.xx = double_to_d16(font->scale_x);
     scale.xy = 0;
     scale.yx = 0;
-    scale.yy = double_to_d16(font->scale_y);
+    scale.yy  = double_to_d16(font->scale_y);
 
     outl = &((FT_OutlineGlyph) glyph)->outline;
     FT_Outline_Transform(outl, &scale);
@@ -573,6 +621,8 @@ void ass_font_free(ASS_Font *font)
     for (i = 0; i < font->n_faces; ++i)
         if (font->faces[i])
             FT_Done_Face(font->faces[i]);
+    if (font->shaper_priv)
+        ass_shaper_font_data_free(font->shaper_priv);
     free(font->desc.family);
     free(font);
 }
@@ -630,9 +680,9 @@ static int get_contour_direction(FT_Vector *points, int start, int end)
  * \param border_x border size, x direction, d6 format
  * \param border_x border size, y direction, d6 format
  */
-void fix_freetype_stroker(FT_OutlineGlyph glyph, int border_x, int border_y)
+void fix_freetype_stroker(FT_Outline *outline, int border_x, int border_y)
 {
-    int nc = glyph->outline.n_contours;
+    int nc = outline->n_contours;
     int begin, stop;
     char modified = 0;
     char *valid_cont = malloc(nc);
@@ -642,14 +692,14 @@ void fix_freetype_stroker(FT_OutlineGlyph glyph, int border_x, int border_y)
     int i, j;
     int inside_direction;
 
-    inside_direction = FT_Outline_Get_Orientation(&glyph->outline) ==
+    inside_direction = FT_Outline_Get_Orientation(outline) ==
         FT_ORIENTATION_TRUETYPE;
 
     // create a list of cboxes of the contours
     for (i = 0; i < nc; i++) {
         start = end + 1;
-        end = glyph->outline.contours[i];
-        get_contour_cbox(&boxes[i], glyph->outline.points, start, end);
+        end = outline->contours[i];
+        get_contour_cbox(&boxes[i], outline->points, start, end);
     }
 
     // for each contour, check direction and whether it's "outside"
@@ -658,8 +708,8 @@ void fix_freetype_stroker(FT_OutlineGlyph glyph, int border_x, int border_y)
     for (i = 0; i < nc; i++) {
         int dir;
         start = end + 1;
-        end = glyph->outline.contours[i];
-        dir = get_contour_direction(glyph->outline.points, start, end);
+        end = outline->contours[i];
+        dir = get_contour_direction(outline->points, start, end);
         valid_cont[i] = 1;
         if (dir == inside_direction) {
             for (j = 0; j < nc; j++) {
@@ -675,12 +725,12 @@ void fix_freetype_stroker(FT_OutlineGlyph glyph, int border_x, int border_y)
              * inside of - assume the font is buggy and it should be
              * an "outside" contour, and reverse it */
             for (j = 0; j < (end + 1 - start) / 2; j++) {
-                FT_Vector temp = glyph->outline.points[start + j];
-                char temp2 = glyph->outline.tags[start + j];
-                glyph->outline.points[start + j] = glyph->outline.points[end - j];
-                glyph->outline.points[end - j] = temp;
-                glyph->outline.tags[start + j] = glyph->outline.tags[end - j];
-                glyph->outline.tags[end - j] = temp2;
+                FT_Vector temp = outline->points[start + j];
+                char temp2 = outline->tags[start + j];
+                outline->points[start + j] = outline->points[end - j];
+                outline->points[end - j] = temp;
+                outline->tags[start + j] = outline->tags[end - j];
+                outline->tags[end - j] = temp2;
             }
             dir ^= 1;
         }
@@ -688,7 +738,7 @@ void fix_freetype_stroker(FT_OutlineGlyph glyph, int border_x, int border_y)
         if (dir == inside_direction) {
             FT_BBox box;
             int width, height;
-            get_contour_cbox(&box, glyph->outline.points, start, end);
+            get_contour_cbox(&box, outline->points, start, end);
             width = box.xMax - box.xMin;
             height = box.yMax - box.yMin;
             if (width < border_x * 2 || height < border_y * 2) {
@@ -701,13 +751,12 @@ void fix_freetype_stroker(FT_OutlineGlyph glyph, int border_x, int border_y)
     // if we need to modify the outline, rewrite it and skip
     // the contours that we determined should be removed.
     if (modified) {
-        FT_Outline *outline = &glyph->outline;
         int p = 0, c = 0;
         for (i = 0; i < nc; i++) {
             if (!valid_cont[i])
                 continue;
-            begin = (i == 0) ? 0 : glyph->outline.contours[i - 1] + 1;
-            stop = glyph->outline.contours[i];
+            begin = (i == 0) ? 0 : outline->contours[i - 1] + 1;
+            stop = outline->contours[i];
             for (j = begin; j <= stop; j++) {
                 outline->points[p].x = outline->points[j].x;
                 outline->points[p].y = outline->points[j].y;
index ab40548..481a630 100644 (file)
 #include <stdint.h>
 #include <ft2build.h>
 #include FT_GLYPH_H
+#include FT_OUTLINE_H
+
 #include "ass.h"
 #include "ass_types.h"
 
+#define VERTICAL_LOWER_BOUND 0x02f1
+
 #define ASS_FONT_MAX_FACES 10
 #define DECO_UNDERLINE 1
 #define DECO_STRIKETHROUGH 2
 
+typedef struct ass_shaper_font_data ASS_ShaperFontData;
+
 typedef struct {
     char *family;
     unsigned bold;
@@ -42,25 +48,33 @@ typedef struct {
     ASS_Library *library;
     FT_Library ftlibrary;
     FT_Face faces[ASS_FONT_MAX_FACES];
+    ASS_ShaperFontData *shaper_priv;
     int n_faces;
     double scale_x, scale_y;    // current transform
     FT_Vector v;                // current shift
     double size;
 } ASS_Font;
 
-// FIXME: passing the hashmap via a void pointer is very ugly.
-ASS_Font *ass_font_new(void *font_cache, ASS_Library *library,
+#include "ass_cache.h"
+
+ASS_Font *ass_font_new(Cache *font_cache, ASS_Library *library,
                        FT_Library ftlibrary, void *fc_priv,
                        ASS_FontDesc *desc);
 void ass_font_set_transform(ASS_Font *font, double scale_x,
                             double scale_y, FT_Vector *v);
+void ass_face_set_size(FT_Face face, double size);
 void ass_font_set_size(ASS_Font *font, double size);
 void ass_font_get_asc_desc(ASS_Font *font, uint32_t ch, int *asc,
                            int *desc);
+int ass_font_get_index(void *fcpriv, ASS_Font *font, uint32_t symbol,
+                       int *face_index, int *glyph_index);
 FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
-                            uint32_t ch, ASS_Hinting hinting, int flags);
+                            uint32_t ch, int face_index, int index,
+                            ASS_Hinting hinting, int deco);
 FT_Vector ass_font_get_kerning(ASS_Font *font, uint32_t c1, uint32_t c2);
 void ass_font_free(ASS_Font *font);
-void fix_freetype_stroker(FT_OutlineGlyph glyph, int border_x, int border_y);
+void fix_freetype_stroker(FT_Outline *outline, int border_x, int border_y);
+void outline_copy(FT_Library lib, FT_Outline *source, FT_Outline **dest);
+void outline_free(FT_Library lib, FT_Outline *outline);
 
 #endif                          /* LIBASS_FONT_H */
index 5bca644..b33ca55 100644 (file)
@@ -78,6 +78,7 @@ void ass_set_style_overrides(ASS_Library *priv, char **list)
             free(*p);
     }
     free(priv->style_overrides);
+    priv->style_overrides = NULL;
 
     if (!list)
         return;
index 55e8fd1..92a47b3 100644 (file)
@@ -47,17 +47,18 @@ static inline int mystrcmp(char **p, const char *sample)
         return 0;
 }
 
-static void change_font_size(ASS_Renderer *render_priv, double sz)
+double ensure_font_size(ASS_Renderer *priv, double size)
 {
-    double size = sz * render_priv->font_scale;
-
     if (size < 1)
         size = 1;
-    else if (size > render_priv->height * 2)
-        size = render_priv->height * 2;
+    else if (size > priv->height * 2)
+        size = priv->height * 2;
 
-    ass_font_set_size(render_priv->state.font, size);
+    return size;
+}
 
+static void change_font_size(ASS_Renderer *render_priv, double sz)
+{
     render_priv->state.font_size = sz;
 }
 
@@ -189,17 +190,18 @@ interpolate_alpha(long long now, long long t1, long long t2, long long t3,
 {
     unsigned a;
     double cf;
-    if (now <= t1) {
+
+    if (now < t1) {
         a = a1;
     } else if (now >= t4) {
         a = a3;
-    } else if (now < t2) {      // and > t1
+    } else if (now < t2 && t2 > t1) {
         cf = ((double) (now - t1)) / (t2 - t1);
         a = a1 * (1 - cf) + a2 * cf;
-    } else if (now > t3) {
+    } else if (now >= t3 && t4 > t3) {
         cf = ((double) (now - t3)) / (t4 - t3);
         a = a2 * (1 - cf) + a3 * cf;
-    } else {                    // t2 <= now <= t3
+    } else {                    // t2 <= now < t3
         a = a2;
     }
 
@@ -216,13 +218,9 @@ static char *parse_vector_clip(ASS_Renderer *render_priv, char *p)
     int res = 0;
     ASS_Drawing *drawing = render_priv->state.clip_drawing;
 
-    if (drawing && drawing->glyph)
-        FT_Done_Glyph((FT_Glyph) drawing->glyph);
     ass_drawing_free(drawing);
-    render_priv->state.clip_drawing = ass_drawing_new(
-        render_priv->fontconfig_priv,
-        render_priv->state.font,
-        render_priv->ftlibrary);
+    render_priv->state.clip_drawing =
+        ass_drawing_new(render_priv->library, render_priv->ftlibrary);
     drawing = render_priv->state.clip_drawing;
     skipopt('(');
     res = mystrtoi(&p, &scale);
@@ -259,6 +257,7 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
         else
             val = -1.;
         change_border(render_priv, val, render_priv->state.border_y);
+        render_priv->state.bm_run_id++;
     } else if (mystrcmp(&p, "ybord")) {
         double val;
         if (mystrtod(&p, &val))
@@ -273,6 +272,7 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
         else
             val = 0.;
         render_priv->state.shadow_x = val;
+        render_priv->state.bm_run_id++;
     } else if (mystrcmp(&p, "yshad")) {
         double val;
         if (mystrtod(&p, &val))
@@ -280,6 +280,7 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
         else
             val = 0.;
         render_priv->state.shadow_y = val;
+        render_priv->state.bm_run_id++;
     } else if (mystrcmp(&p, "fax")) {
         double val;
         if (mystrtod(&p, &val))
@@ -331,6 +332,7 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
             render_priv->state.blur = val;
         } else
             render_priv->state.blur = 0.0;
+        render_priv->state.bm_run_id++;
         // ASS standard tags
     } else if (mystrcmp(&p, "fsc")) {
         char tp = *p++;
@@ -391,6 +393,7 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
         } else
             val = -1.;          // reset to default
         change_border(render_priv, val, val);
+        render_priv->state.bm_run_id++;
     } else if (mystrcmp(&p, "move")) {
         double x1, x2, y1, y2;
         long long t1, t2, delta_t, t;
@@ -492,6 +495,7 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
             change_alpha(&render_priv->state.c[3],
                          render_priv->state.style->BackColour, pwr);
         }
+        render_priv->state.bm_run_id++;
         // FIXME: simplify
     } else if (mystrcmp(&p, "an")) {
         int val;
@@ -682,6 +686,7 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
             val = render_priv->state.style->PrimaryColour;
         ass_msg(render_priv->library, MSGL_DBG2, "color: %X", val);
         change_color(&render_priv->state.c[0], val, pwr);
+        render_priv->state.bm_run_id++;
     } else if ((*p >= '1') && (*p <= '4') && (++p)
                && (mystrcmp(&p, "c") || mystrcmp(&p, "a"))) {
         char n = *(p - 2);
@@ -711,9 +716,11 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
         switch (cmd) {
         case 'c':
             change_color(render_priv->state.c + cidx, val, pwr);
+            render_priv->state.bm_run_id++;
             break;
         case 'a':
             change_alpha(render_priv->state.c + cidx, val >> 24, pwr);
+            render_priv->state.bm_run_id++;
             break;
         default:
             ass_msg(render_priv->library, MSGL_WARN, "Bad command: %c%c",
@@ -733,6 +740,7 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
             render_priv->state.be = val;
         } else
             render_priv->state.be = 0;
+        render_priv->state.bm_run_id++;
     } else if (mystrcmp(&p, "b")) {
         int b;
         if (mystrtoi(&p, &b)) {
@@ -781,18 +789,21 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
         } else
             val = 0.;
         render_priv->state.shadow_x = render_priv->state.shadow_y = val;
+        render_priv->state.bm_run_id++;
     } else if (mystrcmp(&p, "s")) {
         int val;
         if (mystrtoi(&p, &val) && val)
             render_priv->state.flags |= DECO_STRIKETHROUGH;
         else
             render_priv->state.flags &= ~DECO_STRIKETHROUGH;
+        render_priv->state.bm_run_id++;
     } else if (mystrcmp(&p, "u")) {
         int val;
         if (mystrtoi(&p, &val) && val)
             render_priv->state.flags |= DECO_UNDERLINE;
         else
             render_priv->state.flags &= ~DECO_UNDERLINE;
+        render_priv->state.bm_run_id++;
     } else if (mystrcmp(&p, "pbo")) {
         double val = 0;
         if (mystrtod(&p, &val))
@@ -809,6 +820,11 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
         if (!mystrtoi(&p, &val))
             val = render_priv->track->WrapStyle;
         render_priv->state.wrap_style = val;
+    } else if (mystrcmp(&p, "fe")) {
+        int val;
+        if (!mystrtoi(&p, &val))
+            val = render_priv->state.style->Encoding;
+        render_priv->state.font_encoding = val;
     }
 
     return p;
@@ -890,6 +906,77 @@ void apply_transition_effects(ASS_Renderer *render_priv, ASS_Event *event)
 }
 
 /**
+ * \brief determine karaoke effects
+ * Karaoke effects cannot be calculated during parse stage (get_next_char()),
+ * so they are done in a separate step.
+ * Parse stage: when karaoke style override is found, its parameters are stored in the next glyph's
+ * (the first glyph of the karaoke word)'s effect_type and effect_timing.
+ * This function:
+ * 1. sets effect_type for all glyphs in the word (_karaoke_ word)
+ * 2. sets effect_timing for all glyphs to x coordinate of the border line between the left and right karaoke parts
+ * (left part is filled with PrimaryColour, right one - with SecondaryColour).
+ */
+void process_karaoke_effects(ASS_Renderer *render_priv)
+{
+    GlyphInfo *cur, *cur2;
+    GlyphInfo *s1, *e1;      // start and end of the current word
+    GlyphInfo *s2;           // start of the next word
+    int i;
+    int timing;                 // current timing
+    int tm_start, tm_end;       // timings at start and end of the current word
+    int tm_current;
+    double dt;
+    int x;
+    int x_start, x_end;
+
+    tm_current = render_priv->time - render_priv->state.event->Start;
+    timing = 0;
+    s1 = s2 = 0;
+    for (i = 0; i <= render_priv->text_info.length; ++i) {
+        cur = render_priv->text_info.glyphs + i;
+        if ((i == render_priv->text_info.length)
+            || (cur->effect_type != EF_NONE)) {
+            s1 = s2;
+            s2 = cur;
+            if (s1) {
+                e1 = s2 - 1;
+                tm_start = timing + s1->effect_skip_timing;
+                tm_end = tm_start + s1->effect_timing;
+                timing = tm_end;
+                x_start = 1000000;
+                x_end = -1000000;
+                for (cur2 = s1; cur2 <= e1; ++cur2) {
+                    x_start = FFMIN(x_start, d6_to_int(cur2->bbox.xMin + cur2->pos.x));
+                    x_end = FFMAX(x_end, d6_to_int(cur2->bbox.xMax + cur2->pos.x));
+                }
+
+                dt = (tm_current - tm_start);
+                if ((s1->effect_type == EF_KARAOKE)
+                    || (s1->effect_type == EF_KARAOKE_KO)) {
+                    if (dt > 0)
+                        x = x_end + 1;
+                    else
+                        x = x_start;
+                } else if (s1->effect_type == EF_KARAOKE_KF) {
+                    dt /= (tm_end - tm_start);
+                    x = x_start + (x_end - x_start) * dt;
+                } else {
+                    ass_msg(render_priv->library, MSGL_ERR,
+                            "Unknown effect type");
+                    continue;
+                }
+
+                for (cur2 = s1; cur2 <= e1; ++cur2) {
+                    cur2->effect_type = s1->effect_type;
+                    cur2->effect_timing = x - d6_to_int(cur2->pos.x);
+                }
+            }
+        }
+    }
+}
+
+
+/**
  * \brief Get next ucs4 char from string, parsing and executing style overrides
  * \param str string pointer
  * \return ucs4 code of the next char
index c65b565..2e145dc 100644 (file)
 #define _a(c)   ((c) & 0xFF)
 
 void update_font(ASS_Renderer *render_priv);
+double ensure_font_size(ASS_Renderer *priv, double size);
 void change_border(ASS_Renderer *render_priv, double border_x,
                    double border_y);
 void apply_transition_effects(ASS_Renderer *render_priv, ASS_Event *event);
+void process_karaoke_effects(ASS_Renderer *render_priv);
 unsigned get_next_char(ASS_Renderer *render_priv, char **str);
 extern void change_alpha(uint32_t *var, uint32_t new, double pwr);
 extern uint32_t mult_alpha(uint32_t a, uint32_t b);
index 919b2b0..b6c0159 100644 (file)
 
 #include "ass_render.h"
 #include "ass_parse.h"
+#include "ass_shaper.h"
 
 #define MAX_GLYPHS_INITIAL 1024
 #define MAX_LINES_INITIAL 64
 #define SUBPIXEL_MASK 63
 #define SUBPIXEL_ACCURACY 7
 
-static void ass_lazy_track_init(ASS_Renderer *render_priv)
-{
-    ASS_Track *track = render_priv->track;
-
-    if (track->PlayResX && track->PlayResY)
-        return;
-    if (!track->PlayResX && !track->PlayResY) {
-        ass_msg(render_priv->library, MSGL_WARN,
-               "Neither PlayResX nor PlayResY defined. Assuming 384x288");
-        track->PlayResX = 384;
-        track->PlayResY = 288;
-    } else {
-        if (!track->PlayResY && track->PlayResX == 1280) {
-            track->PlayResY = 1024;
-            ass_msg(render_priv->library, MSGL_WARN,
-                   "PlayResY undefined, setting to %d", track->PlayResY);
-        } else if (!track->PlayResY) {
-            track->PlayResY = track->PlayResX * 3 / 4;
-            ass_msg(render_priv->library, MSGL_WARN,
-                   "PlayResY undefined, setting to %d", track->PlayResY);
-        } else if (!track->PlayResX && track->PlayResY == 1024) {
-            track->PlayResX = 1280;
-            ass_msg(render_priv->library, MSGL_WARN,
-                   "PlayResX undefined, setting to %d", track->PlayResX);
-        } else if (!track->PlayResX) {
-            track->PlayResX = track->PlayResY * 4 / 3;
-            ass_msg(render_priv->library, MSGL_WARN,
-                   "PlayResX undefined, setting to %d", track->PlayResX);
-        }
-    }
-}
-
 ASS_Renderer *ass_renderer_init(ASS_Library *library)
 {
     int error;
@@ -75,10 +44,8 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library)
     }
 
     FT_Library_Version(ft, &vmajor, &vminor, &vpatch);
-    ass_msg(library, MSGL_V, "FreeType library version: %d.%d.%d",
+    ass_msg(library, MSGL_V, "Raster: FreeType %d.%d.%d",
            vmajor, vminor, vpatch);
-    ass_msg(library, MSGL_V, "FreeType headers version: %d.%d.%d",
-           FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
 
     priv = calloc(1, sizeof(ASS_Renderer));
     if (!priv) {
@@ -92,10 +59,10 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library)
     priv->ftlibrary = ft;
     // images_root and related stuff is zero-filled in calloc
 
-    priv->cache.font_cache = ass_font_cache_init(library);
-    priv->cache.bitmap_cache = ass_bitmap_cache_init(library);
-    priv->cache.composite_cache = ass_composite_cache_init(library);
-    priv->cache.glyph_cache = ass_glyph_cache_init(library);
+    priv->cache.font_cache = ass_font_cache_create();
+    priv->cache.bitmap_cache = ass_bitmap_cache_create();
+    priv->cache.composite_cache = ass_composite_cache_create();
+    priv->cache.outline_cache = ass_outline_cache_create();
     priv->cache.glyph_max = GLYPH_CACHE_MAX;
     priv->cache.bitmap_max_size = BITMAP_CACHE_MAX_SIZE;
 
@@ -106,11 +73,19 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library)
 
     priv->settings.font_size_coeff = 1.;
 
+    priv->shaper = ass_shaper_new(0);
+    ass_shaper_info(library);
+#ifdef CONFIG_HARFBUZZ
+    priv->settings.shaper = ASS_SHAPING_COMPLEX;
+#else
+    priv->settings.shaper = ASS_SHAPING_SIMPLE;
+#endif
+
   ass_init_exit:
     if (priv)
-        ass_msg(library, MSGL_V, "Init");
+        ass_msg(library, MSGL_V, "Initialized");
     else
-        ass_msg(library, MSGL_ERR, "Init failed");
+        ass_msg(library, MSGL_ERR, "Initialization failed");
 
     return priv;
 }
@@ -131,10 +106,10 @@ static void free_list_clear(ASS_Renderer *render_priv)
 
 void ass_renderer_done(ASS_Renderer *render_priv)
 {
-    ass_font_cache_done(render_priv->cache.font_cache);
-    ass_bitmap_cache_done(render_priv->cache.bitmap_cache);
-    ass_composite_cache_done(render_priv->cache.composite_cache);
-    ass_glyph_cache_done(render_priv->cache.glyph_cache);
+    ass_cache_done(render_priv->cache.font_cache);
+    ass_cache_done(render_priv->cache.bitmap_cache);
+    ass_cache_done(render_priv->cache.composite_cache);
+    ass_cache_done(render_priv->cache.outline_cache);
 
     ass_free_images(render_priv->images_root);
     ass_free_images(render_priv->prev_images_root);
@@ -149,6 +124,7 @@ void ass_renderer_done(ASS_Renderer *render_priv)
         fontconfig_done(render_priv->fontconfig_priv);
     if (render_priv->synth_priv)
         ass_synth_done(render_priv->synth_priv);
+    ass_shaper_free(render_priv->shaper);
     free(render_priv->eimg);
     free(render_priv->text_info.glyphs);
     free(render_priv->text_info.lines);
@@ -328,18 +304,18 @@ static ASS_Image **render_glyph_i(ASS_Renderer *render_priv,
         // split up into left and right for karaoke, if needed
         if (lbrk > r[j].x0) {
             if (lbrk > r[j].x1) lbrk = r[j].x1;
-            img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->w + r[j].x0,
+            img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->stride + r[j].x0,
                 lbrk - r[j].x0, r[j].y1 - r[j].y0,
-                bm->w, dst_x + r[j].x0, dst_y + r[j].y0, color);
+                bm->stride, dst_x + r[j].x0, dst_y + r[j].y0, color);
             if (!img) break;
             *tail = img;
             tail = &img->next;
         }
         if (lbrk < r[j].x1) {
             if (lbrk < r[j].x0) lbrk = r[j].x0;
-            img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->w + lbrk,
+            img = my_draw_bitmap(bm->buffer + r[j].y0 * bm->stride + lbrk,
                 r[j].x1 - lbrk, r[j].y1 - r[j].y0,
-                bm->w, dst_x + lbrk, dst_y + r[j].y0, color2);
+                bm->stride, dst_x + lbrk, dst_y + r[j].y0, color2);
             if (!img) break;
             *tail = img;
             tail = &img->next;
@@ -365,6 +341,7 @@ static ASS_Image **
 render_glyph(ASS_Renderer *render_priv, Bitmap *bm, int dst_x, int dst_y,
              uint32_t color, uint32_t color2, int brk, ASS_Image **tail)
 {
+
     // brk is relative to dst_x
     // color = color left of brk
     // color2 = color right of brk
@@ -419,8 +396,8 @@ render_glyph(ASS_Renderer *render_priv, Bitmap *bm, int dst_x, int dst_y,
     if (brk > b_x0) {           // draw left part
         if (brk > b_x1)
             brk = b_x1;
-        img = my_draw_bitmap(bm->buffer + bm->w * b_y0 + b_x0,
-                             brk - b_x0, b_y1 - b_y0, bm->w,
+        img = my_draw_bitmap(bm->buffer + bm->stride * b_y0 + b_x0,
+                             brk - b_x0, b_y1 - b_y0, bm->stride,
                              dst_x + b_x0, dst_y + b_y0, color);
         if (!img) return tail;
         *tail = img;
@@ -429,8 +406,8 @@ render_glyph(ASS_Renderer *render_priv, Bitmap *bm, int dst_x, int dst_y,
     if (brk < b_x1) {           // draw right part
         if (brk < b_x0)
             brk = b_x0;
-        img = my_draw_bitmap(bm->buffer + bm->w * b_y0 + brk,
-                             b_x1 - brk, b_y1 - b_y0, bm->w,
+        img = my_draw_bitmap(bm->buffer + bm->stride * b_y0 + brk,
+                             b_x1 - brk, b_y1 - b_y0, bm->stride,
                              dst_x + brk, dst_y + b_y0, color2);
         if (!img) return tail;
         *tail = img;
@@ -516,7 +493,7 @@ render_overlap(ASS_Renderer *render_priv, ASS_Image **last_tail,
     hk.by = by;
     hk.as = as;
     hk.bs = bs;
-    hv = cache_find_composite(render_priv->cache.composite_cache, &hk);
+    hv = ass_cache_get(render_priv->cache.composite_cache, &hk);
     if (hv) {
         (*last_tail)->bitmap = hv->a;
         (*tail)->bitmap = hv->b;
@@ -539,7 +516,7 @@ render_overlap(ASS_Renderer *render_priv, ASS_Image **last_tail,
     // Insert bitmaps into the cache
     chv.a = (*last_tail)->bitmap;
     chv.b = (*tail)->bitmap;
-    cache_add_composite(render_priv->cache.composite_cache, &hk, &chv);
+    ass_cache_put(render_priv->cache.composite_cache, &hk, &chv);
 }
 
 static void free_list_add(ASS_Renderer *render_priv, void *object)
@@ -564,32 +541,31 @@ static void free_list_add(ASS_Renderer *render_priv, void *object)
 static void blend_vector_clip(ASS_Renderer *render_priv,
                               ASS_Image *head)
 {
-    FT_Glyph glyph;
-    FT_BitmapGlyph clip_bm;
+    FT_Outline *outline;
+    Bitmap *clip_bm = NULL;
     ASS_Image *cur;
     ASS_Drawing *drawing = render_priv->state.clip_drawing;
-    GlyphHashKey key;
-    GlyphHashValue *val;
+    BitmapHashKey key;
+    BitmapHashValue *val;
     int error;
 
     if (!drawing)
         return;
 
     // Try to get mask from cache
-    ass_drawing_hash(drawing);
     memset(&key, 0, sizeof(key));
-    key.ch = -2;
-    key.drawing_hash = drawing->hash;
-    val = cache_find_glyph(render_priv->cache.glyph_cache, &key);
+    key.type = BITMAP_CLIP;
+    key.u.clip.text = drawing->text;
+    val = ass_cache_get(render_priv->cache.bitmap_cache, &key);
 
     if (val) {
-        clip_bm = (FT_BitmapGlyph) val->glyph;
+        clip_bm = val->bm;
     } else {
-        GlyphHashValue v;
+        BitmapHashValue v;
 
         // Not found in cache, parse and rasterize it
-        glyph = (FT_Glyph) *ass_drawing_parse(drawing, 1);
-        if (!glyph) {
+        outline = ass_drawing_parse(drawing, 1);
+        if (!outline) {
             ass_msg(render_priv->library, MSGL_WARN,
                     "Clip vector parsing failed. Skipping.");
             goto blend_vector_error;
@@ -598,41 +574,30 @@ static void blend_vector_clip(ASS_Renderer *render_priv,
         // We need to translate the clip according to screen borders
         if (render_priv->settings.left_margin != 0 ||
             render_priv->settings.top_margin != 0) {
-            FT_Vector trans = {
-                trans.x = int_to_d6(render_priv->settings.left_margin),
-                trans.y = -int_to_d6(render_priv->settings.top_margin),
-            };
-            FT_Outline_Translate(&drawing->glyph->outline,
-                                 trans.x, trans.y);
-        }
-
-        // Check glyph bounding box size
-        if (check_glyph_area(render_priv->library, glyph)) {
-            FT_Done_Glyph(glyph);
-            glyph = 0;
-            goto blend_vector_error;
+            FT_Vector trans;
+            trans.x = int_to_d6(render_priv->settings.left_margin);
+            trans.y = -int_to_d6(render_priv->settings.top_margin);
+            FT_Outline_Translate(outline, trans.x, trans.y);
         }
 
         ass_msg(render_priv->library, MSGL_DBG2,
                 "Parsed vector clip: scales (%f, %f) string [%s]\n",
                 drawing->scale_x, drawing->scale_y, drawing->text);
 
-        error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
-        if (error) {
+        clip_bm = outline_to_bitmap(render_priv->library,
+                render_priv->ftlibrary, outline, 0);
+        if (clip_bm == NULL) {
             ass_msg(render_priv->library, MSGL_WARN,
                 "Clip vector rasterization failed: %d. Skipping.", error);
-            FT_Done_Glyph(glyph);
-            glyph = 0;
         }
 
-blend_vector_error:
-        clip_bm = (FT_BitmapGlyph) glyph;
-
         // Add to cache
         memset(&v, 0, sizeof(v));
-        v.glyph = glyph;
-        cache_add_glyph(render_priv->cache.glyph_cache, &key, &v);
+        key.u.clip.text = strdup(drawing->text);
+        v.bm = clip_bm;
+        ass_cache_put(render_priv->cache.bitmap_cache, &key, &v);
     }
+blend_vector_error:
 
     if (!clip_bm) goto blend_vector_exit;
 
@@ -645,17 +610,17 @@ blend_vector_error:
         unsigned char *abuffer, *bbuffer, *nbuffer;
 
         abuffer = cur->bitmap;
-        bbuffer = clip_bm->bitmap.buffer;
+        bbuffer = clip_bm->buffer;
         ax = cur->dst_x;
         ay = cur->dst_y;
         aw = cur->w;
         ah = cur->h;
         as = cur->stride;
         bx = clip_bm->left;
-        by = -clip_bm->top;
-        bw = clip_bm->bitmap.width;
-        bh = clip_bm->bitmap.rows;
-        bs = clip_bm->bitmap.pitch;
+        by = clip_bm->top;
+        bw = clip_bm->w;
+        bh = clip_bm->h;
+        bs = clip_bm->stride;
 
         // Calculate overlap coordinates
         left = (ax > bx) ? ax : bx;
@@ -739,22 +704,31 @@ static ASS_Image *render_text(ASS_Renderer *render_priv, int dst_x, int dst_y)
             || (info->shadow_x == 0 && info->shadow_y == 0) || info->skip)
             continue;
 
-        pen_x =
-            dst_x + (info->pos.x >> 6) +
-            (int) (info->shadow_x * render_priv->border_scale);
-        pen_y =
-            dst_y + (info->pos.y >> 6) +
-            (int) (info->shadow_y * render_priv->border_scale);
-        bm = info->bm_s;
-
-        here_tail = tail;
-        tail =
-            render_glyph(render_priv, bm, pen_x, pen_y, info->c[3], 0,
-                         1000000, tail);
-        if (last_tail && tail != here_tail && ((info->c[3] & 0xff) > 0))
-            render_overlap(render_priv, last_tail, here_tail);
-
-        last_tail = here_tail;
+        while (info) {
+            if (!info->bm_s) {
+                info = info->next;
+                continue;
+            }
+
+            pen_x =
+                dst_x + (info->pos.x >> 6) +
+                (int) (info->shadow_x * render_priv->border_scale);
+            pen_y =
+                dst_y + (info->pos.y >> 6) +
+                (int) (info->shadow_y * render_priv->border_scale);
+            bm = info->bm_s;
+
+            here_tail = tail;
+            tail =
+                render_glyph(render_priv, bm, pen_x, pen_y, info->c[3], 0,
+                        1000000, tail);
+
+            if (last_tail && tail != here_tail && ((info->c[3] & 0xff) > 0))
+                render_overlap(render_priv, last_tail, here_tail);
+            last_tail = here_tail;
+
+            info = info->next;
+        }
     }
 
     last_tail = 0;
@@ -764,22 +738,30 @@ static ASS_Image *render_text(ASS_Renderer *render_priv, int dst_x, int dst_y)
             || info->skip)
             continue;
 
-        pen_x = dst_x + (info->pos.x >> 6);
-        pen_y = dst_y + (info->pos.y >> 6);
-        bm = info->bm_o;
+        while (info) {
+            if (!info->bm_o) {
+                info = info->next;
+                continue;
+            }
 
-        if ((info->effect_type == EF_KARAOKE_KO)
-            && (info->effect_timing <= (info->bbox.xMax >> 6))) {
-            // do nothing
-        } else {
-            here_tail = tail;
-            tail =
-                render_glyph(render_priv, bm, pen_x, pen_y, info->c[2],
-                             0, 1000000, tail);
-            if (last_tail && tail != here_tail && ((info->c[2] & 0xff) > 0))
-                render_overlap(render_priv, last_tail, here_tail);
+            pen_x = dst_x + (info->pos.x >> 6);
+            pen_y = dst_y + (info->pos.y >> 6);
+            bm = info->bm_o;
 
-            last_tail = here_tail;
+            if ((info->effect_type == EF_KARAOKE_KO)
+                    && (info->effect_timing <= (info->bbox.xMax >> 6))) {
+                // do nothing
+            } else {
+                here_tail = tail;
+                tail =
+                    render_glyph(render_priv, bm, pen_x, pen_y, info->c[2],
+                            0, 1000000, tail);
+                if (last_tail && tail != here_tail && ((info->c[2] & 0xff) > 0))
+                    render_overlap(render_priv, last_tail, here_tail);
+
+                last_tail = here_tail;
+            }
+            info = info->next;
         }
     }
 
@@ -789,28 +771,36 @@ static ASS_Image *render_text(ASS_Renderer *render_priv, int dst_x, int dst_y)
             || info->skip)
             continue;
 
-        pen_x = dst_x + (info->pos.x >> 6);
-        pen_y = dst_y + (info->pos.y >> 6);
-        bm = info->bm;
+        while (info) {
+            if (!info->bm) {
+                info = info->next;
+                continue;
+            }
 
-        if ((info->effect_type == EF_KARAOKE)
-            || (info->effect_type == EF_KARAOKE_KO)) {
-            if (info->effect_timing > (info->bbox.xMax >> 6))
+            pen_x = dst_x + (info->pos.x >> 6);
+            pen_y = dst_y + (info->pos.y >> 6);
+            bm = info->bm;
+
+            if ((info->effect_type == EF_KARAOKE)
+                    || (info->effect_type == EF_KARAOKE_KO)) {
+                if (info->effect_timing > (info->bbox.xMax >> 6))
+                    tail =
+                        render_glyph(render_priv, bm, pen_x, pen_y,
+                                info->c[0], 0, 1000000, tail);
+                else
+                    tail =
+                        render_glyph(render_priv, bm, pen_x, pen_y,
+                                info->c[1], 0, 1000000, tail);
+            } else if (info->effect_type == EF_KARAOKE_KF) {
                 tail =
-                    render_glyph(render_priv, bm, pen_x, pen_y,
-                                 info->c[0], 0, 1000000, tail);
-            else
+                    render_glyph(render_priv, bm, pen_x, pen_y, info->c[0],
+                            info->c[1], info->effect_timing, tail);
+            else
                 tail =
-                    render_glyph(render_priv, bm, pen_x, pen_y,
-                                 info->c[1], 0, 1000000, tail);
-        } else if (info->effect_type == EF_KARAOKE_KF) {
-            tail =
-                render_glyph(render_priv, bm, pen_x, pen_y, info->c[0],
-                             info->c[1], info->effect_timing, tail);
-        } else
-            tail =
-                render_glyph(render_priv, bm, pen_x, pen_y, info->c[0],
-                             0, 1000000, tail);
+                    render_glyph(render_priv, bm, pen_x, pen_y, info->c[0],
+                            0, 1000000, tail);
+            info = info->next;
+        }
     }
 
     *tail = 0;
@@ -819,24 +809,27 @@ static ASS_Image *render_text(ASS_Renderer *render_priv, int dst_x, int dst_y)
     return head;
 }
 
-static void compute_string_bbox(TextInfo *info, DBBox *bbox)
+static void compute_string_bbox(TextInfo *text, DBBox *bbox)
 {
     int i;
 
-    if (info->length > 0) {
+    if (text->length > 0) {
         bbox->xMin = 32000;
         bbox->xMax = -32000;
-        bbox->yMin = -1 * info->lines[0].asc + d6_to_double(info->glyphs[0].pos.y);
-        bbox->yMax = info->height - info->lines[0].asc +
-                     d6_to_double(info->glyphs[0].pos.y);
-
-        for (i = 0; i < info->length; ++i) {
-            double s, e;
-            if (info->glyphs[i].skip) continue;
-            s = d6_to_double(info->glyphs[i].pos.x);
-            e = s + d6_to_double(info->glyphs[i].advance.x);
-            bbox->xMin = FFMIN(bbox->xMin, s);
-            bbox->xMax = FFMAX(bbox->xMax, e);
+        bbox->yMin = -1 * text->lines[0].asc + d6_to_double(text->glyphs[0].pos.y);
+        bbox->yMax = text->height - text->lines[0].asc +
+                     d6_to_double(text->glyphs[0].pos.y);
+
+        for (i = 0; i < text->length; ++i) {
+            GlyphInfo *info = text->glyphs + i;
+            if (info->skip) continue;
+            while (info) {
+                double s = d6_to_double(info->pos.x);
+                double e = s + d6_to_double(info->advance.x);
+                bbox->xMin = FFMIN(bbox->xMin, s);
+                bbox->xMax = FFMAX(bbox->xMax, e);
+                info = info->next;
+            }
         }
     } else
         bbox->xMin = bbox->xMax = bbox->yMin = bbox->yMax = 0.;
@@ -878,6 +871,7 @@ void reset_render_context(ASS_Renderer *render_priv)
     render_priv->state.frz = M_PI * render_priv->state.style->Angle / 180.;
     render_priv->state.fax = render_priv->state.fay = 0.;
     render_priv->state.wrap_style = render_priv->track->WrapStyle;
+    render_priv->state.font_encoding = render_priv->state.style->Encoding;
 }
 
 /**
@@ -910,10 +904,10 @@ init_render_context(ASS_Renderer *render_priv, ASS_Event *event)
     render_priv->state.effect_type = EF_NONE;
     render_priv->state.effect_timing = 0;
     render_priv->state.effect_skip_timing = 0;
+    render_priv->state.bm_run_id = 0;
     ass_drawing_free(render_priv->state.drawing);
-    render_priv->state.drawing = ass_drawing_new(render_priv->fontconfig_priv,
-                                                 render_priv->state.font,
-                                                 render_priv->ftlibrary);
+    render_priv->state.drawing = ass_drawing_new(render_priv->library,
+            render_priv->ftlibrary);
 
     apply_transition_effects(render_priv, event);
 }
@@ -931,31 +925,19 @@ static void free_render_context(ASS_Renderer *render_priv)
  * Replace the outline of a glyph by a contour which makes up a simple
  * opaque rectangle.
  */
-static void draw_opaque_box(ASS_Renderer *render_priv, uint32_t ch,
-                            FT_Glyph glyph, int sx, int sy)
+static void draw_opaque_box(ASS_Renderer *render_priv, int asc, int desc,
+                            FT_Outline *ol, FT_Vector advance, int sx, int sy)
 {
-    int asc = 0, desc = 0;
     int i;
-    int adv = d16_to_d6(glyph->advance.x);
+    int adv = advance.x;
     double scale_y = render_priv->state.scale_y;
     double scale_x = render_priv->state.scale_x;
-    FT_OutlineGlyph og = (FT_OutlineGlyph) glyph;
-    FT_Outline *ol;
     FT_Vector points[4];
 
     // to avoid gaps
     sx = FFMAX(64, sx);
     sy = FFMAX(64, sy);
 
-    if (ch == -1) {
-        asc = render_priv->state.drawing->asc;
-        desc = render_priv->state.drawing->desc;
-    } else {
-        ass_font_get_asc_desc(render_priv->state.font, ch, &asc, &desc);
-        asc  *= scale_y;
-        desc *= scale_y;
-    }
-
     // Emulate the WTFish behavior of VSFilter, i.e. double-scale
     // the sizes of the opaque box.
     adv += double_to_d6(render_priv->state.hspacing * render_priv->font_scale
@@ -975,10 +957,8 @@ static void draw_opaque_box(ASS_Renderer *render_priv, uint32_t ch,
     points[3].x = -sx;
     points[3].y = -desc - sy;
 
-    FT_Outline_Done(render_priv->ftlibrary, &og->outline);
-    FT_Outline_New(render_priv->ftlibrary, 4, 1, &og->outline);
+    FT_Outline_New(render_priv->ftlibrary, 4, 1, ol);
 
-    ol = &og->outline;
     ol->n_points = ol->n_contours = 0;
     for (i = 0; i < 4; i++) {
         ol->points[ol->n_points] = points[i];
@@ -991,40 +971,53 @@ static void draw_opaque_box(ASS_Renderer *render_priv, uint32_t ch,
  * Stroke an outline glyph in x/y direction.  Applies various fixups to get
  * around limitations of the FreeType stroker.
  */
-static void stroke_outline_glyph(ASS_Renderer *render_priv,
-                                 FT_OutlineGlyph *glyph, int sx, int sy)
+static void stroke_outline(ASS_Renderer *render_priv, FT_Outline *outline,
+                           int sx, int sy)
 {
     if (sx <= 0 && sy <= 0)
         return;
 
-    fix_freetype_stroker(*glyph, sx, sy);
+    fix_freetype_stroker(outline, sx, sy);
 
     // Borders are equal; use the regular stroker
     if (sx == sy && render_priv->state.stroker) {
         int error;
-        error = FT_Glyph_StrokeBorder((FT_Glyph *) glyph,
-                                      render_priv->state.stroker, 0, 1);
-        if (error)
+        unsigned n_points, n_contours;
+
+        FT_StrokerBorder border = FT_Outline_GetOutsideBorder(outline);
+        error = FT_Stroker_ParseOutline(render_priv->state.stroker, outline, 0);
+        if (error) {
             ass_msg(render_priv->library, MSGL_WARN,
-                    "FT_Glyph_Stroke error: %d", error);
+                    "FT_Stroker_ParseOutline failed, error: %d", error);
+        }
+        error = FT_Stroker_GetBorderCounts(render_priv->state.stroker, border,
+                &n_points, &n_contours);
+        if (error) {
+            ass_msg(render_priv->library, MSGL_WARN,
+                    "FT_Stroker_GetBorderCounts failed, error: %d", error);
+        }
+        FT_Outline_Done(render_priv->ftlibrary, outline);
+        FT_Outline_New(render_priv->ftlibrary, n_points, n_contours, outline);
+        outline->n_points = outline->n_contours = 0;
+        FT_Stroker_ExportBorder(render_priv->state.stroker, border, outline);
 
     // "Stroke" with the outline emboldener in two passes.
     // The outlines look uglier, but the emboldening never adds any points
     } else {
         int i;
-        FT_Outline *ol = &(*glyph)->outline;
         FT_Outline nol;
-        FT_Outline_New(render_priv->ftlibrary, ol->n_points,
-                       ol->n_contours, &nol);
-        FT_Outline_Copy(ol, &nol);
 
-        FT_Outline_Embolden(ol, sx * 2);
-        FT_Outline_Translate(ol, -sx, -sx);
+        FT_Outline_New(render_priv->ftlibrary, outline->n_points,
+                       outline->n_contours, &nol);
+        FT_Outline_Copy(outline, &nol);
+
+        FT_Outline_Embolden(outline, sx * 2);
+        FT_Outline_Translate(outline, -sx, -sx);
         FT_Outline_Embolden(&nol, sy * 2);
         FT_Outline_Translate(&nol, -sy, -sy);
 
-        for (i = 0; i < ol->n_points; i++)
-            ol->points[i].y = nol.points[i].y;
+        for (i = 0; i < outline->n_points; i++)
+            outline->points[i].y = nol.points[i].y;
 
         FT_Outline_Done(render_priv->ftlibrary, &nol);
     }
@@ -1034,37 +1027,41 @@ static void stroke_outline_glyph(ASS_Renderer *render_priv,
  * \brief Prepare glyph hash
  */
 static void
-fill_glyph_hash(ASS_Renderer *priv, GlyphHashKey *key,
-                ASS_Drawing *drawing, uint32_t ch)
+fill_glyph_hash(ASS_Renderer *priv, OutlineHashKey *outline_key,
+                GlyphInfo *info)
 {
-    if (drawing->hash) {
-        key->scale_x = double_to_d16(priv->state.scale_x);
-        key->scale_y = double_to_d16(priv->state.scale_y);
-        key->outline.x = priv->state.border_x * 0xFFFF;
-        key->outline.y = priv->state.border_y * 0xFFFF;
+    if (info->drawing) {
+        DrawingHashKey *key = &outline_key->u.drawing;
+        outline_key->type = OUTLINE_DRAWING;
+        key->scale_x = double_to_d16(info->scale_x);
+        key->scale_y = double_to_d16(info->scale_y);
+        key->outline.x = double_to_d16(info->border_x);
+        key->outline.y = double_to_d16(info->border_y);
         key->border_style = priv->state.style->BorderStyle;
-        key->drawing_hash = drawing->hash;
-        // not very clean, but works
-        key->size = drawing->scale;
-        key->ch = -1;
+        key->hash = info->drawing->hash;
+        key->text = info->drawing->text;
+        key->pbo = info->drawing->pbo;
+        key->scale = info->drawing->scale;
     } else {
-        key->font = priv->state.font;
-        key->size = priv->state.font_size;
-        key->ch = ch;
-        key->bold = priv->state.bold;
-        key->italic = priv->state.italic;
-        key->scale_x = double_to_d16(priv->state.scale_x);
-        key->scale_y = double_to_d16(priv->state.scale_y);
-        key->outline.x = priv->state.border_x * 0xFFFF;
-        key->outline.y = priv->state.border_y * 0xFFFF;
-        key->flags = priv->state.flags;
+        GlyphHashKey *key = &outline_key->u.glyph;
+        outline_key->type = OUTLINE_GLYPH;
+        key->font = info->font;
+        key->size = info->font_size;
+        key->face_index = info->face_index;
+        key->glyph_index = info->glyph_index;
+        key->bold = info->bold;
+        key->italic = info->italic;
+        key->scale_x = double_to_d16(info->scale_x);
+        key->scale_y = double_to_d16(info->scale_y);
+        key->outline.x = double_to_d16(info->border_x);
+        key->outline.y = double_to_d16(info->border_y);
+        key->flags = info->flags;
         key->border_style = priv->state.style->BorderStyle;
     }
 }
 
 /**
  * \brief Get normal and outline (border) glyphs
- * \param symbol ucs4 char
  * \param info out: struct filled with extracted data
  * Tries to get both glyphs from cache.
  * If they can't be found, gets a glyph from font face, generates outline with FT_Stroker,
@@ -1072,80 +1069,102 @@ fill_glyph_hash(ASS_Renderer *priv, GlyphHashKey *key,
  * The glyphs are returned in info->glyph and info->outline_glyph
  */
 static void
-get_outline_glyph(ASS_Renderer *render_priv, int symbol, GlyphInfo *info,
-                  ASS_Drawing *drawing)
+get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info)
 {
-    GlyphHashValue *val;
-    GlyphHashKey key;
+    OutlineHashValue *val;
+    OutlineHashKey key;
 
-    memset(&key, 0, sizeof(key));
-    memset(info, 0, sizeof(GlyphInfo));
+    memset(&info->hash_key, 0, sizeof(key));
 
-    fill_glyph_hash(render_priv, &key, drawing, symbol);
-    val = cache_find_glyph(render_priv->cache.glyph_cache, &key);
-    if (val) {
-        info->glyph = val->glyph;
-        info->outline_glyph = val->outline_glyph;
-        info->bbox = val->bbox_scaled;
-        info->advance.x = val->advance.x;
-        info->advance.y = val->advance.y;
-        if (drawing->hash) {
-            drawing->asc = val->asc;
-            drawing->desc = val->desc;
-        }
-    } else {
-        GlyphHashValue v;
-        if (drawing->hash) {
+    fill_glyph_hash(priv, &key, info);
+    val = ass_cache_get(priv->cache.outline_cache, &key);
+
+    if (!val) {
+        OutlineHashValue v;
+        memset(&v, 0, sizeof(v));
+
+        if (info->drawing) {
+            ASS_Drawing *drawing = info->drawing;
+            ass_drawing_hash(drawing);
             if(!ass_drawing_parse(drawing, 0))
                 return;
-            info->glyph = (FT_Glyph) drawing->glyph;
+            outline_copy(priv->ftlibrary, &drawing->outline,
+                    &v.outline);
+            v.advance.x = drawing->advance.x;
+            v.advance.y = drawing->advance.y;
+            v.asc = drawing->asc;
+            v.desc = drawing->desc;
+            key.u.drawing.text = strdup(drawing->text);
         } else {
-            info->glyph =
-                ass_font_get_glyph(render_priv->fontconfig_priv,
-                                   render_priv->state.font, symbol,
-                                   render_priv->settings.hinting,
-                                   render_priv->state.flags);
+            FT_Glyph glyph;
+            ass_face_set_size(info->font->faces[info->face_index],
+                    info->font_size);
+            ass_font_set_transform(info->font, info->scale_x,
+                    info->scale_y, NULL);
+            glyph =
+                ass_font_get_glyph(priv->fontconfig_priv, info->font,
+                        info->symbol, info->face_index, info->glyph_index,
+                        priv->settings.hinting, info->flags);
+            if (glyph != NULL) {
+                outline_copy(priv->ftlibrary,
+                        &((FT_OutlineGlyph)glyph)->outline, &v.outline);
+                if (priv->settings.shaper == ASS_SHAPING_SIMPLE) {
+                    v.advance.x = d16_to_d6(glyph->advance.x);
+                    v.advance.y = d16_to_d6(glyph->advance.y);
+                }
+                FT_Done_Glyph(glyph);
+                ass_font_get_asc_desc(info->font, info->symbol,
+                        &v.asc, &v.desc);
+                v.asc  *= info->scale_y;
+                v.desc *= info->scale_y;
+            }
         }
-        if (!info->glyph)
+
+        if (!v.outline)
             return;
 
-        info->advance.x = d16_to_d6(info->glyph->advance.x);
-        info->advance.y = d16_to_d6(info->glyph->advance.y);
-        FT_Glyph_Get_CBox(info->glyph, FT_GLYPH_BBOX_SUBPIXELS, &info->bbox);
-
-        if (render_priv->state.style->BorderStyle == 3 &&
-            (render_priv->state.border_x > 0||
-             render_priv->state.border_y > 0)) {
-            FT_Glyph_Copy(info->glyph, &info->outline_glyph);
-            draw_opaque_box(render_priv, symbol, info->outline_glyph,
-                            double_to_d6(render_priv->state.border_x *
-                                         render_priv->border_scale),
-                            double_to_d6(render_priv->state.border_y *
-                                         render_priv->border_scale));
-        } else if ((render_priv->state.border_x > 0
-                    || render_priv->state.border_y > 0)
-                   && key.scale_x && key.scale_y) {
-
-            FT_Glyph_Copy(info->glyph, &info->outline_glyph);
-            stroke_outline_glyph(render_priv,
-                                 (FT_OutlineGlyph *) &info->outline_glyph,
-                                 double_to_d6(render_priv->state.border_x *
-                                              render_priv->border_scale),
-                                 double_to_d6(render_priv->state.border_y *
-                                              render_priv->border_scale));
-        }
+        FT_Outline_Get_CBox(v.outline, &v.bbox_scaled);
 
-        memset(&v, 0, sizeof(v));
-        v.glyph = info->glyph;
-        v.outline_glyph = info->outline_glyph;
-        v.advance = info->advance;
-        v.bbox_scaled = info->bbox;
-        if (drawing->hash) {
-            v.asc = drawing->asc;
-            v.desc = drawing->desc;
+        if (priv->state.style->BorderStyle == 3 &&
+                (info->border_x > 0 || info->border_y > 0)) {
+            FT_Vector advance;
+
+            v.border = calloc(1, sizeof(FT_Outline));
+
+            if (priv->settings.shaper == ASS_SHAPING_SIMPLE || info->drawing)
+                advance = v.advance;
+            else
+                advance = info->advance;
+
+            draw_opaque_box(priv, v.asc, v.desc, v.border, advance,
+                    double_to_d6(info->border_x * priv->border_scale),
+                    double_to_d6(info->border_y * priv->border_scale));
+
+        } else if ((info->border_x > 0 || info->border_y > 0)
+                && double_to_d6(info->scale_x) && double_to_d6(info->scale_y)) {
+
+            outline_copy(priv->ftlibrary, v.outline, &v.border);
+            stroke_outline(priv, v.border,
+                    double_to_d6(info->border_x * priv->border_scale),
+                    double_to_d6(info->border_y * priv->border_scale));
         }
-        cache_add_glyph(render_priv->cache.glyph_cache, &key, &v);
+
+        v.lib = priv->ftlibrary;
+        val = ass_cache_put(priv->cache.outline_cache, &key, &v);
+    }
+
+    info->hash_key.u.outline.outline = val;
+    info->outline = val->outline;
+    info->border = val->border;
+    info->bbox = val->bbox_scaled;
+    if (info->drawing || priv->settings.shaper == ASS_SHAPING_SIMPLE) {
+        info->cluster_advance.x = info->advance.x = val->advance.x;
+        info->cluster_advance.y = info->advance.y = val->advance.y;
     }
+    info->asc = val->asc;
+    info->desc = val->desc;
+
+    ass_drawing_free(info->drawing);
 }
 
 /**
@@ -1154,7 +1173,7 @@ get_outline_glyph(ASS_Renderer *render_priv, int symbol, GlyphInfo *info,
  * onto the screen plane.
  */
 static void
-transform_3d_points(FT_Vector shift, FT_Glyph glyph, double frx, double fry,
+transform_3d_points(FT_Vector shift, FT_Outline *outline, double frx, double fry,
                     double frz, double fax, double fay, double scale,
                     int yshift)
 {
@@ -1164,7 +1183,6 @@ transform_3d_points(FT_Vector shift, FT_Glyph glyph, double frx, double fry,
     double cx = cos(frx);
     double cy = cos(fry);
     double cz = cos(frz);
-    FT_Outline *outline = &((FT_OutlineGlyph) glyph)->outline;
     FT_Vector *p = outline->points;
     double x, y, z, xx, yy, zz;
     int i, dist;
@@ -1207,19 +1225,19 @@ transform_3d_points(FT_Vector shift, FT_Glyph glyph, double frx, double fry,
  * Rotates both glyphs by frx, fry and frz. Shift vector is added before rotation and subtracted after it.
  */
 static void
-transform_3d(FT_Vector shift, FT_Glyph *glyph, FT_Glyph *glyph2,
+transform_3d(FT_Vector shift, FT_Outline *outline, FT_Outline *border,
              double frx, double fry, double frz, double fax, double fay,
              double scale, int yshift)
 {
     frx = -frx;
     frz = -frz;
     if (frx != 0. || fry != 0. || frz != 0. || fax != 0. || fay != 0.) {
-        if (glyph && *glyph)
-            transform_3d_points(shift, *glyph, frx, fry, frz,
+        if (outline)
+            transform_3d_points(shift, outline, frx, fry, frz,
                                 fax, fay, scale, yshift);
 
-        if (glyph2 && *glyph2)
-            transform_3d_points(shift, *glyph2, frx, fry, frz,
+        if (border)
+            transform_3d_points(shift, border, frx, fry, frz,
                                 fax, fay, scale, yshift);
     }
 }
@@ -1236,84 +1254,83 @@ static void
 get_bitmap_glyph(ASS_Renderer *render_priv, GlyphInfo *info)
 {
     BitmapHashValue *val;
-    BitmapHashKey *key = &info->hash_key;
+    OutlineBitmapHashKey *key = &info->hash_key.u.outline;
+
+    if (!info->outline || info->symbol == '\n' || info->symbol == 0 || info->skip)
+        return;
 
-    val = cache_find_bitmap(render_priv->cache.bitmap_cache, key);
+    val = ass_cache_get(render_priv->cache.bitmap_cache, &info->hash_key);
 
-    if (val) {
-        info->bm = val->bm;
-        info->bm_o = val->bm_o;
-        info->bm_s = val->bm_s;
-    } else {
+    if (!val) {
         FT_Vector shift;
         BitmapHashValue hash_val;
         int error;
         double fax_scaled, fay_scaled;
-        info->bm = info->bm_o = info->bm_s = 0;
-        if (info->glyph && info->symbol != '\n' && info->symbol != 0
-            && !info->skip) {
-            FT_Glyph glyph;
-            FT_Glyph outline;
-            FT_Matrix m;
-            double scale_x = render_priv->font_scale_x;
-
-            FT_Glyph_Copy(info->glyph, &glyph);
-            FT_Glyph_Copy(info->outline_glyph, &outline);
-            // calculating rotation shift vector (from rotation origin to the glyph basepoint)
-            shift.x = key->shift_x;
-            shift.y = key->shift_y;
-            fax_scaled = info->fax *
-                         render_priv->state.scale_x;
-            fay_scaled = info->fay * render_priv->state.scale_y;
-            // apply rotation
-            transform_3d(shift, &glyph, &outline,
-                         info->frx, info->fry, info->frz, fax_scaled,
-                         fay_scaled, render_priv->font_scale, info->asc);
-
-            // PAR correction scaling
-            m.xx = double_to_d16(scale_x);
-            m.xy = 0;
-            m.yx = 0;
-            m.yy = double_to_d16(1.0);
-
-            // subpixel shift
-            if (glyph) {
-                FT_Outline *outl = &((FT_OutlineGlyph) glyph)->outline;
-                if (scale_x != 1.0)
-                    FT_Outline_Transform(outl, &m);
-                FT_Outline_Translate(outl, key->advance.x, -key->advance.y);
-            }
-            if (outline) {
-                FT_Outline *outl = &((FT_OutlineGlyph) outline)->outline;
-                if (scale_x != 1.0)
-                    FT_Outline_Transform(outl, &m);
-                FT_Outline_Translate(outl, key->advance.x, -key->advance.y);
-            }
-            // render glyph
-            error = glyph_to_bitmap(render_priv->library,
-                                    render_priv->synth_priv,
-                                    glyph, outline,
-                                    &info->bm, &info->bm_o,
-                                    &info->bm_s, info->be,
-                                    info->blur * render_priv->border_scale,
-                                    key->shadow_offset, key->border_style);
-            if (error)
-                info->symbol = 0;
-
-            // add bitmaps to cache
-            hash_val.bm_o = info->bm_o;
-            hash_val.bm = info->bm;
-            hash_val.bm_s = info->bm_s;
-            cache_add_bitmap(render_priv->cache.bitmap_cache, key, &hash_val);
-
-            FT_Done_Glyph(glyph);
-            FT_Done_Glyph(outline);
+        FT_Outline *outline, *border;
+        double scale_x = render_priv->font_scale_x;
+        FT_Matrix m;
+
+        hash_val.bm = hash_val.bm_o = hash_val.bm_s = 0;
+
+        outline_copy(render_priv->ftlibrary, info->outline, &outline);
+        outline_copy(render_priv->ftlibrary, info->border, &border);
+
+        // calculating rotation shift vector (from rotation origin to the glyph basepoint)
+        shift.x = key->shift_x;
+        shift.y = key->shift_y;
+        fax_scaled = info->fax * render_priv->state.scale_x;
+        fay_scaled = info->fay * render_priv->state.scale_y;
+
+        // apply rotation
+        transform_3d(shift, outline, border,
+                info->frx, info->fry, info->frz, fax_scaled,
+                fay_scaled, render_priv->font_scale, info->asc);
+
+        // PAR correction scaling
+        m.xx = double_to_d16(scale_x);
+        m.xy = 0;
+        m.yx = 0;
+        m.yy = double_to_d16(1.0);
+
+        // subpixel shift
+        if (outline) {
+            if (scale_x != 1.0)
+                FT_Outline_Transform(outline, &m);
+            FT_Outline_Translate(outline, key->advance.x, -key->advance.y);
+        }
+        if (border) {
+            if (scale_x != 1.0)
+                FT_Outline_Transform(border, &m);
+            FT_Outline_Translate(border, key->advance.x, -key->advance.y);
         }
+
+        // render glyph
+        error = outline_to_bitmap3(render_priv->library,
+                render_priv->synth_priv,
+                render_priv->ftlibrary,
+                outline, border,
+                &hash_val.bm, &hash_val.bm_o,
+                &hash_val.bm_s, info->be,
+                info->blur * render_priv->border_scale,
+                key->shadow_offset,
+                render_priv->state.style->BorderStyle);
+        if (error)
+            info->symbol = 0;
+
+        val = ass_cache_put(render_priv->cache.bitmap_cache, &info->hash_key,
+                &hash_val);
+
+        outline_free(render_priv->ftlibrary, outline);
+        outline_free(render_priv->ftlibrary, border);
     }
 
+    info->bm = val->bm;
+    info->bm_o = val->bm_o;
+    info->bm_s = val->bm_s;
+
     // VSFilter compatibility: invisible fill and no border?
     // In this case no shadow is supposed to be rendered.
-    if (!info->outline_glyph && (info->c[0] & 0xFF) == 0xFF)
+    if (!info->border && (info->c[0] & 0xFF) == 0xFF)
         info->bm_s = 0;
 }
 
@@ -1441,6 +1458,7 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width)
     double pen_shift_x;
     double pen_shift_y;
     int cur_line;
+    int run_offset;
     TextInfo *text_info = &render_priv->text_info;
 
     last_space = -1;
@@ -1481,12 +1499,13 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width)
                                            sizeof(LineInfo) *
                                            text_info->max_lines);
             }
-            if (lead < text_info->length)
+            if (lead < text_info->length) {
                 text_info->glyphs[lead].linebreak = break_type;
-            last_space = -1;
-            s1 = text_info->glyphs + lead;
-            s_offset = d6_to_double(s1->bbox.xMin + s1->pos.x);
-            text_info->n_lines++;
+                last_space = -1;
+                s1 = text_info->glyphs + lead;
+                s_offset = d6_to_double(s1->bbox.xMin + s1->pos.x);
+                text_info->n_lines++;
+            }
         }
     }
 #define DIFF(x,y) (((x) < (y)) ? (y - x) : (x - y))
@@ -1550,6 +1569,7 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width)
     pen_shift_x = 0.;
     pen_shift_y = 0.;
     cur_line = 1;
+    run_offset = 0;
 
     i = 0;
     cur = text_info->glyphs + i;
@@ -1566,86 +1586,31 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width)
             height =
                 text_info->lines[cur_line - 1].desc +
                 text_info->lines[cur_line].asc;
+            text_info->lines[cur_line - 1].len = i -
+                text_info->lines[cur_line - 1].offset;
+            text_info->lines[cur_line].offset = i;
             cur_line++;
+            run_offset++;
             pen_shift_x = d6_to_double(-cur->pos.x);
             pen_shift_y += height + render_priv->settings.line_spacing;
             ass_msg(render_priv->library, MSGL_DBG2,
                    "shifting from %d to %d by (%f, %f)", i,
                    text_info->length - 1, pen_shift_x, pen_shift_y);
         }
+        cur->bm_run_id += run_offset;
         cur->pos.x += double_to_d6(pen_shift_x);
         cur->pos.y += double_to_d6(pen_shift_y);
     }
-}
-
-/**
- * \brief determine karaoke effects
- * Karaoke effects cannot be calculated during parse stage (get_next_char()),
- * so they are done in a separate step.
- * Parse stage: when karaoke style override is found, its parameters are stored in the next glyph's
- * (the first glyph of the karaoke word)'s effect_type and effect_timing.
- * This function:
- * 1. sets effect_type for all glyphs in the word (_karaoke_ word)
- * 2. sets effect_timing for all glyphs to x coordinate of the border line between the left and right karaoke parts
- * (left part is filled with PrimaryColour, right one - with SecondaryColour).
- */
-static void process_karaoke_effects(ASS_Renderer *render_priv)
-{
-    GlyphInfo *cur, *cur2;
-    GlyphInfo *s1, *e1;      // start and end of the current word
-    GlyphInfo *s2;           // start of the next word
-    int i;
-    int timing;                 // current timing
-    int tm_start, tm_end;       // timings at start and end of the current word
-    int tm_current;
-    double dt;
-    int x;
-    int x_start, x_end;
-
-    tm_current = render_priv->time - render_priv->state.event->Start;
-    timing = 0;
-    s1 = s2 = 0;
-    for (i = 0; i <= render_priv->text_info.length; ++i) {
-        cur = render_priv->text_info.glyphs + i;
-        if ((i == render_priv->text_info.length)
-            || (cur->effect_type != EF_NONE)) {
-            s1 = s2;
-            s2 = cur;
-            if (s1) {
-                e1 = s2 - 1;
-                tm_start = timing + s1->effect_skip_timing;
-                tm_end = tm_start + s1->effect_timing;
-                timing = tm_end;
-                x_start = 1000000;
-                x_end = -1000000;
-                for (cur2 = s1; cur2 <= e1; ++cur2) {
-                    x_start = FFMIN(x_start, d6_to_int(cur2->bbox.xMin + cur2->pos.x));
-                    x_end = FFMAX(x_end, d6_to_int(cur2->bbox.xMax + cur2->pos.x));
-                }
-
-                dt = (tm_current - tm_start);
-                if ((s1->effect_type == EF_KARAOKE)
-                    || (s1->effect_type == EF_KARAOKE_KO)) {
-                    if (dt > 0)
-                        x = x_end + 1;
-                    else
-                        x = x_start;
-                } else if (s1->effect_type == EF_KARAOKE_KF) {
-                    dt /= (tm_end - tm_start);
-                    x = x_start + (x_end - x_start) * dt;
-                } else {
-                    ass_msg(render_priv->library, MSGL_ERR,
-                            "Unknown effect type");
-                    continue;
-                }
-
-                for (cur2 = s1; cur2 <= e1; ++cur2) {
-                    cur2->effect_type = s1->effect_type;
-                    cur2->effect_timing = x - d6_to_int(cur2->pos.x);
-                }
-            }
-        }
+    text_info->lines[cur_line - 1].len =
+        text_info->length - text_info->lines[cur_line - 1].offset;
+
+#if 0
+    // print line info
+    for (i = 0; i < text_info->n_lines; i++) {
+        printf("line %d offset %d length %d\n", i, text_info->lines[i].offset,
+                text_info->lines[i].len);
     }
+#endif
 }
 
 /**
@@ -1688,38 +1653,22 @@ static void get_base_point(DBBox *bbox, int alignment, double *bx, double *by)
  * Prepare bitmap hash key of a glyph
  */
 static void
-fill_bitmap_hash(ASS_Renderer *priv, BitmapHashKey *hash_key,
-                 ASS_Drawing *drawing, FT_Vector pen, uint32_t code)
+fill_bitmap_hash(ASS_Renderer *priv, GlyphInfo *info,
+                 OutlineBitmapHashKey *hash_key)
 {
-    if (!drawing->hash) {
-        hash_key->font = priv->state.font;
-        hash_key->size = priv->state.font_size;
-        hash_key->bold = priv->state.bold;
-        hash_key->italic = priv->state.italic;
-    } else {
-        hash_key->drawing_hash = drawing->hash;
-        hash_key->size = drawing->scale;
-    }
-    hash_key->ch = code;
-    hash_key->outline.x = double_to_d16(priv->state.border_x);
-    hash_key->outline.y = double_to_d16(priv->state.border_y);
-    hash_key->scale_x = double_to_d16(priv->state.scale_x);
-    hash_key->scale_y = double_to_d16(priv->state.scale_y);
-    hash_key->frx = rot_key(priv->state.frx);
-    hash_key->fry = rot_key(priv->state.fry);
-    hash_key->frz = rot_key(priv->state.frz);
-    hash_key->fax = double_to_d16(priv->state.fax);
-    hash_key->fay = double_to_d16(priv->state.fay);
-    hash_key->be = priv->state.be;
-    hash_key->blur = priv->state.blur;
-    hash_key->border_style = priv->state.style->BorderStyle;
+    hash_key->frx = rot_key(info->frx);
+    hash_key->fry = rot_key(info->fry);
+    hash_key->frz = rot_key(info->frz);
+    hash_key->fax = double_to_d16(info->fax);
+    hash_key->fay = double_to_d16(info->fay);
+    hash_key->be = info->be;
+    hash_key->blur = info->blur;
     hash_key->shadow_offset.x = double_to_d6(
-            priv->state.shadow_x * priv->border_scale -
-            (int) (priv->state.shadow_x * priv->border_scale));
+            info->shadow_x * priv->border_scale -
+            (int) (info->shadow_x * priv->border_scale));
     hash_key->shadow_offset.y = double_to_d6(
-            priv->state.shadow_y * priv->border_scale -
-            (int) (priv->state.shadow_y * priv->border_scale));
-    hash_key->flags = priv->state.flags;
+            info->shadow_y * priv->border_scale -
+            (int) (info->shadow_y * priv->border_scale));
 }
 
 /**
@@ -1742,12 +1691,15 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
     int MarginL, MarginR, MarginV;
     int last_break;
     int alignment, halign, valign;
-    int kern = render_priv->track->Kerning;
     double device_x = 0;
     double device_y = 0;
     TextInfo *text_info = &render_priv->text_info;
     GlyphInfo *glyphs = render_priv->text_info.glyphs;
     ASS_Drawing *drawing;
+    double max_text_width = 0;
+    FriBidiStrIndex *cmap = NULL;
+    int lineno = 1;
+    int left = 0;
 
     if (event->Style >= render_priv->track->n_styles) {
         ass_msg(render_priv->library, MSGL_WARN, "No style found");
@@ -1762,11 +1714,9 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
 
     drawing = render_priv->state.drawing;
     text_info->length = 0;
-    pen.x = 0;
-    pen.y = 0;
-    previous = 0;
     num_glyphs = 0;
     p = event->Text;
+
     // Event parsing.
     while (1) {
         // get next char, executing style override
@@ -1777,15 +1727,26 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
                 ass_drawing_add_char(drawing, (char) code);
         } while (code && render_priv->state.drawing_mode);      // skip everything in drawing mode
 
+        if (text_info->length >= text_info->max_glyphs) {
+            // Raise maximum number of glyphs
+            text_info->max_glyphs *= 2;
+            text_info->glyphs = glyphs =
+                realloc(text_info->glyphs,
+                        sizeof(GlyphInfo) * text_info->max_glyphs);
+        }
+
+        // Clear current GlyphInfo
+        memset(&glyphs[text_info->length], 0, sizeof(GlyphInfo));
+
         // Parse drawing
         if (drawing->i) {
             drawing->scale_x = render_priv->state.scale_x *
                                      render_priv->font_scale;
             drawing->scale_y = render_priv->state.scale_y *
                                      render_priv->font_scale;
-            ass_drawing_hash(drawing);
             p--;
-            code = -1;
+            code = 0xfffc; // object replacement character
+            glyphs[text_info->length].drawing = drawing;
         }
 
         // face could have been changed in get_next_char
@@ -1797,61 +1758,9 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
         if (code == 0)
             break;
 
-        if (text_info->length >= text_info->max_glyphs) {
-            // Raise maximum number of glyphs
-            text_info->max_glyphs *= 2;
-            text_info->glyphs = glyphs =
-                realloc(text_info->glyphs,
-                        sizeof(GlyphInfo) * text_info->max_glyphs);
-        }
-
-        // Add kerning to pen
-        if (kern && previous && code && !drawing->hash) {
-            FT_Vector delta;
-            delta =
-                ass_font_get_kerning(render_priv->state.font, previous,
-                                     code);
-            pen.x += delta.x * render_priv->state.scale_x;
-            pen.y += delta.y * render_priv->state.scale_y;
-        }
-
-        ass_font_set_transform(render_priv->state.font,
-                               render_priv->state.scale_x,
-                               render_priv->state.scale_y, NULL);
-
-        get_outline_glyph(render_priv, code,
-                          glyphs + text_info->length, drawing);
-
-        // Add additional space after italic to non-italic style changes
-        if (text_info->length &&
-            glyphs[text_info->length - 1].hash_key.italic &&
-            !render_priv->state.italic) {
-            int back = text_info->length - 1;
-            GlyphInfo *og = &glyphs[back];
-            while (back && og->bbox.xMax - og->bbox.xMin == 0
-                   && og->hash_key.italic)
-                og = &glyphs[--back];
-            if (og->bbox.xMax > og->advance.x) {
-                // The FreeType oblique slants by 6/16
-                pen.x += og->bbox.yMax * 0.375;
-            }
-        }
-
-        glyphs[text_info->length].pos.x = pen.x;
-        glyphs[text_info->length].pos.y = pen.y;
-
-        pen.x += glyphs[text_info->length].advance.x;
-        pen.x += double_to_d6(render_priv->state.hspacing *
-                              render_priv->font_scale
-                              * render_priv->state.scale_x);
-        pen.y += glyphs[text_info->length].advance.y;
-        pen.y += (render_priv->state.fay * render_priv->state.scale_y) *
-                 glyphs[text_info->length].advance.x;
-
-        previous = code;
-
+        // Fill glyph information
         glyphs[text_info->length].symbol = code;
-        glyphs[text_info->length].linebreak = 0;
+        glyphs[text_info->length].font = render_priv->state.font;
         for (i = 0; i < 4; ++i) {
             uint32_t clr = render_priv->state.c[i];
             change_alpha(&clr,
@@ -1863,53 +1772,108 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
             render_priv->state.effect_timing;
         glyphs[text_info->length].effect_skip_timing =
             render_priv->state.effect_skip_timing;
+        glyphs[text_info->length].font_size = ensure_font_size(render_priv,
+                    render_priv->state.font_size * render_priv->font_scale);
         glyphs[text_info->length].be = render_priv->state.be;
         glyphs[text_info->length].blur = render_priv->state.blur;
         glyphs[text_info->length].shadow_x = render_priv->state.shadow_x;
         glyphs[text_info->length].shadow_y = render_priv->state.shadow_y;
+        glyphs[text_info->length].scale_x= render_priv->state.scale_x;
+        glyphs[text_info->length].scale_y = render_priv->state.scale_y;
+        glyphs[text_info->length].border_x= render_priv->state.border_x;
+        glyphs[text_info->length].border_y = render_priv->state.border_y;
+        glyphs[text_info->length].bold = render_priv->state.bold;
+        glyphs[text_info->length].italic = render_priv->state.italic;
+        glyphs[text_info->length].flags = render_priv->state.flags;
         glyphs[text_info->length].frx = render_priv->state.frx;
         glyphs[text_info->length].fry = render_priv->state.fry;
         glyphs[text_info->length].frz = render_priv->state.frz;
         glyphs[text_info->length].fax = render_priv->state.fax;
         glyphs[text_info->length].fay = render_priv->state.fay;
-        if (drawing->hash) {
-            glyphs[text_info->length].asc = drawing->asc;
-            glyphs[text_info->length].desc = drawing->desc;
-        } else {
-            ass_font_get_asc_desc(render_priv->state.font, code,
-                                  &glyphs[text_info->length].asc,
-                                  &glyphs[text_info->length].desc);
+        glyphs[text_info->length].bm_run_id = render_priv->state.bm_run_id;
 
-            glyphs[text_info->length].asc *= render_priv->state.scale_y;
-            glyphs[text_info->length].desc *= render_priv->state.scale_y;
+        if (glyphs[text_info->length].drawing) {
+            drawing = render_priv->state.drawing =
+                ass_drawing_new(render_priv->library, render_priv->ftlibrary);
         }
 
-        // fill bitmap hash
-        fill_bitmap_hash(render_priv, &glyphs[text_info->length].hash_key,
-                         drawing, pen, code);
-
         text_info->length++;
 
         render_priv->state.effect_type = EF_NONE;
         render_priv->state.effect_timing = 0;
         render_priv->state.effect_skip_timing = 0;
 
-        if (drawing->hash) {
-            ass_drawing_free(drawing);
-            drawing = render_priv->state.drawing =
-                ass_drawing_new(render_priv->fontconfig_priv,
-                    render_priv->state.font,
-                    render_priv->ftlibrary);
-        }
     }
 
-
     if (text_info->length == 0) {
         // no valid symbols in the event; this can be smth like {comment}
         free_render_context(render_priv);
         return 1;
     }
 
+    // Find shape runs and shape text
+    ass_shaper_set_base_direction(render_priv->shaper,
+            resolve_base_direction(render_priv->state.font_encoding));
+    ass_shaper_find_runs(render_priv->shaper, render_priv, glyphs,
+            text_info->length);
+    ass_shaper_shape(render_priv->shaper, text_info);
+
+    // Retrieve glyphs
+    for (i = 0; i < text_info->length; i++) {
+        GlyphInfo *info = glyphs + i;
+        while (info) {
+            get_outline_glyph(render_priv, info);
+            info = info->next;
+        }
+        info = glyphs + i;
+
+        // Add additional space after italic to non-italic style changes
+        if (i && glyphs[i - 1].italic && !info->italic) {
+            int back = i - 1;
+            GlyphInfo *og = &glyphs[back];
+            while (back && og->bbox.xMax - og->bbox.xMin == 0
+                    && og->italic)
+                og = &glyphs[--back];
+            if (og->bbox.xMax > og->cluster_advance.x)
+                og->cluster_advance.x = og->bbox.xMax;
+        }
+
+        // add horizontal letter spacing
+        info->cluster_advance.x += double_to_d6(render_priv->state.hspacing *
+                render_priv->font_scale * info->scale_x);
+
+        // add displacement for vertical shearing
+        info->cluster_advance.y += (info->fay * info->scale_y) * info->cluster_advance.x;
+
+    }
+
+    // Preliminary layout (for line wrapping)
+    previous = 0;
+    pen.x = 0;
+    pen.y = 0;
+    for (i = 0; i < text_info->length; i++) {
+        GlyphInfo *info = glyphs + i;
+        FT_Vector cluster_pen = pen;
+        while (info) {
+            info->pos.x = cluster_pen.x;
+            info->pos.y = cluster_pen.y;
+
+            cluster_pen.x += info->advance.x;
+            cluster_pen.y += info->advance.y;
+
+            // fill bitmap hash
+            info->hash_key.type = BITMAP_OUTLINE;
+            fill_bitmap_hash(render_priv, info, &info->hash_key.u.outline);
+
+            info = info->next;
+        }
+        info = glyphs + i;
+        pen.x += info->cluster_advance.x;
+        pen.y += info->cluster_advance.y;
+        previous = info->symbol;
+    }
+
+
     // depends on glyph x coordinates being monotonous, so it should be done before line wrap
     process_karaoke_effects(render_priv);
 
@@ -1925,40 +1889,64 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
     MarginV =
         (event->MarginV) ? event->MarginV : render_priv->state.style->MarginV;
 
-    if (render_priv->state.evt_type != EVENT_HSCROLL) {
-        double max_text_width;
-
-        // calculate max length of a line
-        max_text_width =
-            x2scr(render_priv,
-                  render_priv->track->PlayResX - MarginR) -
-            x2scr(render_priv, MarginL);
+    // calculate max length of a line
+    max_text_width =
+        x2scr(render_priv, render_priv->track->PlayResX - MarginR) -
+        x2scr(render_priv, MarginL);
 
+    // wrap lines
+    if (render_priv->state.evt_type != EVENT_HSCROLL) {
         // rearrange text in several lines
         wrap_lines_smart(render_priv, max_text_width);
+    } else {
+        // no breaking or wrapping, everything in a single line
+        text_info->lines[0].offset = 0;
+        text_info->lines[0].len = text_info->length;
+        text_info->n_lines = 1;
+        measure_text(render_priv);
+    }
+
+    // Reorder text into visual order
+    cmap = ass_shaper_reorder(render_priv->shaper, text_info);
+
+    // Reposition according to the map
+    pen.x = 0;
+    pen.y = 0;
+    for (i = 0; i < text_info->length; i++) {
+        GlyphInfo *info = glyphs + cmap[i];
+        FT_Vector cluster_pen;
+        if (glyphs[i].linebreak) {
+            pen.x = 0;
+            pen.y += double_to_d6(text_info->lines[lineno-1].desc);
+            pen.y += double_to_d6(text_info->lines[lineno].asc);
+            pen.y += double_to_d6(render_priv->settings.line_spacing);
+            lineno++;
+        }
+        if (info->skip) continue;
+        cluster_pen = pen;
+        while (info) {
+            info->pos.x = info->offset.x + cluster_pen.x;
+            info->pos.y = info->offset.y + cluster_pen.y;
+            cluster_pen.x += info->advance.x;
+            cluster_pen.y += info->advance.y;
+            info = info->next;
+        }
+        info = glyphs + cmap[i];
+        pen.x += info->cluster_advance.x;
+        pen.y += info->cluster_advance.y;
+    }
 
-        // align text
+    // align lines
+    if (render_priv->state.evt_type != EVENT_HSCROLL) {
+        double width = 0;
         last_break = -1;
-        for (i = 1; i < text_info->length + 1; ++i) {   // (text_info->length + 1) is the end of the last line
-            if ((i == text_info->length)
-                || glyphs[i].linebreak) {
-                double width, shift = 0;
-                GlyphInfo *first_glyph =
-                    glyphs + last_break + 1;
-                GlyphInfo *last_glyph = glyphs + i - 1;
-
-                while (first_glyph < last_glyph && first_glyph->skip)
-                    first_glyph++;
-
-                while ((last_glyph > first_glyph)
-                       && ((last_glyph->symbol == '\n')
-                           || (last_glyph->symbol == 0)
-                           || (last_glyph->skip)))
-                    last_glyph--;
-
-                width = d6_to_double(
-                    last_glyph->pos.x + last_glyph->advance.x -
-                    first_glyph->pos.x);
+        for (i = 0; i <= text_info->length; ++i) {   // (text_info->length + 1) is the end of the last line
+            if ((i == text_info->length) || glyphs[i].linebreak) {
+                double shift = 0;
+                // remove letter spacing (which is included in cluster_advance)
+                if (i > 0)
+                    width -= render_priv->state.hspacing * render_priv->font_scale *
+                        glyphs[i-1].scale_x;
                 if (halign == HALIGN_LEFT) {    // left aligned, no action
                     shift = 0;
                 } else if (halign == HALIGN_RIGHT) {    // right aligned
@@ -1967,13 +1955,20 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
                     shift = (max_text_width - width) / 2.0;
                 }
                 for (j = last_break + 1; j < i; ++j) {
-                    glyphs[j].pos.x += double_to_d6(shift);
+                    GlyphInfo *info = glyphs + j;
+                    while (info) {
+                        info->pos.x += double_to_d6(shift);
+                        info = info->next;
+                    }
                 }
                 last_break = i - 1;
+                width = 0;
+            }
+            if (i < text_info->length && !glyphs[i].skip &&
+                    glyphs[i].symbol != '\n' && glyphs[i].symbol != 0) {
+                width += d6_to_double(glyphs[i].cluster_advance.x);
             }
         }
-    } else {                    // render_priv->state.evt_type == EVENT_HSCROLL
-        measure_text(render_priv);
     }
 
     // determing text bounding box
@@ -2099,32 +2094,38 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
 
         for (i = 0; i < text_info->length; ++i) {
             GlyphInfo *info = glyphs + i;
+            while (info) {
+                OutlineBitmapHashKey *key = &info->hash_key.u.outline;
 
-            if (info->hash_key.frx || info->hash_key.fry
-                || info->hash_key.frz || info->hash_key.fax
-                || info->hash_key.fay) {
-                info->hash_key.shift_x = info->pos.x + double_to_d6(device_x - center.x);
-                info->hash_key.shift_y =
-                    -(info->pos.y + double_to_d6(device_y - center.y));
-            } else {
-                info->hash_key.shift_x = 0;
-                info->hash_key.shift_y = 0;
+                if (key->frx || key->fry || key->frz || key->fax || key->fay) {
+                    key->shift_x = info->pos.x + double_to_d6(device_x - center.x);
+                    key->shift_y = -(info->pos.y + double_to_d6(device_y - center.y));
+                } else {
+                    key->shift_x = 0;
+                    key->shift_y = 0;
+                }
+                info = info->next;
             }
         }
     }
 
     // convert glyphs to bitmaps
-    device_x *= render_priv->font_scale_x;
+    left = render_priv->settings.left_margin;
+    device_x = (device_x - left) * render_priv->font_scale_x + left;
     for (i = 0; i < text_info->length; ++i) {
-        GlyphInfo *g = glyphs + i;
-        g->pos.x *= render_priv->font_scale_x;
-        g->hash_key.advance.x =
-            double_to_d6(device_x - (int) device_x +
-            d6_to_double(g->pos.x & SUBPIXEL_MASK)) & ~SUBPIXEL_ACCURACY;
-        g->hash_key.advance.y =
-            double_to_d6(device_y - (int) device_y +
-            d6_to_double(g->pos.y & SUBPIXEL_MASK)) & ~SUBPIXEL_ACCURACY;
-        get_bitmap_glyph(render_priv, glyphs + i);
+        GlyphInfo *info = glyphs + i;
+        while (info) {
+            OutlineBitmapHashKey *key = &info->hash_key.u.outline;
+            info->pos.x *= render_priv->font_scale_x;
+            key->advance.x =
+                double_to_d6(device_x - (int) device_x +
+                        d6_to_double(info->pos.x & SUBPIXEL_MASK)) & ~SUBPIXEL_ACCURACY;
+            key->advance.y =
+                double_to_d6(device_y - (int) device_y +
+                        d6_to_double(info->pos.y & SUBPIXEL_MASK)) & ~SUBPIXEL_ACCURACY;
+            get_bitmap_glyph(render_priv, info);
+            info = info->next;
+        }
     }
 
     memset(event_images, 0, sizeof(*event_images));
@@ -2139,6 +2140,7 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
     event_images->event = event;
     event_images->imgs = render_text(render_priv, (int) device_x, (int) device_y);
 
+    ass_shaper_cleanup(render_priv->shaper, text_info);
     free_render_context(render_priv);
 
     return 0;
@@ -2162,24 +2164,16 @@ void ass_free_images(ASS_Image *img)
  */
 static void check_cache_limits(ASS_Renderer *priv, CacheStore *cache)
 {
-    if (cache->bitmap_cache->cache_size > cache->bitmap_max_size) {
-        ass_msg(priv->library, MSGL_V,
-                "Hitting hard bitmap cache limit (was: %ld bytes), "
-                "resetting.", (long) cache->bitmap_cache->cache_size);
-        cache->bitmap_cache = ass_bitmap_cache_reset(cache->bitmap_cache);
-        cache->composite_cache = ass_composite_cache_reset(
-            cache->composite_cache);
+    if (ass_cache_empty(cache->bitmap_cache, cache->bitmap_max_size)) {
+        ass_cache_empty(cache->composite_cache, 0);
         ass_free_images(priv->prev_images_root);
         priv->prev_images_root = 0;
     }
-
-    if (cache->glyph_cache->count > cache->glyph_max
-        || cache->glyph_cache->cache_size > cache->bitmap_max_size) {
-        ass_msg(priv->library, MSGL_V,
-            "Hitting hard glyph cache limit (was: %d glyphs, %ld bytes), "
-            "resetting.",
-            cache->glyph_cache->count, (long) cache->glyph_cache->cache_size);
-        cache->glyph_cache = ass_glyph_cache_reset(cache->glyph_cache);
+    if (ass_cache_empty(cache->outline_cache, cache->glyph_max)) {
+        ass_cache_empty(cache->bitmap_cache, 0);
+        ass_cache_empty(cache->composite_cache, 0);
+        ass_free_images(priv->prev_images_root);
+        priv->prev_images_root = 0;
     }
 }
 
@@ -2210,7 +2204,7 @@ ass_start_frame(ASS_Renderer *render_priv, ASS_Track *track,
     render_priv->track = track;
     render_priv->time = now;
 
-    ass_lazy_track_init(render_priv);
+    ass_lazy_track_init(render_priv->library, render_priv->track);
 
     render_priv->font_scale = settings_priv->font_size_coeff *
         render_priv->orig_height / render_priv->track->PlayResY;
@@ -2221,6 +2215,11 @@ ass_start_frame(ASS_Renderer *render_priv, ASS_Track *track,
     else
         render_priv->border_scale = 1.;
 
+    ass_shaper_set_kerning(render_priv->shaper, track->Kerning);
+    if (track->Language)
+        ass_shaper_set_language(render_priv->shaper, track->Language);
+    ass_shaper_set_level(render_priv->shaper, render_priv->settings.shaper);
+
     // PAR correction
     render_priv->font_scale_x = render_priv->settings.aspect /
                                 render_priv->settings.storage_aspect;
index 78c7339..d3c1bbb 100644 (file)
@@ -27,6 +27,9 @@
 #include FT_GLYPH_H
 #include FT_SYNTHESIS_H
 
+// XXX: fix the inclusion mess so we can avoid doing this here
+typedef struct ass_shaper ASS_Shaper;
+
 #include "ass.h"
 #include "ass_font.h"
 #include "ass_bitmap.h"
@@ -73,6 +76,7 @@ typedef struct {
     double aspect;              // frame aspect ratio, d_width / d_height.
     double storage_aspect;      // pixel ratio of the source image
     ASS_Hinting hinting;
+    ASS_ShapingLevel shaper;
 
     char *default_font;
     char *default_family;
@@ -96,19 +100,26 @@ typedef enum {
 
 // describes a glyph
 // GlyphInfo and TextInfo are used for text centering and word-wrapping operations
-typedef struct {
+typedef struct glyph_info {
     unsigned symbol;
     unsigned skip;              // skip glyph when layouting text
-    FT_Glyph glyph;
-    FT_Glyph outline_glyph;
+    ASS_Font *font;
+    int face_index;
+    int glyph_index;
+    double font_size;
+    ASS_Drawing *drawing;
+    FT_Outline *outline;
+    FT_Outline *border;
     Bitmap *bm;                 // glyph bitmap
     Bitmap *bm_o;               // outline bitmap
     Bitmap *bm_s;               // shadow bitmap
     FT_BBox bbox;
     FT_Vector pos;
+    FT_Vector offset;
     char linebreak;             // the first (leading) glyph of some line ?
     uint32_t c[4];              // colors
     FT_Vector advance;          // 26.6
+    FT_Vector cluster_advance;
     Effect effect_type;
     int effect_timing;          // time duration of current karaoke word
     // after process_karaoke_effects: distance in pixels from the glyph origin.
@@ -121,12 +132,24 @@ typedef struct {
     double shadow_y;
     double frx, fry, frz;       // rotation
     double fax, fay;            // text shearing
+    double scale_x, scale_y;
+    double border_x, border_y;
+    unsigned italic;
+    unsigned bold;
+    int flags;
+
+    int bm_run_id;
+    int shape_run_id;
 
     BitmapHashKey hash_key;
+
+    // next glyph in this cluster
+    struct glyph_info *next;
 } GlyphInfo;
 
 typedef struct {
     double asc, desc;
+    int offset, len;
 } LineInfo;
 
 typedef struct {
@@ -147,7 +170,6 @@ typedef struct {
     int parsed_tags;
 
     ASS_Font *font;
-    char *font_path;
     double font_size;
     int flags;                  // decoration flags (underline/strike-through)
 
@@ -186,6 +208,9 @@ typedef struct {
     int effect_timing;
     int effect_skip_timing;
 
+    // bitmap run id (used for final bitmap rendering)
+    int bm_run_id;
+
     enum {
         SCROLL_LR,              // left-to-right
         SCROLL_RL,
@@ -200,13 +225,14 @@ typedef struct {
     unsigned italic;
     int treat_family_as_pattern;
     int wrap_style;
+    int font_encoding;
 } RenderContext;
 
 typedef struct {
-    Hashmap *font_cache;
-    Hashmap *glyph_cache;
-    Hashmap *bitmap_cache;
-    Hashmap *composite_cache;
+    Cache *font_cache;
+    Cache *outline_cache;
+    Cache *bitmap_cache;
+    Cache *composite_cache;
     size_t glyph_max;
     size_t bitmap_max_size;
 } CacheStore;
@@ -218,6 +244,7 @@ struct ass_renderer {
     ASS_Settings settings;
     int render_id;
     ASS_SynthPriv *synth_priv;
+    ASS_Shaper *shaper;
 
     ASS_Image *images_root;     // rendering result is stored here
     ASS_Image *prev_images_root;
@@ -265,4 +292,7 @@ typedef struct {
 void reset_render_context(ASS_Renderer *render_priv);
 void ass_free_images(ASS_Image *img);
 
+// XXX: this is actually in ass.c, includes should be fixed later on
+void ass_lazy_track_init(ASS_Library *lib, ASS_Track *track);
+
 #endif /* LIBASS_RENDER_H */
index 65cfa58..8bf9e5d 100644 (file)
@@ -25,12 +25,9 @@ static void ass_reconfigure(ASS_Renderer *priv)
     ASS_Settings *settings = &priv->settings;
 
     priv->render_id++;
-    priv->cache.glyph_cache =
-        ass_glyph_cache_reset(priv->cache.glyph_cache);
-    priv->cache.bitmap_cache =
-        ass_bitmap_cache_reset(priv->cache.bitmap_cache);
-    priv->cache.composite_cache =
-        ass_composite_cache_reset(priv->cache.composite_cache);
+    ass_cache_empty(priv->cache.outline_cache, 0);
+    ass_cache_empty(priv->cache.bitmap_cache, 0);
+    ass_cache_empty(priv->cache.composite_cache, 0);
     ass_free_images(priv->prev_images_root);
     priv->prev_images_root = 0;
 
@@ -61,6 +58,17 @@ void ass_set_frame_size(ASS_Renderer *priv, int w, int h)
     }
 }
 
+void ass_set_shaper(ASS_Renderer *priv, ASS_ShapingLevel level)
+{
+#ifdef CONFIG_HARFBUZZ
+    // select the complex shaper for illegal values
+    if (level == ASS_SHAPING_SIMPLE || level == ASS_SHAPING_COMPLEX)
+        priv->settings.shaper = level;
+    else
+        priv->settings.shaper = ASS_SHAPING_COMPLEX;
+#endif
+}
+
 void ass_set_margins(ASS_Renderer *priv, int t, int b, int l, int r)
 {
     if (priv->settings.left_margin != l || priv->settings.right_margin != r ||
diff --git a/lib/libass/libass/ass_shaper.c b/lib/libass/libass/ass_shaper.c
new file mode 100644 (file)
index 0000000..cf563ad
--- /dev/null
@@ -0,0 +1,733 @@
+/*
+ * Copyright (C) 2011 Grigori Goronzy <greg@chown.ath.cx>
+ *
+ * This file is part of libass.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <fribidi/fribidi.h>
+
+#include "ass_shaper.h"
+#include "ass_render.h"
+#include "ass_font.h"
+#include "ass_parse.h"
+#include "ass_cache.h"
+
+#define MAX_RUNS 50
+
+#ifdef CONFIG_HARFBUZZ
+#include <hb-ft.h>
+enum {
+    VERT = 0,
+    VKNA,
+    KERN
+};
+#define NUM_FEATURES 3
+#endif
+
+struct ass_shaper {
+    ASS_ShapingLevel shaping_level;
+
+    // FriBidi log2vis
+    int n_glyphs;
+    FriBidiChar *event_text;
+    FriBidiCharType *ctypes;
+    FriBidiLevel *emblevels;
+    FriBidiStrIndex *cmap;
+    FriBidiParType base_direction;
+
+#ifdef CONFIG_HARFBUZZ
+    // OpenType features
+    int n_features;
+    hb_feature_t *features;
+    hb_language_t language;
+
+    // Glyph metrics cache, to speed up shaping
+    Cache *metrics_cache;
+#endif
+};
+
+#ifdef CONFIG_HARFBUZZ
+struct ass_shaper_metrics_data {
+    Cache *metrics_cache;
+    GlyphMetricsHashKey hash_key;
+    int vertical;
+};
+
+struct ass_shaper_font_data {
+    hb_font_t *fonts[ASS_FONT_MAX_FACES];
+    hb_font_funcs_t *font_funcs[ASS_FONT_MAX_FACES];
+    struct ass_shaper_metrics_data *metrics_data[ASS_FONT_MAX_FACES];
+};
+#endif
+
+/**
+ * \brief Print version information
+ */
+void ass_shaper_info(ASS_Library *lib)
+{
+    ass_msg(lib, MSGL_V, "Shaper: FriBidi "
+            FRIBIDI_VERSION " (SIMPLE)"
+#ifdef CONFIG_HARFBUZZ
+            " HarfBuzz-ng %s (COMPLEX)", hb_version_string()
+#endif
+           );
+}
+
+/**
+ * \brief grow arrays, if needed
+ * \param new_size requested size
+ */
+static void check_allocations(ASS_Shaper *shaper, size_t new_size)
+{
+    if (new_size > shaper->n_glyphs) {
+        shaper->event_text = realloc(shaper->event_text, sizeof(FriBidiChar) * new_size);
+        shaper->ctypes     = realloc(shaper->ctypes, sizeof(FriBidiCharType) * new_size);
+        shaper->emblevels  = realloc(shaper->emblevels, sizeof(FriBidiLevel) * new_size);
+        shaper->cmap       = realloc(shaper->cmap, sizeof(FriBidiStrIndex) * new_size);
+    }
+}
+
+/**
+ * \brief Free shaper and related data
+ */
+void ass_shaper_free(ASS_Shaper *shaper)
+{
+#ifdef CONFIG_HARFBUZZ
+    ass_cache_done(shaper->metrics_cache);
+    free(shaper->features);
+#endif
+    free(shaper->event_text);
+    free(shaper->ctypes);
+    free(shaper->emblevels);
+    free(shaper->cmap);
+    free(shaper);
+}
+
+void ass_shaper_font_data_free(ASS_ShaperFontData *priv)
+{
+#ifdef CONFIG_HARFBUZZ
+    int i;
+    for (i = 0; i < ASS_FONT_MAX_FACES; i++)
+        if (priv->fonts[i]) {
+            free(priv->metrics_data[i]);
+            hb_font_destroy(priv->fonts[i]);
+            hb_font_funcs_destroy(priv->font_funcs[i]);
+        }
+    free(priv);
+#endif
+}
+
+#ifdef CONFIG_HARFBUZZ
+/**
+ * \brief set up the HarfBuzz OpenType feature list with some
+ * standard features.
+ */
+static void init_features(ASS_Shaper *shaper)
+{
+    shaper->features = calloc(sizeof(hb_feature_t), NUM_FEATURES);
+
+    shaper->n_features = NUM_FEATURES;
+    shaper->features[VERT].tag = HB_TAG('v', 'e', 'r', 't');
+    shaper->features[VERT].end = INT_MAX;
+    shaper->features[VKNA].tag = HB_TAG('v', 'k', 'n', 'a');
+    shaper->features[VKNA].end = INT_MAX;
+    shaper->features[KERN].tag = HB_TAG('k', 'e', 'r', 'n');
+    shaper->features[KERN].end = INT_MAX;
+}
+
+/**
+ * \brief Set features depending on properties of the run
+ */
+static void set_run_features(ASS_Shaper *shaper, GlyphInfo *info)
+{
+        // enable vertical substitutions for @font runs
+        if (info->font->desc.vertical)
+            shaper->features[VERT].value = shaper->features[VKNA].value = 1;
+        else
+            shaper->features[VERT].value = shaper->features[VKNA].value = 0;
+}
+
+/**
+ * \brief Update HarfBuzz's idea of font metrics
+ * \param hb_font HarfBuzz font
+ * \param face associated FreeType font face
+ */
+static void update_hb_size(hb_font_t *hb_font, FT_Face face)
+{
+    hb_font_set_scale (hb_font,
+            ((uint64_t) face->size->metrics.x_scale * (uint64_t) face->units_per_EM) >> 16,
+            ((uint64_t) face->size->metrics.y_scale * (uint64_t) face->units_per_EM) >> 16);
+    hb_font_set_ppem (hb_font, face->size->metrics.x_ppem,
+            face->size->metrics.y_ppem);
+}
+
+
+/*
+ * Cached glyph metrics getters follow
+ *
+ * These functions replace HarfBuzz' standard FreeType font functions
+ * and provide cached access to essential glyph metrics. This usually
+ * speeds up shaping a lot. It also allows us to use custom load flags.
+ *
+ */
+
+GlyphMetricsHashValue *
+get_cached_metrics(struct ass_shaper_metrics_data *metrics, FT_Face face,
+                   hb_codepoint_t glyph)
+{
+    GlyphMetricsHashValue *val;
+
+    metrics->hash_key.glyph_index = glyph;
+    val = ass_cache_get(metrics->metrics_cache, &metrics->hash_key);
+
+    if (!val) {
+        int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
+            | FT_LOAD_IGNORE_TRANSFORM;
+        GlyphMetricsHashValue new_val;
+
+        if (FT_Load_Glyph(face, glyph, load_flags))
+            return NULL;
+
+        memcpy(&new_val.metrics, &face->glyph->metrics, sizeof(FT_Glyph_Metrics));
+        val = ass_cache_put(metrics->metrics_cache, &metrics->hash_key, &new_val);
+    }
+
+    return val;
+}
+
+static hb_bool_t
+get_glyph(hb_font_t *font, void *font_data, hb_codepoint_t unicode,
+          hb_codepoint_t variation, hb_codepoint_t *glyph, void *user_data)
+{
+    FT_Face face = font_data;
+
+    if (variation)
+        *glyph = FT_Face_GetCharVariantIndex(face, unicode, variation);
+    else
+        *glyph = FT_Get_Char_Index(face, unicode);
+
+    return *glyph != 0;
+}
+
+static hb_position_t
+cached_h_advance(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
+                 void *user_data)
+{
+    FT_Face face = font_data;
+    struct ass_shaper_metrics_data *metrics_priv = user_data;
+    GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, glyph);
+
+    if (!metrics)
+        return 0;
+
+    if (metrics_priv->vertical && glyph > VERTICAL_LOWER_BOUND)
+        return metrics->metrics.vertAdvance;
+
+    return metrics->metrics.horiAdvance;
+}
+
+static hb_position_t
+cached_v_advance(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
+                 void *user_data)
+{
+    FT_Face face = font_data;
+    struct ass_shaper_metrics_data *metrics_priv = user_data;
+    GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, glyph);
+
+    if (!metrics)
+        return 0;
+
+    return metrics->metrics.vertAdvance;
+
+}
+
+static hb_bool_t
+cached_h_origin(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
+                hb_position_t *x, hb_position_t *y, void *user_data)
+{
+    return 1;
+}
+
+static hb_bool_t
+cached_v_origin(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
+                hb_position_t *x, hb_position_t *y, void *user_data)
+{
+    FT_Face face = font_data;
+    struct ass_shaper_metrics_data *metrics_priv = user_data;
+    GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, glyph);
+
+    if (!metrics)
+        return 0;
+
+    *x = metrics->metrics.horiBearingX - metrics->metrics.vertBearingX;
+    *y = metrics->metrics.horiBearingY - (-metrics->metrics.vertBearingY);
+
+    return 1;
+}
+
+static hb_position_t
+get_h_kerning(hb_font_t *font, void *font_data, hb_codepoint_t first,
+                 hb_codepoint_t second, void *user_data)
+{
+    FT_Face face = font_data;
+    FT_Vector kern;
+
+    if (FT_Get_Kerning (face, first, second, FT_KERNING_DEFAULT, &kern))
+        return 0;
+
+    return kern.x;
+}
+
+static hb_position_t
+get_v_kerning(hb_font_t *font, void *font_data, hb_codepoint_t first,
+                 hb_codepoint_t second, void *user_data)
+{
+    return 0;
+}
+
+static hb_bool_t
+cached_extents(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
+               hb_glyph_extents_t *extents, void *user_data)
+{
+    FT_Face face = font_data;
+    struct ass_shaper_metrics_data *metrics_priv = user_data;
+    GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, glyph);
+
+    if (!metrics)
+        return 0;
+
+    extents->x_bearing = metrics->metrics.horiBearingX;
+    extents->y_bearing = metrics->metrics.horiBearingY;
+    extents->width     = metrics->metrics.width;
+    extents->height    = metrics->metrics.height;
+
+    return 1;
+}
+
+static hb_bool_t
+get_contour_point(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
+                     unsigned int point_index, hb_position_t *x,
+                     hb_position_t *y, void *user_data)
+{
+    FT_Face face = font_data;
+    int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
+        | FT_LOAD_IGNORE_TRANSFORM;
+
+    if (FT_Load_Glyph(face, glyph, load_flags))
+        return 0;
+
+    if (point_index >= (unsigned)face->glyph->outline.n_points)
+        return 0;
+
+    *x = face->glyph->outline.points[point_index].x;
+    *y = face->glyph->outline.points[point_index].y;
+
+    return 1;
+}
+
+/**
+ * \brief Retrieve HarfBuzz font from cache.
+ * Create it from FreeType font, if needed.
+ * \param info glyph cluster
+ * \return HarfBuzz font
+ */
+static hb_font_t *get_hb_font(ASS_Shaper *shaper, GlyphInfo *info)
+{
+    ASS_Font *font = info->font;
+    hb_font_t **hb_fonts;
+
+    if (!font->shaper_priv)
+        font->shaper_priv = calloc(sizeof(ASS_ShaperFontData), 1);
+
+
+    hb_fonts = font->shaper_priv->fonts;
+    if (!hb_fonts[info->face_index]) {
+        hb_fonts[info->face_index] =
+            hb_ft_font_create(font->faces[info->face_index], NULL);
+
+        // set up cached metrics access
+        font->shaper_priv->metrics_data[info->face_index] =
+            calloc(sizeof(struct ass_shaper_metrics_data), 1);
+        struct ass_shaper_metrics_data *metrics =
+            font->shaper_priv->metrics_data[info->face_index];
+        metrics->metrics_cache = shaper->metrics_cache;
+        metrics->vertical = info->font->desc.vertical;
+
+        hb_font_funcs_t *funcs = hb_font_funcs_create();
+        font->shaper_priv->font_funcs[info->face_index] = funcs;
+        hb_font_funcs_set_glyph_func(funcs, get_glyph,
+                metrics, NULL);
+        hb_font_funcs_set_glyph_h_advance_func(funcs, cached_h_advance,
+                metrics, NULL);
+        hb_font_funcs_set_glyph_v_advance_func(funcs, cached_v_advance,
+                metrics, NULL);
+        hb_font_funcs_set_glyph_h_origin_func(funcs, cached_h_origin,
+                metrics, NULL);
+        hb_font_funcs_set_glyph_v_origin_func(funcs, cached_v_origin,
+                metrics, NULL);
+        hb_font_funcs_set_glyph_h_kerning_func(funcs, get_h_kerning,
+                metrics, NULL);
+        hb_font_funcs_set_glyph_v_kerning_func(funcs, get_v_kerning,
+                metrics, NULL);
+        hb_font_funcs_set_glyph_extents_func(funcs, cached_extents,
+                metrics, NULL);
+        hb_font_funcs_set_glyph_contour_point_func(funcs, get_contour_point,
+                metrics, NULL);
+        hb_font_set_funcs(hb_fonts[info->face_index], funcs,
+                font->faces[info->face_index], NULL);
+    }
+
+    ass_face_set_size(font->faces[info->face_index], info->font_size);
+    update_hb_size(hb_fonts[info->face_index], font->faces[info->face_index]);
+
+    // update hash key for cached metrics
+    struct ass_shaper_metrics_data *metrics =
+        font->shaper_priv->metrics_data[info->face_index];
+    metrics->hash_key.font = info->font;
+    metrics->hash_key.face_index = info->face_index;
+    metrics->hash_key.size = info->font_size;
+    metrics->hash_key.scale_x = double_to_d6(info->scale_x);
+    metrics->hash_key.scale_y = double_to_d6(info->scale_y);
+
+    return hb_fonts[info->face_index];
+}
+
+/**
+ * \brief Shape event text with HarfBuzz. Full OpenType shaping.
+ * \param glyphs glyph clusters
+ * \param len number of clusters
+ */
+static void shape_harfbuzz(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
+{
+    int i, j;
+    int run = 0;
+    struct {
+        int offset;
+        int end;
+        hb_buffer_t *buf;
+        hb_font_t *font;
+    } runs[MAX_RUNS];
+
+
+    for (i = 0; i < len && run < MAX_RUNS; i++, run++) {
+        // get length and level of the current run
+        int k = i;
+        int level = glyphs[i].shape_run_id;
+        int direction = shaper->emblevels[k] % 2;
+        while (i < (len - 1) && level == glyphs[i+1].shape_run_id)
+            i++;
+        runs[run].offset = k;
+        runs[run].end    = i;
+        runs[run].buf    = hb_buffer_create();
+        runs[run].font   = get_hb_font(shaper, glyphs + k);
+        set_run_features(shaper, glyphs + k);
+        hb_buffer_pre_allocate(runs[run].buf, i - k + 1);
+        hb_buffer_set_direction(runs[run].buf, direction ? HB_DIRECTION_RTL :
+                HB_DIRECTION_LTR);
+        hb_buffer_set_language(runs[run].buf, shaper->language);
+        hb_buffer_add_utf32(runs[run].buf, shaper->event_text + k, i - k + 1,
+                0, i - k + 1);
+        hb_shape(runs[run].font, runs[run].buf, shaper->features,
+                shaper->n_features);
+    }
+
+    // Initialize: skip all glyphs, this is undone later as needed
+    for (i = 0; i < len; i++)
+        glyphs[i].skip = 1;
+
+    // Update glyph indexes, positions and advances from the shaped runs
+    for (i = 0; i < run; i++) {
+        int num_glyphs = hb_buffer_get_length(runs[i].buf);
+        hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(runs[i].buf, NULL);
+        hb_glyph_position_t *pos    = hb_buffer_get_glyph_positions(runs[i].buf, NULL);
+
+        for (j = 0; j < num_glyphs; j++) {
+            int idx = glyph_info[j].cluster + runs[i].offset;
+            GlyphInfo *info = glyphs + idx;
+            GlyphInfo *root = info;
+
+            // if we have more than one glyph per cluster, allocate a new one
+            // and attach to the root glyph
+            if (info->skip == 0) {
+                while (info->next)
+                    info = info->next;
+                info->next = malloc(sizeof(GlyphInfo));
+                memcpy(info->next, info, sizeof(GlyphInfo));
+                info = info->next;
+                info->next = NULL;
+            }
+
+            // set position and advance
+            info->skip = 0;
+            info->glyph_index = glyph_info[j].codepoint;
+            info->offset.x    = pos[j].x_offset * info->scale_x;
+            info->offset.y    = -pos[j].y_offset * info->scale_y;
+            info->advance.x   = pos[j].x_advance * info->scale_x;
+            info->advance.y   = -pos[j].y_advance * info->scale_y;
+
+            // accumulate advance in the root glyph
+            root->cluster_advance.x += info->advance.x;
+            root->cluster_advance.y += info->advance.y;
+        }
+    }
+
+    // Free runs and associated data
+    for (i = 0; i < run; i++) {
+        hb_buffer_destroy(runs[i].buf);
+    }
+
+}
+#endif
+
+/**
+ * \brief Shape event text with FriBidi. Does mirroring and simple
+ * Arabic shaping.
+ * \param len number of clusters
+ */
+static void shape_fribidi(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
+{
+    int i;
+    FriBidiJoiningType *joins = calloc(sizeof(*joins), len);
+
+    // shape on codepoint level
+    fribidi_get_joining_types(shaper->event_text, len, joins);
+    fribidi_join_arabic(shaper->ctypes, len, shaper->emblevels, joins);
+    fribidi_shape(FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC,
+            shaper->emblevels, len, joins, shaper->event_text);
+
+    // update indexes
+    for (i = 0; i < len; i++) {
+        GlyphInfo *info = glyphs + i;
+        FT_Face face = info->font->faces[info->face_index];
+        info->symbol = shaper->event_text[i];
+        info->glyph_index = FT_Get_Char_Index(face, shaper->event_text[i]);
+    }
+
+    free(joins);
+}
+
+/**
+ * \brief Toggle kerning for HarfBuzz shaping.
+ * NOTE: currently only works with OpenType fonts, the TrueType fallback *always*
+ * kerns. It's a bug in HarfBuzz.
+ */
+void ass_shaper_set_kerning(ASS_Shaper *shaper, int kern)
+{
+#ifdef CONFIG_HARFBUZZ
+    shaper->features[KERN].value = !!kern;
+#endif
+}
+
+/**
+ * \brief Find shape runs according to the event's selected fonts
+ */
+void ass_shaper_find_runs(ASS_Shaper *shaper, ASS_Renderer *render_priv,
+                          GlyphInfo *glyphs, size_t len)
+{
+    int i;
+    int shape_run = 0;
+
+    for (i = 0; i < len; i++) {
+        GlyphInfo *last = glyphs + i - 1;
+        GlyphInfo *info = glyphs + i;
+        // skip drawings
+        if (info->symbol == 0xfffc)
+            continue;
+        // set size and get glyph index
+        ass_font_get_index(render_priv->fontconfig_priv, info->font,
+                info->symbol, &info->face_index, &info->glyph_index);
+        // shape runs share the same font face and size
+        if (i > 0 && (last->font != info->font ||
+                    last->font_size != info->font_size ||
+                    last->face_index != info->face_index))
+            shape_run++;
+        info->shape_run_id = shape_run;
+    }
+
+}
+
+/**
+ * \brief Set base direction (paragraph direction) of the text.
+ * \param dir base direction
+ */
+void ass_shaper_set_base_direction(ASS_Shaper *shaper, FriBidiParType dir)
+{
+    shaper->base_direction = dir;
+}
+
+/**
+ * \brief Set language hint. Some languages have specific character variants,
+ * like Serbian Cyrillic.
+ * \param lang ISO 639-1 two-letter language code
+ */
+void ass_shaper_set_language(ASS_Shaper *shaper, const char *code)
+{
+#ifdef CONFIG_HARFBUZZ
+    shaper->language = hb_language_from_string(code, -1);
+#endif
+}
+
+/**
+ * Set shaping level. Essentially switches between FriBidi and HarfBuzz.
+ */
+void ass_shaper_set_level(ASS_Shaper *shaper, ASS_ShapingLevel level)
+{
+    shaper->shaping_level = level;
+}
+
+/**
+ * \brief Shape an event's text. Calculates directional runs and shapes them.
+ * \param text_info event's text
+ */
+void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info)
+{
+    int i, last_break;
+    FriBidiParType dir;
+    GlyphInfo *glyphs = text_info->glyphs;
+
+    check_allocations(shaper, text_info->length);
+
+    // Get bidi character types and embedding levels
+    last_break = 0;
+    for (i = 0; i < text_info->length; i++) {
+        shaper->event_text[i] = glyphs[i].symbol;
+        // embedding levels should be calculated paragraph by paragraph
+        if (glyphs[i].symbol == '\n' || i == text_info->length - 1) {
+            dir = shaper->base_direction;
+            fribidi_get_bidi_types(shaper->event_text + last_break,
+                    i - last_break + 1, shaper->ctypes + last_break);
+            fribidi_get_par_embedding_levels(shaper->ctypes + last_break,
+                    i - last_break + 1, &dir, shaper->emblevels + last_break);
+            last_break = i + 1;
+        }
+    }
+
+    // add embedding levels to shape runs for final runs
+    for (i = 0; i < text_info->length; i++) {
+        glyphs[i].shape_run_id += shaper->emblevels[i];
+    }
+
+#ifdef CONFIG_HARFBUZZ
+    switch (shaper->shaping_level) {
+    case ASS_SHAPING_SIMPLE:
+        shape_fribidi(shaper, glyphs, text_info->length);
+        break;
+    case ASS_SHAPING_COMPLEX:
+        shape_harfbuzz(shaper, glyphs, text_info->length);
+        break;
+    }
+#else
+        shape_fribidi(shaper, glyphs, text_info->length);
+#endif
+
+
+    // clean up
+    for (i = 0; i < text_info->length; i++) {
+        // Skip direction override control characters
+        // NOTE: Behdad said HarfBuzz is supposed to remove these, but this hasn't
+        // been implemented yet
+        if (glyphs[i].symbol <= 0x202F && glyphs[i].symbol >= 0x202a) {
+            glyphs[i].symbol = 0;
+            glyphs[i].skip++;
+        }
+    }
+}
+
+/**
+ * \brief Create a new shaper instance and preallocate data structures
+ * \param prealloc preallocation size
+ */
+ASS_Shaper *ass_shaper_new(size_t prealloc)
+{
+    ASS_Shaper *shaper = calloc(sizeof(*shaper), 1);
+
+    shaper->base_direction = FRIBIDI_PAR_ON;
+    check_allocations(shaper, prealloc);
+
+#ifdef CONFIG_HARFBUZZ
+    init_features(shaper);
+    shaper->metrics_cache = ass_glyph_metrics_cache_create();
+#endif
+
+    return shaper;
+}
+
+
+/**
+ * \brief clean up additional data temporarily needed for shaping and
+ * (e.g. additional glyphs allocated)
+ */
+void ass_shaper_cleanup(ASS_Shaper *shaper, TextInfo *text_info)
+{
+    int i;
+
+    for (i = 0; i < text_info->length; i++) {
+        GlyphInfo *info = text_info->glyphs + i;
+        info = info->next;
+        while (info) {
+            GlyphInfo *next = info->next;
+            free(info);
+            info = next;
+        }
+    }
+}
+
+/**
+ * \brief Calculate reorder map to render glyphs in visual order
+ */
+FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info)
+{
+    int i;
+
+    // Initialize reorder map
+    for (i = 0; i < text_info->length; i++)
+        shaper->cmap[i] = i;
+
+    // Create reorder map line-by-line
+    for (i = 0; i < text_info->n_lines; i++) {
+        LineInfo *line = text_info->lines + i;
+        int level;
+        FriBidiParType dir = FRIBIDI_PAR_ON;
+
+        level = fribidi_reorder_line(0,
+                shaper->ctypes + line->offset, line->len, 0, dir,
+                shaper->emblevels + line->offset, NULL,
+                shaper->cmap + line->offset);
+    }
+
+    return shaper->cmap;
+}
+
+/**
+ * \brief Resolve a Windows font encoding number to a suitable
+ * base direction. 177 and 178 are Hebrew and Arabic respectively, and
+ * they map to RTL. 1 is autodetection and is mapped to just that.
+ * Everything else is mapped to LTR.
+ * \param enc Windows font encoding
+ */
+FriBidiParType resolve_base_direction(int enc)
+{
+    switch (enc) {
+        case 1:
+            return FRIBIDI_PAR_ON;
+        case 177:
+        case 178:
+            return FRIBIDI_PAR_RTL;
+        default:
+            return FRIBIDI_PAR_LTR;
+    }
+}
diff --git a/lib/libass/libass/ass_shaper.h b/lib/libass/libass/ass_shaper.h
new file mode 100644 (file)
index 0000000..81499dd
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 Grigori Goronzy <greg@chown.ath.cx>
+ *
+ * This file is part of libass.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef LIBASS_SHAPER_H
+#define LIBASS_SHAPER_H
+
+#include "config.h"
+
+#include <fribidi/fribidi.h>
+#include "ass_render.h"
+
+void ass_shaper_info(ASS_Library *lib);
+ASS_Shaper *ass_shaper_new(size_t prealloc);
+void ass_shaper_free(ASS_Shaper *shaper);
+void ass_shaper_set_kerning(ASS_Shaper *shaper, int kern);
+void ass_shaper_find_runs(ASS_Shaper *shaper, ASS_Renderer *render_priv,
+                          GlyphInfo *glyphs, size_t len);
+void ass_shaper_set_base_direction(ASS_Shaper *shaper, FriBidiParType dir);
+void ass_shaper_set_language(ASS_Shaper *shaper, const char *code);
+void ass_shaper_set_level(ASS_Shaper *shaper, ASS_ShapingLevel level);
+void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info);
+void ass_shaper_cleanup(ASS_Shaper *shaper, TextInfo *text_info);
+FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info);
+FriBidiParType resolve_base_direction(int font_encoding);
+
+void ass_shaper_font_data_free(ASS_ShaperFontData *priv);
+
+#endif
index 6a6f1ae..20fd825 100644 (file)
@@ -112,6 +112,7 @@ typedef struct ass_track {
     int WrapStyle;
     int ScaledBorderAndShadow;
     int Kerning;
+    char *Language;
 
     int default_style;      // index of default style
     char *name;             // file name in case of external subs, 0 for streams
index 0ea8792..f8fa145 100644 (file)
@@ -34,3 +34,4 @@ ass_set_message_cb
 ass_fonts_update
 ass_set_cache_limits
 ass_flush_events
+ass_set_shaper
index 9adad4d..208c9cf 100644 (file)
@@ -4,4 +4,4 @@ noinst_PROGRAMS = test
 test_SOURCES = test.c
 test_CPPFLAGS = -I../libass
 test_LDADD = ../libass/libass.la
-test_LDFLAGS = -lpng
+test_LDFLAGS = $(AM_LDFLAGS) $(LIBPNG_LIBS)
index 432a44f..d6cd9b8 100644 (file)
@@ -194,6 +194,8 @@ int main(int argc, char *argv[])
     ass_library_done(ass_library);
 
     write_png(imgfile, frame);
+    free(frame->buffer);
+    free(frame);
 
     return 0;
 }
index e5059ae..fc341b2 100644 (file)
@@ -65,6 +65,7 @@
       <WarningLevel>Level3</WarningLevel>
       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
       <DisableSpecificWarnings>4001;4996;4244;4267;4018;4005;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <CompileAs>CompileAsC</CompileAs>
     </ClCompile>
     <Link>
       <AdditionalDependencies>fontconfig.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
     <ClInclude Include="..\..\libass\ass_library.h" />
     <ClInclude Include="..\..\libass\ass_parse.h" />
     <ClInclude Include="..\..\libass\ass_render.h" />
+    <ClInclude Include="..\..\libass\ass_shaper.h" />
     <ClInclude Include="..\..\libass\ass_types.h" />
     <ClInclude Include="..\..\libass\ass_utils.h" />
     <ClInclude Include="config.h" />
     <ClCompile Include="..\..\libass\ass_parse.c" />
     <ClCompile Include="..\..\libass\ass_render.c" />
     <ClCompile Include="..\..\libass\ass_render_api.c" />
+    <ClCompile Include="..\..\libass\ass_shaper.c" />
     <ClCompile Include="..\..\libass\ass_strtod.c" />
-    <ClCompile Include="..\..\libass\ass_utils.c" />
+    <ClCompile Include="..\..\libass\ass_utils.c">
+      <CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Default</CompileAs>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\..\enca\libenca_win32\libenca_win32.vcxproj">
index 8776161..ec307c4 100644 (file)
@@ -7,17 +7,17 @@
 
 # lib name, version
 LIBNAME=libcec
-VERSION=1.2.0
+VERSION=latest
 SOURCE=$(LIBNAME)-$(VERSION)
 
 # download location and format
-BASE_URL=http://mirrors.xbmc.org/build-deps/darwin-libs
-ARCHIVE=$(SOURCE).tar.gz 
+BASE_URL=http://packages.pulse-eight.net/pulse/sources/libcec
+ARCHIVE=$(SOURCE).tar.bz2 
 TARBALLS_LOCATION=.
 RETRIEVE_TOOL=/usr/bin/curl
 RETRIEVE_TOOL_FLAGS=-Ls --create-dirs --output $(TARBALLS_LOCATION)/$(ARCHIVE)
 ARCHIVE_TOOL=tar
-ARCHIVE_TOOL_FLAGS=xf
+ARCHIVE_TOOL_FLAGS=jxf
 
 PREFIX ?= /usr/local
 LIBCEC_CONFIGOPTS ?= --prefix=$(PREFIX)
@@ -25,30 +25,30 @@ LIBCEC_CONFIGOPTS ?= --prefix=$(PREFIX)
 # configuration settings
 CONFIGURE=./configure CFLAGS=-D_FILE_OFFSET_BITS=64 $(LIBCEC_CONFIGOPTS)
 
-SO_NAME=$(SOURCE)/.libs/$(LIBNAME).so
+SO_NAME=$(LIBNAME)/.libs/$(LIBNAME).so
 
 all: $(SO_NAME)
 
 $(TARBALLS_LOCATION)/$(ARCHIVE):
        $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE)
 
-$(SOURCE): $(TARBALLS_LOCATION)/$(ARCHIVE)
-       rm -rf $(SOURCE)
+$(LIBNAME): $(TARBALLS_LOCATION)/$(ARCHIVE)
+       rm -rf $(LIBNAME)
        $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
-       echo $(SOURCE) > .gitignore
-       cd $(SOURCE); autoreconf -vif
-       cd $(SOURCE); $(CONFIGURE)
+       echo $(LIBNAME) > .gitignore
+       cd $(LIBNAME); autoreconf -vif
+       cd $(LIBNAME); $(CONFIGURE)
 
-$(SO_NAME): $(SOURCE)
-       make -j 1 -C $(SOURCE)
+$(SO_NAME): $(LIBNAME)
+       make -j 1 -C $(LIBNAME)
 
 install:
-       make -C $(SOURCE) install
+       make -C $(LIBNAME) install
        ldconfig
 
 clean:
-       rm -rf $(SOURCE)
+       rm -rf $(LIBNAME)
 
 distclean::
-       rm -rf $(SOURCE)
+       rm -rf $(LIBNAME)
 
index 686b407..1534f33 100644 (file)
@@ -66,15 +66,15 @@ $(SYSDIR)/libdvdnav-$(ARCH).so: $(WRAPPER) $(DVDCSS_A) libdvdread/obj/libdvdread
 
 endif
 
-libdvdcss/src/.libs/libdvdcss.a: libdvdcss
+libdvdcss/src/.libs/libdvdcss.a: libdvdcss;
 libdvdcss: compile
        $(MAKE) -C $@
 
-libdvdread/obj/libdvdread.a: libdvdread
+libdvdread/obj/libdvdread.a: libdvdread;
 libdvdread: compile
        $(MAKE) -C $@
 
-libdvdnav/obj/libdvdnav.a: libdvdnav
+libdvdnav/obj/libdvdnav.a: libdvdnav;
 libdvdnav: compile
        $(MAKE) -C $@
 
index 0d3475e..ed66bf4 100644 (file)
@@ -224,14 +224,9 @@ timemapdone:
 
     if(found) {
 
-      length = cell->last_sector - cell->first_sector + 1;
-      if (target >= length) {
-        target -= length;
-      } else {
-        /* convert the target sector from Cell-relative to absolute physical sector */
-        target += cell->first_sector;
-        break;
-      }
+      if (target >= cell->first_sector
+      &&  target <= cell->last_sector)
+         break;
 
     } else {
 
index 74ecbbe..2386fd3 100644 (file)
@@ -413,7 +413,13 @@ void CExifParse::ProcessDir(const unsigned char* const DirStart,
     // Extract useful components of tag
     switch(Tag)
     {
-//      case TAG_DESCRIPTION:       strncpy(m_ExifInfo->Description, ValuePtr, 5);    break;
+      case TAG_DESCRIPTION:
+      {
+        int length = max(ByteCount, 0);
+        length = min(length, MAX_COMMENT);
+        strncpy(m_ExifInfo->Description, (char *)ValuePtr, length);
+        break;
+      }
       case TAG_MAKE:              strncpy(m_ExifInfo->CameraMake, (char *)ValuePtr, 32);    break;
       case TAG_MODEL:             strncpy(m_ExifInfo->CameraModel, (char *)ValuePtr, 40);    break;
 //      case TAG_SOFTWARE:          strncpy(m_ExifInfo->Software, ValuePtr, 5);    break;
@@ -446,7 +452,7 @@ void CExifParse::ProcessDir(const unsigned char* const DirStart,
       {
         const int EXIF_COMMENT_HDR_LENGTH = 8;        // All comment tags have 8 bytes of header info
         int length = max(ByteCount - EXIF_COMMENT_HDR_LENGTH, 0);
-        length = min(length, 2000);
+        length = min(length, MAX_COMMENT);
         strncpy(m_ExifInfo->Comments, (char *)ValuePtr+EXIF_COMMENT_HDR_LENGTH, length);
 //        FixComment(comment);                          // Ensure comment is printable
       }
index 9b21c64..b58e1f0 100644 (file)
@@ -37,6 +37,7 @@
 #include "ExifParse.h"
 
 // Supported IPTC entry types
+#define IPTC_RECORD_VERSION         0x00
 #define IPTC_SUPLEMENTAL_CATEGORIES 0x14
 #define IPTC_KEYWORDS               0x19
 #define IPTC_CAPTION                0x78
@@ -58,6 +59,9 @@
 #define IPTC_COPYRIGHT              0x0A
 #define IPTC_COUNTRY_CODE           0x64
 #define IPTC_REFERENCE_SERVICE      0x2D
+#define IPTC_TIME_CREATED           0x3C
+#define IPTC_SUB_LOCATION           0x5C
+#define IPTC_IMAGE_TYPE             0x82
 
 
 //--------------------------------------------------------------------------
@@ -89,66 +93,100 @@ bool CIptcParse::Process (const unsigned char* const Data, const unsigned short
 
   // Check IPTC signatures
   char* pos = (char*)(Data + sizeof(short));  // position data pointer after length field
+  char* maxpos = (char*)(Data+itemlen);
+  unsigned char headerLen = 0;
+  unsigned char dataLen = 0;
+  memset(info, 0, sizeof(IPTCInfo_t));
 
-  if (memcmp(pos, IptcSignature1, strlen(IptcSignature1)) != 0) return false;
-  pos += strlen(IptcSignature1) + 1;          // move data pointer to the next field
+  if (itemlen < 25) return false;
 
-  if (memcmp(pos, IptcSignature2, strlen(IptcSignature2)) != 0) return false;
-  pos += strlen(IptcSignature2);              // move data pointer to the next field
+  if (memcmp(pos, IptcSignature1, strlen(IptcSignature1)-1) != 0) return false;
+  pos += sizeof(IptcSignature1);          // move data pointer to the next field
 
-  if (memcmp(pos, IptcSignature3, sizeof(IptcSignature3)) != 0) return false;
-  pos += sizeof(IptcSignature3);              // move data pointer to the next field
+  if (memcmp(pos, IptcSignature2, strlen(IptcSignature2)-1) != 0) return false;
+  pos += sizeof(IptcSignature2)-1;              // move data pointer to the next field
+
+  while (memcmp(pos, IptcSignature3, sizeof(IptcSignature3)) != 0) { // loop on valid Photoshop blocks
+
+    pos += sizeof(IptcSignature3); // move data pointer to the Header Length
+    // Skip header
+    headerLen = *pos; // get header length and move data pointer to the next field
+    pos += (headerLen & 0xfe) + 2; // move data pointer to the next field (Header is padded to even length, counting the length byte)
+
+    pos += 3; // move data pointer to length, assume only one byte, TODO: use all 4 bytes
+
+    dataLen = *pos++;
+    pos += dataLen; // skip data section
+
+    if (memcmp(pos, IptcSignature2, sizeof(IptcSignature2) - 1) != 0) return false;
+    pos += sizeof(IptcSignature2) - 1; // move data pointer to the next field
+  }
+
+  pos += sizeof(IptcSignature3);          // move data pointer to the next field
+  if (pos >= maxpos) return false;
 
   // IPTC section found
 
   // Skip header
-  unsigned char headerLen = *pos++;           // get header length and move data pointer to the next field
+  headerLen = *pos++;           // get header length and move data pointer to the next field
   pos += headerLen + 1 - (headerLen % 2);     // move data pointer to the next field (Header is padded to even length, counting the length byte)
 
-  // Get length (Motorola format)
-  unsigned long length = CExifParse::Get32(pos);
+  if (pos + 4 >= maxpos) return false;
+
   pos += 4;                                   // move data pointer to the next field
 
   // Now read IPTC data
   while (pos < (char*)(Data + itemlen-5))
   {
+    if (pos + 5 > maxpos) return false;
+
     short signature = (*pos << 8) + (*(pos+1));
 
-    pos += sizeof(short);
-    if (signature != 0x1C02)
+    pos += 2;
+    if (signature != 0x1C01 && signature != 0x1C02)
       break;
 
     unsigned char  type = *pos++;
     unsigned short length  = (*pos << 8) + (*(pos+1));
-    pos += sizeof(short);                   // Skip tag length
+    pos += 2;                   // Skip tag length
+
+    if (pos + length > maxpos) return false;
+
     // Process tag here
     char *tag = NULL;
-    switch (type)
+    if (signature == 0x1C02)
     {
-      case IPTC_SUPLEMENTAL_CATEGORIES:   tag = info->SupplementalCategories;  break;
-      case IPTC_KEYWORDS:                 tag = info->Keywords;                break;
-      case IPTC_CAPTION:                  tag = info->Caption;                 break;
-      case IPTC_AUTHOR:                   tag = info->Author;                  break;
-      case IPTC_HEADLINE:                 tag = info->Headline;                break;
-      case IPTC_SPECIAL_INSTRUCTIONS:     tag = info->SpecialInstructions;     break;
-      case IPTC_CATEGORY:                 tag = info->Category;                break;
-      case IPTC_BYLINE:                   tag = info->Byline;                  break;
-      case IPTC_BYLINE_TITLE:             tag = info->BylineTitle;             break;
-      case IPTC_CREDIT:                   tag = info->Credit;                  break;
-      case IPTC_SOURCE:                   tag = info->Source;                  break;
-      case IPTC_COPYRIGHT_NOTICE:         tag = info->CopyrightNotice;         break;
-      case IPTC_OBJECT_NAME:              tag = info->ObjectName;              break;
-      case IPTC_CITY:                     tag = info->City;                    break;
-      case IPTC_STATE:                    tag = info->State;                   break;
-      case IPTC_COUNTRY:                  tag = info->Country;                 break;
-      case IPTC_TRANSMISSION_REFERENCE:   tag = info->TransmissionReference;   break;
-      case IPTC_DATE:                     tag = info->Date;                    break;
-      case IPTC_COPYRIGHT:                tag = info->Copyright;               break;
-      case IPTC_REFERENCE_SERVICE:        tag = info->ReferenceService;        break;
-      case IPTC_COUNTRY_CODE:             tag = info->CountryCode;             break;
-      default:
-        printf("IptcParse: Unrecognised IPTC tag: 0x%02x", type);
-      break;
+      switch (type)
+      {
+        case IPTC_RECORD_VERSION:           tag = info->RecordVersion;           break;
+        case IPTC_SUPLEMENTAL_CATEGORIES:   tag = info->SupplementalCategories;  break;
+        case IPTC_KEYWORDS:                 tag = info->Keywords;                break;
+        case IPTC_CAPTION:                  tag = info->Caption;                 break;
+        case IPTC_AUTHOR:                   tag = info->Author;                  break;
+        case IPTC_HEADLINE:                 tag = info->Headline;                break;
+        case IPTC_SPECIAL_INSTRUCTIONS:     tag = info->SpecialInstructions;     break;
+        case IPTC_CATEGORY:                 tag = info->Category;                break;
+        case IPTC_BYLINE:                   tag = info->Byline;                  break;
+        case IPTC_BYLINE_TITLE:             tag = info->BylineTitle;             break;
+        case IPTC_CREDIT:                   tag = info->Credit;                  break;
+        case IPTC_SOURCE:                   tag = info->Source;                  break;
+        case IPTC_COPYRIGHT_NOTICE:         tag = info->CopyrightNotice;         break;
+        case IPTC_OBJECT_NAME:              tag = info->ObjectName;              break;
+        case IPTC_CITY:                     tag = info->City;                    break;
+        case IPTC_STATE:                    tag = info->State;                   break;
+        case IPTC_COUNTRY:                  tag = info->Country;                 break;
+        case IPTC_TRANSMISSION_REFERENCE:   tag = info->TransmissionReference;   break;
+        case IPTC_DATE:                     tag = info->Date;                    break;
+        case IPTC_COPYRIGHT:                tag = info->Copyright;               break;
+        case IPTC_REFERENCE_SERVICE:        tag = info->ReferenceService;        break;
+        case IPTC_COUNTRY_CODE:             tag = info->CountryCode;             break;
+        case IPTC_TIME_CREATED:             tag = info->TimeCreated;             break;
+        case IPTC_SUB_LOCATION:             tag = info->SubLocation;             break;
+        case IPTC_IMAGE_TYPE:               tag = info->ImageType;               break;
+        default:
+          printf("IptcParse: Unrecognised IPTC tag: 0x%02x", type);
+          break;
+      }
     }
 
     if (tag)
index e889892..f7dc532 100644 (file)
@@ -48,6 +48,7 @@ extern "C" {
 #define MAX_IPTC_STRING 256
 
 typedef struct {
+  char RecordVersion[MAX_IPTC_STRING];
   char SupplementalCategories[MAX_IPTC_STRING];
   char Keywords[MAX_IPTC_STRING];
   char Caption[MAX_IPTC_STRING];
@@ -69,6 +70,9 @@ typedef struct {
   char Copyright[MAX_IPTC_STRING];
   char ReferenceService[MAX_IPTC_STRING];
   char CountryCode[MAX_IPTC_STRING];
+  char TimeCreated[MAX_IPTC_STRING];
+  char SubLocation[MAX_IPTC_STRING];
+  char ImageType[MAX_IPTC_STRING];
 } IPTCInfo_t;
 
 #define MAX_COMMENT 2000
@@ -98,6 +102,7 @@ typedef struct {
     int   ISOequivalent;
     int   LightSource;
     char  Comments[MAX_COMMENT];
+    char  Description[MAX_COMMENT];
 
     unsigned ThumbnailOffset;          // Exif offset to thumbnail
     unsigned ThumbnailSize;            // Size of thumbnail.
index 8f02398..35cb4f6 100644 (file)
@@ -141,7 +141,7 @@ int translate_APIC(struct id3_frame *frame, char const *oldid,
                   id3_byte_t const *data, id3_length_t length)
 {
   id3_byte_t const *end;
-  char type[3];
+  char type[4];
   enum id3_field_textencoding encoding;
   int result = 0;
   
index 8b7d43f..bc758f5 100644 (file)
@@ -76,6 +76,7 @@ error "gperf generated tables don't work with this execution character set. Plea
 # define TX(id)    #id, translate_##id
 
 static id3_compat_func_t translate_TCON;
+static id3_compat_func_t translate_APIC;
 
 #define TOTAL_KEYWORDS 75
 #define MIN_WORD_LENGTH 3
@@ -276,7 +277,7 @@ id3_compat_lookup (str, len)
 #line 96 "compat.gperf"
       {"TIME", OBSOLETE  /* Time [obsolete] */},
 #line 75 "compat.gperf"
-      {"PIC",  EQ(APIC)  /* Attached picture */},
+      {"PIC",  TX(APIC)  /* Attached picture */},
 #line 127 "compat.gperf"
       {"UFI",  EQ(UFID)  /* Unique file identifier */},
 #line 72 "compat.gperf"
@@ -346,7 +347,7 @@ int translate_APIC(struct id3_frame *frame, char const *oldid,
                   id3_byte_t const *data, id3_length_t length)
 {
   id3_byte_t const *end;
-  char type[3];
+  char type[4];
   enum id3_field_textencoding encoding;
   int result = 0;
   
index 6da472c..7dee1e0 100644 (file)
@@ -299,30 +299,7 @@ const id3_ucs4_t* id3_metadata_getcomment(const struct id3_tag* tag, enum id3_fi
   union id3_field const *field;
   struct id3_frame const *frame;
   int commentNumber = 0;
-//on ios use the "old" version without the bugfix from https://github.com/xbmc/xbmc/commit/e09cb07
-//because it somehow exposes a bug which leads to unreproducable crashs on id3v2 tags
-#ifdef TARGET_DARWIN_IOS
   const id3_ucs4_t* ucs4 = 0;
-  // return the first non-empty comment
-  do
-  {
-    frame = id3_tag_findframe(tag, ID3_FRAME_COMMENT, commentNumber++);
-    if (frame == 0)
-           return id3_ucs4_empty;
-
-    *encoding = id3_field_gettextencoding(id3_frame_field(frame, 0));
-
-    field = id3_frame_field(frame, 3);
-    if (field == 0)
-      return id3_ucs4_empty;
-    
-    ucs4 = id3_field_getfullstring(field);
-    if (!ucs4)
-      return id3_ucs4_empty;
-  }
-  while (*ucs4 == 0);
-#else
-  const id3_ucs4_t* ucs4 = id3_ucs4_empty;
 
   // return the first non-empty comment
   do
@@ -355,16 +332,13 @@ const id3_ucs4_t* id3_metadata_getcomment(const struct id3_tag* tag, enum id3_fi
         //finally fetch the comment
         field = id3_frame_field(frame, 3);
         if (field == 0)
-          break;
+          continue;
     
-        ucs4 = id3_field_getfullstring(field);
-        //done
-        break;  
+        return id3_field_getfullstring(field);
       }
     }
   }
   while (frame);
-#endif//else TARGET_DARWIN_IOS
   return ucs4;
 }
 
index bb3991c..013c951 100644 (file)
Binary files a/media/Splash.png and b/media/Splash.png differ
index 51ee6ad..a57be50 100644 (file)
Binary files a/media/weather.zip and b/media/weather.zip differ
index 18605e0..4392867 100644 (file)
@@ -1,5 +1,5 @@
 ; filename                          mirror of the file
-boost-1_46_1-xbmc-win32.7z                     http://mirrors.xbmc.org/build-deps/win32/
+boost-1_46_1-xbmc-win32-1.7z                   http://mirrors.xbmc.org/build-deps/win32/
 ;boost_1_46_1-headers-win32.7z      http://mirrors.xbmc.org/build-deps/win32/
 ;boost_1_46_1-libs-win32.7z         http://mirrors.xbmc.org/build-deps/win32/
 ;boost_1_46_1-debug-libs-win32.7z   http://mirrors.xbmc.org/build-deps/win32/
index 94554c2..1cf948c 100644 (file)
@@ -20,7 +20,7 @@ xcopy lib\* "%MINGW_INSTALL_PATH%\lib" /E /Q /I /Y
 xcopy share\* "%MINGW_INSTALL_PATH%\share" /E /Q /I /Y
 xcopy libexec\* "%MINGW_INSTALL_PATH%\libexec" /E /Q /I /Y
 xcopy mingw32\* "%MINGW_INSTALL_PATH%\mingw32" /E /Q /I /Y
-copy yasm-1.1.0-win32.exe "%MINGW_INSTALL_PATH%\bin\yasm.exe" /Y
+copy yasm-1.2.0-win32.exe "%MINGW_INSTALL_PATH%\bin\yasm.exe" /Y
 copy xasm.exe "%MINGW_INSTALL_PATH%\bin\xasm.exe" /Y
 copy mads.exe "%MINGW_INSTALL_PATH%\bin\mads.exe" /Y
 rem xcopy curl-7.21.0-devel-mingw32\include\curl "%CUR_PATH%\include\curl" /E /Q /I /Y
index 37d84a8..7a52d8b 100644 (file)
@@ -2,12 +2,12 @@
 mingwrt-3.20-mingw32-dev.tar.gz             http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/RuntimeLibrary/MinGW-RT/mingwrt-3.20/
 mingwrt-3.20-mingw32-dll.tar.gz             http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/RuntimeLibrary/MinGW-RT/mingwrt-3.20/
 w32api-3.17-2-mingw32-dev.tar.lzma          http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/RuntimeLibrary/Win32-API/w32api-3.17/
-gcc-core-4.5.2-1-mingw32-bin.tar.lzma       http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GCC/Version4/gcc-4.5.2-1/
-gcc-c++-4.5.2-1-mingw32-bin.tar.lzma        http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GCC/Version4/gcc-4.5.2-1/
-libstdc++-4.5.2-1-mingw32-dll-6.tar.lzma    http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GCC/Version4/gcc-4.5.2-1/
+gcc-core-4.6.2-1-mingw32-bin.tar.lzma       http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GCC/Version4/gcc-4.6.2-1/
+gcc-c++-4.6.2-1-mingw32-bin.tar.lzma        http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GCC/Version4/gcc-4.6.2-1/
+libstdc++-4.6.2-1-mingw32-dll-6.tar.lzma    http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GCC/Version4/gcc-4.6.2-1/
 binutils-2.22-1-mingw32-bin.tar.lzma        http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/GNU-Binutils/binutils-2.22/
-yasm-1.1.0-win32.exe                        http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://www.tortall.net/projects/yasm/releases/
-dlfcn-win32-static-r19.tar.bz2              http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://dlfcn-win32.googlecode.com/files/
+yasm-1.2.0-win32.exe                        http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://www.tortall.net/projects/yasm/releases/
+dlfcn-win32-static-r19.tar.bz2              http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://code.google.com/p/dlfcn-win32/downloads/list
 libexpat-2.0.1-1-mingw32-dev.tar.gz         http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/expat/expat-2.0.1-1/
 libz-1.2.5-1-mingw32-dev.tar.lzma           http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/zlib/zlib-1.2.5-1-mingw32/
 libgmp-5.0.1-1-mingw32-dll-10.tar.lzma      http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/gmp/gmp-5.0.1-1/
@@ -15,12 +15,13 @@ libmpc-0.8.1-1-mingw32-dll-2.tar.lzma       http://mirrors.xbmc.org/build-deps/w
 libmpfr-2.4.1-1-mingw32-dll-1.tar.lzma      http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/mpfr/mpfr-2.4.1-1/
 automake1.11-1.11.1-1-mingw32-bin.tar.lzma  http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/automake/automake1.11/automake1.11-1.11.1-1/
 libtool-2.4-1-mingw32-bin.tar.lzma          http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/libtool/libtool-2.4-1/
-mads_1.9.2.7z                               http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://mads.atari8.info/
+mads_1.9.3.7z                               http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://mads.atari8.info/
 xasm-3.0.2-windows.zip                      http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://atariarea.krap.pl/x-asm/
+plibc-0.1.6.zip                             http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://sourceforge.net/projects/plibc/files/plibc/0.1.6/
+pthreads-w32-2.9.0-mingw32-pre-20110507-2-dev.tar.lzma   http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/pthreads-w32/pthreads-w32-2.9.0-pre-20110507-2/pthreads-w32-2.9.0-mingw32-pre-20110507-2-dev.tar.lzma
+libpthreadgc-2.9.0-mingw32-pre-20110507-2-dll-2.tar.lzma       http://mirrors.xbmc.org/build-deps/win32/mingw-msys/    http://downloads.sourceforge.net/project/mingw/MinGW/Base/pthreads-w32/pthreads-w32-2.9.0-pre-20110507-2/libpthreadgc-2.9.0-mingw32-pre-20110507-2-dll-2.tar.lzma
+gnutls-dev_2.4.2-1_win32.zip                http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://ftp.acc.umu.se/pub/gnome/binaries/win32/dependencies/gnutls-dev_2.4.2-1_win32.zip
+gettext-0.17-1-mingw32-dev.tar.lzma         http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/gettext/gettext-0.17-1/gettext-0.17-1-mingw32-dev.tar.lzma
 libintl-0.17-1-mingw32-dll-8.tar.lzma       http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://sourceforge.net/projects/mingw/files/MinGW/gettext/gettext-0.17-1/
 libiconv-1.13.1-1-mingw32-dll-2.tar.lzma    http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://sourceforge.net/projects/mingw/files/MinGW/libiconv/libiconv-1.13.1-1/
-libiconv-1.13.1-1-mingw32-dev.tar.lzma      http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://sourceforge.net/projects/mingw/files/MinGW/libiconv/libiconv-1.13.1-1/
-plibc-0.1.5.zip                             http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://sourceforge.net/projects/plibc/files/plibc/0.1.5/
-pthreads-w32-2.8.0-3-mingw32-dev.tar.lzma   http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/pthreads-w32/pthreads-w32-2.8.0-3/pthreads-w32-2.8.0-3-mingw32-dev.tar.lzma
-gnutls-dev_2.4.2-1_win32.zip                http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://ftp.acc.umu.se/pub/gnome/binaries/win32/dependencies/gnutls-dev_2.4.2-1_win32.zip
-gettext-0.17-1-mingw32-dev.tar.lzma         http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://downloads.sourceforge.net/project/mingw/MinGW/gettext/gettext-0.17-1/gettext-0.17-1-mingw32-dev.tar.lzma
\ No newline at end of file
+libiconv-1.13.1-1-mingw32-dev.tar.lzma      http://mirrors.xbmc.org/build-deps/win32/mingw-msys/        http://sourceforge.net/projects/mingw/files/MinGW/libiconv/libiconv-1.13.1-1/
\ No newline at end of file
index 27160b4..86a2797 100644 (file)
@@ -7,7 +7,8 @@ CALL dlextract.bat libcec %FILES%
 
 cd %TMP_PATH%
 
-xcopy libcec\include\* "%CUR_PATH%\include" /E /Q /I /Y
+mkdir "%CUR_PATH%\include\libcec"
+xcopy libcec\include\* "%CUR_PATH%\include\libcec\." /E /Q /I /Y
 
 copy libcec\libcec.dll "%XBMC_PATH%\system\."
 copy libcec\pthreadVC2.dll "%XBMC_PATH%\system\."
index ec9df80..c9718f5 100644 (file)
@@ -1,3 +1,3 @@
 ; filename                        source of the file
 
-libcec1.2.zip                     http://packages.pulse-eight.net/windows/
+libcec-1.5.2.zip                  http://mirrors.xbmc.org/build-deps/win32/
index 45c9aa8..ae7613d 100644 (file)
@@ -1,2 +1,2 @@
 ; filename                      mirror                                      source of the file
-fribidi-0.19.2-lib.zip          http://mirrors.xbmc.org/build-deps/win32/   http://xbmcwindeps.googlecode.com/files/
+fribidi-0.19.2-lib-1.zip          http://mirrors.xbmc.org/build-deps/win32/   http://xbmcwindeps.googlecode.com/files/
index 6c09174..65d5158 100644 (file)
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\CrystalHD.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDInputStreams\DVDInputStreamBluray.cpp" />
     <ClCompile Include="..\..\xbmc\cores\paplayer\BXAcodec.cpp" />
+    <ClCompile Include="..\..\xbmc\cores\paplayer\PCMCodec.cpp" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\RenderCapture.cpp" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\WinVideoFilter.cpp" />
     <ClCompile Include="..\..\xbmc\CueDocument.cpp" />
     <ClCompile Include="..\..\xbmc\DynamicDll.cpp" />
     <ClCompile Include="..\..\xbmc\Favourites.cpp" />
     <ClCompile Include="..\..\xbmc\FileItem.cpp" />
-    <ClCompile Include="..\..\xbmc\filesystem\CacheCircular.cpp" />
-    <ClCompile Include="..\..\xbmc\filesystem\FileNFS.cpp" />
-    <ClCompile Include="..\..\xbmc\filesystem\FilePipe.cpp" />
-    <ClCompile Include="..\..\xbmc\filesystem\FileUPnP.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\iso9660.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\ISO9660Directory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileUDF.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\AddonsDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\AFPDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\AFPFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\ASAPFileDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\CacheStrategy.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\CDDADirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\CDDAFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\CircularCache.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\CurlFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\DAAPDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\DAAPFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\DAVDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\Directory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\DirectoryCache.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\DirectoryFactory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\DirectoryHistory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\DllLibCurl.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\File.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\FileCache.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\FileDirectoryFactory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\FileFactory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\FileReaderFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\FTPDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\FTPParse.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\HDDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\HDFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\HDHomeRunDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\HDHomeRunFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\HTSPDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\HTSPSession.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\HTTPDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\IDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\IFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\iso9660.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\ISO9660Directory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\ISOFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\LastFMDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\LastFMFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\MemBufferCache.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\MultiPathDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\MultiPathFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\MusicDatabaseDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\MusicDatabaseFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\MusicFileDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\MusicSearchDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\MythDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\MythFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\MythSession.cpp" />
     <ClCompile Include="..\..\xbmc\filesystem\NFSDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\NFSFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\NptXbmcFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\NSFFileDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\OGGFileDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\PipeFile.cpp" />
     <ClCompile Include="..\..\xbmc\filesystem\PipesManager.cpp" />
-    <ClCompile Include="..\..\xbmc\filesystem\Slingbox.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\udf25.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\UDFDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\PlaylistDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\PlaylistFileDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\PluginDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\RarDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\RarFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\RarManager.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\RSSDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\RTVDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\RTVFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SAPDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SAPFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SFTPDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SFTPFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\ShoutcastFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SIDFileDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SlingboxDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SlingboxFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SmartPlaylistDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SourcesDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SpecialProtocol.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SpecialProtocolDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\SpecialProtocolFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\StackDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\TuxBoxDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\TuxBoxFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\udf25.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\UDFDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\UDFFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\UPnPDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\UPnPFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\VideoDatabaseDirectory.cpp" />
     <ClCompile Include="..\..\xbmc\FileSystem\VideoDatabaseDirectory\DirectoryNodeCountry.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\windows\WINFileSMB.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\windows\WINSMBDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\VirtualDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\VTPDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\VTPFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\VTPSession.cpp" />
     <ClCompile Include="..\..\xbmc\filesystem\ZeroconfDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\ZipDirectory.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\ZipFile.cpp" />
+    <ClCompile Include="..\..\xbmc\filesystem\ZipManager.cpp" />
     <ClCompile Include="..\..\xbmc\GUIInfoManager.cpp" />
     <ClCompile Include="..\..\xbmc\GUILargeTextureManager.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\AnimatedGif.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\DirectXGraphics.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\DirtyRegionSolvers.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\DirtyRegionTracker.cpp" />
-    <ClCompile Include="..\..\xbmc\guilib\FrameBufferObject.cpp" />
+    <ClCompile Include="..\..\xbmc\guilib\FrameBufferObject.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\guilib\GraphicContext.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUIAction.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUIAudioManager.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUIFontManager.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUIFontTTF.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUIFontTTFDX.cpp" />
-    <ClCompile Include="..\..\xbmc\guilib\GUIFontTTFGL.cpp" />
+    <ClCompile Include="..\..\xbmc\guilib\GUIFontTTFGL.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\guilib\GUIImage.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUIIncludes.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUIInfoTypes.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUITextLayout.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUITexture.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUITextureD3D.cpp" />
-    <ClCompile Include="..\..\xbmc\guilib\GUITextureGL.cpp" />
-    <ClCompile Include="..\..\xbmc\guilib\GUITextureGLES.cpp" />
+    <ClCompile Include="..\..\xbmc\guilib\GUITextureGL.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\guilib\GUITextureGLES.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\guilib\GUIToggleButtonControl.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUIVideoControl.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\GUIVisualisationControl.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\Key.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\LocalizeStrings.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\MatrixGLES.cpp" />
-    <ClCompile Include="..\..\xbmc\guilib\Shader.cpp" />
+    <ClCompile Include="..\..\xbmc\guilib\Shader.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\guilib\Texture.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\TextureBundle.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\TextureBundleXBT.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\TextureBundleXPR.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\TextureDX.cpp" />
-    <ClCompile Include="..\..\xbmc\guilib\TextureGL.cpp" />
+    <ClCompile Include="..\..\xbmc\guilib\TextureGL.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\guilib\TextureManager.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\VisibleEffect.cpp" />
     <ClCompile Include="..\..\xbmc\guilib\XBTF.cpp" />
     <ClCompile Include="..\..\xbmc\interfaces\json-rpc\AudioLibrary.cpp" />
     <ClCompile Include="..\..\xbmc\interfaces\json-rpc\FileItemHandler.cpp" />
     <ClCompile Include="..\..\xbmc\interfaces\json-rpc\FileOperations.cpp" />
+    <ClCompile Include="..\..\xbmc\interfaces\json-rpc\GUIOperations.cpp" />
     <ClCompile Include="..\..\xbmc\interfaces\json-rpc\InputOperations.cpp" />
     <ClCompile Include="..\..\xbmc\interfaces\json-rpc\JSONRPC.cpp" />
     <ClCompile Include="..\..\xbmc\interfaces\json-rpc\JSONServiceDescription.cpp" />
     <ClCompile Include="..\..\xbmc\network\EventServer.cpp" />
     <ClCompile Include="..\..\xbmc\network\GUIDialogAccessPoints.cpp" />
     <ClCompile Include="..\..\xbmc\network\GUIDialogNetworkSetup.cpp" />
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\HTTPApiHandler.cpp" />
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\HTTPJsonRpcHandler.cpp" />
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\HTTPVfsHandler.cpp" />
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\HTTPWebinterfaceAddonsHandler.cpp" />
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\HTTPWebinterfaceHandler.cpp" />
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\IHTTPRequestHandler.cpp" />
     <ClCompile Include="..\..\xbmc\network\libscrobbler\lastfmscrobbler.cpp" />
     <ClCompile Include="..\..\xbmc\network\libscrobbler\librefmscrobbler.cpp" />
     <ClCompile Include="..\..\xbmc\network\libscrobbler\scrobbler.cpp" />
     <ClCompile Include="..\..\xbmc\network\UdpClient.cpp" />
     <ClCompile Include="..\..\xbmc\network\UPnP.cpp" />
     <ClCompile Include="..\..\xbmc\network\WebServer.cpp" />
+    <ClCompile Include="..\..\xbmc\network\websocket\WebSocket.cpp" />
+    <ClCompile Include="..\..\xbmc\network\websocket\WebSocketManager.cpp" />
+    <ClCompile Include="..\..\xbmc\network\websocket\WebSocketV13.cpp" />
+    <ClCompile Include="..\..\xbmc\network\websocket\WebSocketV8.cpp" />
     <ClCompile Include="..\..\xbmc\network\windows\NetworkWin32.cpp" />
     <ClCompile Include="..\..\xbmc\network\windows\ZeroconfWIN.cpp" />
     <ClCompile Include="..\..\xbmc\network\Zeroconf.cpp" />
     <ClCompile Include="..\..\xbmc\programs\Shortcut.cpp" />
     <ClCompile Include="..\..\xbmc\rendering\dx\GUIWindowTestPatternDX.cpp" />
     <ClCompile Include="..\..\xbmc\rendering\dx\RenderSystemDX.cpp" />
-    <ClCompile Include="..\..\xbmc\rendering\gl\GUIWindowTestPatternGL.cpp" />
-    <ClCompile Include="..\..\xbmc\rendering\gl\RenderSystemGL.cpp" />
+    <ClCompile Include="..\..\xbmc\rendering\gl\GUIWindowTestPatternGL.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\rendering\gl\RenderSystemGL.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\rendering\RenderSystem.cpp" />
     <ClCompile Include="..\..\xbmc\SectionLoader.cpp" />
     <ClCompile Include="..\..\xbmc\settings\AdvancedSettings.cpp" />
     <ClCompile Include="..\..\xbmc\SortFileItem.cpp" />
     <ClCompile Include="..\..\xbmc\storage\AutorunMediaJob.cpp" />
     <ClCompile Include="..\..\xbmc\storage\cdioSupport.cpp" />
-    <ClCompile Include="..\..\xbmc\storage\DetectDVDType.cpp" />
     <ClCompile Include="..\..\xbmc\storage\IoSupport.cpp" />
     <ClCompile Include="..\..\xbmc\storage\MediaManager.cpp" />
     <ClCompile Include="..\..\xbmc\storage\windows\Win32StorageProvider.cpp" />
     <ClCompile Include="..\..\xbmc\threads\LockFree.cpp" />
     <ClCompile Include="..\..\xbmc\threads\platform\Implementation.cpp" />
     <ClInclude Include="..\..\xbmc\cores\AudioRenderers\IAudioRenderer.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\FileUPnP.h" />
-    <ClInclude Include="..\..\xbmc\storage\DetectDVDType.h" />
+    <ClInclude Include="..\..\xbmc\cores\paplayer\PCMCodec.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\windows\WINFileSMB.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\windows\WINSMBDirectory.h" />
+    <ClInclude Include="..\..\xbmc\interfaces\python\xbmcmodule\pythreadstate.h" />
+    <ClInclude Include="..\..\xbmc\network\websocket\WebSocket.h" />
+    <ClInclude Include="..\..\xbmc\network\websocket\WebSocketManager.h" />
+    <ClInclude Include="..\..\xbmc\network\websocket\WebSocketV13.h" />
+    <ClInclude Include="..\..\xbmc\network\websocket\WebSocketV8.h" />
+    <ClInclude Include="..\..\xbmc\interfaces\json-rpc\IJSONRPCAnnouncer.h" />
+    <ClInclude Include="..\..\xbmc\interfaces\json-rpc\JSONRPCUtils.h" />
+    <ClInclude Include="..\..\xbmc\interfaces\json-rpc\GUIOperations.h" />
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\HTTPApiHandler.h" />
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\HTTPJsonRpcHandler.h" />
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\HTTPVfsHandler.h" />
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\HTTPWebinterfaceAddonsHandler.h" />
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\HTTPWebinterfaceHandler.h" />
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\IHTTPRequestHandler.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\CircularCache.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DirectoryCache.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\FileCache.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\MemBufferCache.h" />
+    <ClInclude Include="..\..\xbmc\interfaces\python\xbmcmodule\pythreadstate.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\AddonsDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\AFPDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\AFPFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\ASAPFileDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\CacheStrategy.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\CDDADirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\CDDAFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\CurlFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DAAPDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DAAPFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DAVDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\Directory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DirectoryFactory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DirectoryHistory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DllHDHomeRunDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DllHDHomeRunFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DllLibAfp.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DllLibCMyth.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DllLibCurl.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\DllLibNfs.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\File.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\FileDirectoryFactory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\FileFactory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\FileReaderFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\FTPDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\FTPParse.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\HDDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\HDFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\HDHomeRunDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\HDHomeRunFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\HTSPDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\HTSPSession.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\HTTPDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\IDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\IFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\IFileDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\ILiveTV.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\iso9660.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\ISO9660Directory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\ISOFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\LastFMDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\LastFMFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\MultiPathDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\MultiPathFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\MusicDatabaseDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\MusicDatabaseFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\MusicFileDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\MusicSearchDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\MythDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\MythFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\MythSession.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\NFSDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\NFSFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\NSFFileDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\OGGFileDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\PipeFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\PipesManager.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\PlaylistDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\PlaylistFileDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\PluginDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\RarDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\RarFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\RarManager.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\RSSDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\RTVDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\RTVFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SAPDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SAPFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SFTPDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SFTPFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\ShoutcastFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SIDFileDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SlingboxDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SlingboxFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SmartPlaylistDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SourcesDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SpecialProtocol.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SpecialProtocolDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\SpecialProtocolFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\StackDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\TuxBoxDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\TuxBoxFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\udf25.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\UDFDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\UDFFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\UPnPDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\UPnPFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\VideoDatabaseDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\VirtualDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\VTPDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\VTPFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\VTPSession.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\ZeroconfDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\ZipDirectory.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\ZipFile.h" />
+    <ClInclude Include="..\..\xbmc\filesystem\ZipManager.h" />
     <ClInclude Include="..\..\xbmc\threads\platform\win\Implementation.cpp" />
     <ClCompile Include="..\..\xbmc\threads\SystemClock.cpp" />
     <ClCompile Include="..\..\xbmc\threads\Thread.cpp" />
     <ClCompile Include="..\..\xbmc\utils\Archive.cpp" />
     <ClCompile Include="..\..\xbmc\utils\AsyncFileCopy.cpp" />
     <ClCompile Include="..\..\xbmc\utils\AutoPtrHandle.cpp" />
+    <ClCompile Include="..\..\xbmc\utils\Base64.cpp" />
     <ClCompile Include="..\..\xbmc\utils\BitstreamStats.cpp" />
     <ClCompile Include="..\..\xbmc\utils\CharsetConverter.cpp" />
     <ClCompile Include="..\..\xbmc\utils\CPUInfo.cpp" />
       <CompileAs Condition="'$(Configuration)|$(Platform)'=='Release (OpenGL)|Win32'">CompileAsCpp</CompileAs>
       <CompileAs Condition="'$(Configuration)|$(Platform)'=='Template|Win32'">CompileAsCpp</CompileAs>
     </ClCompile>
-    <ClCompile Include="..\..\xbmc\utils\GLUtils.cpp" />
+    <ClCompile Include="..\..\xbmc\utils\GLUtils.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\utils\HTMLTable.cpp" />
     <ClCompile Include="..\..\xbmc\utils\HTMLUtil.cpp" />
     <ClCompile Include="..\..\xbmc\utils\HttpHeader.cpp" />
     <ClCompile Include="..\..\xbmc\utils\HttpParser.cpp" />
+    <ClCompile Include="..\..\xbmc\utils\HttpResponse.cpp" />
     <ClCompile Include="..\..\xbmc\utils\InfoLoader.cpp" />
     <ClCompile Include="..\..\xbmc\utils\JobManager.cpp" />
     <ClCompile Include="..\..\xbmc\utils\JSONVariantParser.cpp" />
     <ClCompile Include="..\..\xbmc\utils\LCD.cpp" />
     <ClCompile Include="..\..\xbmc\utils\log.cpp" />
     <ClCompile Include="..\..\xbmc\utils\md5.cpp" />
+    <ClCompile Include="..\..\xbmc\utils\Mime.cpp" />
     <ClCompile Include="..\..\xbmc\utils\PCMAmplifier.cpp" />
     <ClCompile Include="..\..\xbmc\utils\PerformanceSample.cpp" />
     <ClCompile Include="..\..\xbmc\utils\PerformanceStats.cpp" />
     <ClCompile Include="..\..\xbmc\win32\WIN32Util.cpp" />
     <ClCompile Include="..\..\xbmc\win32\WINDirectSound.cpp" />
     <ClCompile Include="..\..\xbmc\win32\WindowHelper.cpp" />
-    <ClCompile Include="..\..\xbmc\win32\WINFileSMB.cpp" />
-    <ClCompile Include="..\..\xbmc\win32\WINSMBDirectory.cpp" />
     <ClCompile Include="..\..\xbmc\win32\XBMC_PC.cpp" />
     <ClCompile Include="..\..\xbmc\cores\DummyVideoPlayer.cpp" />
     <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDAudio.cpp" />
     </ClCompile>
     <ClCompile Include="..\..\xbmc\cores\DllLoader\exports\util\EmuFileWrapper.cpp" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\BaseRenderer.cpp" />
-    <ClCompile Include="..\..\xbmc\cores\VideoRenderers\LinuxRendererGL.cpp" />
+    <ClCompile Include="..\..\xbmc\cores\VideoRenderers\LinuxRendererGL.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\OverlayRenderer.cpp" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\OverlayRendererDX.cpp" />
-    <ClCompile Include="..\..\xbmc\cores\VideoRenderers\OverlayRendererGL.cpp" />
+    <ClCompile Include="..\..\xbmc\cores\VideoRenderers\OverlayRendererGL.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\OverlayRendererUtil.cpp" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\RenderManager.cpp" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\WinRenderer.cpp" />
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\ConvolutionKernels.cpp" />
-    <ClCompile Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\VideoFilterShader.cpp" />
+    <ClCompile Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\VideoFilterShader.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\YUV2RGBShader.cpp" />
     <ClCompile Include="..\..\xbmc\cores\AudioRenderers\AudioRendererFactory.cpp" />
     <ClCompile Include="..\..\xbmc\cores\AudioRenderers\NullDirectSound.cpp" />
     <ClCompile Include="..\..\xbmc\cores\ExternalPlayer\ExternalPlayer.cpp" />
     <ClCompile Include="..\..\xbmc\cores\playercorefactory\PlayerCoreFactory.cpp" />
     <ClCompile Include="..\..\xbmc\cores\playercorefactory\PlayerSelectionRule.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\AddonsDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\ASAPFileDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\CacheMemBuffer.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\CacheStrategy.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\CDDADirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\DAAPDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\DAVDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\Directory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\DirectoryCache.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\DirectoryHistory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\DirectoryTuxBox.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\DllLibCurl.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FactoryDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FactoryFileDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\File.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileCache.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileCDDA.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileCurl.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileDAAP.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileFactory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileFileReader.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileHD.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileISO.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileLastFM.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileMusicDatabase.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileRar.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileRTV.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileSFTP.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileShoutcast.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileSpecialProtocol.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileTuxBox.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FileZip.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FTPDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\FTPParse.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\HDDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\HDHomeRun.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\HTSPDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\HTSPSession.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\HTTPDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\IDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\IFile.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\LastFMDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\MultiPathDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\MultiPathFile.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\MusicFileDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\MusicSearchDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\MythDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\MythFile.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\MythSession.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\NptXbmcFile.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\NSFFileDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\OGGFileDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\PlaylistDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\PlaylistFileDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\PluginDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\RarDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\RarManager.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\RSSDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\RTVDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\SAPDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\SAPFile.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\SFTPDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\SIDFileDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\SmartPlaylistDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\SpecialProtocol.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\SpecialProtocolDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\StackDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\SourcesDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\UPnPDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\VideoDatabaseDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\VirtualDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\VTPDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\VTPFile.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\VTPSession.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\ZipDirectory.cpp" />
-    <ClCompile Include="..\..\xbmc\FileSystem\ZipManager.cpp" />
     <ClCompile Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory\DirectoryNode.cpp" />
     <ClCompile Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory\DirectoryNodeAlbum.cpp" />
     <ClCompile Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory\DirectoryNodeAlbumCompilations.cpp" />
     <ClCompile Include="..\..\xbmc\windowing\windows\WinEventsWin32.cpp" />
     <ClCompile Include="..\..\xbmc\windowing\windows\WinSystemWin32.cpp" />
     <ClCompile Include="..\..\xbmc\windowing\windows\WinSystemWin32DX.cpp" />
-    <ClCompile Include="..\..\xbmc\windowing\windows\WinSystemWin32GL.cpp" />
+    <ClCompile Include="..\..\xbmc\windowing\windows\WinSystemWin32GL.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\windowing\WinEventsSDL.cpp" />
     <ClCompile Include="..\..\xbmc\windowing\WinSystem.cpp" />
     <ClCompile Include="..\..\xbmc\windows\GUIMediaWindow.cpp" />
     <ClInclude Include="..\..\xbmc\DynamicDll.h" />
     <ClInclude Include="..\..\xbmc\Favourites.h" />
     <ClInclude Include="..\..\xbmc\FileItem.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\CacheCircular.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\Directory.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\DirectoryHistory.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\FactoryDirectory.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\File.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\FileFactory.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\FileHD.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\FileNFS.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\FilePipe.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\HDDirectory.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\IDirectory.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\IFile.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\IFileDirectory.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\ILiveTV.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\iso9660.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\ISO9660Directory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileUDF.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\NFSDirectory.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\PipesManager.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\Slingbox.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\udf25.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\UDFDirectory.h" />
     <ClInclude Include="..\..\xbmc\FileSystem\VideoDatabaseDirectory\DirectoryNodeCountry.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\VirtualDirectory.h" />
-    <ClInclude Include="..\..\xbmc\filesystem\ZeroconfDirectory.h" />
     <ClInclude Include="..\..\xbmc\GUIInfoManager.h" />
     <ClInclude Include="..\..\xbmc\GUILargeTextureManager.h" />
     <ClInclude Include="..\..\xbmc\guilib\AnimatedGif.h" />
     <ClInclude Include="..\..\xbmc\guilib\DirtyRegion.h" />
     <ClInclude Include="..\..\xbmc\guilib\DirtyRegionSolvers.h" />
     <ClInclude Include="..\..\xbmc\guilib\DirtyRegionTracker.h" />
-    <ClInclude Include="..\..\xbmc\guilib\FrameBufferObject.h" />
+    <ClInclude Include="..\..\xbmc\guilib\FrameBufferObject.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\guilib\Geometry.h" />
     <ClInclude Include="..\..\xbmc\guilib\GraphicContext.h" />
     <ClInclude Include="..\..\xbmc\guilib\gui3d.h" />
     <ClInclude Include="..\..\xbmc\guilib\GUIFontManager.h" />
     <ClInclude Include="..\..\xbmc\guilib\GUIFontTTF.h" />
     <ClInclude Include="..\..\xbmc\guilib\GUIFontTTFDX.h" />
-    <ClInclude Include="..\..\xbmc\guilib\GUIFontTTFGL.h" />
+    <ClInclude Include="..\..\xbmc\guilib\GUIFontTTFGL.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\guilib\GUIImage.h" />
     <ClInclude Include="..\..\xbmc\guilib\GUIIncludes.h" />
     <ClInclude Include="..\..\xbmc\guilib\GUIInfoTypes.h" />
     <ClInclude Include="..\..\xbmc\guilib\GUITextLayout.h" />
     <ClInclude Include="..\..\xbmc\guilib\GUITexture.h" />
     <ClInclude Include="..\..\xbmc\guilib\GUITextureD3D.h" />
-    <ClInclude Include="..\..\xbmc\guilib\GUITextureGL.h" />
-    <ClInclude Include="..\..\xbmc\guilib\GUITextureGLES.h" />
+    <ClInclude Include="..\..\xbmc\guilib\GUITextureGL.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\guilib\GUITextureGLES.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\guilib\GUIToggleButtonControl.h" />
     <ClInclude Include="..\..\xbmc\guilib\GUIVideoControl.h" />
     <ClInclude Include="..\..\xbmc\guilib\GUIVisualisationControl.h" />
     <ClInclude Include="..\..\xbmc\guilib\LocalizeStrings.h" />
     <ClInclude Include="..\..\xbmc\guilib\MatrixGLES.h" />
     <ClInclude Include="..\..\xbmc\guilib\Resolution.h" />
-    <ClInclude Include="..\..\xbmc\guilib\Shader.h" />
+    <ClInclude Include="..\..\xbmc\guilib\Shader.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\guilib\Texture.h" />
     <ClInclude Include="..\..\xbmc\guilib\TextureBundle.h" />
     <ClInclude Include="..\..\xbmc\guilib\TextureBundleXBT.h" />
     <ClInclude Include="..\..\xbmc\guilib\TextureBundleXPR.h" />
     <ClInclude Include="..\..\xbmc\guilib\TextureDX.h" />
-    <ClInclude Include="..\..\xbmc\guilib\TextureGL.h" />
+    <ClInclude Include="..\..\xbmc\guilib\TextureGL.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\guilib\TextureManager.h" />
     <ClInclude Include="..\..\xbmc\guilib\TransformMatrix.h" />
     <ClInclude Include="..\..\xbmc\guilib\Tween.h" />
     <ClInclude Include="..\..\xbmc\programs\Shortcut.h" />
     <ClInclude Include="..\..\xbmc\rendering\dx\GUIWindowTestPatternDX.h" />
     <ClInclude Include="..\..\xbmc\rendering\dx\RenderSystemDX.h" />
-    <ClInclude Include="..\..\xbmc\rendering\gl\GUIWindowTestPatternGL.h" />
-    <ClInclude Include="..\..\xbmc\rendering\gl\RenderSystemGL.h" />
+    <ClInclude Include="..\..\xbmc\rendering\gl\GUIWindowTestPatternGL.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\rendering\gl\RenderSystemGL.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\rendering\RenderSystem.h" />
     <ClInclude Include="..\..\xbmc\SectionLoader.h" />
     <ClInclude Include="..\..\xbmc\settings\AdvancedSettings.h" />
     <ClInclude Include="..\..\xbmc\utils\Archive.h" />
     <ClInclude Include="..\..\xbmc\utils\AsyncFileCopy.h" />
     <ClInclude Include="..\..\xbmc\utils\AutoPtrHandle.h" />
+    <ClInclude Include="..\..\xbmc\utils\Base64.h" />
     <ClInclude Include="..\..\xbmc\utils\BitstreamStats.h" />
     <ClInclude Include="..\..\xbmc\utils\CharsetConverter.h" />
     <ClInclude Include="..\..\xbmc\utils\CPUInfo.h" />
     <ClInclude Include="..\..\xbmc\utils\FileUtils.h" />
     <ClInclude Include="..\..\xbmc\utils\fstrcmp.h" />
     <ClInclude Include="..\..\xbmc\utils\GlobalsHandling.h" />
-    <ClInclude Include="..\..\xbmc\utils\GLUtils.h" />
+    <ClInclude Include="..\..\xbmc\utils\GLUtils.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\utils\HTMLTable.h" />
     <ClInclude Include="..\..\xbmc\utils\HTMLUtil.h" />
     <ClInclude Include="..\..\xbmc\utils\HttpHeader.h" />
     <ClInclude Include="..\..\xbmc\utils\HttpParser.h" />
+    <ClInclude Include="..\..\xbmc\utils\HttpResponse.h" />
     <ClInclude Include="..\..\xbmc\utils\InfoLoader.h" />
     <ClInclude Include="..\..\xbmc\utils\ISerializable.h" />
     <ClInclude Include="..\..\xbmc\utils\Job.h" />
     <ClInclude Include="..\..\xbmc\utils\log.h" />
     <ClInclude Include="..\..\xbmc\utils\MathUtils.h" />
     <ClInclude Include="..\..\xbmc\utils\md5.h" />
+    <ClInclude Include="..\..\xbmc\utils\Mime.h" />
     <ClInclude Include="..\..\xbmc\utils\PCMAmplifier.h" />
     <ClInclude Include="..\..\xbmc\utils\PerformanceSample.h" />
     <ClInclude Include="..\..\xbmc\utils\PerformanceStats.h" />
     <ClInclude Include="..\..\xbmc\win32\WIN32Util.h" />
     <ClInclude Include="..\..\xbmc\win32\WINDirectSound.h" />
     <ClInclude Include="..\..\xbmc\win32\WindowHelper.h" />
-    <ClInclude Include="..\..\xbmc\win32\WINFileSMB.h" />
-    <ClInclude Include="..\..\xbmc\win32\WINSMBDirectory.h" />
     <ClInclude Include="..\..\xbmc\cores\DummyVideoPlayer.h" />
     <ClInclude Include="..\..\xbmc\cores\IPlayer.h" />
     <ClInclude Include="..\..\xbmc\cores\dvdplayer\dvd_config.h" />
     <ClInclude Include="..\..\xbmc\cores\DllLoader\exports\emu_socket\emu_socket.h" />
     <ClInclude Include="..\..\xbmc\cores\DllLoader\exports\util\EmuFileWrapper.h" />
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\BaseRenderer.h" />
-    <ClInclude Include="..\..\xbmc\cores\VideoRenderers\LinuxRendererGL.h" />
+    <ClInclude Include="..\..\xbmc\cores\VideoRenderers\LinuxRendererGL.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\OverlayRenderer.h" />
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\OverlayRendererDX.h" />
-    <ClInclude Include="..\..\xbmc\cores\VideoRenderers\OverlayRendererGL.h" />
+    <ClInclude Include="..\..\xbmc\cores\VideoRenderers\OverlayRendererGL.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\OverlayRendererUtil.h" />
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\RenderManager.h" />
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\WinRenderer.h" />
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\ConvolutionKernels.h" />
-    <ClInclude Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\VideoFilterShader.h" />
+    <ClInclude Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\VideoFilterShader.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\YUV2RGBShader.h" />
     <ClInclude Include="..\..\xbmc\cores\AudioRenderers\AudioRendererFactory.h" />
     <ClInclude Include="..\..\xbmc\cores\AudioRenderers\NullDirectSound.h" />
     <ClInclude Include="..\..\xbmc\cores\playercorefactory\PlayerCoreConfig.h" />
     <ClInclude Include="..\..\xbmc\cores\playercorefactory\PlayerCoreFactory.h" />
     <ClInclude Include="..\..\xbmc\cores\playercorefactory\PlayerSelectionRule.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\AddonsDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\ASAPFileDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\CacheMemBuffer.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\CacheStrategy.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\CDDADirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\DAAPDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\DAVDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\DirectoryCache.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\DirectoryTuxBox.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\DllLibCMyth.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\DllLibCurl.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FactoryFileDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileCache.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileCDDA.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileCurl.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileDAAP.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileFileReader.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileISO.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileLastFM.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileMusicDatabase.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileRar.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileRTV.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileSFTP.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileShoutcast.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileSpecialProtocol.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileTuxBox.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FileZip.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FTPDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\FTPParse.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\HDHomeRun.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\HTSPDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\HTSPSession.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\HTTPDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\LastFMDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\MultiPathDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\MultiPathFile.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\MusicFileDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\MusicSearchDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\MythDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\MythFile.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\MythSession.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\NSFFileDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\OGGFileDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\PlaylistDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\PlaylistFileDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\PluginDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\RarDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\RarManager.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\RSSDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\RTVDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\SAPDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\SAPFile.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\SFTPDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\SIDFileDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\SmartPlaylistDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\SpecialProtocol.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\SpecialProtocolDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\StackDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\SourcesDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\UPnPDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\VideoDatabaseDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\VTPDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\VTPFile.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\VTPSession.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\ZipDirectory.h" />
-    <ClInclude Include="..\..\xbmc\FileSystem\ZipManager.h" />
     <ClInclude Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory\DirectoryNode.h" />
     <ClInclude Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory\DirectoryNodeAlbum.h" />
     <ClInclude Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory\DirectoryNodeAlbumCompilations.h" />
     <ClInclude Include="..\..\xbmc\windowing\windows\WinEventsWin32.h" />
     <ClInclude Include="..\..\xbmc\windowing\windows\WinSystemWin32.h" />
     <ClInclude Include="..\..\xbmc\windowing\windows\WinSystemWin32DX.h" />
-    <ClInclude Include="..\..\xbmc\windowing\windows\WinSystemWin32GL.h" />
+    <ClInclude Include="..\..\xbmc\windowing\windows\WinSystemWin32GL.h">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\windowing\WinEvents.h" />
     <ClInclude Include="..\..\xbmc\windowing\WinEventsSDL.h" />
     <ClInclude Include="..\..\xbmc\windowing\WinSystem.h" />
     </VisualStudio>
   </ProjectExtensions>
   <Import Project="$(SolutionDir)\$(ProjectFileName).targets.user" Condition="Exists('$(SolutionDir)\$(ProjectFileName).targets.user')" />
-</Project>
\ No newline at end of file
+</Project>
index f1bb61c..9e8d3cf 100644 (file)
     <Filter Include="peripherals\dialogs">
       <UniqueIdentifier>{9571e2bc-891d-4496-bcba-2ec3eed45704}</UniqueIdentifier>
     </Filter>
+    <Filter Include="network\websocket">
+      <UniqueIdentifier>{88e84682-dede-4bdf-9e33-a8023dd5ac78}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="filesystem\windows">
+      <UniqueIdentifier>{1cc693eb-11ad-4f53-8640-198d5ab9bcc8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="network\httprequesthandler">
+      <UniqueIdentifier>{9029e610-aa5a-4414-9e96-1d69f03b3bd8}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\xbmc\win32\pch.cpp">
     <ClCompile Include="..\..\xbmc\win32\WindowHelper.cpp">
       <Filter>win32</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\xbmc\win32\WINFileSMB.cpp">
-      <Filter>win32</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\win32\WINSMBDirectory.cpp">
-      <Filter>win32</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\xbmc\win32\XBMC_PC.cpp">
       <Filter>win32</Filter>
     </ClCompile>
     <ClCompile Include="..\..\xbmc\cores\playercorefactory\PlayerSelectionRule.cpp">
       <Filter>cores\PlayerCoreFactory</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\AddonsDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\ASAPFileDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\CacheMemBuffer.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\CacheStrategy.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\CDDADirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\DAAPDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\DAVDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\Directory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\DirectoryCache.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\DirectoryHistory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\DirectoryTuxBox.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\DllLibCurl.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FactoryDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FactoryFileDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\File.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileCache.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileCDDA.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileCurl.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileDAAP.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileFactory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileFileReader.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileHD.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileISO.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileLastFM.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileMusicDatabase.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileRar.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileRTV.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileSFTP.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileShoutcast.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileSpecialProtocol.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileTuxBox.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileZip.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FTPDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FTPParse.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\HDDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\HDHomeRun.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\HTSPDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\HTSPSession.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\HTTPDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\IDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\IFile.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\iso9660.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\ISO9660Directory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\LastFMDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\MultiPathDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\MultiPathFile.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\MusicFileDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\MusicSearchDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\MythDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\MythFile.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\MythSession.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\NptXbmcFile.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\NSFFileDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\OGGFileDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\PlaylistDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\PlaylistFileDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\PluginDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\RarDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\RarManager.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\RSSDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\RTVDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\SAPDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\SAPFile.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\SFTPDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\SIDFileDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\SmartPlaylistDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\SpecialProtocol.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\SpecialProtocolDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\StackDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\SourcesDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\UPnPDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\VideoDatabaseDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\VirtualDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\VTPDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\VTPFile.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\VTPSession.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\ZipDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\ZipManager.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory\DirectoryNode.cpp">
       <Filter>filesystem\MusicDatabaseDirectory</Filter>
     </ClCompile>
     <ClCompile Include="..\..\xbmc\dialogs\GUIDialogYesNo.cpp">
       <Filter>dialogs</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\xbmc\filesystem\ZeroconfDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\xbmc\Application.cpp" />
     <ClCompile Include="..\..\xbmc\MediaSource.cpp" />
     <ClCompile Include="..\..\xbmc\SystemGlobals.cpp" />
     <ClCompile Include="..\..\xbmc\utils\LangCodeExpander.cpp">
       <Filter>utils</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\udf25.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\UDFDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\FileSystem\FileUDF.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\xbmc\ApplicationMessenger.cpp">
       <Filter>utils</Filter>
     </ClCompile>
     <ClCompile Include="..\..\lib\SlingboxLib\SlingboxLib.cpp">
       <Filter>libs\SlingboxLib</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\xbmc\filesystem\Slingbox.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\xbmc\dialogs\GUIDialogPlayEject.cpp">
       <Filter>dialogs</Filter>
     </ClCompile>
     <ClCompile Include="..\..\xbmc\interfaces\json-rpc\InputOperations.cpp">
       <Filter>interfaces\json-rpc</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\xbmc\filesystem\CacheCircular.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\xbmc\input\XBMC_keytable.cpp">
       <Filter>input</Filter>
     </ClCompile>
     <ClCompile Include="..\..\xbmc\guilib\JpegIO.cpp">
       <Filter>guilib</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\xbmc\filesystem\FileNFS.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\filesystem\NFSDirectory.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\filesystem\FilePipe.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\xbmc\filesystem\PipesManager.cpp">
-      <Filter>filesystem</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\xbmc\cores\paplayer\BXAcodec.cpp">
       <Filter>cores\paplayer</Filter>
     </ClCompile>
     <ClCompile Include="..\..\xbmc\interfaces\python\xbmcmodule\pyrendercapture.cpp">
       <Filter>interfaces\python\xbmcmodule</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\xbmc\filesystem\FileUPnP.cpp">
+    <ClCompile Include="..\..\xbmc\filesystem\AddonsDirectory.cpp">
       <Filter>filesystem</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\xbmc\storage\DetectDVDType.cpp">
-      <Filter>storage</Filter>
+    <ClCompile Include="..\..\xbmc\cores\paplayer\PCMCodec.cpp">
+      <Filter>cores\paplayer</Filter>
+       </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\AFPDirectory.cpp">
+      <Filter>filesystem</Filter>
     </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\xbmc\win32\pch.h">
-      <Filter>win32</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\win32\PlatformDefs.h">
-      <Filter>win32</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\win32\WIN32Util.h">
-      <Filter>win32</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\win32\WINDirectSound.h">
-      <Filter>win32</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\win32\WindowHelper.h">
-      <Filter>win32</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\win32\WINFileSMB.h">
-      <Filter>win32</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\win32\WINSMBDirectory.h">
-      <Filter>win32</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\DummyVideoPlayer.h">
-      <Filter>cores</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\IPlayer.h">
-      <Filter>cores</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\dvd_config.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDAudio.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDClock.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDDemuxSPU.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDDemuxers\DVDDemuxVobsub.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDFileInfo.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDInputStreams\DVDInputStreamTV.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDMessage.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDMessageQueue.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDMessageTracker.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDOverlayContainer.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDOverlayRenderer.h">
-      <Filter>cores\dvdplayer</Filter>
-    </ClInclude>
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\HTTPApiHandler.cpp">
+      <Filter>network\httprequesthandler</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\HTTPVfsHandler.cpp">
+      <Filter>network\httprequesthandler</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\utils\Base64.cpp">
+      <Filter>utils</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\utils\HttpResponse.cpp">
+      <Filter>utils</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\network\websocket\WebSocket.cpp">
+      <Filter>network\websocket</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\network\websocket\WebSocketV8.cpp">
+      <Filter>network\websocket</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\network\websocket\WebSocketManager.cpp">
+      <Filter>network\websocket</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\network\websocket\WebSocketV13.cpp">
+      <Filter>network\websocket</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\windows\WINFileSMB.cpp">
+      <Filter>filesystem\windows</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\windows\WINSMBDirectory.cpp">
+      <Filter>filesystem\windows</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\interfaces\json-rpc\GUIOperations.cpp">
+      <Filter>interfaces\json-rpc</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\utils\Mime.cpp">
+      <Filter>utils</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\HTTPWebinterfaceHandler.cpp">
+      <Filter>network\httprequesthandler</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\HTTPWebinterfaceAddonsHandler.cpp">
+      <Filter>network\httprequesthandler</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\HTTPJsonRpcHandler.cpp">
+      <Filter>network\httprequesthandler</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\network\httprequesthandler\IHTTPRequestHandler.cpp">
+      <Filter>network\httprequesthandler</Filter>
+       </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\AFPFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\ASAPFileDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\CacheStrategy.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\CDDADirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\CDDAFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\CurlFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\DAAPDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\DAAPFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\DAVDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\Directory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\DirectoryFactory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\DirectoryHistory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\DllLibCurl.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\File.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\FileDirectoryFactory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\FileFactory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\FileReaderFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\FTPDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\FTPParse.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\HDDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\HDFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\HDHomeRunDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\HDHomeRunFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\HTSPDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\HTSPSession.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\HTTPDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\IDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\IFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\iso9660.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\ISO9660Directory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\ISOFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\LastFMDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\LastFMFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\MultiPathDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\MultiPathFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\MusicDatabaseDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\MusicDatabaseFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\MusicFileDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\MusicSearchDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\MythDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\MythFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\MythSession.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\NFSDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\NFSFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\NptXbmcFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\NSFFileDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\OGGFileDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\PipeFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\PipesManager.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\PlaylistDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\PlaylistFileDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\PluginDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\RarDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\RarFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\RarManager.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\RSSDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\RTVDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\RTVFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SAPDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SAPFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SFTPDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SFTPFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\ShoutcastFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SIDFileDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SlingboxDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SlingboxFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SmartPlaylistDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SourcesDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SpecialProtocol.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SpecialProtocolDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\SpecialProtocolFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\StackDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\TuxBoxDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\TuxBoxFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\udf25.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\UDFDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\UDFFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\UPnPDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\UPnPFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\VideoDatabaseDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\VirtualDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\VTPDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\VTPFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\VTPSession.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\ZeroconfDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\ZipDirectory.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\ZipFile.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\ZipManager.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\CircularCache.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\DirectoryCache.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\FileCache.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\xbmc\filesystem\MemBufferCache.cpp">
+      <Filter>filesystem</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\xbmc\win32\pch.h">
+      <Filter>win32</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\win32\PlatformDefs.h">
+      <Filter>win32</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\win32\WIN32Util.h">
+      <Filter>win32</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\win32\WINDirectSound.h">
+      <Filter>win32</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\win32\WindowHelper.h">
+      <Filter>win32</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\win32\WINFileSMB.h">
+      <Filter>win32</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\win32\WINSMBDirectory.h">
+      <Filter>win32</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\DummyVideoPlayer.h">
+      <Filter>cores</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\IPlayer.h">
+      <Filter>cores</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\dvd_config.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDAudio.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDClock.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDDemuxSPU.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDDemuxers\DVDDemuxVobsub.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDFileInfo.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDInputStreams\DVDInputStreamTV.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDMessage.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDMessageQueue.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDMessageTracker.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDOverlayContainer.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDOverlayRenderer.h">
+      <Filter>cores\dvdplayer</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDPerformanceCounter.h">
       <Filter>cores\dvdplayer</Filter>
     </ClInclude>
     <ClInclude Include="..\..\xbmc\cores\playercorefactory\PlayerSelectionRule.h">
       <Filter>cores\PlayerCoreFactory</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\AddonsDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\ASAPFileDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\CacheMemBuffer.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\CacheStrategy.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\CDDADirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\DAAPDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\DAVDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\DirectoryCache.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\DirectoryTuxBox.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\DllLibCMyth.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\DllLibCurl.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FactoryFileDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileCache.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileCDDA.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileCurl.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileDAAP.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileFileReader.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileISO.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileLastFM.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileMusicDatabase.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileRar.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileRTV.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileSFTP.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileShoutcast.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileSpecialProtocol.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileTuxBox.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileZip.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FTPDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FTPParse.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\HDHomeRun.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\HTSPDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\HTSPSession.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\HTTPDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\ISO9660Directory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\LastFMDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\MultiPathDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\MultiPathFile.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\MusicFileDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\MusicSearchDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\MythDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\MythFile.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\MythSession.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\NSFFileDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\OGGFileDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\PlaylistDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\PlaylistFileDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\PluginDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\RarDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\RarManager.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\RSSDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\RTVDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\SAPDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\SAPFile.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\SFTPDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\SIDFileDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\SmartPlaylistDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\SpecialProtocol.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\SpecialProtocolDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\StackDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\SourcesDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\UPnPDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\VideoDatabaseDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\VTPDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\VTPFile.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\VTPSession.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\ZipDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\ZipManager.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\xbmc\FileSystem\MusicDatabaseDirectory\DirectoryNode.h">
       <Filter>filesystem\MusicDatabaseDirectory</Filter>
     </ClInclude>
     <ClInclude Include="..\..\xbmc\dialogs\GUIDialogYesNo.h">
       <Filter>dialogs</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\ILiveTV.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\ZeroconfDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\xbmc\Application.h" />
     <ClInclude Include="..\..\xbmc\system.h" />
     <ClInclude Include="..\..\xbmc\guilib\AnimatedGif.h">
     <ClInclude Include="..\..\xbmc\guilib\XBTFReader.h">
       <Filter>guilib</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\Directory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\DirectoryHistory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\FactoryDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\File.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\FileFactory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\FileHD.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\HDDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\IDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\IFile.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\IFileDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\iso9660.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\VirtualDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\xbmc\input\ButtonTranslator.h">
       <Filter>input</Filter>
     </ClInclude>
     <ClInclude Include="..\..\xbmc\windows\GUIWindowWeather.h">
       <Filter>windows</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\xbmc\utils\LangCodeExpander.h">
-      <Filter>utils</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\udf25.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\UDFDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\FileSystem\FileUDF.h">
-      <Filter>filesystem</Filter>
+    <ClInclude Include="..\..\xbmc\utils\LangCodeExpander.h">
+      <Filter>utils</Filter>
     </ClInclude>
     <ClInclude Include="..\..\xbmc\ApplicationMessenger.h">
       <Filter>utils</Filter>
     <ClInclude Include="..\..\lib\SlingboxLib\SlingboxLib.h">
       <Filter>libs\SlingboxLib</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\Slingbox.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\CacheCircular.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\xbmc\dialogs\GUIDialogPlayEject.h">
       <Filter>dialogs</Filter>
     </ClInclude>
     <ClInclude Include="..\..\xbmc\guilib\JpegIO.h">
       <Filter>guilib</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\FileNFS.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\NFSDirectory.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\FilePipe.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\PipesManager.h">
-      <Filter>filesystem</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\xbmc\cores\paplayer\BXAcodec.h">
       <Filter>cores\paplayer</Filter>
     </ClInclude>
     <ClInclude Include="..\..\xbmc\threads\platform\win\Implementation.cpp">
       <Filter>threads\platform\win</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\xbmc\filesystem\FileUPnP.h">
+    <ClInclude Include="..\..\xbmc\filesystem\ZipManager.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\AddonsDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\AFPDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\AFPFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\ASAPFileDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\CacheStrategy.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\CDDADirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\CDDAFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\CurlFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DAAPDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DAAPFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DAVDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\Directory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DirectoryFactory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DirectoryHistory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DllHDHomeRunDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DllHDHomeRunFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DllLibAfp.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DllLibCMyth.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DllLibCurl.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DllLibNfs.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\File.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\FileDirectoryFactory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\FileFactory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\FileReaderFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\FTPDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\FTPParse.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\HDDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\HDFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\HDHomeRunDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\HDHomeRunFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\HTSPDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\HTSPSession.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\HTTPDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\IDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\IFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\IFileDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\ILiveTV.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\iso9660.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\ISO9660Directory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\ISOFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\LastFMDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\LastFMFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\MultiPathDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\MultiPathFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\MusicDatabaseDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\MusicDatabaseFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\MusicFileDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\MusicSearchDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\MythDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\MythFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\MythSession.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\NFSDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\NFSFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\NSFFileDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\OGGFileDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\PipeFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\PipesManager.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\PlaylistDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\PlaylistFileDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\PluginDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\RarDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\RarFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\RarManager.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\RSSDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\RTVDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\RTVFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SAPDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SAPFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SFTPDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SFTPFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\ShoutcastFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SIDFileDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SlingboxDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SlingboxFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SmartPlaylistDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SourcesDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SpecialProtocol.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SpecialProtocolDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\SpecialProtocolFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\StackDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\TuxBoxDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\TuxBoxFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\udf25.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\UDFDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\UDFFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\UPnPDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\UPnPFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\VideoDatabaseDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\VirtualDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\VTPDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\VTPFile.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\VTPSession.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\ZeroconfDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\ZipDirectory.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\ZipFile.h">
       <Filter>filesystem</Filter>
     </ClInclude>
     <ClInclude Include="..\..\xbmc\cores\AudioRenderers\IAudioRenderer.h" />
-    <ClInclude Include="..\..\xbmc\storage\DetectDVDType.h">
-      <Filter>storage</Filter>
+    <ClInclude Include="..\..\xbmc\interfaces\python\xbmcmodule\pythreadstate.h">
+      <Filter>interfaces\python\xbmcmodule</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\cores\paplayer\PCMCodec.h">
+      <Filter>cores\paplayer</Filter>
+       </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\MemBufferCache.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\CircularCache.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\DirectoryCache.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\FileCache.h">
+      <Filter>filesystem</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\utils\Base64.h">
+      <Filter>utils</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\utils\HttpResponse.h">
+      <Filter>utils</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\network\websocket\WebSocket.h">
+      <Filter>network\websocket</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\network\websocket\WebSocketV8.h">
+      <Filter>network\websocket</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\network\websocket\WebSocketManager.h">
+      <Filter>network\websocket</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\network\websocket\WebSocketV13.h">
+      <Filter>network\websocket</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\windows\WINFileSMB.h">
+      <Filter>filesystem\windows</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\filesystem\windows\WINSMBDirectory.h">
+      <Filter>filesystem\windows</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\interfaces\json-rpc\JSONRPCUtils.h">
+      <Filter>interfaces\json-rpc</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\interfaces\json-rpc\IJSONRPCAnnouncer.h">
+      <Filter>interfaces\json-rpc</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\interfaces\json-rpc\GUIOperations.h">
+      <Filter>interfaces\json-rpc</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\utils\Mime.h">
+      <Filter>utils</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\IHTTPRequestHandler.h">
+      <Filter>network\httprequesthandler</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\HTTPApiHandler.h">
+      <Filter>network\httprequesthandler</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\HTTPVfsHandler.h">
+      <Filter>network\httprequesthandler</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\HTTPWebinterfaceHandler.h">
+      <Filter>network\httprequesthandler</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\HTTPWebinterfaceAddonsHandler.h">
+      <Filter>network\httprequesthandler</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\xbmc\network\httprequesthandler\HTTPJsonRpcHandler.h">
+      <Filter>network\httprequesthandler</Filter>
     </ClInclude>
   </ItemGroup>
   <ItemGroup>
       <Filter>win32</Filter>
     </CustomBuild>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index fe15ce2..9bf8b86 100644 (file)
       <v>XBMC.ActivateWindow(Teletext)</v>
       <up mod="ctrl">SubtitleShiftUp</up>
       <down mod="ctrl">SubtitleShiftDown</down>
+      <pageup>SkipNext</pageup>
+      <pagedown>SkipPrevious</pagedown>
     </keyboard>
   </FullscreenVideo>
   <VideoTimeSeek>
       <escape>Fullscreen</escape>
       <return>Select</return>
       <enter>Select</enter>      <!-- backspace>Fullscreen</backspace -->
+      <pageup>SkipNext</pageup>
+      <pagedown>SkipPrevious</pagedown>
     </keyboard>
   </VideoMenu>
   <OSDVideoSettings>
index f5cf50d..c6852f7 100644 (file)
@@ -1,22 +1,29 @@
 <peripherals>
   <peripheral vendor_product="1915:003B,22B8:003B" bus="usb" name="Motorola Nyxboard Hybrid" mapTo="nyxboard">
-    <setting key="keymap_enabled" type="bool" value="1" label="35008" />
+    <setting key="do_not_use_custom_keymap" type="bool" value="0" label="35009" order="1" />
     <setting key="keymap" value="nyxboard" label="35007" configurable="0" />
-    <setting key="enable_flip_commands" type="bool" value="1" label="36005" />
-    <setting key="flip_keyboard" value="XBMC.VideoLibrary.Search" label="36002" />
-    <setting key="flip_remote" value="Dialog.Close(virtualkeyboard)" label="36003" />
-    <setting key="key_user" value="" label="36004" />
+    <setting key="enable_flip_commands" type="bool" value="1" label="36005" order="2" />
+    <setting key="flip_keyboard" value="XBMC.VideoLibrary.Search" label="36002" order="3" />
+    <setting key="flip_remote" value="Dialog.Close(virtualkeyboard)" label="36003" order="4" />
+    <setting key="key_user" value="" label="36004" order="5" />
   </peripheral>
 
-  <peripheral vendor_product="2548:1001" bus="usb" name="Pulse-Eight CEC Adaptor" mapTo="cec">
-    <setting key="enabled" type="bool" value="1" label="305" />
-    <setting key="port" type="string" value="" label="792" />
-    <setting key="cec_hdmi_port" type="int" value="1" min="1" max="16" label="36015" />
-    <setting key="cec_power_on_startup" type="bool" value="1" label="36007" />
-    <setting key="cec_power_off_shutdown" type="bool" value="1" label="36008" />
-    <setting key="cec_standby_screensaver" type="bool" value="1" label="36009" />
-    <setting key="standby_pc_on_tv_standby" type="bool" value="1" label="36014" />
-    <setting key="cec_debug_logging" type="bool" value="0" label="20191" />
-    <setting key="use_tv_menu_language" type="bool" value="1" label="36018" />
+  <peripheral vendor_product="2548:1001" bus="usb" name="Pulse-Eight CEC Adapter" mapTo="cec">
+    <setting key="enabled" type="bool" value="1" label="305" order="1" />
+    <setting key="activate_source" type="bool" value="1" label="36020" order="2" />
+    <setting key="wake_devices" type="string" value="0" label="36007" order="3" />
+    <setting key="standby_devices" type="string" value="0" label="36008" order="4" />
+    <setting key="cec_standby_screensaver" type="bool" value="1" label="36009" order="5" />
+    <setting key="standby_pc_on_tv_standby" type="bool" value="1" label="36014" order="6" />
+    <setting key="send_inactive_source" type="bool" value="1" label="36025" order="7" />
+    <setting key="use_tv_menu_language" type="bool" value="1" label="36018" order="8" />
+    <setting key="physical_address" type="string" label="36021" value="0" order="9" />
+    <setting key="cec_hdmi_port" type="int" value="1" min="1" max="16" label="36015" order="10" />
+    <setting key="connected_device" type="int" label="36019" value="0" min="0" max="15" step="1" order="11" />
+    <setting key="port" type="string" value="" label="36022" order="12" />
+
+    <setting key="tv_vendor" type="int" value="0" configurable="0" />
+    <setting key="device_name" type="string" value="XBMC" configurable="0" />
+    <setting key="device_type" type="int" value="1" configurable="0" />
   </peripheral>
 </peripherals>
index f01e45f..cd2e09d 100644 (file)
@@ -35,7 +35,7 @@ def error(errorLine):
         try:
             print(errorLine)
         except:
-            print errorLine
+            print(errorLine)
 
     exit(1)
 
index e88f966..46e2f8e 100644 (file)
@@ -8,3 +8,15 @@ Icon=xbmc
 Terminal=false
 Type=Application
 Categories=AudioVideo;Video;Player;TV;
+
+Actions=Fullscreen;Standalone
+
+[Desktop Action Fullscreen]
+Name=Open in fullscreen
+Exec=xbmc -fs
+OnlyShowIn=Unity
+
+[Desktop Action Standalone]
+Name=Open in standalone mode
+Exect=xbmc --standalone
+OnlyShowIn=Unity
index c6b44c0..057b310 100644 (file)
@@ -2,7 +2,7 @@ include ../Makefile.include
 
 # lib name, version
 LIBNAME=libcec
-VERSION=1.2.0
+VERSION=1.5.2
 SOURCE=$(LIBNAME)-$(VERSION)
 ARCHIVE=$(SOURCE).tar.gz
 
@@ -16,14 +16,14 @@ all: $(LIBDYLIB) .installed
 $(TARBALLS_LOCATION)/$(ARCHIVE):
        $(RETRIEVE_TOOL) $(RETRIEVE_TOOL_FLAGS) $(BASE_URL)/$(ARCHIVE)
 
-$(SOURCE): $(TARBALLS_LOCATION)/$(ARCHIVE)
+$(LIBNAME): $(TARBALLS_LOCATION)/$(ARCHIVE)
        rm -rf $(SOURCE)
        $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
        echo $(SOURCE) > .gitignore
        cd $(SOURCE); autoreconf -vif
        cd $(SOURCE); $(CONFIGURE)
 
-$(LIBDYLIB): $(SOURCE)
+$(LIBDYLIB): $(LIBNAME)
        make -j 1 -C $(SOURCE)
 
 .installed:
index 5efd9fe..b43cf8e 100644 (file)
@@ -8,6 +8,10 @@ CONFIGURE=./configure --prefix=$(PREFIX) \
   PKG_CONFIG_PATH=$(PREFIX)/lib/pkgconfig \
   PYTHON=$(PREFIX)/bin/python
 
+ifeq ($(XBMC_DARWIN_RELEASE),1)
+       CONFIGURE+= --disable-debug
+endif
+
 all: configure
 
 configure:
index 4b0990b..d1d0b80 100644 (file)
@@ -7,7 +7,7 @@ include ../../../../Makefile.include
 $(TARGET): dist/XBMC.dmg
        mv -f dist/XBMC.dmg $(TARGET)
 
-ifeq ($(findstring D_DEBUG,$(CFLAGS)), D_DEBUG)
+ifeq ($(findstring D_DEBUG,$(CFLAGS)),D_DEBUG)
 dist/XBMC.dmg:
        if [ -e "/Volumes/XBMC" ] ; then umount /Volumes/XBMC ; fi
        ./dmgmaker.pl ../../../../build/Debug/XBMC.app
index cedda60..a24c89d 100644 (file)
 #include "video/Bookmark.h"
 #ifdef HAS_WEB_SERVER
 #include "network/WebServer.h"
+#include "network/httprequesthandler/HTTPVfsHandler.h"
+#ifdef HAS_HTTPAPI
+#include "network/httprequesthandler/HTTPApiHandler.h"
+#endif
+#ifdef HAS_JSONRPC
+#include "network/httprequesthandler/HTTPJsonRpcHandler.h"
+#endif
+#ifdef HAS_WEB_INTERFACE
+#include "network/httprequesthandler/HTTPWebinterfaceHandler.h"
+#include "network/httprequesthandler/HTTPWebinterfaceAddonsHandler.h"
+#endif
 #endif
 #ifdef HAS_LCD
 #include "utils/LCDFactory.h"
 #include "filesystem/SMBDirectory.h"
 #endif
 #ifdef HAS_FILESYSTEM_NFS
-#include "filesystem/FileNFS.h"
+#include "filesystem/NFSFile.h"
 #endif
 #ifdef HAS_FILESYSTEM_AFP
-#include "filesystem/FileAFP.h"
+#include "filesystem/AFPFile.h"
 #endif
 #ifdef HAS_FILESYSTEM_SFTP
-#include "filesystem/FileSFTP.h"
+#include "filesystem/SFTPFile.h"
 #endif
 #include "PartyModeManager.h"
 #ifdef HAS_VIDEO_PLAYBACK
 #endif
 #include "interfaces/AnnouncementManager.h"
 #include "peripherals/Peripherals.h"
-#ifdef HAVE_LIBCEC
-#include "peripherals/devices/PeripheralCecAdapter.h"
-#endif
 #include "peripherals/dialogs/GUIDialogPeripheralManager.h"
 #include "peripherals/dialogs/GUIDialogPeripheralSettings.h"
 
 #ifdef TARGET_WINDOWS
 #include <shlobj.h>
 #include "win32util.h"
-#include "storage/DetectDVDType.h"
 #endif
 #ifdef HAS_XRANDR
 #include "windowing/X11/XRandR.h"
@@ -339,6 +346,17 @@ CApplication::CApplication(void)
   : m_pPlayer(NULL)
 #ifdef HAS_WEB_SERVER
   , m_WebServer(*new CWebServer)
+  , m_httpVfsHandler(*new CHTTPVfsHandler)
+#ifdef HAS_JSONRPC
+  , m_httpJsonRpcHandler(*new CHTTPJsonRpcHandler)
+#endif
+#ifdef HAS_HTTPAPI
+  , m_httpApiHandler(*new CHTTPApiHandler)
+#endif
+#ifdef HAS_WEB_INTERFACE
+  , m_httpWebinterfaceHandler(*new CHTTPWebinterfaceHandler)
+  , m_httpWebinterfaceAddonsHandler(*new CHTTPWebinterfaceAddonsHandler)
+#endif
 #endif
   , m_itemCurrentFile(new CFileItem)
   , m_progressTrackingVideoResumeBookmark(*new CBookmark)
@@ -388,6 +406,17 @@ CApplication::~CApplication(void)
 {
 #ifdef HAS_WEB_SERVER
   delete &m_WebServer;
+  delete &m_httpVfsHandler;
+#ifdef HAS_HTTPAPI
+  delete &m_httpApiHandler;
+#endif
+#ifdef HAS_JSONRPC
+  delete &m_httpJsonRpcHandler;
+#endif
+#ifdef HAS_WEB_INTERFACE
+  delete &m_httpWebinterfaceHandler;
+  delete &m_httpWebinterfaceAddonsHandler;
+#endif
 #endif
   delete &m_progressTrackingVideoResumeBookmark;
 #ifdef HAS_DVD_DRIVE
@@ -544,10 +573,10 @@ bool CApplication::Create()
   CopyUserDataIfNeeded("special://masterprofile/", "Lircmap.xml");
   CopyUserDataIfNeeded("special://masterprofile/", "LCD.xml");
 
-  if (!CLog::Init(_P(g_settings.m_logFolder).c_str()))
+  if (!CLog::Init(CSpecialProtocol::TranslatePath(g_settings.m_logFolder).c_str()))
   {
     fprintf(stderr,"Could not init logging classes. Permission errors on ~/.xbmc (%s)\n",
-      _P(g_settings.m_logFolder).c_str());
+      CSpecialProtocol::TranslatePath(g_settings.m_logFolder).c_str());
     return false;
   }
 
@@ -748,7 +777,7 @@ bool CApplication::Create()
     g_guiSettings.m_LookAndFeelResolution = RES_DESKTOP;
   }
 
-#ifdef __APPLE__
+#ifdef TARGET_DARWIN_OSX
   // force initial window creation to be windowed, if fullscreen, it will switch to it below
   // fixes the white screen of death if starting fullscreen and switching to windowed.
   bool bFullScreen = false;
@@ -1016,26 +1045,13 @@ bool CApplication::InitDirectoriesWin32()
   CSpecialProtocol::SetMasterProfilePath(URIUtils::AddFileToFolder(strWin32UserFolder, "userdata"));
   CSpecialProtocol::SetTempPath(URIUtils::AddFileToFolder(strWin32UserFolder,"cache"));
 
-  SetEnvironmentVariable("XBMC_PROFILE_USERDATA",_P("special://masterprofile/").c_str());
+  SetEnvironmentVariable("XBMC_PROFILE_USERDATA",CSpecialProtocol::TranslatePath("special://masterprofile/").c_str());
 
   CreateUserDirs();
 
   // Expand the DLL search path with our directories
   CWIN32Util::ExtendDllPath();
 
-  // check for a DVD drive
-  VECSOURCES vShare;
-  CWIN32Util::GetDrivesByType(vShare, DVD_DRIVES);
-  if(!vShare.empty())
-    g_mediaManager.SetHasOpticalDrive(true);
-
-  // Can be removed once the StorageHandler supports optical media
-  VECSOURCES::const_iterator it;
-  for(it=vShare.begin();it!=vShare.end();++it)
-    if(g_mediaManager.GetDriveStatus(it->strPath) == DRIVE_CLOSED_MEDIA_PRESENT)
-      CJobManager::GetInstance().AddJob(new CDetectDisc(it->strPath, false), NULL);
-  // remove end
-
   return true;
 #else
   return false;
@@ -1085,6 +1101,20 @@ bool CApplication::Initialize()
   g_curlInterface.Load();
   g_curlInterface.Unload();
 
+#ifdef HAS_WEB_SERVER
+  CWebServer::RegisterRequestHandler(&m_httpVfsHandler);
+#ifdef HAS_JSONRPC
+  CWebServer::RegisterRequestHandler(&m_httpJsonRpcHandler);
+#endif
+#ifdef HAS_HTTPAPI
+  CWebServer::RegisterRequestHandler(&m_httpApiHandler);
+#endif
+#ifdef HAS_WEB_INTERFACE
+  CWebServer::RegisterRequestHandler(&m_httpWebinterfaceAddonsHandler);
+  CWebServer::RegisterRequestHandler(&m_httpWebinterfaceHandler);
+#endif
+#endif
+
   StartServices();
 
   // Init DPMS, before creating the corresponding setting control.
@@ -1269,6 +1299,7 @@ bool CApplication::Initialize()
 
   // reset our screensaver (starts timers etc.)
   ResetScreenSaver();
+
   return true;
 }
 
@@ -2260,7 +2291,7 @@ bool CApplication::OnKey(const CKey& key)
       if (!action.GetID())
       {
         // keyboard entry - pass the keys through directly
-        if (key.GetFromHttpApi())
+        if (key.GetFromService())
           action = CAction(key.GetButtonCode() != KEY_INVALID ? key.GetButtonCode() : 0, key.GetUnicode());
         else
         { // see if we've got an ascii key
@@ -2277,7 +2308,7 @@ bool CApplication::OnKey(const CKey& key)
         return true;
       // failed to handle the keyboard action, drop down through to standard action
     }
-    if (key.GetFromHttpApi())
+    if (key.GetFromService())
     {
       if (key.GetButtonCode() != KEY_INVALID)
         action = CButtonTranslator::GetInstance().GetAction(iWin, key);
@@ -2569,6 +2600,10 @@ bool CApplication::OnAction(const CAction &action)
       }
     }
   }
+
+  if (g_peripherals.OnAction(action))
+    return true;
+
   if (action.GetID() == ACTION_MUTE)
   {
     ToggleMute();
@@ -2637,7 +2672,7 @@ bool CApplication::OnAction(const CAction &action)
   }
   if (action.GetID() == ACTION_GUIPROFILE_BEGIN)
   {
-    CGUIControlProfiler::Instance().SetOutputFile(_P("special://home/guiprofiler.xml"));
+    CGUIControlProfiler::Instance().SetOutputFile(CSpecialProtocol::TranslatePath("special://home/guiprofiler.xml"));
     CGUIControlProfiler::Instance().Start();
     return true;
   }
@@ -2844,23 +2879,9 @@ bool CApplication::ProcessRemote(float frameTime)
 
 bool CApplication::ProcessPeripherals(float frameTime)
 {
-#ifdef HAVE_LIBCEC
-  vector<CPeripheral *> peripherals;
-  if (g_peripherals.GetPeripheralsWithFeature(peripherals, FEATURE_CEC))
-  {
-    for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < peripherals.size(); iPeripheralPtr++)
-    {
-      CPeripheralCecAdapter *cecDevice = (CPeripheralCecAdapter *) peripherals.at(iPeripheralPtr);
-      if (cecDevice && cecDevice->GetButton())
-      {
-        CKey key(cecDevice->GetButton(), cecDevice->GetHoldTime());
-        cecDevice->ResetButton();
-        return OnKey(key);
-      }
-    }
-  }
-#endif
-
+  CKey key;
+  if (g_peripherals.GetNextKeypress(frameTime, key))
+    return OnKey(key);
   return false;
 }
 
@@ -2997,7 +3018,10 @@ bool CApplication::ProcessJsonRpcButtons()
 #ifdef HAS_JSONRPC
   CKey tempKey(JSONRPC::CInputOperations::GetKey());
   if (tempKey.GetButtonCode() != KEY_INVALID)
+  {
+    tempKey.SetFromService(true);
     return OnKey(tempKey);
+  }
 #endif
   return false;
 }
@@ -3069,6 +3093,7 @@ bool CApplication::ProcessEventServer(float frameTime)
         key = CKey(wKeyID, 0, 0, 0.0, 0.0, 0.0, -fAmount, frameTime);
       else
         key = CKey(wKeyID);
+      key.SetFromService(true);
       return OnKey(key);
     }
   }
@@ -3092,7 +3117,7 @@ bool CApplication::ProcessEventServer(float frameTime)
   return false;
 }
 
-bool CApplication::ProcessJoystickEvent(const std::string& joystickName, int wKeyID, bool isAxis, float fAmount)
+bool CApplication::ProcessJoystickEvent(const std::string& joystickName, int wKeyID, bool isAxis, float fAmount, unsigned int holdTime /*=0*/)
 {
 #if defined(HAS_EVENT_SERVER)
   m_idleTimer.StartZero();
@@ -3128,7 +3153,7 @@ bool CApplication::ProcessJoystickEvent(const std::string& joystickName, int wKe
    // Translate using regular joystick translator.
    if (CButtonTranslator::GetInstance().TranslateJoystickString(iWin, joystickName.c_str(), wKeyID, isAxis ? JACTIVE_AXIS : JACTIVE_BUTTON, actionID, actionName, fullRange))
    {
-     CAction action(actionID, fAmount, 0.0f, actionName);
+     CAction action(actionID, fAmount, 0.0f, actionName, holdTime);
      g_audioManager.PlayActionSound(action);
      return OnAction(action);
    }
@@ -3225,7 +3250,7 @@ bool CApplication::Cleanup()
     g_windowManager.Remove(WINDOW_SETTINGS_MYMUSIC);
     g_windowManager.Remove(WINDOW_SETTINGS_SYSTEM);
     g_windowManager.Remove(WINDOW_SETTINGS_MYVIDEOS);
-    g_windowManager.Remove(WINDOW_SETTINGS_NETWORK);
+    g_windowManager.Remove(WINDOW_SETTINGS_SERVICE);
     g_windowManager.Remove(WINDOW_SETTINGS_APPEARANCE);
     g_windowManager.Remove(WINDOW_DIALOG_KAI_TOAST);
 
@@ -3297,7 +3322,8 @@ void CApplication::Stop(int exitCode)
 {
   try
   {
-    CAnnouncementManager::Announce(System, "xbmc", "OnQuit");
+    CVariant vExitCode(exitCode);
+    CAnnouncementManager::Announce(System, "xbmc", "OnQuit", vExitCode);
 
     // cancel any jobs from the jobmanager
     CJobManager::GetInstance().CancelJobs();
@@ -3349,6 +3375,20 @@ void CApplication::Stop(int exitCode)
     StopServices();
     //Sleep(5000);
 
+#ifdef HAS_WEB_SERVER
+  CWebServer::UnregisterRequestHandler(&m_httpVfsHandler);
+#ifdef HAS_JSONRPC
+  CWebServer::UnregisterRequestHandler(&m_httpJsonRpcHandler);
+#endif
+#ifdef HAS_HTTPAPI
+  CWebServer::UnregisterRequestHandler(&m_httpApiHandler);
+#endif
+#ifdef HAS_WEB_INTERFACE
+  CWebServer::UnregisterRequestHandler(&m_httpWebinterfaceAddonsHandler);
+  CWebServer::UnregisterRequestHandler(&m_httpWebinterfaceHandler);
+#endif
+#endif
+
 #if defined(__APPLE__) && !defined(__arm__)
     XBMCHelper::GetInstance().ReleaseAllInput();
 #endif
@@ -3657,7 +3697,7 @@ bool CApplication::PlayFile(const CFileItem& item, bool bRestart)
   if (item.IsStack())
     return PlayStack(item, bRestart);
 
-  //Is TuxBox, this should probably be moved to CFileTuxBox
+  //Is TuxBox, this should probably be moved to CTuxBoxFile
   if(item.IsTuxBox())
   {
     CLog::Log(LOGDEBUG, "%s - TuxBox URL Detected %s",__FUNCTION__, item.GetPath().c_str());
@@ -3689,7 +3729,10 @@ bool CApplication::PlayFile(const CFileItem& item, bool bRestart)
   
   if( item.HasProperty("StartPercent") )
   {
-    options.startpercent = item.GetProperty("StartPercent").asDouble();
+    double fallback = 0.0f;
+    if(item.GetProperty("StartPercent").isString())
+      fallback = (double)atof(item.GetProperty("StartPercent").asString().c_str());
+    options.startpercent = item.GetProperty("StartPercent").asDouble(fallback);
   }
   
   PLAYERCOREID eNewCore = EPC_NONE;
@@ -3810,7 +3853,7 @@ bool CApplication::PlayFile(const CFileItem& item, bool bRestart)
 
   // Workaround for bug/quirk in SDL_Mixer on OSX.
   // TODO: Remove after GUI Sounds redux
-#if defined(__APPLE__)
+#if defined(__APPLE__) || defined(_LINUX)
   g_audioManager.Enable(false);
 #endif
 
@@ -3874,7 +3917,7 @@ bool CApplication::PlayFile(const CFileItem& item, bool bRestart)
     }
 #endif
 
-#if !defined(__APPLE__)
+#if !defined(__APPLE__) && !defined(_LINUX)
     g_audioManager.Enable(false);
 #endif
   }
@@ -4148,6 +4191,13 @@ bool CApplication::IsPlayingFullScreenVideo() const
   return IsPlayingVideo() && g_graphicsContext.IsFullScreenVideo();
 }
 
+bool CApplication::IsFullScreen()
+{
+  return IsPlayingFullScreenVideo() ||
+        (g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION) ||
+         g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW;
+}
+
 void CApplication::SaveFileState()
 {
   if (!g_settings.GetCurrentProfile().canWriteDatabases())
@@ -5033,6 +5083,8 @@ void CApplication::ShowVolumeBar(const CAction *action)
 
 bool CApplication::IsMuted() const
 {
+  if (g_peripherals.IsMuted())
+    return true;
   return g_settings.m_bMute;
 }
 
@@ -5046,16 +5098,22 @@ void CApplication::ToggleMute(void)
 
 void CApplication::Mute()
 {
+  if (g_peripherals.Mute())
+    return;
+
   g_settings.m_iPreMuteVolumeLevel = GetVolume();
-  SetVolume(0);
   g_settings.m_bMute = true;
+  SetVolume(0);
 }
 
 void CApplication::UnMute()
 {
+  if (g_peripherals.UnMute())
+    return;
+
+  g_settings.m_bMute = false;
   SetVolume(g_settings.m_iPreMuteVolumeLevel);
   g_settings.m_iPreMuteVolumeLevel = 0;
-  g_settings.m_bMute = false;
 }
 
 void CApplication::SetVolume(long iValue, bool isPercentage /* = true */)
@@ -5070,6 +5128,13 @@ void CApplication::SetVolume(long iValue, bool isPercentage /* = true */)
 #else
   g_audioManager.SetVolume((int)(128.f * (g_settings.m_nVolumeLevel - VOLUME_MINIMUM) / (float)(VOLUME_MAXIMUM - VOLUME_MINIMUM)));
 #endif
+
+  CVariant data(CVariant::VariantTypeObject);
+  data["volume"] = (int)(((float)(g_settings.m_nVolumeLevel - VOLUME_MINIMUM)) / (VOLUME_MAXIMUM - VOLUME_MINIMUM) * 100.0f + 0.5f);
+  /* TODO: add once DRC is available
+  data["drc"] = (int)(((float)(g_settings.m_dynamicRangeCompressionLevel - VOLUME_DRC_MINIMUM)) / (VOLUME_DRC_MAXIMUM - VOLUME_DRC_MINIMUM) * 100.0f + 0.5f);*/
+  data["muted"] = g_settings.m_bMute;
+  CAnnouncementManager::Announce(Application, "xbmc", "OnVolumeChanged", data);
 }
 
 void CApplication::SetHardwareVolume(long hardwareVolume)
@@ -5514,3 +5579,4 @@ CPerformanceStats &CApplication::GetPerformanceStats()
   return m_perfStats;
 }
 #endif
+
index 6e6a005..881c8bf 100644 (file)
@@ -69,6 +69,20 @@ class DPMSSupport;
 class CSplash;
 class CBookmark;
 class CWebServer;
+#ifdef HAS_WEB_SERVER
+class CWebServer;
+class CHTTPVfsHandler;
+#ifdef HAS_JSONRPC
+class CHTTPJsonRpcHandler;
+#endif
+#ifdef HAS_HTTPAPI
+class CHTTPApiHandler;
+#endif
+#ifdef HAS_WEB_INTERFACE
+class CHTTPWebinterfaceHandler;
+class CHTTPWebinterfaceAddonsHandler;
+#endif
+#endif
 
 class CBackgroundPlayer : public CThread
 {
@@ -149,6 +163,7 @@ public:
   bool IsPlayingVideo() const;
   bool IsPlayingFullScreenVideo() const;
   bool IsStartingPlayback() const { return m_bPlaybackStarting; }
+  bool IsFullScreen();
   bool OnKey(const CKey& key);
   bool OnAppCommand(const CAction &action);
   bool OnAction(const CAction &action);
@@ -224,6 +239,17 @@ public:
 
 #ifdef HAS_WEB_SERVER
   CWebServer& m_WebServer;
+  CHTTPVfsHandler& m_httpVfsHandler;
+#ifdef HAS_JSONRPC
+  CHTTPJsonRpcHandler& m_httpJsonRpcHandler;
+#endif
+#ifdef HAS_HTTPAPI
+  CHTTPApiHandler& m_httpApiHandler;
+#endif
+#ifdef HAS_WEB_INTERFACE
+  CHTTPWebinterfaceHandler& m_httpWebinterfaceHandler;
+  CHTTPWebinterfaceAddonsHandler& m_httpWebinterfaceAddonsHandler;
+#endif
 #endif
 
   inline bool IsInScreenSaver() { return m_bScreenSave; };
@@ -363,7 +389,7 @@ protected:
   bool ProcessPeripherals(float frameTime);
   bool ProcessHTTPApiButtons();
   bool ProcessJsonRpcButtons();
-  bool ProcessJoystickEvent(const std::string& joystickName, int button, bool isAxis, float fAmount);
+  bool ProcessJoystickEvent(const std::string& joystickName, int button, bool isAxis, float fAmount, unsigned int holdTime = 0);
 
   float NavigationIdleTime();
   static bool AlwaysProcess(const CAction& action);
index 2e31473..54e6c98 100644 (file)
@@ -331,6 +331,13 @@ case TMSG_POWERDOWN:
               g_application.PlayMedia(*((*list)[0]), playlist);
             else
             {
+              // Handle "shuffled" option if present
+              if (list->HasProperty("shuffled") && list->GetProperty("shuffled").isBoolean())
+                g_playlistPlayer.SetShuffle(playlist, list->GetProperty("shuffled").asBoolean(), false);
+              // Handle "repeat" option if present
+              if (list->HasProperty("repeat") && list->GetProperty("repeat").isInteger())
+                g_playlistPlayer.SetRepeat(playlist, (PLAYLIST::REPEAT_STATE)list->GetProperty("repeat").asInteger(), false);
+
               g_playlistPlayer.Add(playlist, (*list));
               g_playlistPlayer.Play(pMsg->dwParam1);
             }
@@ -707,6 +714,17 @@ case TMSG_POWERDOWN:
       }
       break;
 
+    case TMSG_GUI_MESSAGE:
+      {
+        if (pMsg->lpVoid)
+        {
+          CGUIMessage *message = (CGUIMessage *)pMsg->lpVoid;
+          g_windowManager.SendMessage(*message, pMsg->dwParam1);
+          delete message;
+        }
+      }
+      break;
+
     case TMSG_GUI_INFOLABEL:
       {
         if (pMsg->lpVoid)
@@ -728,23 +746,26 @@ case TMSG_POWERDOWN:
       }
       break;
 
-#ifdef HAS_DVD_DRIVE
     case TMSG_CALLBACK:
       {
         ThreadMessageCallback *callback = (ThreadMessageCallback*)pMsg->lpVoid;
         callback->callback(callback->userptr);
       }
-#endif
+      break;
+
     case TMSG_VOLUME_SHOW:
       {
         CAction action((int)pMsg->dwParam1);
         g_application.ShowVolumeBar(&action);
       }
+      break;
+
     case TMSG_SPLASH_MESSAGE:
       {
         if (g_application.m_splash)
           g_application.m_splash->Show(pMsg->strParam);
       }
+      break;
   }
 }
 
@@ -1136,6 +1157,14 @@ void CApplicationMessenger::SendAction(const CAction &action, int windowID, bool
   SendMessage(tMsg, waitResult);
 }
 
+void CApplicationMessenger::SendGUIMessage(const CGUIMessage &message, int windowID, bool waitResult)
+{
+  ThreadMessage tMsg = {TMSG_GUI_MESSAGE};
+  tMsg.dwParam1 = windowID == WINDOW_INVALID ? 0 : windowID;
+  tMsg.lpVoid = new CGUIMessage(message);
+  SendMessage(tMsg, waitResult);
+}
+
 vector<CStdString> CApplicationMessenger::GetInfoLabels(const vector<CStdString> &properties)
 {
   vector<CStdString> infoLabels;
index 9833e1b..393ee4d 100644 (file)
@@ -34,6 +34,7 @@ class CFileItem;
 class CFileItemList;
 class CGUIDialog;
 class CGUIWindow;
+class CGUIMessage;
 
 // defines here
 #define TMSG_DIALOG_DOMODAL       100
@@ -90,6 +91,7 @@ class CGUIWindow;
 #define TMSG_GUI_ACTION               607
 #define TMSG_GUI_INFOLABEL            608
 #define TMSG_GUI_INFOBOOL             609
+#define TMSG_GUI_MESSAGE              610
 
 #define TMSG_CALLBACK             800
 
@@ -191,6 +193,15 @@ public:
   void Close(CGUIWindow *window, bool forceClose, bool waitResult = true, int nextWindowID = 0, bool enableSound = true);
   void ActivateWindow(int windowID, const std::vector<CStdString> &params, bool swappingWindows);
   void SendAction(const CAction &action, int windowID = WINDOW_INVALID, bool waitResult=true);
+
+  /*! \brief Send a GUIMessage, optionally waiting before it's processed to return.
+   Should be used to send messages to the GUI from other threads.
+   \param msg the GUIMessage to send.
+   \param windowID optional window to send the message to (defaults to no specified window).
+   \param waitResult whether to wait for the result (defaults to false).
+   */
+  void SendGUIMessage(const CGUIMessage &msg, int windowID = WINDOW_INVALID, bool waitResult=false);
+
   std::vector<CStdString> GetInfoLabels(const std::vector<CStdString> &properties);
   std::vector<bool> GetInfoBooleans(const std::vector<CStdString> &properties);
 
index 846b28d..8ad6707 100644 (file)
@@ -31,7 +31,7 @@
 #include "PlayListPlayer.h"
 #include "filesystem/StackDirectory.h"
 #include "filesystem/Directory.h"
-#include "filesystem/FactoryDirectory.h"
+#include "filesystem/DirectoryFactory.h"
 #include "filesystem/File.h"
 #include "settings/GUISettings.h"
 #include "settings/AdvancedSettings.h"
@@ -101,7 +101,7 @@ bool CAutorun::PlayDisc(const CStdString& path, bool bypassSettings, bool startF
     mediaPath = g_mediaManager.TranslateDevicePath("");
 #endif
 
-  auto_ptr<IDirectory> pDir ( CFactoryDirectory::Create( mediaPath ));
+  auto_ptr<IDirectory> pDir ( CDirectoryFactory::Create( mediaPath ));
   bool bPlaying = RunDisc(pDir.get(), mediaPath, nAddedToPlaylist, true, bypassSettings, startFromBeginning);
 
   if ( !bPlaying && nAddedToPlaylist > 0 )
index 27a9adf..e46fd1a 100644 (file)
 #include "utils/Crc32.h"
 #include "filesystem/DirectoryCache.h"
 #include "filesystem/StackDirectory.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 #include "filesystem/MultiPathDirectory.h"
 #include "filesystem/MusicDatabaseDirectory.h"
 #include "filesystem/VideoDatabaseDirectory.h"
-#include "filesystem/FactoryDirectory.h"
+#include "filesystem/DirectoryFactory.h"
 #include "music/tags/MusicInfoTagLoaderFactory.h"
 #include "CueDocument.h"
 #include "video/VideoDatabase.h"
@@ -56,6 +56,7 @@
 #include "utils/Variant.h"
 #include "music/karaoke/karaokelyricsfactory.h"
 #include "ThumbnailCache.h"
+#include "utils/Mime.h"
 
 using namespace std;
 using namespace XFILE;
@@ -96,6 +97,20 @@ CFileItem::CFileItem(const CStdString &path, const CAlbum& album)
   CMusicDatabase::SetPropertiesFromAlbum(*this,album);
 }
 
+CFileItem::CFileItem(const CMusicInfoTag& music)
+{
+  m_musicInfoTag = NULL;
+  m_videoInfoTag = NULL;
+  m_pictureInfoTag = NULL;
+  Reset();
+  SetLabel(music.GetTitle());
+  m_strPath = music.GetURL();
+  m_bIsFolder = URIUtils::HasSlashAtEnd(m_strPath);
+  *GetMusicInfoTag() = music;
+  FillInDefaultIcon();
+  SetCachedMusicThumb();
+}
+
 CFileItem::CFileItem(const CVideoInfoTag& movie)
 {
   m_musicInfoTag = NULL;
@@ -438,7 +453,7 @@ void CFileItem::Serialize(CVariant& value)
   value["size"] = (int) m_dwSize / 1000;
   value["DVDLabel"] = m_strDVDLabel;
   value["title"] = m_strTitle;
-  value["mimetype"] = m_mimetype;
+  value["mimetype"] = GetMimeType();
   value["extrainfo"] = m_extrainfo;
 
   if (m_musicInfoTag)
@@ -1087,13 +1102,13 @@ const CStdString& CFileItem::GetMimeType(bool lookup /*= true*/) const
           || m_strPath.Left(7).Equals("http://")
           || m_strPath.Left(8).Equals("https://"))
     {
-      CFileCurl::GetMimeType(GetAsUrl(), m_ref);
+      CCurlFile::GetMimeType(GetAsUrl(), m_ref);
 
       // try to get mime-type again but with an NSPlayer User-Agent
       // in order for server to provide correct mime-type.  Allows us
       // to properly detect an MMS stream
       if (m_ref.Left(11).Equals("video/x-ms-"))
-        CFileCurl::GetMimeType(GetAsUrl(), m_ref, "NSPlayer/11.00.6001.7000");
+        CCurlFile::GetMimeType(GetAsUrl(), m_ref, "NSPlayer/11.00.6001.7000");
 
       // make sure there are no options set in mime-type
       // mime-type can look like "video/x-ms-asf ; charset=utf8"
@@ -1102,6 +1117,8 @@ const CStdString& CFileItem::GetMimeType(bool lookup /*= true*/) const
         m_ref.Delete(i,m_ref.length()-i);
       m_ref.Trim();
     }
+    else
+      m_ref = CMime::GetMimeType(*this);
 
     // if it's still empty set to an unknown type
     if( m_ref.IsEmpty() )
@@ -2300,7 +2317,7 @@ void CFileItemList::StackFiles()
 bool CFileItemList::Load(int windowID)
 {
   CFile file;
-  if (file.Open(GetDiscCacheFile(windowID)))
+  if (file.Open(GetDisCFileCache(windowID)))
   {
     CLog::Log(LOGDEBUG,"Loading fileitems [%s]",GetPath().c_str());
     CArchive ar(&file, CArchive::load);
@@ -2323,7 +2340,7 @@ bool CFileItemList::Save(int windowID)
   CLog::Log(LOGDEBUG,"Saving fileitems [%s]",GetPath().c_str());
 
   CFile file;
-  if (file.OpenForWrite(GetDiscCacheFile(windowID), true)) // overwrite always
+  if (file.OpenForWrite(GetDisCFileCache(windowID), true)) // overwrite always
   {
     CArchive ar(&file, CArchive::store);
     ar << *this;
@@ -2338,7 +2355,7 @@ bool CFileItemList::Save(int windowID)
 
 void CFileItemList::RemoveDiscCache(int windowID) const
 {
-  CStdString cacheFile(GetDiscCacheFile(windowID));
+  CStdString cacheFile(GetDisCFileCache(windowID));
   if (CFile::Exists(cacheFile))
   {
     CLog::Log(LOGDEBUG,"Clearing cached fileitems [%s]",GetPath().c_str());
@@ -2346,7 +2363,7 @@ void CFileItemList::RemoveDiscCache(int windowID) const
   }
 }
 
-CStdString CFileItemList::GetDiscCacheFile(int windowID) const
+CStdString CFileItemList::GetDisCFileCache(int windowID) const
 {
   CStdString strPath(GetPath());
   URIUtils::RemoveSlashAtEnd(strPath);
@@ -2361,6 +2378,8 @@ CStdString CFileItemList::GetDiscCacheFile(int windowID) const
     cacheFile.Format("special://temp/mdb-%08x.fi", (unsigned __int32)crc);
   else if (IsVideoDb())
     cacheFile.Format("special://temp/vdb-%08x.fi", (unsigned __int32)crc);
+  else if (IsSmartPlayList())
+    cacheFile.Format("special://temp/sp-%08x.fi", (unsigned __int32)crc);
   else if (windowID)
     cacheFile.Format("special://temp/%i-%08x.fi", windowID, (unsigned __int32)crc);
   else
index 73faf0d..4e5eb79 100644 (file)
@@ -73,6 +73,7 @@ public:
   CFileItem(const CStdString &path, const CAlbum& album);
   CFileItem(const CArtist& artist);
   CFileItem(const CGenre& genre);
+  CFileItem(const MUSIC_INFO::CMusicInfoTag& music);
   CFileItem(const CVideoInfoTag& movie);
   CFileItem(const CMediaSource& share);
   virtual ~CFileItem(void);
@@ -501,7 +502,7 @@ public:
 private:
   void Sort(FILEITEMLISTCOMPARISONFUNC func);
   void FillSortFields(FILEITEMFILLFUNC func);
-  CStdString GetDiscCacheFile(int windowID) const;
+  CStdString GetDisCFileCache(int windowID) const;
 
   /*!
    \brief stack files in a CFileItemList
index 5241748..dca7d19 100644 (file)
@@ -212,8 +212,6 @@ const infomap system_labels[] =  {{ "hasnetwork",       SYSTEM_ETHERNET_LINK_ACT
                                   { "isstandalone",     SYSTEM_ISSTANDALONE },
                                   { "loggedon",         SYSTEM_LOGGEDON },
                                   { "showexitbutton",   SYSTEM_SHOW_EXIT_BUTTON },
-                                  { "hasdrivef",        SYSTEM_HAS_DRIVE_F },
-                                  { "hasdriveg",        SYSTEM_HAS_DRIVE_G },
                                   { "canpowerdown",     SYSTEM_CAN_POWERDOWN },
                                   { "cansuspend",       SYSTEM_CAN_SUSPEND },
                                   { "canhibernate",     SYSTEM_CAN_HIBERNATE },
@@ -254,7 +252,8 @@ const infomap system_labels[] =  {{ "hasnetwork",       SYSTEM_ETHERNET_LINK_ACT
                                   { "progressbar",      SYSTEM_PROGRESS_BAR },
                                   { "batterylevel",     SYSTEM_BATTERY_LEVEL },
                                   { "friendlyname",     SYSTEM_FRIENDLY_NAME },
-                                  { "alarmpos",         SYSTEM_ALARM_POS }};
+                                  { "alarmpos",         SYSTEM_ALARM_POS },
+                                  { "haspvr",           SYSTEM_HAS_PVR }};
 
 const infomap system_param[] =   {{ "hasalarm",         SYSTEM_HAS_ALARM },
                                   { "getbool",          SYSTEM_GET_BOOL },
@@ -1888,10 +1887,6 @@ bool CGUIInfoManager::GetBool(int condition1, int contextWindow, const CGUIListI
   else if (condition == SYSTEM_MEDIA_DVD)
     bReturn = g_mediaManager.IsDiscInDrive();
 #ifdef HAS_DVD_DRIVE
-  else if (condition == SYSTEM_HAS_DRIVE_F)
-    bReturn = CIoSupport::DriveExists('F');
-  else if (condition == SYSTEM_HAS_DRIVE_G)
-    bReturn = CIoSupport::DriveExists('G');
   else if (condition == SYSTEM_DVDREADY)
     bReturn = g_mediaManager.GetDriveStatus() != DRIVE_NOT_READY;
   else if (condition == SYSTEM_TRAYOPEN)
@@ -1918,6 +1913,8 @@ bool CGUIInfoManager::GetBool(int condition1, int contextWindow, const CGUIListI
   }
   else if (condition == SYSTEM_HASLOCKS)
     bReturn = g_settings.GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE;
+  else if (condition == SYSTEM_HAS_PVR)
+    bReturn = false;
   else if (condition == SYSTEM_ISMASTER)
     bReturn = g_settings.GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE && g_passwordManager.bMasterUser;
   else if (condition == SYSTEM_ISFULLSCREEN)
index 073dffe..9c1c350 100644 (file)
@@ -139,7 +139,6 @@ namespace INFO
 #define SYSTEM_CURRENT_WINDOW       135
 #define SYSTEM_CURRENT_CONTROL      136
 #define SYSTEM_DVD_LABEL            138
-#define SYSTEM_HAS_DRIVE_F          139
 #define SYSTEM_HASLOCKS             140
 #define SYSTEM_ISMASTER             141
 #define SYSTEM_TRAYOPEN             142
@@ -149,7 +148,6 @@ namespace INFO
 #define SYSTEM_PROFILENAME          146
 #define SYSTEM_PROFILETHUMB         147
 #define SYSTEM_HAS_LOGINSCREEN      148
-#define SYSTEM_HAS_DRIVE_G          149
 #define SYSTEM_HDD_SMART            150
 #define SYSTEM_HDD_TEMPERATURE      151
 #define SYSTEM_HDD_MODEL            152
@@ -178,6 +176,7 @@ namespace INFO
 #define SYSTEM_PROFILECOUNT         181
 #define SYSTEM_ISFULLSCREEN         182
 #define SYSTEM_ISSTANDALONE         183
+#define SYSTEM_HAS_PVR              184
 
 #define NETWORK_IP_ADDRESS          190
 #define NETWORK_MAC_ADDRESS         191
index 8094d52..34b1e3a 100644 (file)
@@ -93,7 +93,8 @@ bool CGUIPassword::IsItemUnlocked(CFileItem* pItem, const CStdString &strType)
         pItem->m_iBadPwdCount = 0;
         pItem->m_iHasLock = 1;
         g_passwordManager.LockSource(strType,strLabel,false);
-        g_settings.UpdateSource(strType, strLabel, "badpwdcount", itoa(pItem->m_iBadPwdCount, buffer, 10));
+        sprintf(buffer,"%i",pItem->m_iBadPwdCount);
+        g_settings.UpdateSource(strType, strLabel, "badpwdcount", buffer);
         g_settings.SaveSources();
         break;
       }
@@ -102,7 +103,8 @@ bool CGUIPassword::IsItemUnlocked(CFileItem* pItem, const CStdString &strType)
         // password entry failed
         if (0 != g_guiSettings.GetInt("masterlock.maxretries"))
           pItem->m_iBadPwdCount++;
-        g_settings.UpdateSource(strType, strLabel, "badpwdcount", itoa(pItem->m_iBadPwdCount, buffer, 10));
+        sprintf(buffer,"%i",pItem->m_iBadPwdCount);
+        g_settings.UpdateSource(strType, strLabel, "badpwdcount", buffer);
         g_settings.SaveSources();
         break;
       }
index 26b7290..ecfaf78 100644 (file)
@@ -111,8 +111,9 @@ bool CPartyModeManager::Enable(PartyModeContext context /*= PARTYMODECONTEXT_MUS
     CMusicDatabase db;
     if (db.Open())
     {
+      set<CStdString> playlists;
       if ( playlistLoaded )
-        m_strCurrentFilterMusic = playlist.GetWhereClause(db);
+        m_strCurrentFilterMusic = playlist.GetWhereClause(db, playlists);
 
       CLog::Log(LOGINFO, "PARTY MODE MANAGER: Registering filter:[%s]", m_strCurrentFilterMusic.c_str());
       m_iMatchingSongs = (int)db.GetSongIDs(m_strCurrentFilterMusic, songIDs);
@@ -139,8 +140,9 @@ bool CPartyModeManager::Enable(PartyModeContext context /*= PARTYMODECONTEXT_MUS
     CVideoDatabase db;
     if (db.Open())
     {
+      set<CStdString> playlists;
       if ( playlistLoaded )
-        m_strCurrentFilterVideo = playlist.GetWhereClause(db);
+        m_strCurrentFilterVideo = playlist.GetWhereClause(db, playlists);
 
       CLog::Log(LOGINFO, "PARTY MODE MANAGER: Registering filter:[%s]", m_strCurrentFilterVideo.c_str());
       m_iMatchingSongs += (int)db.GetMusicVideoIDs(m_strCurrentFilterVideo, songIDs2);
index e69ca91..11461a1 100644 (file)
@@ -175,7 +175,7 @@ void SSortFileItem::ByDateAdded(CFileItemPtr &item)
   if (!item) return;
 
   CStdString label;
-  label.Format("%d", item->GetVideoInfoTag()->m_iFileId);
+  label.Format("%s %d", item->GetVideoInfoTag()->m_dateAdded.GetAsDBDateTime().c_str(), item->GetVideoInfoTag()->m_iFileId);
   item->SetSortLabel(label);
 }
 
index f759f94..271c8cb 100644 (file)
@@ -1638,11 +1638,13 @@ CStdString CUtil::VideoPlaylistsLocation()
 void CUtil::DeleteMusicDatabaseDirectoryCache()
 {
   CUtil::DeleteDirectoryCache("mdb-");
+  CUtil::DeleteDirectoryCache("sp-"); // overkill as it will delete video smartplaylists, but as we can't differentiate based on URL...
 }
 
 void CUtil::DeleteVideoDatabaseDirectoryCache()
 {
   CUtil::DeleteDirectoryCache("vdb-");
+  CUtil::DeleteDirectoryCache("sp-"); // overkill as it will delete music smartplaylists, but as we can't differentiate based on URL...
 }
 
 void CUtil::DeleteDirectoryCache(const CStdString &prefix)
@@ -2173,7 +2175,7 @@ CStdString CUtil::ResolveExecutablePath()
   CStdString strExecutablePath;
 #ifdef WIN32
   wchar_t szAppPathW[MAX_PATH] = L"";
-  ::GetModuleFileNameW(0, szAppPathW, sizeof(szAppPathW) - 1);
+  ::GetModuleFileNameW(0, szAppPathW, sizeof(szAppPathW)/sizeof(szAppPathW[0]) - 1);
   CStdStringW strPathW = szAppPathW;
   g_charsetConverter.wToUTF8(strPathW,strExecutablePath);
 #elif defined(__APPLE__)
@@ -2363,20 +2365,23 @@ void CUtil::ScanForExternalSubtitles(const CStdString& strMovie, std::vector<CSt
       {
         URIUtils::Split(items[j]->GetPath(), strPath, strItem);
         
-        // is this a rar or zip-file
-        if (URIUtils::IsRAR(strItem) || URIUtils::IsZIP(strItem))
+        if (strItem.Left(fnl).Equals(strMovieFileNameNoExt))
         {
-          ScanArchiveForSubtitles( items[j]->GetPath(), strMovieFileNameNoExt, vecSubtitles );
-        }
-        else    // not a rar/zip file
-        {
-          for (int i = 0; sub_exts[i]; i++)
+          // is this a rar or zip-file
+          if (URIUtils::IsRAR(strItem) || URIUtils::IsZIP(strItem))
+          {
+            ScanArchiveForSubtitles( items[j]->GetPath(), strMovieFileNameNoExt, vecSubtitles );
+          }
+          else    // not a rar/zip file
           {
-            //Cache subtitle with same name as movie
-            if (URIUtils::GetExtension(strItem).Equals(sub_exts[i]) && strItem.Left(fnl).Equals(strMovieFileNameNoExt))
+            for (int i = 0; sub_exts[i]; i++)
             {
-              vecSubtitles.push_back( items[j]->GetPath() ); 
-              CLog::Log(LOGINFO, "%s: found subtitle file %s\n", __FUNCTION__, items[j]->GetPath().c_str() );
+              //Cache subtitle with same name as movie
+              if (URIUtils::GetExtension(strItem).Equals(sub_exts[i]))
+              {
+                vecSubtitles.push_back( items[j]->GetPath() ); 
+                CLog::Log(LOGINFO, "%s: found subtitle file %s\n", __FUNCTION__, items[j]->GetPath().c_str() );
+              }
             }
           }
         }
@@ -2457,7 +2462,7 @@ int CUtil::ScanArchiveForSubtitles( const CStdString& strArchivePath, const CStd
     ScanArchiveForSubtitles(strRarInRar,strMovieFileNameNoExt,vecSubtitles);
    }
    // done checking if this is a rar-in-rar
-   
+
    int iPos=0;
     while (sub_exts[iPos])
     {
@@ -2495,8 +2500,11 @@ bool CUtil::FindVobSubPair( const std::vector<CStdString>& vecSubtitles, const C
       CStdString strSubFile;
       CStdString strSubDirectory;
       URIUtils::Split(vecSubtitles[j], strSubDirectory, strSubFile);
+      if (URIUtils::IsInArchive(vecSubtitles[j]))
+        CURL::Decode(strSubDirectory);
       if (URIUtils::GetExtension(strSubFile) == ".sub" &&
-          URIUtils::ReplaceExtension(strIdxFile,"").Equals(URIUtils::ReplaceExtension(strSubFile,"")))
+          (URIUtils::ReplaceExtension(strIdxFile,"").Equals(URIUtils::ReplaceExtension(strSubFile,"")) ||
+           strSubDirectory.Mid(6, strSubDirectory.length()-11).Equals(URIUtils::ReplaceExtension(strIdxPath,""))))
       {
         strSubPath = vecSubtitles[j];
         return true;
@@ -2515,13 +2523,16 @@ bool CUtil::IsVobSub( const std::vector<CStdString>& vecSubtitles, const CStdStr
     CStdString strSubFile;
     CStdString strSubDirectory;
     URIUtils::Split(strSubPath, strSubDirectory, strSubFile);
+    if (URIUtils::IsInArchive(strSubPath))
+      CURL::Decode(strSubDirectory);
     for (unsigned int j=0; j < vecSubtitles.size(); j++)
     {
       CStdString strIdxFile;
       CStdString strIdxDirectory;
       URIUtils::Split(vecSubtitles[j], strIdxDirectory, strIdxFile);
       if (URIUtils::GetExtension(strIdxFile) == ".idx" &&
-          URIUtils::ReplaceExtension(strIdxFile,"").Equals(URIUtils::ReplaceExtension(strSubFile,"")))
+          (URIUtils::ReplaceExtension(strIdxFile,"").Equals(URIUtils::ReplaceExtension(strSubFile,"")) ||
+           strSubDirectory.Mid(6, strSubDirectory.length()-11).Equals(URIUtils::ReplaceExtension(vecSubtitles[j],""))))
         return true;
     }
   }
index 5e97385..1ba5db1 100644 (file)
@@ -1089,19 +1089,15 @@ CStdString CDateTime::GetAsLocalizedTime(const CStdString &format, bool withSeco
     }
     else if (c=='x') // add meridiem symbol
     {
-      int partLength=0;
-
       int pos=strFormat.find_first_not_of(c,i+1);
       if (pos>-1)
       {
         // Get length of the meridiem mask
-        partLength=pos-i;
         i=pos-1;
       }
       else
       {
         // mask ends at the end of the string, extract it
-        partLength=length-i;
         i=length;
       }
 
@@ -1286,3 +1282,15 @@ CStdString CDateTime::GetAsRFC1123DateTime() const
   result.Format("%s, %02i %s %04i %02i:%02i:%02i GMT", DAY_NAMES[time.GetDayOfWeek()], time.GetDay(), MONTH_NAMES[time.GetMonth()-1], time.GetYear(), time.GetHour(), time.GetMinute(), time.GetSecond());
   return result;
 }
+
+int CDateTime::MonthStringToMonthNum(const CStdString& month)
+{
+  const char* months[] = {"january","february","march","april","may","june","july","august","september","october","november","december"};
+  const char* abr_months[] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"};
+
+  int i = 0;
+  for (; i < 12 && month.CompareNoCase(months[i]) != 0 && month.CompareNoCase(abr_months[i]) != 0; i++);
+  i++;
+
+  return i;
+}
index d4a36fe..ee48ddd 100644 (file)
@@ -99,6 +99,7 @@ public:
 
   static CDateTime GetCurrentDateTime();
   static CDateTime GetUTCDateTime();
+  static int MonthStringToMonthNum(const CStdString& month);
 
   const CDateTime& operator =(const SYSTEMTIME& right);
   const CDateTime& operator =(const FILETIME& right);
index 4a61c7e..397c054 100644 (file)
@@ -248,9 +248,9 @@ bool CAddonMgr::Init()
   // would allow partial unloading of addon framework
   m_cp_context = m_cpluff->create_context(&status);
   assert(m_cp_context);
-  status = m_cpluff->register_pcollection(m_cp_context, _P("special://home/addons"));
-  status = m_cpluff->register_pcollection(m_cp_context, _P("special://xbmc/addons"));
-  status = m_cpluff->register_pcollection(m_cp_context, _P("special://xbmcbin/addons"));
+  status = m_cpluff->register_pcollection(m_cp_context, CSpecialProtocol::TranslatePath("special://home/addons"));
+  status = m_cpluff->register_pcollection(m_cp_context, CSpecialProtocol::TranslatePath("special://xbmc/addons"));
+  status = m_cpluff->register_pcollection(m_cp_context, CSpecialProtocol::TranslatePath("special://xbmcbin/addons"));
   if (status != CP_OK)
   {
     CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_register_pcollection() returned status: %i", status);
@@ -681,7 +681,7 @@ AddonPtr CAddonMgr::GetAddonFromDescriptor(const cp_plugin_info_t *info)
 bool CAddonMgr::LoadAddonDescription(const CStdString &path, AddonPtr &addon)
 {
   cp_status_t status;
-  cp_plugin_info_t *info = m_cpluff->load_plugin_descriptor(m_cp_context, _P(path).c_str(), &status);
+  cp_plugin_info_t *info = m_cpluff->load_plugin_descriptor(m_cp_context, CSpecialProtocol::TranslatePath(path).c_str(), &status);
   if (info)
   {
     addon = GetAddonFromDescriptor(info);
index 76c1bc3..ba95143 100644 (file)
@@ -136,4 +136,32 @@ namespace ADDON
 
     return true;
   }
+
+  bool AddonVersion::Test()
+  {
+    AddonVersion v1_0("1.0");
+    AddonVersion v1_00("1.00");
+    AddonVersion v1_0_0("1.0.0");
+    AddonVersion v1_1("1.1");
+    AddonVersion v1_01("1.01");
+    AddonVersion v1_0_1("1.0.1");
+
+    bool ret = false;
+
+    // These are totally sane
+    ret = (v1_0 < v1_1) && (v1_0 < v1_01) && (v1_0 < v1_0_1) &&
+          (v1_1 > v1_0_1) && (v1_01 > v1_0_1);
+
+    // These are rather sane
+    ret &= (v1_0 != v1_0_0) && (v1_0 < v1_0_0) && (v1_0_0 > v1_0) &&
+           (v1_00 != v1_0_0) && (v1_00 < v1_0_0) && (v1_0_0 > v1_00);
+
+    // These aren't totally sane
+    // BEWARE: neither (v1_0 == v1_00) nor (v1_0 < v1_00) nor (v1_0 > v1_00) are true
+    ret &= (v1_0 != v1_00) && !(v1_0 < v1_00) && !(v1_0 > v1_00);
+    // BEWARE: neither (v1_1 == v1_01) nor (v1_1 < v1_01) nor (v1_1 > v1_01) are true
+    ret &= (v1_1 != v1_01) && !(v1_1 < v1_01) && !(v1_1 > v1_01);
+
+    return ret;
+  }
 }
index 945d2ba..2d8cf5a 100644 (file)
@@ -45,6 +45,8 @@ namespace ADDON
 
     static bool SplitFileName(CStdString& ID, CStdString& version,
                               const CStdString& filename);
+
+    static bool Test();
   protected:
     CStdString m_originalVersion;
     int mEpoch;
index 0123aae..a9c4e29 100644 (file)
@@ -129,7 +129,7 @@ void CGUIDialogAddonInfo::OnInitWindow()
 
 void CGUIDialogAddonInfo::UpdateControls()
 {
-  CStdString xbmcPath = _P("special://xbmc/addons");
+  CStdString xbmcPath = CSpecialProtocol::TranslatePath("special://xbmc/addons");
   bool isInstalled = NULL != m_localAddon.get();
   bool isSystem = isInstalled && m_localAddon->Path().Left(xbmcPath.size()).Equals(xbmcPath);
   bool isEnabled = isInstalled && m_item->GetProperty("Addon.Enabled").asBoolean();
index a79c8ec..91f2f95 100644 (file)
@@ -1070,10 +1070,9 @@ CStdString CGUIDialogAddonSettings::GetString(const char *value, bool subSetting
 {
   if (!value)
     return "";
-  int id = atoi(value);
   CStdString prefix(subSetting ? "- " : "");
-  if (id > 0)
-    return prefix + m_addon->GetString(id);
+  if (StringUtils::IsNaturalNumber(value))
+    return prefix + m_addon->GetString(atoi(value));
   return prefix + value;
 }
 
index 7d968a3..6d61267 100644 (file)
@@ -395,11 +395,10 @@ int CGUIWindowAddonBrowser::SelectAddonID(const vector<ADDON::TYPE> &types, CStd
   dialog->SetHeading(heading);
   dialog->Reset();
   dialog->SetUseDetails(true);
-  if (multipleSelection || iTypes > 1)
-  {
+  if (multipleSelection)
     showNone = false;
+  if (multipleSelection || iTypes > 1)
     dialog->EnableButton(true, 186);
-  }
   else
     dialog->EnableButton(true, 21452);
   if (showNone)
index a2d283a..f8517c2 100644 (file)
@@ -21,7 +21,7 @@
 #include "Scraper.h"
 #include "filesystem/File.h"
 #include "filesystem/Directory.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 #include "AddonManager.h"
 #include "utils/ScraperParser.h"
 #include "utils/ScraperUrl.h"
@@ -231,11 +231,11 @@ void CScraper::ClearCache()
 
 // returns a vector of strings: the first is the XML output by the function; the rest
 // is XML output by chained functions, possibly recursively
-// the CFileCurl object is passed in so that URL fetches can be canceled from other threads
+// the CCurlFile object is passed in so that URL fetches can be canceled from other threads
 // throws CScraperError abort on internal failures (e.g., parse errors)
 vector<CStdString> CScraper::Run(const CStdString& function,
                                  const CScraperUrl& scrURL,
-                                 CFileCurl& http,
+                                 CCurlFile& http,
                                  const vector<CStdString>* extras)
 {
   if (!Load())
@@ -268,7 +268,7 @@ vector<CStdString> CScraper::Run(const CStdString& function,
   // skip children of the root element until <url> or <chain>
   while (xchain && strcmp(xchain->Value(),"url") && strcmp(xchain->Value(),"chain"))
       xchain = xchain->NextSiblingElement();
-  while (xchain && xchain->FirstChild())
+  while (xchain)
   {
     // <chain|url function="...">param</>
     const char* szFunction = xchain->Attribute("function");
@@ -278,7 +278,10 @@ vector<CStdString> CScraper::Run(const CStdString& function,
       vector<CStdString> extras;
       // for <chain>, pass the contained text as a parameter; for <url>, as URL content
       if (strcmp(xchain->Value(),"chain")==0)
-        extras.push_back(xchain->FirstChild()->Value());
+      {
+        if (xchain->FirstChild())
+          extras.push_back(xchain->FirstChild()->Value());
+      }
       else
         scrURL2.ParseElement(xchain);
       vector<CStdString> result2 = RunNoThrow(szFunction,scrURL2,http,&extras);
@@ -297,7 +300,7 @@ vector<CStdString> CScraper::Run(const CStdString& function,
 // don't use in new code; errors should be handled appropriately
 std::vector<CStdString> CScraper::RunNoThrow(const CStdString& function,
   const CScraperUrl& url,
-  XFILE::CFileCurl& http,
+  XFILE::CCurlFile& http,
   const std::vector<CStdString>* extras)
 {
   std::vector<CStdString> vcs;
@@ -314,7 +317,7 @@ std::vector<CStdString> CScraper::RunNoThrow(const CStdString& function,
 
 CStdString CScraper::InternalRun(const CStdString& function,
                                  const CScraperUrl& scrURL,
-                                 CFileCurl& http,
+                                 CCurlFile& http,
                                  const vector<CStdString>* extras)
 {
   // walk the list of input URLs and fetch each into parser parameters
@@ -409,7 +412,7 @@ CScraperUrl CScraper::NfoUrl(const CStdString &sNfoContent)
   vector<CStdString> vcsIn;
   vcsIn.push_back(sNfoContent);
   CScraperUrl scurl;
-  CFileCurl fcurl;
+  CCurlFile fcurl;
   vector<CStdString> vcsOut = Run("NfoUrl", scurl, fcurl, &vcsIn);
   if (vcsOut.empty() || vcsOut[0].empty())
     return scurlRet;
@@ -470,7 +473,7 @@ static bool RelevanceSortFunction(const CScraperUrl &left, const CScraperUrl &ri
 
 // fetch list of matching movies sorted by relevance (may be empty);
 // throws CScraperError on error; first called with fFirst set, then unset if first try fails
-std::vector<CScraperUrl> CScraper::FindMovie(XFILE::CFileCurl &fcurl, const CStdString &sMovie,
+std::vector<CScraperUrl> CScraper::FindMovie(XFILE::CCurlFile &fcurl, const CStdString &sMovie,
   bool fFirst)
 {
   // prepare parameters for URL creation
@@ -595,7 +598,7 @@ std::vector<CScraperUrl> CScraper::FindMovie(XFILE::CFileCurl &fcurl, const CStd
 
 // find album by artist, using fcurl for web fetches
 // returns a list of albums (empty if no match or failure)
-std::vector<CMusicAlbumInfo> CScraper::FindAlbum(CFileCurl &fcurl, const CStdString &sAlbum,
+std::vector<CMusicAlbumInfo> CScraper::FindAlbum(CCurlFile &fcurl, const CStdString &sAlbum,
   const CStdString &sArtist)
 {
   CLog::Log(LOGDEBUG, "%s: Searching for '%s - %s' using %s scraper "
@@ -689,7 +692,7 @@ std::vector<CMusicAlbumInfo> CScraper::FindAlbum(CFileCurl &fcurl, const CStdStr
 
 // find artist, using fcurl for web fetches
 // returns a list of artists (empty if no match or failure)
-std::vector<CMusicArtistInfo> CScraper::FindArtist(CFileCurl &fcurl,
+std::vector<CMusicArtistInfo> CScraper::FindArtist(CCurlFile &fcurl,
   const CStdString &sArtist)
 {
   CLog::Log(LOGDEBUG, "%s: Searching for '%s' using %s scraper "
@@ -763,7 +766,7 @@ std::vector<CMusicArtistInfo> CScraper::FindArtist(CFileCurl &fcurl,
 }
 
 // fetch list of episodes from URL (from video database)
-EPISODELIST CScraper::GetEpisodeList(XFILE::CFileCurl &fcurl, const CScraperUrl &scurl)
+EPISODELIST CScraper::GetEpisodeList(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl)
 {
   CLog::Log(LOGDEBUG, "%s: Searching '%s' using %s scraper "
     "(file: '%s', content: '%s', version: '%s')", __FUNCTION__,
@@ -843,7 +846,7 @@ EPISODELIST CScraper::GetEpisodeList(XFILE::CFileCurl &fcurl, const CScraperUrl
 }
 
 // takes URL; returns true and populates video details on success, false otherwise
-bool CScraper::GetVideoDetails(XFILE::CFileCurl &fcurl, const CScraperUrl &scurl,
+bool CScraper::GetVideoDetails(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl,
   bool fMovie/*else episode*/, CVideoInfoTag &video)
 {
   CLog::Log(LOGDEBUG, "%s: Reading %s '%s' using %s scraper "
@@ -884,7 +887,7 @@ bool CScraper::GetVideoDetails(XFILE::CFileCurl &fcurl, const CScraperUrl &scurl
 }
 
 // takes a URL; returns true and populates album on success, false otherwise
-bool CScraper::GetAlbumDetails(CFileCurl &fcurl, const CScraperUrl &scurl, CAlbum &album)
+bool CScraper::GetAlbumDetails(CCurlFile &fcurl, const CScraperUrl &scurl, CAlbum &album)
 {
   CLog::Log(LOGDEBUG, "%s: Reading '%s' using %s scraper "
     "(file: '%s', content: '%s', version: '%s')", __FUNCTION__,
@@ -911,7 +914,7 @@ bool CScraper::GetAlbumDetails(CFileCurl &fcurl, const CScraperUrl &scurl, CAlbu
 
 // takes a URL (one returned from FindArtist), the original search string, and
 // returns true and populates artist on success, false on failure
-bool CScraper::GetArtistDetails(CFileCurl &fcurl, const CScraperUrl &scurl,
+bool CScraper::GetArtistDetails(CCurlFile &fcurl, const CScraperUrl &scurl,
   const CStdString &sSearch, CArtist &artist)
 {
   if (!scurl.m_url.size())
index 63aaddc..7f26974 100644 (file)
@@ -47,7 +47,7 @@ typedef enum
 
 namespace XFILE
 {
-  class CFileCurl;
+  class CCurlFile;
 }
 
 class CScraperUrl;
@@ -121,19 +121,19 @@ public:
   // scraper media functions
   CScraperUrl NfoUrl(const CStdString &sNfoContent);
 
-  std::vector<CScraperUrl> FindMovie(XFILE::CFileCurl &fcurl,
+  std::vector<CScraperUrl> FindMovie(XFILE::CCurlFile &fcurl,
     const CStdString &sMovie, bool fFirst);
-  std::vector<MUSIC_GRABBER::CMusicAlbumInfo> FindAlbum(XFILE::CFileCurl &fcurl,
+  std::vector<MUSIC_GRABBER::CMusicAlbumInfo> FindAlbum(XFILE::CCurlFile &fcurl,
     const CStdString &sAlbum, const CStdString &sArtist = "");
   std::vector<MUSIC_GRABBER::CMusicArtistInfo> FindArtist(
-    XFILE::CFileCurl &fcurl, const CStdString &sArtist);
-  EPISODELIST GetEpisodeList(XFILE::CFileCurl &fcurl, const CScraperUrl &scurl);
+    XFILE::CCurlFile &fcurl, const CStdString &sArtist);
+  EPISODELIST GetEpisodeList(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl);
 
-  bool GetVideoDetails(XFILE::CFileCurl &fcurl, const CScraperUrl &scurl,
+  bool GetVideoDetails(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl,
     bool fMovie/*else episode*/, CVideoInfoTag &video);
-  bool GetAlbumDetails(XFILE::CFileCurl &fcurl, const CScraperUrl &scurl,
+  bool GetAlbumDetails(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl,
     CAlbum &album);
-  bool GetArtistDetails(XFILE::CFileCurl &fcurl, const CScraperUrl &scurl,
+  bool GetArtistDetails(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl,
     const CStdString &sSearch, CArtist &artist);
 
 private:
@@ -144,15 +144,15 @@ private:
   bool Load();
   std::vector<CStdString> Run(const CStdString& function,
                               const CScraperUrl& url,
-                              XFILE::CFileCurl& http,
+                              XFILE::CCurlFile& http,
                               const std::vector<CStdString>* extras = NULL);
   std::vector<CStdString> RunNoThrow(const CStdString& function,
                               const CScraperUrl& url,
-                              XFILE::CFileCurl& http,
+                              XFILE::CCurlFile& http,
                               const std::vector<CStdString>* extras = NULL);
   CStdString InternalRun(const CStdString& function,
                          const CScraperUrl& url,
-                         XFILE::CFileCurl& http,
+                         XFILE::CCurlFile& http,
                          const std::vector<CStdString>* extras);
 
   bool m_fLoaded;
index 77fc2fb..1da9caa 100644 (file)
@@ -49,8 +49,8 @@ bool CScreenSaver::CreateScreenSaver()
   m_pInfo->height     = iHeight;
   m_pInfo->pixelRatio = g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()].fPixelRatio;
   m_pInfo->name       = strdup(Name().c_str());
-  m_pInfo->presets    = strdup(_P(Path()).c_str());
-  m_pInfo->profile    = strdup(_P(Profile()).c_str());
+  m_pInfo->presets    = strdup(CSpecialProtocol::TranslatePath(Path()).c_str());
+  m_pInfo->profile    = strdup(CSpecialProtocol::TranslatePath(Profile()).c_str());
 
   if (CAddonDll<DllScreenSaver, ScreenSaver, SCR_PROPS>::Create())
     return true;
index fd1b252..25b9c97 100644 (file)
@@ -174,7 +174,7 @@ double CSkinInfo::GetMinVersion()
 
 void CSkinInfo::LoadIncludes()
 {
-  CStdString includesPath = PTH_IC(GetSkinPath("includes.xml"));
+  CStdString includesPath = CSpecialProtocol::TranslatePathConvertCase(GetSkinPath("includes.xml"));
   CLog::Log(LOGINFO, "Loading skin includes from %s", includesPath.c_str());
   m_includes.ClearIncludes();
   m_includes.LoadIncludes(includesPath);
index ac65e97..411951d 100644 (file)
@@ -100,8 +100,8 @@ bool CVisualisation::Create(int x, int y, int w, int h)
   m_pInfo->pixelRatio = g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()].fPixelRatio;
 
   m_pInfo->name = strdup(Name().c_str());
-  m_pInfo->presets = strdup(_P(Path()).c_str());
-  m_pInfo->profile = strdup(_P(Profile()).c_str());
+  m_pInfo->presets = strdup(CSpecialProtocol::TranslatePath(Path()).c_str());
+  m_pInfo->profile = strdup(CSpecialProtocol::TranslatePath(Profile()).c_str());
   m_pInfo->submodule = NULL;
 
   if (CAddonDll<DllVisualisation, Visualisation, VIS_PROPS>::Create())
@@ -122,7 +122,7 @@ bool CVisualisation::Create(int x, int y, int w, int h)
     GetPresets();
 
     if (GetSubModules())
-      m_pInfo->submodule = strdup(_P(m_submodules.front()).c_str());
+      m_pInfo->submodule = strdup(CSpecialProtocol::TranslatePath(m_submodules.front()).c_str());
     else
       m_pInfo->submodule = NULL;
 
@@ -359,7 +359,7 @@ bool CVisualisation::UpdateTrack()
   if (Initialized())
   {
     // get the current album art filename
-    m_AlbumThumb = _P(g_infoManager.GetImage(MUSICPLAYER_COVER, WINDOW_INVALID));
+    m_AlbumThumb = CSpecialProtocol::TranslatePath(g_infoManager.GetImage(MUSICPLAYER_COVER, WINDOW_INVALID));
 
     // get the current track tag
     const CMusicInfoTag* tag = g_infoManager.GetCurrentSongTag();
index 6b75961..ec08b19 100644 (file)
@@ -160,10 +160,10 @@ bool CCDDARipper::Rip(const CStdString& strTrackFile, const CStdString& strFile,
   {
     char tmp[MAX_PATH];
 #ifndef _LINUX
-    GetTempFileName(_P("special://temp/"), "riptrack", 0, tmp);
+    GetTempFileName(CSpecialProtocol::TranslatePath("special://temp/"), "riptrack", 0, tmp);
 #else
     int fd;
-    strncpy(tmp, _P("special://temp/riptrackXXXXXX"), MAX_PATH);
+    strncpy(tmp, CSpecialProtocol::TranslatePath("special://temp/riptrackXXXXXX"), MAX_PATH);
     if ((fd = mkstemp(tmp)) == -1)
       strFilename = "";
     close(fd);
index 2ebacb3..3c891cf 100644 (file)
@@ -175,7 +175,7 @@ bool CALSADirectSound::Initialize(IAudioCallback* pCallback, const CStdString& d
     if(deviceuse != device)
     {
       snd_input_t* input;
-      nErr = snd_input_stdio_open(&input, _P("special://xbmc/system/asound.conf").c_str(), "r");
+      nErr = snd_input_stdio_open(&input, CSpecialProtocol::TranslatePath("special://xbmc/system/asound.conf").c_str(), "r");
       if(nErr >= 0)
       {
         nErr = snd_config_load(config, input);
index 653370e..927e8ea 100644 (file)
   return new rendererClass(); \
 }
 
+/* windows channel order */
+static const enum PCMChannels dsound_default_channel_layout[][8] =
+{
+  {PCM_FRONT_CENTER},
+  {PCM_FRONT_LEFT, PCM_FRONT_RIGHT},
+  {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_LOW_FREQUENCY},
+  {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT},
+  {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT},
+  {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT},
+  {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_CENTER, PCM_BACK_LEFT, PCM_BACK_RIGHT},
+  {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_SIDE_LEFT, PCM_SIDE_RIGHT}
+};
+
 IAudioRenderer* CAudioRendererFactory::Create(IAudioCallback* pCallback, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic, IAudioRenderer::EEncoded encoded)
 {
   IAudioRenderer* audioSink = NULL;
   CStdString renderer;
 
+  if(channelMap == NULL)
+  {
+    CLog::Log(LOGINFO, "CAudioRendererFactory: no input channel map specified assume windows\n");
+    channelMap = (enum PCMChannels *)dsound_default_channel_layout[iChannels - 1];
+  }
+
   CStdString deviceString, device;
   if (encoded)
   {
index 1cd5d5d..f4f4430 100644 (file)
@@ -34,6 +34,7 @@
 #include "threads/Atomics.h"
 #include "windowing/WindowingFactory.h"
 #include "utils/log.h"
+#include "utils/SystemInfo.h"
 #include "utils/TimeUtils.h"
 
 const AudioChannelLabel g_LabelMap[] =
@@ -58,6 +59,8 @@ const AudioChannelLabel g_LabelMap[] =
   kAudioChannelLabel_TopBackCenter //  PCM_TOP_BACK_CENTER 
 };
 
+#define MAX_AUDIO_CHANNEL_LABEL kAudioChannelLabel_CenterSurroundDirect
+
 const AudioChannelLayoutTag g_LayoutMap[] = 
 {
   kAudioChannelLayoutTag_Stereo, // PCM_LAYOUT_2_0 = 0,
@@ -68,7 +71,7 @@ const AudioChannelLayoutTag g_LayoutMap[] =
   kAudioChannelLayoutTag_DVD_6, // PCM_LAYOUT_4_1,
   kAudioChannelLayoutTag_MPEG_5_0_A, // PCM_LAYOUT_5_0,
   kAudioChannelLayoutTag_MPEG_5_1_A, // PCM_LAYOUT_5_1,
-  kAudioChannelLayoutTag_AudioUnit_7_0, // PCM_LAYOUT_7_0, ** This layout may be incorrect...no content to testß˚ **
+  kAudioChannelLayoutTag_AudioUnit_7_0, // PCM_LAYOUT_7_0, ** This layout may be incorrect...no content to test **
   kAudioChannelLayoutTag_MPEG_7_1_A, // PCM_LAYOUT_7_1
 };
 
@@ -337,16 +340,153 @@ void CCoreAudioPerformance::Reset()
 //***********************************************************************************************
 // Surround Up/Down Mapping Class
 //***********************************************************************************************
+struct ChannelPatch
+{
+  AudioChannelLabel label; // Target Channel
+  Float32 coeff; // Output level
+};
+
+// TODO: There is not a lot of logic behind these mapping coefficients
+// Routings for Explicit Mapping. These are in priority order.
+// g_ChannelRoutings[channel][routing][patch]
+// These are currently all down-mix routings
+#define MAX_CHANNELS sizeof(g_LabelMap)/sizeof(AudioChannelLabel)
+#define NO_ROUTINGS {{{kAudioChannelLabel_Unknown, 0.0f}}}
+ChannelPatch g_ChannelRoutings[MAX_AUDIO_CHANNEL_LABEL+1][MAX_CHANNELS][MAX_CHANNELS] = 
+{
+  NO_ROUTINGS, // kAudioChannelLabel_Unknown (0)
+  // kAudioChannelLabel_Left (1)
+  {
+    {{kAudioChannelLabel_Center, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  // kAudioChannelLabel_Right (2)
+  {
+    {{kAudioChannelLabel_Center, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  // kAudioChannelLabel_Center (3)
+  {
+    {{kAudioChannelLabel_Left, 0.707f},{kAudioChannelLabel_Right, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  // kAudioChannelLabel_LFEScreen (4)
+  {
+    {{kAudioChannelLabel_Left, 0.707f},{kAudioChannelLabel_Right, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  // kAudioChannelLabel_LeftSurround (5)
+  {
+    {{kAudioChannelLabel_LeftSurroundDirect, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  // kAudioChannelLabel_RightSurround (6)
+  {
+    {{kAudioChannelLabel_RightSurroundDirect, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  // kAudioChannelLabel_LeftCenter (7)
+  {
+    {{kAudioChannelLabel_Center, 0.707f},{kAudioChannelLabel_Left, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  // kAudioChannelLabel_RightCenter (8)
+  {
+    {{kAudioChannelLabel_Center, 0.707f},{kAudioChannelLabel_Right, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  // kAudioChannelLabel_CenterSurround (9)
+  {
+    {{kAudioChannelLabel_LeftSurround, 0.707f},{kAudioChannelLabel_RightSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_LeftSurroundDirect, 0.707f},{kAudioChannelLabel_RightSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Left, 0.707f},{kAudioChannelLabel_Right, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  // kAudioChannelLabel_LeftSurroundDirect (10)
+  {
+    {{kAudioChannelLabel_LeftSurround, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_CenterSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_CenterSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },  
+  // kAudioChannelLabel_RightSurroundDirect (11)
+  {
+    {{kAudioChannelLabel_RightSurround, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_CenterSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_CenterSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  NO_ROUTINGS, //kAudioChannelLabel_TopCenterSurround (12)
+  NO_ROUTINGS, //kAudioChannelLabel_VerticalHeightLeft (13)
+  NO_ROUTINGS, //kAudioChannelLabel_VerticalHeightCenter (14)
+  NO_ROUTINGS, //kAudioChannelLabel_VerticalHeightRight (15)
+  NO_ROUTINGS, //kAudioChannelLabel_TopBackLeft (16)
+  NO_ROUTINGS, //kAudioChannelLabel_TopBackCenter (17)
+  NO_ROUTINGS, //kAudioChannelLabel_VerticalHeightRight (18)
+  NO_ROUTINGS, // INVALID LABEL (19)
+  NO_ROUTINGS, // INVALID LABEL (20)
+  NO_ROUTINGS, // INVALID LABEL (21)
+  NO_ROUTINGS, // INVALID LABEL (22)
+  NO_ROUTINGS, // INVALID LABEL (23)
+  NO_ROUTINGS, // INVALID LABEL (24)
+  NO_ROUTINGS, // INVALID LABEL (25)
+  NO_ROUTINGS, // INVALID LABEL (26)
+  NO_ROUTINGS, // INVALID LABEL (27)
+  NO_ROUTINGS, // INVALID LABEL (28)
+  NO_ROUTINGS, // INVALID LABEL (29)
+  NO_ROUTINGS, // INVALID LABEL (30)
+  NO_ROUTINGS, // INVALID LABEL (31)
+  NO_ROUTINGS, // INVALID LABEL (32)
+  // kAudioChannelLabel_RearSurroundLeft (33)
+  {
+    {{kAudioChannelLabel_LeftSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_LeftSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_CenterSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_CenterSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  // kAudioChannelLabel_RearSurroundRight (34)
+  {
+    {{kAudioChannelLabel_RightSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_RightSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_CenterSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_CenterSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}},
+    {{kAudioChannelLabel_Unknown, 0.0f}}
+  },
+  NO_ROUTINGS, // kAudioChannelLabel_LeftWide (35)
+  NO_ROUTINGS, // kAudioChannelLabel_RightWide (36)
+  NO_ROUTINGS, // kAudioChannelLabel_LFE2 (37)
+  NO_ROUTINGS, // kAudioChannelLabel_LeftTotal (38)
+  NO_ROUTINGS, // kAudioChannelLabel_RightTotal (39)
+  NO_ROUTINGS, // kAudioChannelLabel_HearingImpaired (40)
+  NO_ROUTINGS, // kAudioChannelLabel_Narration (41)
+  NO_ROUTINGS, // kAudioChannelLabel_Mono (42)
+  NO_ROUTINGS, // kAudioChannelLabel_DialogCentricMix (43)
+  NO_ROUTINGS // kAudioChannelLabel_CenterSurroundDirect (44)
+};
+
 CCoreAudioMixMap::CCoreAudioMixMap() :
   m_isValid(false)
 {
-  m_pMap = (Float32*)calloc(sizeof(AudioChannelLayout), 1);
+  m_pMap = (Float32*)calloc(sizeof(Float32), 2);
 }
 
-CCoreAudioMixMap::CCoreAudioMixMap(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout) :
+CCoreAudioMixMap::CCoreAudioMixMap(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout, bool forceExplicit/*=false*/) :
   m_isValid(false)
 {
-  Rebuild(inLayout, outLayout);
+  Rebuild(inLayout, outLayout, forceExplicit);
 }
 
 CCoreAudioMixMap::~CCoreAudioMixMap()
@@ -354,11 +494,10 @@ CCoreAudioMixMap::~CCoreAudioMixMap()
   if (m_pMap)
   {
     free(m_pMap);
-    m_pMap = NULL;
   }
 }
 
-void CCoreAudioMixMap::Rebuild(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout)
+void CCoreAudioMixMap::Rebuild(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout, bool forceExplicit/*=false*/)
 {
   // map[in][out] = mix-level of input_channel[in] into output_channel[out]
 
@@ -371,24 +510,116 @@ void CCoreAudioMixMap::Rebuild(AudioChannelLayout& inLayout, AudioChannelLayout&
   m_inChannels = CCoreAudioChannelLayout::GetChannelCountForLayout(inLayout);
   m_outChannels = CCoreAudioChannelLayout::GetChannelCountForLayout(outLayout);
   
-  // Try to find a 'well-known' matrix
-  const AudioChannelLayout* layouts[] = {&inLayout, &outLayout};
-  UInt32 propSize = 0;
-  OSStatus ret = AudioFormatGetPropertyInfo(kAudioFormatProperty_MatrixMixMap, sizeof(layouts), layouts, &propSize);
-  m_pMap = (Float32*)calloc(1,propSize);
-  
-  // Try and get a predefined mixmap
-  ret = AudioFormatGetProperty(kAudioFormatProperty_MatrixMixMap, sizeof(layouts), layouts, &propSize, m_pMap);
-  if (!ret)
+  // If the caller allows it, try to find a 'well-known' matrix
+  if (!forceExplicit)
   {
-    m_isValid = true;
-    return; // Nothing else to do...a map already exists
+    const AudioChannelLayout* layouts[] = {&inLayout, &outLayout};
+    UInt32 propSize = 0;
+    OSStatus ret = AudioFormatGetPropertyInfo(kAudioFormatProperty_MatrixMixMap, sizeof(layouts), layouts, &propSize);
+    m_pMap = (Float32*)calloc(1,propSize);
+    ret = AudioFormatGetProperty(kAudioFormatProperty_MatrixMixMap, sizeof(layouts), layouts, &propSize, m_pMap);
+    if (!ret)
+    {
+      m_isValid = true;
+      CLog::Log(LOGDEBUG, "CCoreAudioMixMap::Rebuild: Using pre-defined mixing matrix.");
+      return; // Nothing else to do...a map already exists
+    }
+    
+    // No predefined mixing matrix was available. Going to have to build it manually
+    CLog::Log(LOGDEBUG, "CCoreAudioMixMap::Rebuild: Unable to locate pre-defined mixing matrix. Trying to build one explicitly...");
   }
+  else
+    CLog::Log(LOGINFO, "CCoreAudioMixMap::Rebuild: Building explicit mixing matrix [forceExplicit=true]");
+  
+  // Try to build a mixing matrix from scratch
+  m_isValid = BuildExplicit(inLayout, outLayout);
+}
+
+bool CCoreAudioMixMap::BuildExplicit(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout)
+{
+  // Initialize map
+  // map[in][out] = mix-level of input_channel[in] into output_channel[out]
+  m_pMap = (Float32*)calloc(sizeof(Float32), inLayout.mNumberChannelDescriptions * outLayout.mNumberChannelDescriptions);
+  int mappedChannels = 0;
   
-  // No predefined mixmap was available. Going to have to build it manually
-  CLog::Log(LOGDEBUG, "CCoreAudioMixMap::CreateMap: Unable to locate pre-defined mixing matrix");
+  // Initialize array of output channel locations
+  int outPos[MAX_AUDIO_CHANNEL_LABEL + 1];
+  for (UInt32 i = 0; i < (MAX_AUDIO_CHANNEL_LABEL + 1); i++)
+    outPos[i] = -1;
   
-  m_isValid = false;
+  // Map output channel order to output layout
+  for (UInt32 channel = 0; channel < outLayout.mNumberChannelDescriptions; channel++)
+    outPos[outLayout.mChannelDescriptions[channel].mChannelLabel] = channel;
+  
+  CLog::Log(LOGDEBUG, "CCoreAudioMixMap::BuildExplicit: Building mixing matrix [%d input channels, %d output channels]", inLayout.mNumberChannelDescriptions, outLayout.mNumberChannelDescriptions);
+
+  // For each input channel, decide how to route/mix it
+  for (UInt32 channel = 0; channel < inLayout.mNumberChannelDescriptions; channel++)
+  {
+    AudioChannelDescription* pDesc = &inLayout.mChannelDescriptions[channel];
+    
+    if (pDesc->mChannelLabel > MAX_AUDIO_CHANNEL_LABEL)
+    {
+      CLog::Log(LOGINFO, "CCoreAudioMixMap::BuildExplicit:\tUnrecognized input channel encountered (label=%d) - skipping.", pDesc->mChannelLabel);
+      continue;
+    }
+    
+    // Does the channel exist in the output?
+    int outIndex = outPos[pDesc->mChannelLabel];
+    if (outIndex > -1) // If so, just pass it through
+    {
+      // map[in][out] = map[in * outCount + out]
+      CLog::Log(LOGDEBUG, "CCoreAudioMixMap::BuildExplicit:\tin[%d] -> out[%d] @ %0.02f", channel, outIndex, 1.0f);
+      m_pMap[channel * outLayout.mNumberChannelDescriptions + outIndex] = 1.0f;
+      mappedChannels++;
+    }
+    else // The input channel does not exist in the output layout. Decide where to route it...
+    {
+      // Loop through the pre-defined routings strategies for this channel. Use the first compatible one we find
+      for (UInt32 r = 0; r < MAX_CHANNELS; r++)
+      {
+        // If the first patch's label is kAudioChannelLabel_Unknown, this is the routing list terminator
+        if (g_ChannelRoutings[pDesc->mChannelLabel][r][0].label == kAudioChannelLabel_Unknown)
+          break; // No dice...
+        
+        // Check each patch in this routing to see if it is possible. If it is not, give up on this routing
+        bool validRouting = false;
+        for (UInt32 p = 0; ((p < MAX_CHANNELS) && !validRouting); p++)
+        {
+          ChannelPatch* patch = &g_ChannelRoutings[pDesc->mChannelLabel][r][p];
+          if (patch->label == kAudioChannelLabel_Unknown) // End of this routing
+            validRouting = true; // Success...this routing should work.          
+          else if (outPos[patch->label] == -1)
+            break; // The specified output channel is not available. Invalidate the whole routing
+        }
+        
+        // If this is a valid routing (all output channels are available), apply it...
+        if (validRouting)
+        {
+          for (UInt32 p = 0; p < MAX_CHANNELS; p++)
+          {
+            ChannelPatch* patch = &g_ChannelRoutings[pDesc->mChannelLabel][r][p];
+            if (patch->label == kAudioChannelLabel_Unknown) // List terminator
+              break;
+            
+            int outIndex = outPos[patch->label];
+            CLog::Log(LOGDEBUG, "CCoreAudioMixMap::BuildExplicit:\tin[%d] -> out[%d] @ %0.02f", channel, outIndex, patch->coeff);
+            m_pMap[channel * outLayout.mNumberChannelDescriptions + outIndex] = patch->coeff;
+            mappedChannels++;
+          }
+          break;
+        }
+      }
+    }
+  }
+  if (!mappedChannels)
+  {
+    CLog::Log(LOGINFO, "CCoreAudioMixMap::BuildExplicit: No valid patches found.");
+    return false;
+  }
+
+  CLog::Log(LOGINFO, "CCoreAudioMixMap::BuildExplicit: Completed explicit channel map.");
+  return true;
 }
 
 //***********************************************************************************************
@@ -977,7 +1208,7 @@ bool CCoreAudioRenderer::InitializePCM(UInt32 channels, UInt32 samplesPerSecond,
         hasLFE = true;
     }
     
-    // HACK: Fix broken channel layouts coming from some aac sources that include rear channel but no side channels.
+    // HACK: Fix broken channel layouts coming from some aac sources that include rear channels but no side channels.
     // 5.1 streams should include front and side channels. Rear channels are added by 6.1 and 7.1, so any 5.1 
     // source that claims to have rear channels is wrong.
     if (inputFormat.mChannelsPerFrame == 6 && hasLFE) // Check for 5.1 configuration (as best we can without getting too silly)
@@ -1010,7 +1241,15 @@ bool CCoreAudioRenderer::InitializePCM(UInt32 channels, UInt32 samplesPerSecond,
     
     // Get User-Configured (XBMC) Speaker Configuration
     AudioChannelLayout guiLayout;
-    guiLayout.mChannelLayoutTag = g_LayoutMap[(PCMLayout)g_guiSettings.GetInt("audiooutput.channellayout")];
+    if (g_sysinfo.IsAppleTV())
+    {
+      // Force ATV1 to a 2.0 layout (that is all it knows), since it does not provide a usable channel layout
+      CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: AppleTV detected - Forcing channel layout to 2.0 (max available PCM channels)");  
+      guiLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; 
+    }
+    else
+      guiLayout.mChannelLayoutTag = g_LayoutMap[(PCMLayout)g_guiSettings.GetInt("audiooutput.channellayout")];
+    
     CCoreAudioChannelLayout userLayout(guiLayout);
     CStdString strUserLayout;
     CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: User-Configured Speaker Layout: %s", CCoreAudioChannelLayout::ChannelLayoutToString(*(AudioChannelLayout*)userLayout, strUserLayout));  
@@ -1019,7 +1258,43 @@ bool CCoreAudioRenderer::InitializePCM(UInt32 channels, UInt32 samplesPerSecond,
     CCoreAudioChannelLayout deviceLayout;
     if (!m_AudioDevice.GetPreferredChannelLayout(deviceLayout))
       return false;
+        
+    // Detect devices with no Speaker Configuration
+    bool undefinedLayout = true;
+    for (UInt32 c = 0; c < deviceLayout.GetChannelCount(); c++)
+    {
+      // If this is a known channel, then we can't have an undefined layout
+      if (deviceLayout.GetChannelLabel(c) != kAudioChannelLabel_Unknown)
+      {
+        undefinedLayout = false;
+        break;
+      }
+    }
+    if (undefinedLayout)
+    {
+      AudioChannelLayoutTag newLayoutTag = kAudioChannelLayoutTag_UseChannelBitmap;
+      if (g_sysinfo.IsAppleTV()) // AppleTV is only Stereo
+        newLayoutTag = kAudioChannelLayoutTag_Stereo;
+      else  // AppleTV users cannot do this...
+      {
+        CLog::Log(LOGERROR, "CCoreAudioRenderer::InitializePCM: The selected device (%s) does not have a speaker layout configured. Using the default layout.", m_AudioDevice.GetName());
+        CLog::Log(LOGERROR, "CCoreAudioRenderer::InitializePCM: \tPlease go to Applications -> Utilities -> Audio MIDI Setup, and select 'Configure Speakers...'");
 
+        // Pick a default layout based on the number of channels
+        newLayoutTag = GetDefaultLayout(deviceLayout.GetChannelCount());
+        if (newLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) // Undefined, give up...
+        {
+          CLog::Log(LOGERROR, "CCoreAudioRenderer::InitializePCM: Unable to find a suitable default layout for this device.");
+          return false;
+        }
+      }
+      if (!deviceLayout.SetLayout(newLayoutTag))
+      {
+        CLog::Log(LOGERROR, "CCoreAudioRenderer::InitializePCM: Unable to set channel layout from tag.");
+        return false;        
+      }
+    }
+    
     CStdString strOutLayout;
     CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: Output Device Layout: %s", CCoreAudioChannelLayout::ChannelLayoutToString(*(AudioChannelLayout*)deviceLayout, strOutLayout));  
 
@@ -1036,7 +1311,7 @@ bool CCoreAudioRenderer::InitializePCM(UInt32 channels, UInt32 samplesPerSecond,
     //    if (CCoreAudioChannelLayout::GetChannelCountForLayout(guiLayout) < CCoreAudioChannelLayout::GetChannelCountForLayout(deviceLayout))
     //      deviceLayout.CopyLayout(guiLayout);
     
-    // TODO: Skip matrix mixer if input/output are compatible
+    // TODO: Skip matrix mixer if input/output are compatible -> Add a IsPurePassthrough() method to the CCoreAudioMixMap class
 
     AudioChannelLayout* layoutCandidates[] = {(AudioChannelLayout*)deviceLayout, (AudioChannelLayout*)userLayout, NULL};
 
@@ -1125,11 +1400,14 @@ bool CCoreAudioRenderer::InitializePCM(UInt32 channels, UInt32 samplesPerSecond,
     }
     else
     {
+      CLog::Log(LOGERROR, "CCoreAudioRenderer::InitializePCM: No matrix mixer configuration available - unmapped channels will be dropped");
       outputFormat = inputFormat; // We don't know how to map this...let CoreAudio handle it
     }    
   }
   else 
   {
+    if (allowMixing && !channelMap)
+      CLog::Log(LOGINFO, "CCoreAudioRenderer::InitializePCM: No channel map provided - extra channels will be dropped");
     outputFormat = inputFormat;
   }
   
@@ -1327,6 +1605,33 @@ void CCoreAudioRenderer::OnResetDevice()
     }
   }
 }
+
+AudioChannelLayoutTag CCoreAudioRenderer::GetDefaultLayout(UInt32 channelCount)
+{
+  switch(channelCount)
+  {
+    case 1:    
+      return kAudioChannelLayoutTag_Mono; // 1.0 
+    case 2:    
+      return kAudioChannelLayoutTag_Stereo; // 2.0
+    case 3:    
+      return kAudioChannelLayoutTag_DVD_4; // 2.1
+    case 4:    
+      return kAudioChannelLayoutTag_DVD_10; // 3.1
+    case 5:    
+      return kAudioChannelLayoutTag_DVD_6; // 4.1
+    case 6:    
+      return kAudioChannelLayoutTag_MPEG_5_1_A; // 5.1
+    case 7:
+      return kAudioChannelLayoutTag_AudioUnit_7_0; // 7.0
+    case 8:    
+      return kAudioChannelLayoutTag_MPEG_7_1_A; // 7.1
+    case 0:    
+    default:
+      return kAudioChannelLayoutTag_UseChannelBitmap; // Basically 'Undefined'
+  }
+}
+
 #endif
 #endif
 
index 7d653c3..3b06a51 100644 (file)
@@ -104,15 +104,16 @@ class CCoreAudioMixMap
 {
 public:
   CCoreAudioMixMap();
-  CCoreAudioMixMap(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout);
+  CCoreAudioMixMap(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout, bool forceExplicit=false);
   virtual ~CCoreAudioMixMap();
   operator Float32*() const {return m_pMap;} 
   const Float32* GetBuffer() {return m_pMap;}
   UInt32 GetInputChannels() {return m_inChannels;}
   UInt32 GetOutputChannels() {return m_outChannels;}  
   bool IsValid() {return m_isValid;}
-  void Rebuild(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout);
+  void Rebuild(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout, bool forceExplicit=false);
 private:
+  bool BuildExplicit(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout);
   Float32* m_pMap;
   UInt32 m_inChannels;
   UInt32 m_outChannels;
@@ -164,8 +165,7 @@ private:
   bool InitializePCM(UInt32 channels, UInt32 samplesPerSecond, UInt32 bitsPerSample, enum PCMChannels *channelMap, bool allowMixing = true);
   bool InitializePCMEncoded(UInt32 sampleRate);
   
-  bool CreateMixMap();
-  
+  AudioChannelLayoutTag GetDefaultLayout(UInt32 channelCount);
   static OSStatus HardwareListenerProc(AudioHardwarePropertyID property, void *clientref);
   static OSStatus DeviceListenerProc(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *clientref);
 
index 48399b0..1ac8732 100644 (file)
@@ -87,12 +87,8 @@ bool CWin32DirectSound::Initialize(IAudioCallback* pCallback, const CStdString&
 {
   m_uiDataChannels = iChannels;
 
-  if(!bAudioPassthrough)
+  if(!bAudioPassthrough && channelMap)
   {
-    //If no channel map is specified, use the default.
-    if(!channelMap)
-      channelMap = (PCMChannels *)dsound_default_channel_layout[iChannels - 1];
-
     PCMChannels *outLayout = m_remap.SetInputFormat(iChannels, channelMap, uiBitsPerSample / 8, uiSamplesPerSec);
 
     for(iChannels = 0; outLayout[iChannels] != PCM_INVALID;) ++iChannels;
index e7faeca..d5b383a 100644 (file)
@@ -107,12 +107,8 @@ bool CWin32WASAPI::Initialize(IAudioCallback* pCallback, const CStdString& devic
 
   int layoutChannels = 0;
 
-  if(!bAudioPassthrough)
+  if(!bAudioPassthrough && channelMap)
   {
-    //If no channel map is specified, use the default.
-    if(!channelMap)
-      channelMap = (PCMChannels *)wasapi_default_channel_layout[iChannels - 1];
-
     PCMChannels *outLayout = m_remap.SetInputFormat(iChannels, channelMap, uiBitsPerSample / 8, uiSamplesPerSec);
 
     for(PCMChannels *channel = outLayout; *channel != PCM_INVALID; channel++)
@@ -418,7 +414,7 @@ unsigned int CWin32WASAPI::AddPackets(const void* data, unsigned int len)
 {
   CSingleLock lock (m_critSection);
 
-  if (!m_bIsAllocated)
+  if (!m_bIsAllocated || m_bPause)
     return 0;
 
   DWORD dwFlags = m_bMuting || m_nCurrentVolume == VOLUME_MINIMUM ? AUDCLNT_BUFFERFLAGS_SILENT : 0; 
index 3d0c2e1..b7b23e1 100644 (file)
@@ -156,7 +156,7 @@ int DllLoader::Parse()
   int iResult = 0;
 
   CStdString strFileName= GetFileName();
-  FILE* fp = fopen_utf8(_P(strFileName).c_str(), "rb");
+  FILE* fp = fopen_utf8(CSpecialProtocol::TranslatePath(strFileName).c_str(), "rb");
 
   if (fp)
   {
index e201074..97bbd37 100644 (file)
@@ -43,7 +43,7 @@ bool SoLoader::Load()
   if (m_soHandle != NULL)
     return true;
 
-  CStdString strFileName= _P(GetFileName());
+  CStdString strFileName= CSpecialProtocol::TranslatePath(GetFileName());
   int flags = RTLD_LAZY;
   if (m_bGlobal) flags |= RTLD_GLOBAL;
   if (strFileName == "xbmc.so")
index a7af019..a7e17a9 100644 (file)
@@ -158,7 +158,7 @@ bool Win32DllLoader::Load()
   CStdString strFileName = GetFileName();
 
   CStdStringW strDllW;
-  g_charsetConverter.utf8ToW(_P(strFileName), strDllW);
+  g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(strFileName), strDllW);
   m_dllHandle = LoadLibraryExW(strDllW.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
   if (!m_dllHandle)
   {
@@ -166,7 +166,7 @@ bool Win32DllLoader::Load()
     DWORD dw = GetLastError(); 
 
     FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, 0, (LPTSTR) &lpMsgBuf, 0, NULL );
-    CLog::Log(LOGERROR, "%s: Failed to load %s with error %d:%s", __FUNCTION__, _P(strFileName).c_str(), dw, lpMsgBuf);
+    CLog::Log(LOGERROR, "%s: Failed to load %s with error %d:%s", __FUNCTION__, CSpecialProtocol::TranslatePath(strFileName).c_str(), dw, lpMsgBuf);
     LocalFree(lpMsgBuf);
     return false;
   }
@@ -234,7 +234,7 @@ bool Win32DllLoader::HasSymbols()
 void Win32DllLoader::OverrideImports(const CStdString &dll)
 {
   CStdStringW strdllW;
-  g_charsetConverter.utf8ToW(_P(dll), strdllW, false);
+  g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(dll), strdllW, false);
   BYTE* image_base = (BYTE*)GetModuleHandleW(strdllW.c_str());
 
   if (!image_base)
@@ -329,7 +329,7 @@ bool Win32DllLoader::NeedsHooking(const char *dllName)
     }
   }
   CStdStringW strdllNameW;
-  g_charsetConverter.utf8ToW(_P(dllName), strdllNameW, false);
+  g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(dllName), strdllNameW, false);
   HMODULE hModule = GetModuleHandleW(strdllNameW.c_str());
   wchar_t filepathW[MAX_PATH];
   GetModuleFileNameW(hModule, filepathW, MAX_PATH);
@@ -337,9 +337,9 @@ bool Win32DllLoader::NeedsHooking(const char *dllName)
   g_charsetConverter.wToUTF8(filepathW, dllPath);
 
   // compare this filepath with some special directories
-  CStdString xbmcPath = _P("special://xbmc");
-  CStdString homePath = _P("special://home");
-  CStdString tempPath = _P("special://temp");
+  CStdString xbmcPath = CSpecialProtocol::TranslatePath("special://xbmc");
+  CStdString homePath = CSpecialProtocol::TranslatePath("special://home");
+  CStdString tempPath = CSpecialProtocol::TranslatePath("special://temp");
   return ((strncmp(xbmcPath.c_str(), dllPath.c_str(), xbmcPath.GetLength()) == 0) ||
     (strncmp(homePath.c_str(), dllPath.c_str(), homePath.GetLength()) == 0) ||
     (strncmp(tempPath.c_str(), dllPath.c_str(), tempPath.GetLength()) == 0));
index fd7ef79..dee70c1 100644 (file)
@@ -277,6 +277,7 @@ extern "C" DWORD WINAPI dllGetModuleFileNameA(HMODULE hModule, LPSTR lpFilename,
   if (sName)
   {
     strncpy(lpFilename, sName, nSize);
+    lpFilename[nSize] = 0;
     return strlen(lpFilename);
   }
 
index 13a23e2..0493bb7 100644 (file)
@@ -168,12 +168,12 @@ extern "C" HANDLE WINAPI dllFindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA
 #ifdef _WIN32
   struct _WIN32_FIND_DATAW FindFileDataW;
   CStdStringW strwfile;
-  g_charsetConverter.utf8ToW(_P(p), strwfile, false);
+  g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(p), strwfile, false);
   HANDLE res = FindFirstFileW(strwfile.c_str(), &FindFileDataW);
   if (res != INVALID_HANDLE_VALUE)
     to_WIN32_FIND_DATA(&FindFileDataW, lpFindFileData);
 #else
-  HANDLE res = FindFirstFile(_P(p).c_str(), lpFindFileData);
+  HANDLE res = FindFirstFile(CSpecialProtocol::TranslatePath(p).c_str(), lpFindFileData);
 #endif
   free(p);
   return res;
@@ -891,7 +891,11 @@ extern "C" int WINAPI dllMultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCST
     destinationBuffer = (LPWSTR)malloc(destinationBufferSize * sizeof(WCHAR));
   }
 
+#ifdef _WIN32
   int ret = MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, destinationBuffer, destinationBufferSize);
+#else
+  int ret = 0;
+#endif
 
   if (ret > 0)
   {
@@ -929,7 +933,11 @@ extern "C" int WINAPI dllWideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWS
     destinationBuffer = (LPSTR)malloc(destinationBufferSize * sizeof(char));
   }
 
+#ifdef _WIN32
   int ret = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, destinationBuffer, destinationBufferSize, lpDefaultChar, lpUsedDefaultChar);
+#else
+  int ret = 0;
+#endif
 
   if (ret > 0)
   {
@@ -986,7 +994,7 @@ extern "C" HANDLE WINAPI dllCreateFileA(
     IN HANDLE hTemplateFile
     )
 {
-  return CreateFileA(_P(lpFileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
+  return CreateFileA(CSpecialProtocol::TranslatePath(lpFileName), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
 }
 
 extern "C" BOOL WINAPI dllLockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOffBytesToLockLow, DWORD nNumberOffBytesToLockHigh)
index 2fbeb31..076862d 100644 (file)
@@ -148,15 +148,23 @@ extern "C" void __stdcall init_emu_environ()
   {
     // using external python, it's build looking for xxx/lib/python2.6
     // so point it to frameworks which is where python2.6 is located
-    dll_putenv(string("PYTHONPATH=" + _P("special://frameworks")).c_str());
-    dll_putenv(string("PYTHONHOME=" + _P("special://frameworks")).c_str());
-    dll_putenv(string("PATH=.;" + _P("special://xbmc") + ";" + _P("special://frameworks")).c_str());
+    dll_putenv(string("PYTHONPATH=" +
+      CSpecialProtocol::TranslatePath("special://frameworks")).c_str());
+    dll_putenv(string("PYTHONHOME=" +
+      CSpecialProtocol::TranslatePath("special://frameworks")).c_str());
+    dll_putenv(string("PATH=.;" +
+      CSpecialProtocol::TranslatePath("special://xbmc") + ";" +
+      CSpecialProtocol::TranslatePath("special://frameworks")).c_str());
   }
   else
   {
-    dll_putenv(string("PYTHONPATH=" + _P("special://xbmc/system/python/DLLs") + ";" + _P("special://xbmc/system/python/Lib")).c_str());
-    dll_putenv(string("PYTHONHOME=" + _P("special://xbmc/system/python")).c_str());
-    dll_putenv(string("PATH=.;" + _P("special://xbmc") + ";" + _P("special://xbmc/system/python")).c_str());
+    dll_putenv(string("PYTHONPATH=" +
+      CSpecialProtocol::TranslatePath("special://xbmc/system/python/DLLs") + ";" +
+      CSpecialProtocol::TranslatePath("special://xbmc/system/python/Lib")).c_str());
+    dll_putenv(string("PYTHONHOME=" +
+      CSpecialProtocol::TranslatePath("special://xbmc/system/python")).c_str());
+    dll_putenv(string("PATH=.;" + CSpecialProtocol::TranslatePath("special://xbmc") + ";" +
+      CSpecialProtocol::TranslatePath("special://xbmc/system/python")).c_str());
   }
   //dll_putenv("PYTHONCASEOK=1");
   //dll_putenv("PYTHONDEBUG=1");
@@ -528,7 +536,7 @@ extern "C"
     else if (!IS_STD_STREAM(stream))
     {
       // Translate the path
-      return freopen(_P(path).c_str(), mode, stream);
+      return freopen(CSpecialProtocol::TranslatePath(path).c_str(), mode, stream);
     }
 
     // error
@@ -768,7 +776,7 @@ extern "C"
   {
     char str[1024];
     int size = sizeof(str);
-    CURL url(_P(file));
+    CURL url(CSpecialProtocol::TranslatePath(file));
     if (url.IsLocal())
     {
       // move to CFile classes
@@ -792,7 +800,7 @@ extern "C"
       // Make sure the slashes are correct & translate the path
       struct _wfinddata64i32_t wdata;
       CStdStringW strwfile;
-      g_charsetConverter.utf8ToW(CUtil::ValidatePath(_P(str)), strwfile, false);
+      g_charsetConverter.utf8ToW(CUtil::ValidatePath(CSpecialProtocol::TranslatePath(str)), strwfile, false);
       intptr_t ret = _wfindfirst64i32(strwfile.c_str(), &wdata);
       if (ret != -1)
         to_finddata64i32(&wdata, data);
@@ -928,7 +936,7 @@ extern "C"
 
   DIR *dll_opendir(const char *file)
   {
-    CURL url(_P(file));
+    CURL url(CSpecialProtocol::TranslatePath(file));
     if (url.IsLocal())
     { // Make sure the slashes are correct & translate the path
       return opendir(CUtil::ValidatePath(url.Get().c_str()));
@@ -1892,7 +1900,7 @@ extern "C"
     if (!dir) return -1;
 
     // Make sure the slashes are correct & translate the path
-    CStdString strPath = CUtil::ValidatePath(_P(dir));
+    CStdString strPath = CUtil::ValidatePath(CSpecialProtocol::TranslatePath(dir));
 #ifndef _LINUX
     CStdStringW strWPath;
     g_charsetConverter.utf8ToW(strPath, strWPath, false);
@@ -1928,7 +1936,12 @@ extern "C"
 
         memcpy(var, envstring, value_start - envstring);
         var[value_start - envstring] = 0;
-        strupr(var);
+        char* temp = var;
+        while (*temp)
+        {
+          *temp = (char)toupper(*temp);
+          temp++;
+        }
 
         strncpy(value, value_start + 1, size);
         if (size)
index 5f3722b..0558099 100644 (file)
  *
  */
 
-#ifdef _XBOX
-#include <xtl.h>
-#endif
-
 #define SOCK_RAW 3
 
 #define EAFNOSUPPORT WSAEAFNOSUPPORT
@@ -40,21 +36,6 @@ struct mphostent {
          char **h_addr_list; /* list of addresses      from name server */
 };
 
-#ifdef _XBOX
-typedef struct servent {
-               char FAR* s_name;
-               char FAR  FAR** s_aliases;
-               short s_port;
-               char FAR* s_proto;
-} servent;
-
-typedef struct protoent {
-               char FAR* p_name;
-               char FAR  FAR** p_aliases;
-               short p_proto;
-} protoent;
-#endif
-
 #ifndef IN_MULTICAST
 #define IN_MULTICAST(i)            (((i) & 0xf0000000U) == 0xe0000000U)
 #endif
index 5f0e429..3cd8b1b 100644 (file)
  *   in ai_flags?
  */
 
-#ifdef _XBOX
-#include <xtl.h>
-#include <winsockx.h>
-#else
 #include <windows.h>
-#endif
 #include <stddef.h>
 #include "addrinfo.h"
 #include "emu_socket.h"
 #include <stdio.h>
 #include <errno.h>
 
-#ifdef _XBOX
-extern struct mphostent* __stdcall dllgethostbyname(const char* name);
-#define gethostbyname(name) dllgethostbyname(name)
-
-extern struct mphostent* __stdcall dllgethostbyaddr(const char* addr, int len, int type);
-#define gethostbyaddr(addr, len, type) dllgethostbyaddr(addr, len, type)
-
-extern struct servent* __stdcall dllgetservbyname(const char* name, const char* proto);
-#define getservbyname(name, proto) dllgetservbyname(name, proto)
-
-#define hostent mphostent
-#endif
-
 #ifndef HAVE_U_INT32_T
 #include "bittypes.h"
 #endif
@@ -333,18 +315,10 @@ getaddrinfo(const char*hostname, const char*servname,
                                pai->ai_socktype = SOCK_STREAM;
                                break;
                        default:
-#ifdef _XBOX
-                               pai->ai_socktype = SOCK_STREAM;
-#else
                                pai->ai_socktype = SOCK_RAW;
-#endif //_XBOX
                                break;
                        }
                        break;
-#ifndef _XBOX
-               case SOCK_RAW:
-                       break;
-#endif //_XBOX
                case SOCK_DGRAM:
                        if (pai->ai_protocol != IPPROTO_UDP &&
                            pai->ai_protocol != GAI_ANY)
index 0c8f426..0df482a 100644 (file)
  *   modified).
  */
 
-#ifdef _XBOX
-#include <xtl.h>
-#include <winsockx.h>
-#else
 #include <windows.h>
-#endif
 #include <stddef.h>
 #include "addrinfo.h"
 #include "emu_socket.h"
 #include <stdio.h>
 #include <errno.h>
 
-#ifdef _XBOX
-extern struct mphostent* __stdcall dllgethostbyname(const char* name);
-#define gethostbyname(name) dllgethostbyname(name)
-
-extern struct mphostent* __stdcall dllgethostbyaddr(const char* addr, int len, int type);
-#define gethostbyaddr(addr, len, type) dllgethostbyaddr(addr, len, type)
-#endif
-
 extern struct servent* __stdcall dllgetservbyname(const char* name, const char* proto);
 #define getservbyname(name, proto) dllgetservbyname(name, proto)
 
index 37406ac..8b36786 100644 (file)
@@ -30,7 +30,7 @@
 #include "dialogs/GUIDialogOK.h"
 #include "guilib/GUIWindowManager.h"
 #include "Application.h"
-#include "filesystem/FileMusicDatabase.h"
+#include "filesystem/MusicDatabaseFile.h"
 #include "FileItem.h"
 #include "utils/RegExp.h"
 #include "utils/StringUtils.h"
@@ -149,7 +149,7 @@ void CExternalPlayer::Process()
       archiveContent = url.GetFileName();
     }
     if (protocol == "musicdb")
-      mainFile = CFileMusicDatabase::TranslateUrl(url);
+      mainFile = CMusicDatabaseFile::TranslateUrl(url);
   }
 
   if (m_filenameReplacers.size() > 0) 
index 8172750..3bade02 100644 (file)
@@ -439,7 +439,9 @@ void CLinuxRendererGL::LoadPlane( YUVPLANE& plane, int type, unsigned flipindex
   if(currPbo)
     glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, currPbo);
 
-  glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
+  int bps = glFormatElementByteCount(type);
+
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / bps);
   glBindTexture(m_textureTarget, plane.id);
   glTexSubImage2D(m_textureTarget, 0, 0, 0, width, height, type, GL_UNSIGNED_BYTE, data);
 
@@ -454,7 +456,7 @@ void CLinuxRendererGL::LoadPlane( YUVPLANE& plane, int type, unsigned flipindex
     glTexSubImage2D( m_textureTarget, 0
                    , width, 0, 1, height
                    , type, GL_UNSIGNED_BYTE
-                   , (unsigned char*)data + stride - 1);
+                   , (unsigned char*)data + bps * (width-1));
 
   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
   glBindTexture(m_textureTarget, 0);
@@ -1917,12 +1919,12 @@ void CLinuxRendererGL::UploadNV12Texture(int source)
     // Load Odd UV Fields
     LoadPlane( fields[FIELD_TOP][1], GL_LUMINANCE_ALPHA, buf.flipindex
              , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1)
-             , im->stride[1], im->plane[1] );
+             , im->stride[1]*2, im->plane[1] );
 
     // Load Even UV Fields
     LoadPlane( fields[FIELD_BOT][1], GL_LUMINANCE_ALPHA, buf.flipindex
              , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1)
-             , im->stride[1], im->plane[1] + im->stride[1] );
+             , im->stride[1]*2, im->plane[1] + im->stride[1] );
 
   }
   else
@@ -1935,7 +1937,7 @@ void CLinuxRendererGL::UploadNV12Texture(int source)
     // Load UV plane
     LoadPlane( fields[FIELD_FULL][1], GL_LUMINANCE_ALPHA, buf.flipindex
              , im->width >> im->cshift_x, im->height >> im->cshift_y
-             , im->stride[1]/2, im->plane[1] );
+             , im->stride[1], im->plane[1] );
   }
 
   m_eventTexturesDone[source]->Set();
@@ -2380,18 +2382,18 @@ void CLinuxRendererGL::UploadYUV422PackedTexture(int source)
     // Load YUYV fields
     LoadPlane( fields[FIELD_TOP][0], GL_BGRA, buf.flipindex
              , im->width / 2, im->height >> 1
-             , im->stride[0] / 2, im->plane[0] );
+             , im->stride[0] * 2, im->plane[0] );
 
     LoadPlane( fields[FIELD_BOT][0], GL_BGRA, buf.flipindex
              , im->width / 2, im->height >> 1
-             , im->stride[0] / 2, im->plane[0] + im->stride[0]) ;
+             , im->stride[0] * 2, im->plane[0] + im->stride[0]) ;
   }
   else
   {
     // Load YUYV plane
     LoadPlane( fields[FIELD_FULL][0], GL_BGRA, buf.flipindex
              , im->width / 2, im->height
-             , im->stride[0] / 4, im->plane[0] );
+             , im->stride[0], im->plane[0] );
   }
 
   m_eventTexturesDone[source]->Set();
@@ -2862,17 +2864,17 @@ void CLinuxRendererGL::UploadRGBTexture(int source)
   {
     LoadPlane( fields[FIELD_TOP][0] , GL_BGRA, buf.flipindex
              , im->width, im->height >> 1
-             , m_sourceWidth, m_rgbBuffer, &m_rgbPbo );
+             , m_sourceWidth*4, m_rgbBuffer, &m_rgbPbo );
 
     LoadPlane( fields[FIELD_BOT][0], GL_BGRA, buf.flipindex
              , im->width, im->height >> 1
-             , m_sourceWidth, m_rgbBuffer + m_sourceWidth*m_sourceHeight*2, &m_rgbPbo );
+             , m_sourceWidth*4, m_rgbBuffer + m_sourceWidth*m_sourceHeight*2, &m_rgbPbo );
   }
   else
   {
     LoadPlane( fields[FIELD_FULL][0], GL_BGRA, buf.flipindex
              , im->width, im->height
-             , m_sourceWidth, m_rgbBuffer, &m_rgbPbo );
+             , m_sourceWidth*4, m_rgbBuffer, &m_rgbPbo );
   }
 
   //after using the pbo to upload, allocate a new buffer so we don't have to wait
index 6af7ebf..8d5aec5 100644 (file)
@@ -326,27 +326,20 @@ void CLinuxRendererGLES::LoadPlane( YUVPLANE& plane, int type, unsigned flipinde
     return;
 
   const GLvoid *pixelData = data;
-  char *pixelVector = NULL;
 
-  // OpenGL ES does not support strided texture input. Make a copy without stride
-  if(stride != width)
-  {
-    pixelVector = (char *)malloc(width * height * width);
-    
-    const char *src = (const char *)data;
-    char *dst = pixelVector;
-    for (int y = 0;y < height;++y)
-    {
-      fast_memcpy(dst, src, width);
-      src += stride;
-      dst += width;
-    }
-    pixelData = pixelVector;
-    stride = width;
-  }
+  int bps = glFormatElementByteCount(type);
 
   glBindTexture(m_textureTarget, plane.id);
-  glTexSubImage2D(m_textureTarget, 0, 0, 0, width, height, type, GL_UNSIGNED_BYTE, pixelData);
+
+  // OpenGL ES does not support strided texture input.
+  if(stride != width * bps)
+  {
+    unsigned char* src = (unsigned char*)data;
+    for (int y = 0; y < height;++y, src += stride)
+      glTexSubImage2D(m_textureTarget, 0, 0, y, width, 1, type, GL_UNSIGNED_BYTE, src);
+  } else {
+    glTexSubImage2D(m_textureTarget, 0, 0, 0, width, height, type, GL_UNSIGNED_BYTE, pixelData);
+  }
 
   /* check if we need to load any border pixels */
   if(height < plane.texheight)
@@ -359,14 +352,11 @@ void CLinuxRendererGLES::LoadPlane( YUVPLANE& plane, int type, unsigned flipinde
     glTexSubImage2D( m_textureTarget, 0
                    , width, 0, 1, height
                    , type, GL_UNSIGNED_BYTE
-                   , (unsigned char*)pixelData + stride - 1);
+                   , (unsigned char*)pixelData + bps * (width-1));
 
   glBindTexture(m_textureTarget, 0);
 
   plane.flipindex = flipindex;
-
-  if(pixelVector)
-    free(pixelVector);
 }
 
 void CLinuxRendererGLES::Reset()
@@ -1369,17 +1359,17 @@ void CLinuxRendererGLES::UploadYV12Texture(int source)
     {
       LoadPlane( fields[FIELD_TOP][0] , GL_RGBA, buf.flipindex
                , im->width, im->height >> 1
-               , m_sourceWidth*2, m_rgbBuffer );
+               , m_sourceWidth*8, m_rgbBuffer );
 
       LoadPlane( fields[FIELD_BOT][0], GL_RGBA, buf.flipindex
                , im->width, im->height >> 1
-               , m_sourceWidth*2, m_rgbBuffer + m_sourceWidth*4);      
+               , m_sourceWidth*8, m_rgbBuffer + m_sourceWidth*4);      
     }
     else
     {
       LoadPlane( fields[FIELD_FULL][0], GL_RGBA, buf.flipindex
                , im->width, im->height
-               , m_sourceWidth, m_rgbBuffer );
+               , m_sourceWidth*4, m_rgbBuffer );
     }
   }
   else
index a1a37d0..5fbc6ca 100644 (file)
@@ -62,24 +62,7 @@ static void LoadTexture(GLenum target
   char *pixelVector = NULL;
   const GLvoid *pixelData = pixels;
 
-  int bytesPerPixel;
-  switch (externalFormat)
-  {
-#ifndef HAS_GLES
-  case GL_BGRA:
-#endif
-  case GL_RGBA:
-    bytesPerPixel = 4;
-    break;
-#ifndef HAS_GLES
-  case GL_BGR:
-#endif
-  case GL_RGB:
-    bytesPerPixel = 3;
-    break;
-  default:
-    bytesPerPixel = 1;
-  }
+  int bytesPerPixel = glFormatElementByteCount(externalFormat);
 
 #ifdef HAS_GLES
   /** OpenGL ES does not support strided texture input. Make a copy without stride **/
index 7da5eab..b917860 100644 (file)
@@ -103,6 +103,7 @@ CXBMCRenderManager::CXBMCRenderManager()
   m_presentmethod = PRESENT_METHOD_SINGLE;
   m_bReconfigured = false;
   m_hasCaptures = false;
+  m_displayLatency = 0.0f;
 }
 
 CXBMCRenderManager::~CXBMCRenderManager()
@@ -320,6 +321,8 @@ unsigned int CXBMCRenderManager::PreInit()
 #endif
   }
 
+  UpdateDisplayLatency();
+
   return m_pRenderer->PreInit();
 }
 
@@ -712,6 +715,17 @@ void CXBMCRenderManager::Recover()
 #if defined(HAS_GL) && !defined(TARGET_DARWIN)
   glFlush(); // attempt to have gpu done with pixmap and vdpau
 #endif
+
+  UpdateDisplayLatency();
+}
+
+void CXBMCRenderManager::UpdateDisplayLatency()
+{
+  float refresh = g_graphicsContext.GetFPS();
+  if (g_graphicsContext.GetVideoResolution() == RES_WINDOW)
+    refresh = 0; // No idea about refresh rate when windowed, just get the default latency
+  m_displayLatency = (double) g_advancedSettings.GetDisplayLatency(refresh);
+  CLog::Log(LOGDEBUG, "CRenderManager::UpdateDisplayLatency - Latency set to %1.0f msec", m_displayLatency * 1000.0f);
 }
 
 void CXBMCRenderManager::UpdateResolution()
index 961b19f..7f8dbce 100644 (file)
@@ -108,6 +108,7 @@ public:
   float GetMaximumFPS();
   inline bool Paused() { return m_bPauseDrawing; };
   inline bool IsStarted() { return m_bIsStarted;}
+  double GetDisplayLatency() { return m_displayLatency; }
 
   bool Supports(ERENDERFEATURE feature)
   {
@@ -216,6 +217,8 @@ protected:
     PRESENT_METHOD_BOB,
   };
 
+  double m_displayLatency;
+  void UpdateDisplayLatency();
 
   double     m_presenttime;
   double     m_presentcorr;
index fa9f68a..3044187 100644 (file)
@@ -25,7 +25,9 @@
 #include "settings/AdvancedSettings.h"
 #include "guilib/TransformMatrix.h"
 #include "utils/log.h"
+#if defined(HAS_GL) || defined(HAS_GLES)
 #include "utils/GLUtils.h"
+#endif
 
 #include <string>
 #include <sstream>
index 8ff4a12..55d29a6 100644 (file)
@@ -131,13 +131,14 @@ void CWinRenderer::ManageTextures()
 
 void CWinRenderer::SelectRenderMethod()
 {
+  // Set rendering to dxva before trying it, in order to open the correct processor immediately, when deinterlacing method is auto.
+
   // Force dxva renderer after dxva decoding: PS and SW renderers have performance issues after dxva decode.
   if (g_advancedSettings.m_DXVAForceProcessorRenderer && CONF_FLAGS_FORMAT_MASK(m_flags) == CONF_FLAGS_FORMAT_DXVA)
   {
     CLog::Log(LOGNOTICE, "D3D: rendering method forced to DXVA2 processor");
-    if (m_processor.Open(m_sourceWidth, m_sourceHeight, m_flags, m_format))
-        m_renderMethod = RENDER_DXVA;
-    else
+    m_renderMethod = RENDER_DXVA;
+    if (!m_processor.Open(m_sourceWidth, m_sourceHeight, m_flags, m_format))
     {
       CLog::Log(LOGNOTICE, "D3D: unable to open DXVA2 processor");
       m_processor.Close();
@@ -151,11 +152,9 @@ void CWinRenderer::SelectRenderMethod()
     switch(m_iRequestedMethod)
     {
       case RENDER_METHOD_DXVA:
+        m_renderMethod = RENDER_DXVA;
         if (m_processor.Open(m_sourceWidth, m_sourceHeight, m_flags, m_format))
-        {
-            m_renderMethod = RENDER_DXVA;
             break;
-        }
         else
         {
           CLog::Log(LOGNOTICE, "D3D: unable to open DXVA2 processor");
index 1dd1e78..1db47cf 100644 (file)
@@ -72,7 +72,7 @@ public:
     memcpy(alpha          , src.alpha          , sizeof(alpha));
     memcpy(color          , src.color          , sizeof(color));
     memcpy(highlight_alpha, src.highlight_alpha, sizeof(highlight_alpha));
-    memcpy(highlight_color, src.highlight_alpha, sizeof(highlight_color));
+    memcpy(highlight_color, src.highlight_color, sizeof(highlight_color));
   }
 
   BYTE result[2*65536 + 20]; // rle data
index ae107a6..2a6d958 100644 (file)
@@ -23,6 +23,8 @@
 #if defined(_WIN32)
 #include "WIN32Util.h"
 #include "util.h"
+#include "dialogs/GUIDialogKaiToast.h"
+#include "guilib/LocalizeStrings.h"
 #endif
 
 #if defined(HAVE_LIBCRYSTALHD)
@@ -1104,9 +1106,8 @@ CCrystalHD::CCrystalHD() :
 #if (HAVE_LIBCRYSTALHD == 2)
     if (m_device && m_new_lib)
     {
-      BCM::BC_INFO_CRYSTAL bc_info_crystal;
-      m_dll->DtsCrystalHDVersion(m_device, &bc_info_crystal);
-      m_has_bcm70015 = (bc_info_crystal.device == 1);
+      m_dll->DtsCrystalHDVersion(m_device, (BCM::PBC_INFO_CRYSTAL)&m_bc_info_crystal);
+      m_has_bcm70015 = (m_bc_info_crystal.device == 1);
       // bcm70012 can do nv12 (420), yuy2 (422) and uyvy (422)
       // bcm70015 can do only yuy2 (422)
       if (m_has_bcm70015)
@@ -1229,6 +1230,22 @@ bool CCrystalHD::OpenDecoder(CRYSTALHD_CODEC_TYPE codec_type, CDVDStreamInfo &hi
   if (!m_device)
     return false;
 
+#if (HAVE_LIBCRYSTALHD == 2) && defined(TARGET_WINDOWS)
+  // Drivers prior to 3.6.9.32 don't have proper support for CRYSTALHD_CODEC_ID_AVC1
+  // The internal version numbers are different for some reason...
+  if (   (m_bc_info_crystal.dilVersion.dilRelease < 3)
+      || (m_bc_info_crystal.dilVersion.dilRelease == 3 && m_bc_info_crystal.dilVersion.dilMajor < 22)
+      || (m_bc_info_crystal.drvVersion.drvRelease < 3)
+      || (m_bc_info_crystal.drvVersion.drvRelease == 3 && m_bc_info_crystal.drvVersion.drvMajor < 7) )
+  {
+    CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, "CrystalHD", g_localizeStrings.Get(2101));
+    CLog::Log(LOGWARNING, "CrystalHD drivers too old, please upgrade to 3.6.9 or later. Make sure to uninstall the old version first or the upgrade won't work.");
+
+    if (codec_type == CRYSTALHD_CODEC_ID_AVC1)
+      return false;
+  }
+#endif
+
   uint32_t videoAlg = 0;
   switch (codec_type)
   {
index b30f269..6f104f2 100644 (file)
@@ -99,6 +99,46 @@ enum _CRYSTALHD_CODEC_TYPES
 };
 
 typedef uint32_t CRYSTALHD_CODEC_TYPE;
+
+#if (HAVE_LIBCRYSTALHD == 2)
+
+  typedef struct _BC_INFO_CRYSTAL_ {
+         uint8_t device;
+         union {
+                 struct {
+                         uint32_t dilRelease:8;
+                         uint32_t dilMajor:8;
+                         uint32_t dilMinor:16;
+                 };
+                 uint32_t version;
+         } dilVersion;
+
+         union {
+                 struct {
+                         uint32_t drvRelease:4;
+                         uint32_t drvMajor:8;
+                         uint32_t drvMinor:12;
+                         uint32_t drvBuild:8;
+                 };
+                 uint32_t version;
+         } drvVersion;
+
+         union {
+                 struct {
+                         uint32_t fwRelease:4;
+                         uint32_t fwMajor:8;
+                         uint32_t fwMinor:12;
+                         uint32_t fwBuild:8;
+                 };
+                 uint32_t version;
+         } fwVersion;
+
+         uint32_t Reserved1; // For future expansion
+         uint32_t Reserved2; // For future expansion
+  } BC_INFO_CRYSTAL, *PBC_INFO_CRYSTAL;
+
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////////////////
 
 #define CRYSTALHD_FIELD_FULL        0x00
@@ -163,6 +203,9 @@ protected:
 
   CMPCOutputThread *m_pOutputThread;
   CSyncPtrQueue<CPictureBuffer> m_BusyList;
+#if (HAVE_LIBCRYSTALHD == 2)
+  BC_INFO_CRYSTAL m_bc_info_crystal;
+#endif
 
 private:
   CCrystalHD();
index a90b557..b4e1451 100644 (file)
@@ -449,8 +449,8 @@ int CDVDVideoCodecFFmpeg::Decode(BYTE* pData, int iSize, double dts, double pts)
   avpkt.flags = AV_PKT_FLAG_KEY;
   len = m_dllAvCodec.avcodec_decode_video2(m_pCodecContext, m_pFrame, &iGotPicture, &avpkt);
 
-  if(m_iLastKeyframe < m_pCodecContext->has_b_frames + 1)
-    m_iLastKeyframe = m_pCodecContext->has_b_frames + 1;
+  if(m_iLastKeyframe < m_pCodecContext->has_b_frames + 2)
+    m_iLastKeyframe = m_pCodecContext->has_b_frames + 2;
 
   if (len < 0)
   {
@@ -464,12 +464,20 @@ int CDVDVideoCodecFFmpeg::Decode(BYTE* pData, int iSize, double dts, double pts)
   if (!iGotPicture)
     return VC_BUFFER;
 
-  if(m_pFrame->key_frame || m_pCodecContext->codec_id == CODEC_ID_H264) /* h264 doesn't always have keyframes + won't output before first keyframe anyway */
+  if(m_pFrame->key_frame)
   {
     m_started = true;
-    m_iLastKeyframe = m_pCodecContext->has_b_frames + 1;
+    m_iLastKeyframe = m_pCodecContext->has_b_frames + 2;
   }
 
+  /* put a limit on convergence count to avoid huge mem usage on streams without keyframes */
+  if(m_iLastKeyframe > 300)
+    m_iLastKeyframe = 300;
+
+  /* h264 doesn't always have keyframes + won't output before first keyframe anyway */
+  if(m_pCodecContext->codec_id == CODEC_ID_H264)
+    m_started = true;
+
   if(m_pCodecContext->pix_fmt != PIX_FMT_YUV420P
   && m_pCodecContext->pix_fmt != PIX_FMT_YUVJ420P
   && m_pHardware == NULL)
index 5b6ce25..0238864 100644 (file)
@@ -781,10 +781,11 @@ bool CDVDVideoCodecVDA::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
         m_max_ref_frames = 2;
     }
 
-    if (hints.profile == 77 && hints.level == 32 && (m_max_ref_frames > 4))
+    if (hints.profile == FF_PROFILE_H264_MAIN && hints.level == 32 && m_max_ref_frames > 4)
     {
       // Main@L3.2, VDA cannot handle greater than 4 reference frames
       CLog::Log(LOGNOTICE, "%s - Main@L3.2 detected, VDA cannot decode.", __FUNCTION__);
+      CFRelease(avcCData);
       return false;
     }
  
@@ -1000,7 +1001,7 @@ int CDVDVideoCodecVDA::Decode(BYTE* pData, int iSize, double dts, double pts)
     }
   }
 
-  if (!m_queue_depth || m_queue_depth < m_max_ref_frames)
+  if (m_queue_depth < m_max_ref_frames)
   {
     return VC_BUFFER;
   }
index 31b07ee..a78b1b8 100644 (file)
@@ -1192,20 +1192,22 @@ bool CDVDVideoCodecVideoToolBox::Open(CDVDStreamInfo &hints, CDVDCodecOptions &o
       break;
     }
 
-    if (profile == 77 && level == 32 && m_max_ref_frames > 4)
+    if(m_fmt_desc == NULL)
+    {
+      CLog::Log(LOGNOTICE, "%s - created avcC atom of failed", __FUNCTION__);
+      m_pFormatName = "";
+      return false;
+    }
+
+    if (profile == FF_PROFILE_H264_MAIN && level == 32 && m_max_ref_frames > 4)
     {
       // Main@L3.2, VTB cannot handle greater than 4 ref frames (ie. flash video)
       CLog::Log(LOGNOTICE, "%s - Main@L3.2 detected, VTB cannot decode with %d ref frames",
         __FUNCTION__, m_max_ref_frames);
+      CFRelease(m_fmt_desc);
       return false;
     }
  
-    if(m_fmt_desc == NULL)
-    {
-      CLog::Log(LOGNOTICE, "%s - created avcC atom of failed", __FUNCTION__);
-      m_pFormatName = "";
-      return false;
-    }
     if (m_max_ref_frames == 0)
       m_max_ref_frames = 2;
 
@@ -1385,7 +1387,7 @@ int CDVDVideoCodecVideoToolBox::Decode(BYTE* pData, int iSize, double dts, doubl
 
   // TODO: queue depth is related to the number of reference frames in encoded h.264.
   // so we need to buffer until we get N ref frames + 1.
-  if (!m_queue_depth || m_queue_depth < m_max_ref_frames)
+  if (m_queue_depth < m_max_ref_frames)
     return VC_BUFFER;
 
   return VC_PICTURE | VC_BUFFER;
index 5b6c035..0961eff 100644 (file)
@@ -249,6 +249,22 @@ static DWORD VP3DeviceID [] = {
   0x0000
 };
 
+typedef struct {
+    DWORD VendorID;
+    DWORD DeviceID;
+} pci_device;
+
+// List of devices that drop frames with a deinterlacing processor for progressive material.
+static const pci_device NoDeintProcForProgDevices[] = {
+  { PCIV_nVidia, 0x0865 }, // ION
+  { PCIV_nVidia, 0x0874 }, // ION
+  { PCIV_nVidia, 0x0876 }, // ION
+  { PCIV_nVidia, 0x087D }, // ION
+  { PCIV_nVidia, 0x087E }, // ION LE
+  { PCIV_nVidia, 0x087F }, // ION LE
+  { 0          , 0x0000 }
+};
+
 static CStdString GUIDToString(const GUID& guid)
 {
   CStdString buffer;
@@ -1151,6 +1167,19 @@ bool CProcessor::Open(UINT width, UINT height, unsigned int flags, unsigned int
       return false;
   }
 
+  // frame flags are not available to do the complete calculation of the deinterlacing mode, as done in Render()
+  // It's OK, as it doesn't make any difference for all hardware except the few GPUs on the quirk list.
+  // And for those GPUs, the correct values will be calculated with the first Render() and the correct processor
+  // will replace the one allocated here, before the user sees anything.
+  // It's a bit inefficient, that's all.
+  m_deinterlace_mode = g_settings.m_currentVideoSettings.m_DeinterlaceMode;
+  m_interlace_method = g_renderManager.AutoInterlaceMethod(g_settings.m_currentVideoSettings.m_InterlaceMethod);;
+
+  EvaluateQuirkNoDeintProcForProg();
+
+  if (g_advancedSettings.m_DXVANoDeintProcForProgressive || m_quirk_nodeintprocforprog)
+    CLog::Log(LOGNOTICE, "DXVA: Auto deinterlacing mode workaround activated. Deinterlacing processor will be used only for interlaced frames.");
+
   if (!OpenProcessor())
     return false;
 
@@ -1159,6 +1188,22 @@ bool CProcessor::Open(UINT width, UINT height, unsigned int flags, unsigned int
   return true;
 }
 
+void CProcessor::EvaluateQuirkNoDeintProcForProg()
+{
+  D3DADAPTER_IDENTIFIER9 AIdentifier = g_Windowing.GetAIdentifier();
+
+  for (unsigned idx = 0; NoDeintProcForProgDevices[idx].VendorID != 0; idx++)
+  {
+    if(NoDeintProcForProgDevices[idx].VendorID == AIdentifier.VendorId
+    && NoDeintProcForProgDevices[idx].DeviceID == AIdentifier.DeviceId)
+    {
+      m_quirk_nodeintprocforprog = true;
+      return;
+    }
+  }
+  m_quirk_nodeintprocforprog = false;
+}
+
 bool CProcessor::SelectProcessor()
 {
   // The CProcessor can be run after dxva or software decoding, possibly after software deinterlacing.
@@ -1409,12 +1454,18 @@ bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFEREN
 {
   CSingleLock lock(m_section);
 
+  // With auto deinterlacing, the Ion Gen. 1 drops some frames with deinterlacing processor + progressive flags for progressive material.
+  // For that GPU (or when specified by an advanced setting), use the progressive processor.
+  // This is at the expense of the switch speed when video interlacing flags change and a deinterlacing processor is actually required.
+  EDEINTERLACEMODE mode = g_settings.m_currentVideoSettings.m_DeinterlaceMode;
+  if (g_advancedSettings.m_DXVANoDeintProcForProgressive || m_quirk_nodeintprocforprog)
+    mode = (flags & RENDER_FLAG_FIELD0 || flags & RENDER_FLAG_FIELD1) ? VS_DEINTERLACEMODE_FORCE : VS_DEINTERLACEMODE_OFF;
   EINTERLACEMETHOD method = g_renderManager.AutoInterlaceMethod(g_settings.m_currentVideoSettings.m_InterlaceMethod);
   if(m_interlace_method != method
-  || m_deinterlace_mode != g_settings.m_currentVideoSettings.m_DeinterlaceMode
+  || m_deinterlace_mode != mode
   || !m_process)
   {
-    m_deinterlace_mode = g_settings.m_currentVideoSettings.m_DeinterlaceMode;
+    m_deinterlace_mode = mode;
     m_interlace_method = method;
 
     if (!OpenProcessor())
@@ -1479,7 +1530,7 @@ bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFEREN
       // Override the sample format when the processor doesn't need to deinterlace or when deinterlacing is forced and flags are missing.
       if (m_progressive)
         vs.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
-      else if (g_settings.m_currentVideoSettings.m_DeinterlaceMode == VS_DEINTERLACEMODE_FORCE && vs.SampleFormat.SampleFormat == DXVA2_SampleProgressiveFrame)
+      else if (m_deinterlace_mode == VS_DEINTERLACEMODE_FORCE && vs.SampleFormat.SampleFormat == DXVA2_SampleProgressiveFrame)
         vs.SampleFormat.SampleFormat = DXVA2_SampleFieldInterleavedEvenFirst;
 
       valid++;
index 7af28c7..db7b040 100644 (file)
@@ -137,6 +137,7 @@ protected:
   bool CreateSurfaces();
   bool OpenProcessor();
   bool SelectProcessor();
+  void EvaluateQuirkNoDeintProcForProg();
 
   IDirectXVideoProcessorService* m_service;
   IDirectXVideoProcessor*        m_process;
@@ -171,6 +172,8 @@ protected:
 
   LPDIRECT3DSURFACE9* m_surfaces;
   CSurfaceContext* m_context;
+
+  bool             m_quirk_nodeintprocforprog;
 };
 
 };
index 867f4a7..ea1f0bd 100644 (file)
@@ -413,9 +413,11 @@ int CVDPAU::Check(AVCodecContext* avctx)
     if (!m_DisplayEvent.WaitMSec(2000))
     {
       CLog::Log(LOGERROR, "CVDPAU::Check - device didn't reset in reasonable time");
-      return VC_ERROR;
+      state = VDPAU_RESET;
     }
-    { CSharedLock lock(m_DisplaySection);
+    else
+    {
+      CSharedLock lock(m_DisplaySection);
       state = m_DisplayState;
     }
   }
@@ -1612,7 +1614,10 @@ bool CVDPAU::CheckStatus(VdpStatus vdp_st, int line)
     if(m_DisplayState == VDPAU_OPEN)
     {
       if (vdp_st == VDP_STATUS_DISPLAY_PREEMPTED)
+      {
+        m_DisplayEvent.Reset();
         m_DisplayState = VDPAU_LOST;
+      }
       else
         m_DisplayState = VDPAU_ERROR;
     }
index ee49fac..46287a8 100644 (file)
@@ -1190,7 +1190,7 @@ void CDVDDemuxFFmpeg::AddStream(int iId)
 
 std::string CDVDDemuxFFmpeg::GetFileName()
 {
-  if(m_pInput && m_pInput)
+  if(m_pInput)
     return m_pInput->GetFileName();
   else
     return "";
index 8cc4898..3235fb8 100644 (file)
@@ -202,7 +202,9 @@ bool CDVDFileInfo::ExtractThumb(const CStdString &strPath, const CStdString &str
         {
           {
             int nWidth = g_advancedSettings.m_thumbSize;
-            double aspect = (double)picture.iWidth / (double)picture.iHeight;
+            double aspect = (double)picture.iDisplayWidth / (double)picture.iDisplayHeight;
+            if(hint.forced_aspect && hint.aspect != 0)
+              aspect = hint.aspect;
             int nHeight = (int)((double)g_advancedSettings.m_thumbSize / aspect);
 
             DllSwScale dllSwScale;
index 812fbd4..77ffda6 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "DVDInputStreamHttp.h"
 #include "URL.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 
 using namespace XFILE;
 
@@ -55,7 +55,7 @@ bool CDVDInputStreamHttp::Open(const char* strFile, const std::string& content)
 {
   if (!CDVDInputStream::Open(strFile, content)) return false;
 
-  m_pFile = new CFileCurl();
+  m_pFile = new CCurlFile();
   if (!m_pFile) return false;
 
   std::string filename = strFile;
index 603e034..e868374 100644 (file)
@@ -26,7 +26,7 @@
 
 namespace XFILE
 {
-  class CFileCurl;
+  class CCurlFile;
 }
 
 class CDVDInputStreamHttp : public CDVDInputStream
@@ -44,7 +44,7 @@ public:
   CHttpHeader* GetHttpHeader();
 
 protected:
-  XFILE::CFileCurl* m_pFile;
+  XFILE::CCurlFile* m_pFile;
   CHttpHeader m_httpHeader;
   bool m_eof;
 };
index 5ed50a9..30a02a8 100644 (file)
@@ -22,7 +22,7 @@
 #include "DVDInputStreamTV.h"
 #include "filesystem/MythFile.h"
 #include "filesystem/VTPFile.h"
-#include "filesystem/Slingbox.h"
+#include "filesystem/SlingboxFile.h"
 #include "URL.h"
 
 using namespace XFILE;
index 5f2c1da..89863e3 100644 (file)
  *
  */
 
+#if (defined HAVE_CONFIG_H) && (!defined WIN32)
+  #include "config.h"
+#endif
+#ifdef _WIN32
+#include "system.h"
+#endif
+
 #include "DllDvdNav.h"
 #include "tinyXML/tinyxml.h"
 
index 052cc46..3f6fc09 100644 (file)
@@ -2433,7 +2433,7 @@ void CDVDPlayer::GetGeneralInfo(CStdString& strGeneralInfo)
 {
   if (!m_bStop)
   {
-    double dDelay = (double)m_dvdPlayerVideo.GetDelay() / DVD_TIME_BASE;
+    double dDelay = m_dvdPlayerVideo.GetDelay() / DVD_TIME_BASE - g_renderManager.GetDisplayLatency();
 
     double apts = m_dvdPlayerAudio.GetCurrentPts();
     double vpts = m_dvdPlayerVideo.GetCurrentPts();
@@ -2740,7 +2740,10 @@ bool CDVDPlayer::OpenVideoStream(int iStream, int source)
     /* set aspect ratio as requested by navigator for dvd's */
     float aspect = static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->GetVideoAspectRatio();
     if(aspect != 0.0)
+    {
       hint.aspect = aspect;
+      hint.forced_aspect = true;
+    }
     hint.software = true;
     hint.stills   = static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->IsInMenu();
   }
@@ -2807,7 +2810,7 @@ bool CDVDPlayer::OpenSubtitleStream(int iStream, int source)
     {
       CLog::Log(LOGNOTICE, "Opening Subtitle file: %s", st.filename.c_str());
       auto_ptr<CDVDDemuxVobsub> demux(new CDVDDemuxVobsub());
-      if(!demux->Open(st.filename))
+      if(!demux->Open(st.filename, st.filename2))
         return false;
       m_pSubtitleDemuxer = demux.release();
     }
@@ -3304,14 +3307,12 @@ bool CDVDPlayer::OnAction(const CAction &action)
       switch (action.GetID())
       {
       case ACTION_NEXT_ITEM:
-      case ACTION_PAGE_UP:
         THREAD_ACTION(action);
         CLog::Log(LOGDEBUG, " - pushed next in menu, stream will decide");
         pStream->OnNext();
         g_infoManager.SetDisplayAfterSeek();
         return true;
       case ACTION_PREV_ITEM:
-      case ACTION_PAGE_DOWN:
         THREAD_ACTION(action);
         CLog::Log(LOGDEBUG, " - pushed prev in menu, stream will decide");
         pStream->OnPrevious();
@@ -3414,14 +3415,12 @@ bool CDVDPlayer::OnAction(const CAction &action)
     switch (action.GetID())
     {
       case ACTION_NEXT_ITEM:
-      case ACTION_PAGE_UP:
         m_messenger.Put(new CDVDMsg(CDVDMsg::PLAYER_CHANNEL_NEXT));
         g_infoManager.SetDisplayAfterSeek();
         return true;
       break;
 
       case ACTION_PREV_ITEM:
-      case ACTION_PAGE_DOWN:
         m_messenger.Put(new CDVDMsg(CDVDMsg::PLAYER_CHANNEL_PREV));
         g_infoManager.SetDisplayAfterSeek();
         return true;
@@ -3442,7 +3441,6 @@ bool CDVDPlayer::OnAction(const CAction &action)
   switch (action.GetID())
   {
     case ACTION_NEXT_ITEM:
-    case ACTION_PAGE_UP:
       if(GetChapterCount() > 0)
       {
         m_messenger.Put(new CDVDMsgPlayerSeekChapter(GetChapter()+1));
@@ -3452,7 +3450,6 @@ bool CDVDPlayer::OnAction(const CAction &action)
       else
         break;
     case ACTION_PREV_ITEM:
-    case ACTION_PAGE_DOWN:
       if(GetChapterCount() > 0)
       {
         m_messenger.Put(new CDVDMsgPlayerSeekChapter(GetChapter()-1));
@@ -3612,6 +3609,7 @@ int CDVDPlayer::AddSubtitleFile(const std::string& filename, const std::string&
     m_SelectionStreams.Update(NULL, &v);
     int index = m_SelectionStreams.IndexOf(STREAM_SUBTITLE, m_SelectionStreams.Source(STREAM_SOURCE_DEMUX_SUB, filename), 0);
     m_SelectionStreams.Get(STREAM_SUBTITLE, index).flags = flags;
+    m_SelectionStreams.Get(STREAM_SUBTITLE, index).filename2 = vobsubfile;
     return index;
   }
   if(ext == ".sub")
index 15e11d2..e28faaf 100644 (file)
@@ -1111,8 +1111,8 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
     pts -= DVD_TIME_BASE * interval;
   }
 
-  //User set delay
-  pts += m_iVideoDelay;
+  // Correct pts by user set delay and rendering delay
+  pts += m_iVideoDelay - DVD_SEC_TO_TIME(g_renderManager.GetDisplayLatency());
 
   // calculate the time we need to delay this picture before displaying
   double iSleepTime, iClockSleep, iFrameSleep, iPlayingClock, iCurrentClock, iFrameDuration;
index a932b5f..3a896a3 100644 (file)
@@ -64,7 +64,7 @@ CDVDSubtitlesLibass::CDVDSubtitlesLibass()
   CLog::Log(LOGINFO, "CDVDSubtitlesLibass: Initializing ASS library font settings");
   // libass uses fontconfig (system lib) which is not wrapped
   //  so translate the path before calling into libass
-  m_dll.ass_set_fonts_dir(m_library,  _P(strPath).c_str());
+  m_dll.ass_set_fonts_dir(m_library,  CSpecialProtocol::TranslatePath(strPath).c_str());
   m_dll.ass_set_extract_fonts(m_library, 1);
   m_dll.ass_set_style_overrides(m_library, NULL);
 
@@ -86,7 +86,7 @@ CDVDSubtitlesLibass::CDVDSubtitlesLibass()
 
   // libass uses fontconfig (system lib) which is not wrapped
   //  so translate the path before calling into libass
-  m_dll.ass_set_fonts(m_renderer, _P(strPath).c_str(), "Arial", fc, NULL, 1);
+  m_dll.ass_set_fonts(m_renderer, CSpecialProtocol::TranslatePath(strPath).c_str(), "Arial", fc, NULL, 1);
 }
 
 
index 1e6ce3f..ae02e4f 100644 (file)
@@ -182,6 +182,8 @@ bool CEdl::ReadEdl(const CStdString& strMovie, const float fFramesPerSecond)
     if (bError)
       CLog::Log(LOGWARNING, "%s - Error on line %i in EDL file: %s", __FUNCTION__, iLine, edlFilename.c_str());
 
+    bError = false;
+
     iLine++;
 
     CStdStringArray strFields(2);
index 8b3ca68..bc30c63 100644 (file)
 #include "URL.h"
 #include "DVDPlayerCodec.h"
 #include "BXAcodec.h" 
+#include "PCMCodec.h"
 
 ICodec* CodecFactory::CreateCodec(const CStdString& strFileType)
 {
   if (strFileType.Equals("mp3") || strFileType.Equals("mp2"))
     return new MP3Codec();
+  else if (strFileType.Equals("pcm") || strFileType.Equals("l16"))
+    return new PCMCodec();
   else if (strFileType.Equals("ape") || strFileType.Equals("mac"))
     return new DVDPlayerCodec();
   else if (strFileType.Equals("cdda"))
@@ -117,6 +120,12 @@ ICodec* CodecFactory::CreateCodecDemux(const CStdString& strFile, const CStdStri
   if( strContent.Equals("audio/mpeg")
   ||  strContent.Equals("audio/mp3") )
     return new MP3Codec();
+  else if (strContent.Left(9).Equals("audio/l16"))
+  {
+    PCMCodec * pcm_codec = new PCMCodec();
+    pcm_codec->SetMimeParams(strContent);
+    return pcm_codec;
+  }
   else if( strContent.Equals("audio/aac")
     || strContent.Equals("audio/aacp") )
   {
index 3a7adaa..035cabd 100644 (file)
@@ -17,6 +17,7 @@ SRCS=ADPCMCodec.cpp \
      OggCallback.cpp \
      OGGcodec.cpp \
      PAPlayer.cpp \
+     PCMCodec.cpp \
      ReplayGain.cpp \
      SIDCodec.cpp \
      TimidityCodec.cpp \
diff --git a/xbmc/cores/paplayer/PCMCodec.cpp b/xbmc/cores/paplayer/PCMCodec.cpp
new file mode 100644 (file)
index 0000000..19cedf1
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *      Copyright (C) 2011-2012 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "PCMCodec.h"
+#include "utils/log.h"
+#include "utils/EndianSwap.h"
+#include "utils/StringUtils.h"
+
+PCMCodec::PCMCodec()
+{
+  m_CodecName = "PCM";
+  m_TotalTime = 0;
+  m_SampleRate = 44100;
+  m_Channels = 2;
+  m_BitsPerSample = 16;
+  m_Bitrate = m_SampleRate * m_Channels * m_BitsPerSample;
+}
+
+PCMCodec::~PCMCodec()
+{
+  DeInit();
+}
+
+bool PCMCodec::Init(const CStdString &strFile, unsigned int filecache)
+{
+  m_file.Close();
+  if (!m_file.Open(strFile, READ_CACHED))
+  {
+    CLog::Log(LOGERROR, "PCMCodec::Init - Failed to open file");
+    return false;
+  }
+
+  int64_t length = m_file.GetLength();
+
+  if (m_Bitrate)
+    m_TotalTime = 1000 * 8 * length / m_Bitrate;
+
+  m_file.Seek(0, SEEK_SET);
+
+  return true;
+}
+
+void PCMCodec::DeInit()
+{
+  m_file.Close();
+}
+
+__int64 PCMCodec::Seek(__int64 iSeekTime)
+{
+  m_file.Seek((iSeekTime / 1000) * (m_Bitrate / 8));
+  return iSeekTime;
+}
+
+int PCMCodec::ReadPCM(BYTE *pBuffer, int size, int *actualsize)
+{
+  *actualsize = 0;
+
+  int iAmountRead = m_file.Read(pBuffer, 2 * (size / 2));
+  if (iAmountRead > 0)
+  {
+    uint16_t *buffer = (uint16_t*) pBuffer;
+
+    iAmountRead = 2 * (iAmountRead / 2);
+
+    for (int i = 0; i < (iAmountRead / 2); i++)
+      buffer[i] = Endian_SwapBE16(buffer[i]);   // L16 PCM is in network byte order (Big Endian)
+
+    *actualsize = iAmountRead;
+
+    return READ_SUCCESS;
+  }
+  return READ_ERROR;
+}
+
+bool PCMCodec::CanInit()
+{
+  return true;
+}
+
+void PCMCodec::SetMimeParams(const CStdString& strMimeParams)
+{
+  CStdStringArray mimeParams;
+
+  // if there are no parameters, the default is 2 channels, 44100 samples/sec
+  m_Channels = 2;
+  m_SampleRate = 44100;
+
+  StringUtils::SplitString(strMimeParams, ";", mimeParams);
+  for (size_t i = 0; i < mimeParams.size(); i++)
+  {
+    CStdStringArray thisParam;
+    StringUtils::SplitString(mimeParams[i], "=", thisParam, 2);
+    if (thisParam.size() > 1)
+    {
+      if (thisParam[0] == "rate")
+      {
+        m_SampleRate = atoi(thisParam[1].Trim());
+      }
+      else if (thisParam[0] == "channels")
+      {
+        m_Channels = atoi(thisParam[1].Trim());
+      }
+    }
+  }
+
+  m_Bitrate = m_SampleRate * m_Channels * m_BitsPerSample;
+}
diff --git a/xbmc/cores/paplayer/PCMCodec.h b/xbmc/cores/paplayer/PCMCodec.h
new file mode 100644 (file)
index 0000000..6175fa5
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *      Copyright (C) 2011-2012 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include "CachingCodec.h"
+
+class PCMCodec : public CachingCodec
+{
+public:
+  PCMCodec(void);
+  virtual ~PCMCodec(void);
+  virtual bool Init(const CStdString &strFile, unsigned int filecache);
+  virtual void DeInit();
+  virtual __int64 Seek(__int64 iSeekTime);
+  virtual int ReadPCM(BYTE *pBuffer, int size, int *actualsize);
+  virtual bool CanInit();
+  virtual void SetMimeParams(const CStdString& strMimeParams);
+private:
+  int iBytesPerSecond;
+};
+
+
index 6d08a98..15bbfa7 100644 (file)
@@ -114,7 +114,7 @@ bool TimidityCodec::Init(const CStdString &strFile, unsigned int filecache)
     url.Parse(file);
   }
 
-  m_mid = m_dll.LoadMID(_P(url.Get()).c_str());
+  m_mid = m_dll.LoadMID(CSpecialProtocol::TranslatePath(url.Get()).c_str());
   if (!m_mid)
   {
     CLog::Log(LOGERROR,"TimidityCodec: error opening file %s: %s",strFile.c_str(), m_dll.ErrorMsg());
index 5cacd05..1f7575a 100644 (file)
@@ -48,6 +48,7 @@ void CPlayerSelectionRule::Initialize(TiXmlElement* pRule)
   m_tAudio = GetTristate(pRule->Attribute("audio"));
   m_tVideo = GetTristate(pRule->Attribute("video"));
 
+  m_tBD = GetTristate(pRule->Attribute("bd"));
   m_tDVD = GetTristate(pRule->Attribute("dvd"));
   m_tDVDFile = GetTristate(pRule->Attribute("dvdfile"));
   m_tDVDImage = GetTristate(pRule->Attribute("dvdimage"));
@@ -111,6 +112,7 @@ void CPlayerSelectionRule::GetPlayers(const CFileItem& item, VECPLAYERCORES &vec
   if (m_tVideo >= 0 && (m_tVideo > 0) != item.IsVideo()) return;
   if (m_tInternetStream >= 0 && (m_tInternetStream > 0) != item.IsInternetStream()) return;
 
+  if (m_tBD >= 0 && (m_tBD > 0) != (item.IsBDFile() && item.IsOnDVD())) return;
   if (m_tDVD >= 0 && (m_tDVD > 0) != item.IsDVD()) return;
   if (m_tDVDFile >= 0 && (m_tDVDFile > 0) != item.IsDVDFile()) return;
   if (m_tDVDImage >= 0 && (m_tDVDImage > 0) != item.IsDVDImage()) return;
index 7896ab3..ad3c61f 100644 (file)
@@ -49,6 +49,7 @@ private:
   int m_tVideo;
   int m_tInternetStream;
 
+  int m_tBD;
   int m_tDVD;
   int m_tDVDFile;
   int m_tDVDImage;
index f2aa1d8..bf35173 100644 (file)
@@ -278,7 +278,7 @@ bool CDatabase::Open(const DatabaseSettings &settings)
   else
   {
     dbSettings.type = "sqlite3";
-    dbSettings.host = _P(g_settings.GetDatabaseFolder());
+    dbSettings.host = CSpecialProtocol::TranslatePath(g_settings.GetDatabaseFolder());
     dbSettings.name = GetBaseDBName();
   }
 
index 14c1c49..8a72933 100644 (file)
@@ -258,7 +258,7 @@ int MysqlDatabase::copy(const char *backup_name) {
               backup_name, row[0], row[0]);
 
       if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
-        throw DbErrors("Can't copy data for table '%s'\nError: %s", db.c_str(), ret);
+        throw DbErrors("Can't copy data for table '%s'\nError: %s", row[0], ret);
     }
   }
 
@@ -1198,9 +1198,9 @@ MYSQL* MysqlDataset::handle(){
 void MysqlDataset::make_query(StringList &_sql) {
   string query;
   int result = 0;
+  if (db == NULL) throw DbErrors("No Database Connection");
   try
   {
-    if (db == NULL) throw DbErrors("No Database Connection");
     if (autocommit) db->start_transaction();
 
     for (list<string>::iterator i =_sql.begin(); i!=_sql.end(); i++)
index 9d4fa8a..1833d6f 100644 (file)
@@ -272,7 +272,7 @@ int SqliteDatabase::copy(const char *backup_name) {
   if (active == false)
     throw DbErrors("Can't copy database: no active connection...");
 
-  CLog::Log(LOGDEBUG, "Copying from %s to %s at %s", backup_name, db.c_str(), host.c_str());
+  CLog::Log(LOGDEBUG, "Copying from %s to %s at %s", db.c_str(), backup_name, host.c_str());
 
   int rc;
   string backup_db = backup_name;
@@ -444,10 +444,10 @@ sqlite3* SqliteDataset::handle(){
 
 void SqliteDataset::make_query(StringList &_sql) {
   string query;
+  if (db == NULL) throw DbErrors("No Database Connection");
 
  try {
 
-  if (db == NULL) throw DbErrors("No Database Connection");
   if (autocommit) db->start_transaction();
 
 
index 64d9337..ffbe20f 100644 (file)
@@ -95,7 +95,6 @@ bool CGUIDialogMediaSource::OnMessage(CGUIMessage& message)
   case GUI_MSG_WINDOW_INIT:
     {
       m_confirmed = false;
-      m_bRunScan = false;
       m_bNameChanged=false;
       UpdateButtons();
     }
@@ -149,16 +148,6 @@ bool CGUIDialogMediaSource::ShowAndAddMediaSource(const CStdString &type)
       share.m_strThumbnailImage = dialog->m_paths->Get(0)->GetThumbnailImage();
     }
     g_settings.AddShare(type, share);
-
-    if (type == "video")
-    {
-      if (dialog->m_bRunScan)
-      {
-        CGUIDialogVideoScan* scanner = (CGUIDialogVideoScan*)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
-        if (scanner)
-          scanner->StartScanning(share.strPath, true);
-      }
-    }
   }
   dialog->m_paths->Clear();
   return confirmed;
@@ -345,7 +334,7 @@ void CGUIDialogMediaSource::OnOK()
     if (m_type == "video" && !URIUtils::IsLiveTV(share.strPath) && 
         !share.strPath.Left(6).Equals("rss://"))
     {
-      CGUIWindowVideoBase::OnAssignContent(share.strPath, 0, m_info, m_settings);
+      CGUIWindowVideoBase::OnAssignContent(share.strPath);
     }
   }
 
index 4856efe..ba96f15 100644 (file)
@@ -22,7 +22,6 @@
  */
 
 #include "guilib/GUIDialog.h"
-#include "video/VideoInfoScanner.h"
 
 class CFileItemList;
 class CMediaSource;
@@ -61,9 +60,5 @@ protected:
   CStdString m_name;
   CFileItemList* m_paths;
   bool m_confirmed;
-  ADDON::ScraperPtr m_info;
-  bool m_bRunScan;
   bool m_bNameChanged;
-
-  VIDEO::SScanSettings m_settings;
 };
index 43e3438..8dfe1be 100644 (file)
@@ -185,6 +185,13 @@ void CGUIDialogSmartPlaylistRule::OnBrowse()
     if (m_type.Equals("songs") || m_type.Equals("albums"))
       path = "special://musicplaylists/";
     XFILE::CDirectory::GetDirectory(path, items, ".xsp",false,false,XFILE::DIR_CACHE_ONCE,true,true);
+    for (int i = 0; i < items.Size(); i++)
+    {
+      CFileItemPtr item = items[i];
+      CSmartPlaylist playlist;
+      if (playlist.OpenAndReadName(item->GetPath()))
+        item->SetLabel(playlist.GetName());
+    }
     iLabel = 559;
   }
   else if (m_rule.m_field == CSmartPlaylistRule::FIELD_PATH)
index d43b0f9..d5e3345 100644 (file)
@@ -23,7 +23,7 @@
 
 #if defined(HAS_FILESYSTEM_AFP)
 #include "AFPDirectory.h"
-#include "FileAFP.h"
+#include "AFPFile.h"
 #include "Util.h"
 #include "guilib/LocalizeStrings.h"
 #include "Application.h"
diff --git a/xbmc/filesystem/AFPFile.cpp b/xbmc/filesystem/AFPFile.cpp
new file mode 100644 (file)
index 0000000..fbfe0ec
--- /dev/null
@@ -0,0 +1,735 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FileAFP.cpp: implementation of the CAFPFile class.
+//
+//////////////////////////////////////////////////////////////////////
+#ifdef _LINUX
+#include "system.h"
+
+#if defined(HAS_FILESYSTEM_AFP)
+#include "AFPFile.h"
+#include "PasswordManager.h"
+#include "AFPDirectory.h"
+#include "Util.h"
+#include "settings/AdvancedSettings.h"
+#include "settings/GUISettings.h"
+#include "threads/SingleLock.h"
+#include "utils/log.h"
+#include "utils/TimeUtils.h"
+
+using namespace XFILE;
+
+#define AFP_MAX_READ_SIZE 131072
+
+CStdString URLEncode(const CStdString value)
+{
+  CStdString encoded(value);
+  CURL::Encode(encoded);
+  return encoded;
+}
+
+void AfpConnectionLog(void *priv, enum loglevels loglevel, int logtype, const char *message)
+{
+  if (!message) return;
+  CStdString msg = "LIBAFPCLIENT: " + CStdString(message);
+
+  switch(logtype)
+  {
+    case LOG_WARNING:
+      CLog::Log(LOGWARNING, "%s", msg.c_str());
+      break;
+    case LOG_ERR:
+      CLog::Log(LOGERROR, "%s", msg.c_str());
+      break;
+    default:
+      CLog::Log(LOGDEBUG, "%s", msg.c_str());
+      break;
+  }
+}
+
+CAfpConnection::CAfpConnection()
+ : m_OpenConnections(0)
+ , m_IdleTimeout(0)
+ , m_pAfpServer(NULL)
+ , m_pAfpVol(NULL)
+ , m_pAfpUrl((struct afp_url*)malloc(sizeof(struct afp_url)))
+ , m_pAfpClient((struct libafpclient*)malloc(sizeof(struct libafpclient)))
+ , m_pLibAfp(new DllLibAfp())
+ , m_bDllInited(false)
+{
+}
+
+CAfpConnection::~CAfpConnection()
+{
+  Disconnect();
+  free(m_pAfpClient);
+  free(m_pAfpUrl);
+  if (m_pLibAfp->IsLoaded())
+    m_pLibAfp->Unload();
+  delete m_pLibAfp;
+}
+
+bool CAfpConnection::initLib()
+{
+  if (!m_bDllInited)
+  {
+    if (m_pLibAfp->Load())
+    {
+      m_pAfpClient->unmount_volume = NULL;
+      m_pAfpClient->log_for_client = AfpConnectionLog;
+      m_pAfpClient->forced_ending_hook = NULL;
+      m_pAfpClient->scan_extra_fds = NULL;
+      m_pAfpClient->loop_started = NULL;
+
+      m_pLibAfp->libafpclient_register(m_pAfpClient);
+      m_pLibAfp->init_uams();
+      m_pLibAfp->afp_main_quick_startup(NULL);
+      CLog::Log(LOGDEBUG, "AFP: Supported UAMs: %s", m_pLibAfp->get_uam_names_list());
+      m_bDllInited = true;
+    }
+    else
+    {
+      CLog::Log(LOGERROR, "AFP: Error loading afpclient lib.");
+    }
+  }
+
+  return m_bDllInited;
+}
+
+//only unmount here - afpclient lib is not
+//stoppable (no afp_main_quick_shutdown as counter part
+//for afp_main_quick_startup)
+void CAfpConnection::Deinit()
+{
+  if(m_pAfpVol && m_pLibAfp->IsLoaded())
+  {
+    disconnectVolume();
+    Disconnect();
+    m_pAfpUrl->servername[0] = '\0';
+  }        
+}
+
+void CAfpConnection::Disconnect()
+{
+  CSingleLock lock(*this);
+  m_pAfpServer = NULL;
+}
+
+void CAfpConnection::disconnectVolume()
+{
+  if (m_pAfpVol)
+  {
+    // afp_unmount_volume(m_pAfpVol);
+    m_pLibAfp->afp_unmount_all_volumes(m_pAfpServer);
+    m_pAfpVol = NULL;
+  }
+}
+
+// taken from cmdline tool
+bool CAfpConnection::connectVolume(const char *volumename, struct afp_volume *&pVolume)
+{
+  bool ret = false;
+  if (strlen(volumename) != 0)
+  {
+    // Ah, we're not connected to a volume
+    unsigned int len = 0;
+    char mesg[1024];
+
+    if ((pVolume = m_pLibAfp->find_volume_by_name(m_pAfpServer, volumename)) == NULL)
+    {
+      CLog::Log(LOGDEBUG, "AFP: Could not find a volume called %s\n", volumename);
+    }
+    else
+    {
+      pVolume->mapping = AFP_MAPPING_LOGINIDS;
+      pVolume->extra_flags |= VOLUME_EXTRA_FLAGS_NO_LOCKING;
+
+      if (m_pLibAfp->afp_connect_volume(pVolume, m_pAfpServer, mesg, &len, 1024 ))
+      {
+        CLog::Log(LOGDEBUG, "AFP: Could not access volume %s (error: %s)\n", pVolume->volume_name, mesg);
+        pVolume = NULL;
+      }
+      else
+      {
+        CLog::Log(LOGDEBUG, "AFP: Connected to volume %s\n", pVolume->volume_name_printable);
+        ret = true;
+      }
+    }
+  }
+
+  return ret;
+}
+
+CStdString CAfpConnection::getAuthenticatedPath(const CURL &url)
+{
+  CURL authURL(url);
+  CStdString ret;
+  CPasswordManager::GetInstance().AuthenticateURL(authURL);
+  ret = authURL.Get();
+  return ret;
+}
+
+CAfpConnection::afpConnnectError CAfpConnection::Connect(const CURL& url)
+{
+  CSingleLock lock(*this);
+  struct afp_connection_request *conn_req = NULL;
+  struct afp_url tmpurl;
+  CURL nonConstUrl(getAuthenticatedPath(url)); // we need a editable copy of the url
+  bool serverChanged=false;
+
+  if (!initLib())
+    return AfpFailed;
+
+  m_pLibAfp->afp_default_url(&tmpurl);
+
+  // if hostname has changed - assume server changed
+  if (!nonConstUrl.GetHostName().Equals(m_pAfpUrl->servername, false)|| (m_pAfpServer && m_pAfpServer->connect_state == 0))
+  {
+    serverChanged = true;
+    Disconnect();
+  }
+
+  // if volume changed - also assume server changed (afpclient can't reuse old servobject it seems)
+  if (!nonConstUrl.GetShareName().Equals(m_pAfpUrl->volumename, false))
+  {
+   // no reusing of old server object possible with libafpclient it seems...
+    serverChanged = true;
+    Disconnect();
+  }
+
+  // first, try to parse the URL
+  if (m_pLibAfp->afp_parse_url(&tmpurl, nonConstUrl.Get().c_str(), 0) != 0)
+  {
+    // Okay, this isn't a real URL
+    CLog::Log(LOGDEBUG, "AFP: Could not parse url: %s!\n", nonConstUrl.Get().c_str());
+    return AfpFailed;
+  }
+  else // parsed sucessfull
+  {
+    // this is our current url object whe are connected to (at least we try)
+    *m_pAfpUrl = tmpurl;
+  }
+
+  // if no username and password is set - use no user authent uam
+  if (strlen(m_pAfpUrl->password) == 0 && strlen(m_pAfpUrl->username) == 0)
+  {
+    // try anonymous
+    strncpy(m_pAfpUrl->uamname, "No User Authent", sizeof(m_pAfpUrl->uamname));
+    CLog::Log(LOGDEBUG, "AFP: Using anonymous authentication.");
+  }
+  else if ((nonConstUrl.GetPassWord().IsEmpty() || nonConstUrl.GetUserName().IsEmpty()) && serverChanged)
+  {
+    // this is our current url object whe are connected to (at least we try)
+    return AfpAuth;
+  }
+
+  // we got a password in the url
+  if (!nonConstUrl.GetPassWord().IsEmpty())
+  {
+    // copy password because afp_parse_url just puts garbage into the password field :(
+    strncpy(m_pAfpUrl->password, nonConstUrl.GetPassWord().c_str(), 127);
+  }
+
+  // whe are not connected or we want to connect to another server
+  if (!m_pAfpServer || serverChanged)
+  {
+    // code from cmdline tool
+    conn_req = (struct afp_connection_request*)malloc(sizeof(struct afp_connection_request));
+    memset(conn_req, 0, sizeof(struct afp_connection_request));
+
+    conn_req->url = *m_pAfpUrl;
+    conn_req->url.requested_version = 31;
+
+    if (strlen(m_pAfpUrl->uamname)>0)
+    {
+      if ((conn_req->uam_mask = m_pLibAfp->find_uam_by_name(m_pAfpUrl->uamname)) == 0)
+      {
+        CLog::Log(LOGDEBUG, "AFP:I don't know about UAM %s\n", m_pAfpUrl->uamname);
+        m_pAfpUrl->volumename[0] = '\0';
+        m_pAfpUrl->servername[0] = '\0';
+        free(conn_req);
+        return AfpFailed;
+      }
+    }
+    else
+    {
+      conn_req->uam_mask = m_pLibAfp->default_uams_mask();
+    }
+
+    // try to connect
+#ifdef USE_CVS_AFPFS
+    if ((m_pAfpServer = m_pLibAfp->afp_wrap_server_full_connect(NULL, conn_req, NULL)) == NULL)
+#else
+    if ((m_pAfpServer = m_pLibAfp->afp_wrap_server_full_connect(NULL, conn_req)) == NULL)
+#endif
+    {
+      m_pAfpUrl->volumename[0] = '\0';
+      m_pAfpUrl->servername[0] = '\0';
+      free(conn_req);
+      CLog::Log(LOGERROR, "AFP: Error connecting to %s", url.Get().c_str());
+      return AfpFailed;
+    }
+    // success!
+    CLog::Log(LOGDEBUG, "AFP: Connected to server %s using UAM \"%s\"\n",
+      m_pAfpServer->server_name, m_pLibAfp->uam_bitmap_to_string(m_pAfpServer->using_uam));
+    // we don't need it after here ...
+    free(conn_req);
+  }
+
+  // if server changed reconnect volume
+  if (serverChanged)
+  {
+    connectVolume(m_pAfpUrl->volumename, m_pAfpVol); // connect new volume
+  }
+  return AfpOk;
+}
+
+int CAfpConnection::stat(const CURL &url, struct stat *statbuff)
+{
+  CSingleLock lock(*this);
+  CStdString strPath = gAfpConnection.GetPath(url);
+  struct afp_volume *pTmpVol = NULL;
+  struct afp_url tmpurl;
+  int iResult = -1;
+  CURL nonConstUrl(getAuthenticatedPath(url)); // we need a editable copy of the url
+
+  if (!initLib() || !m_pAfpServer)
+    return -1;
+
+  m_pLibAfp->afp_default_url(&tmpurl);
+
+  // first, try to parse the URL
+  if (m_pLibAfp->afp_parse_url(&tmpurl, nonConstUrl.Get().c_str(), 0) != 0)
+  {
+    // Okay, this isn't a real URL
+    CLog::Log(LOGDEBUG, "AFP: Could not parse url: %s!\n", nonConstUrl.Get().c_str());
+    return -1;
+  }
+
+  // if no username and password is set - use no user authent uam
+  if (strlen(tmpurl.password) == 0 && strlen(tmpurl.username) == 0)
+  {
+    // try anonymous
+    strncpy(tmpurl.uamname, "No User Authent", sizeof(tmpurl.uamname));
+    CLog::Log(LOGDEBUG, "AFP: Using anonymous authentication.");
+  }
+  else if ((nonConstUrl.GetPassWord().IsEmpty() || nonConstUrl.GetUserName().IsEmpty()))
+  {
+    // this is our current url object whe are connected to (at least we try)
+    return -1;
+  }
+
+  // we got a password in the url
+  if (!nonConstUrl.GetPassWord().IsEmpty())
+  {
+    // copy password because afp_parse_url just puts garbage into the password field :(
+    strncpy(tmpurl.password, nonConstUrl.GetPassWord().c_str(), 127);
+  }
+
+  // connect new volume
+  if(connectVolume(tmpurl.volumename, pTmpVol) && pTmpVol)
+  {
+    iResult = m_pLibAfp->afp_wrap_getattr(pTmpVol, strPath.c_str(), statbuff);
+    //unmount single volume crashs
+    //we will get rid of the mounted volume
+    //once the context is changed in connect function
+    //ppppooooorrrr!!
+    //m_pLibAfp->afp_unmount_volume(pTmpVol);
+  }
+  return iResult;
+}
+
+
+/* This is called from CApplication::ProcessSlow() and is used to tell if afp have been idle for too long */
+void CAfpConnection::CheckIfIdle()
+{
+  /* We check if there are open connections. This is done without a lock to not halt the mainthread. It should be thread safe as
+   worst case scenario is that m_OpenConnections could read 0 and then changed to 1 if this happens it will enter the if wich will lead to another check, wich is locked.  */
+  if (m_OpenConnections == 0 && m_pAfpVol != NULL)
+  { /* I've set the the maxiumum IDLE time to be 1 min and 30 sec. */
+    CSingleLock lock(*this);
+    if (m_OpenConnections == 0 /* check again - when locked */)
+    {
+      if (m_IdleTimeout > 0)
+      {
+        m_IdleTimeout--;
+      }
+      else
+      {
+        CLog::Log(LOGNOTICE, "AFP is idle. Closing the remaining connections.");
+        gAfpConnection.Deinit();
+      }
+    }
+  }
+}
+
+/* The following two function is used to keep track on how many Opened files/directories there are.
+needed for unloading the dylib*/
+void CAfpConnection::AddActiveConnection()
+{
+  CSingleLock lock(*this);
+  m_OpenConnections++;
+}
+
+void CAfpConnection::AddIdleConnection()
+{
+  CSingleLock lock(*this);
+  m_OpenConnections--;
+  /* If we close a file we reset the idle timer so that we don't have any wierd behaviours if a user
+   leaves the movie paused for a long while and then press stop */
+  m_IdleTimeout = 180;
+}
+
+CStdString CAfpConnection::GetPath(const CURL &url)
+{
+  struct afp_url tmpurl;
+  CStdString ret = "";
+
+  m_pLibAfp->afp_default_url(&tmpurl);
+
+  // First, try to parse the URL
+  if (m_pLibAfp->afp_parse_url(&tmpurl, url.Get().c_str(), 0) != 0 )
+  {
+    // Okay, this isn't a real URL
+    CLog::Log(LOGDEBUG, "AFP: Could not parse url.\n");
+  }
+  else
+  {
+    ret = CStdString(tmpurl.path);
+  }
+  return ret;
+}
+
+CAfpConnection gAfpConnection;
+
+CAFPFile::CAFPFile()
+ : m_fileSize(0)
+ , m_fileOffset(0)
+ , m_pFp(NULL)
+ , m_pAfpVol(NULL)
+{
+  gAfpConnection.AddActiveConnection();
+}
+
+CAFPFile::~CAFPFile()
+{
+  gAfpConnection.AddIdleConnection();
+  Close();
+}
+
+int64_t CAFPFile::GetPosition()
+{
+  if (m_pFp == NULL) return 0;
+  return m_fileOffset;
+}
+
+int64_t CAFPFile::GetLength()
+{
+  if (m_pFp == NULL) return 0;
+  return m_fileSize;
+}
+
+bool CAFPFile::Open(const CURL& url)
+{
+  Close();
+  // we can't open files like afp://file.f or afp://server/file.f
+  // if a file matches the if below return false, it can't exist on a afp share.
+  if (!IsValidFile(url.GetFileName()))
+  {
+    CLog::Log(LOGNOTICE, "FileAfp: Bad URL : '%s'", url.GetFileName().c_str());
+    return false;
+  }
+
+  CSingleLock lock(gAfpConnection);
+  if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume())
+    return false;
+  m_pAfpVol = gAfpConnection.GetVolume();
+
+  CStdString strPath = gAfpConnection.GetPath(url);
+
+  if (gAfpConnection.GetImpl()->afp_wrap_open(m_pAfpVol, strPath.c_str(), O_RDONLY, &m_pFp))
+  {
+    if (gAfpConnection.GetImpl()->afp_wrap_open(m_pAfpVol, URLEncode(strPath.c_str()).c_str(), O_RDONLY, &m_pFp))
+    {
+      // write error to logfile
+      CLog::Log(LOGINFO, "CAFPFile::Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strPath.c_str(), errno, strerror(errno));
+      return false;
+    }
+  }
+  
+  CLog::Log(LOGDEBUG,"CAFPFile::Open - opened %s, fd=%d",url.GetFileName().c_str(), m_pFp ? m_pFp->fileid:-1);
+  m_url = url;
+  
+#ifdef _LINUX
+  struct __stat64 tmpBuffer;
+#else
+  struct stat tmpBuffer;
+#endif  
+  if(Stat(&tmpBuffer))
+  {
+    m_url.Reset();
+    Close();
+    return false;
+  }
+
+  m_fileSize = tmpBuffer.st_size;
+  m_fileOffset = 0;
+  // We've successfully opened the file!
+  return true;
+}
+
+
+bool CAFPFile::Exists(const CURL& url)
+{
+  return Stat(url, NULL) == 0;
+}
+
+int CAFPFile::Stat(struct __stat64* buffer)
+{
+  if (m_pFp == NULL)
+    return -1;
+  return Stat(m_url, buffer);
+}
+
+// TODO - maybe check returncode!
+int CAFPFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  CSingleLock lock(gAfpConnection);
+  if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume())
+    return -1;
+
+  CStdString strPath = gAfpConnection.GetPath(url);
+
+  struct stat tmpBuffer = {0};
+  int iResult = gAfpConnection.GetImpl()->afp_wrap_getattr(gAfpConnection.GetVolume(), strPath.c_str(), &tmpBuffer);
+
+  if (buffer)
+  {
+    memset(buffer, 0, sizeof(struct __stat64));
+    buffer->st_dev   = tmpBuffer.st_dev;
+    buffer->st_ino   = tmpBuffer.st_ino;
+    buffer->st_mode  = tmpBuffer.st_mode;
+    buffer->st_nlink = tmpBuffer.st_nlink;
+    buffer->st_uid   = tmpBuffer.st_uid;
+    buffer->st_gid   = tmpBuffer.st_gid;
+    buffer->st_rdev  = tmpBuffer.st_rdev;
+    buffer->st_size  = tmpBuffer.st_size;
+    buffer->st_atime = tmpBuffer.st_atime;
+    buffer->st_mtime = tmpBuffer.st_mtime;
+    buffer->st_ctime = tmpBuffer.st_ctime;
+  }
+
+  return iResult;
+}
+
+unsigned int CAFPFile::Read(void *lpBuf, int64_t uiBufSize)
+{
+  CSingleLock lock(gAfpConnection);
+  if (m_pFp == NULL || !m_pAfpVol)
+    return 0;
+
+  if (uiBufSize > AFP_MAX_READ_SIZE)
+    uiBufSize = AFP_MAX_READ_SIZE;
+
+#ifdef USE_CVS_AFPFS
+  char *name = m_pFp->basename;
+#else
+  char *name = m_pFp->name;
+  if (strlen(name) == 0)
+    name = m_pFp->basename;
+
+#endif
+  int eof = 0;
+  int bytesRead = gAfpConnection.GetImpl()->afp_wrap_read(m_pAfpVol,
+    name, (char *)lpBuf,(size_t)uiBufSize, m_fileOffset, m_pFp, &eof);
+  if (bytesRead > 0)
+    m_fileOffset += bytesRead;
+
+  if (bytesRead < 0)
+  {
+    CLog::Log(LOGERROR, "%s - Error( %d, %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno));
+    return 0;
+  }
+
+  return (unsigned int)bytesRead;
+}
+
+int64_t CAFPFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  off_t newOffset = m_fileOffset;
+  if (m_pFp == NULL) return -1;
+
+  switch(iWhence)
+  {
+    case SEEK_SET:
+      newOffset = iFilePosition;
+      break;
+    case SEEK_END:
+      newOffset = m_fileSize+iFilePosition;
+      break;
+    case SEEK_CUR:
+      newOffset += iFilePosition;
+      break;
+  }
+
+  if ( newOffset < 0 || newOffset > m_fileSize)
+  {
+    CLog::Log(LOGERROR, "%s - Error( %"PRId64")", __FUNCTION__, newOffset);
+    return -1;
+  }
+
+  m_fileOffset = newOffset;
+  return (int64_t)m_fileOffset;
+}
+
+void CAFPFile::Close()
+{
+  CSingleLock lock(gAfpConnection);
+  if (m_pFp != NULL && m_pAfpVol)
+  {
+    CLog::Log(LOGDEBUG, "CAFPFile::Close closing fd %d", m_pFp->fileid);
+#ifdef USE_CVS_AFPFS
+    char *name = m_pFp->basename;
+#else
+    char *name = m_pFp->name;
+    if (strlen(name) == 0)
+      name = m_pFp->basename;
+#endif
+    gAfpConnection.GetImpl()->afp_wrap_close(m_pAfpVol, name, m_pFp);
+    delete m_pFp;
+    m_pFp = NULL;
+    m_pAfpVol = NULL;
+  }
+}
+
+int CAFPFile::Write(const void* lpBuf, int64_t uiBufSize)
+{
+  CSingleLock lock(gAfpConnection);
+  if (m_pFp == NULL || !m_pAfpVol)
+   return -1;
+
+  int numberOfBytesWritten = 0;
+  uid_t uid;
+  gid_t gid;
+
+  // FIXME need a better way to get server's uid/gid
+  uid = getuid();
+  gid = getgid();
+#ifdef USE_CVS_AFPFS
+  char *name = m_pFp->basename;
+#else
+  char *name = m_pFp->name;
+  if (strlen(name) == 0)
+    name = m_pFp->basename;
+#endif
+  numberOfBytesWritten = gAfpConnection.GetImpl()->afp_wrap_write(m_pAfpVol,
+    name, (const char *)lpBuf, (size_t)uiBufSize, m_fileOffset, m_pFp, uid, gid);
+
+  return numberOfBytesWritten;
+}
+
+bool CAFPFile::Delete(const CURL& url)
+{
+  CSingleLock lock(gAfpConnection);
+  if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume())
+    return false;
+
+  CStdString strPath = gAfpConnection.GetPath(url);
+
+  int result = gAfpConnection.GetImpl()->afp_wrap_unlink(gAfpConnection.GetVolume(), strPath.c_str());
+
+  if (result != 0)
+    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno));
+
+  return (result == 0);
+}
+
+bool CAFPFile::Rename(const CURL& url, const CURL& urlnew)
+{
+  CSingleLock lock(gAfpConnection);
+  if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume())
+    return false;
+
+  CStdString strFile = gAfpConnection.GetPath(url);
+  CStdString strFileNew = gAfpConnection.GetPath(urlnew);
+
+  int result = gAfpConnection.GetImpl()->afp_wrap_rename(gAfpConnection.GetVolume(), strFile.c_str(), strFileNew.c_str());
+
+  if (result != 0)
+    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno));
+
+  return (result == 0);
+}
+
+bool CAFPFile::OpenForWrite(const CURL& url, bool bOverWrite)
+{
+
+  int ret = 0;
+  m_fileSize = 0;
+  m_fileOffset = 0;
+
+  Close();
+  CSingleLock lock(gAfpConnection);
+  if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume())
+    return false;
+
+  // we can't open files like afp://file.f or afp://server/file.f
+  // if a file matches the if below return false, it can't exist on a afp share.
+  if (!IsValidFile(url.GetFileName()))
+    return false;
+
+  m_pAfpVol = gAfpConnection.GetVolume();
+
+  CStdString strPath = gAfpConnection.GetPath(url);
+
+  if (bOverWrite)
+  {
+    CLog::Log(LOGWARNING, "FileAFP::OpenForWrite() called with overwriting enabled! - %s", strPath.c_str());
+    ret = gAfpConnection.GetImpl()->afp_wrap_creat(m_pAfpVol, strPath.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+  }
+
+  ret = gAfpConnection.GetImpl()->afp_wrap_open(m_pAfpVol, strPath.c_str(), O_RDWR, &m_pFp);
+
+  if (ret || m_pFp == NULL)
+  {
+    // write error to logfile
+    CLog::Log(LOGERROR, "CAFPFile::Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strPath.c_str(), errno, strerror(errno));
+    return false;
+  }
+
+  // We've successfully opened the file!
+  return true;
+}
+
+bool CAFPFile::IsValidFile(const CStdString& strFileName)
+{
+  if (strFileName.Find('/') == -1   || // doesn't have sharename
+      strFileName.Right(2)  == "/." || // not current folder
+      strFileName.Right(3)  == "/..")  // not parent folder
+  {
+    return false;
+  }
+
+  return true;
+}
+#endif // HAS_FILESYSTEM_AFP
+#endif // _LINUX
diff --git a/xbmc/filesystem/AFPFile.h b/xbmc/filesystem/AFPFile.h
new file mode 100644 (file)
index 0000000..f9edc13
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FileAFP.h: interface for the CAFPFile class.
+#ifndef FILEAFP_H_
+#define FILEAFP_H_
+
+
+#ifdef _LINUX
+
+#include "IFile.h"
+#include "URL.h"
+#include "threads/CriticalSection.h"
+#include "DllLibAfp.h"
+
+// libafpclient includes
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+CStdString URLEncode(CStdString str);
+
+class CAfpConnection : public CCriticalSection
+{
+public:
+    enum eAfpConnectError
+    {
+      AfpOk     = 0,
+      AfpFailed = 1,
+      AfpAuth   = 2,
+    };
+    typedef enum eAfpConnectError afpConnnectError;
+
+   CAfpConnection();
+  ~CAfpConnection();
+
+  afpConnnectError      Connect(const CURL &url);
+  void                  Disconnect(void);
+  struct afp_server     *GetServer()    {return m_pAfpServer;}
+  struct afp_volume     *GetVolume()    {return m_pAfpVol;};
+  struct afp_url        *GetUrl()       {return m_pAfpUrl;};
+  CStdString            GetPath(const CURL &url);
+  DllLibAfp             *GetImpl()      {return m_pLibAfp;}
+  
+  const char            *GetConnectedIp() const { if(m_pAfpUrl) return m_pAfpUrl->servername;else return "";}
+  
+  //special stat which uses its own context
+  //needed for getting intervolume symlinks to work
+  //it uses the same global server connection
+  //but its own volume
+  int                   stat(const CURL &url, struct stat *statbuff);
+  
+  void AddActiveConnection();
+  void AddIdleConnection();
+  void CheckIfIdle();  
+  void Deinit();  
+
+private:
+  bool                  initLib(void);
+  bool                  connectVolume(const char *volumename, struct afp_volume *&pVolume);
+  void                  disconnectVolume(void);
+  CStdString            getAuthenticatedPath(const CURL &url);
+
+  int                   m_OpenConnections;
+  int                   m_IdleTimeout;
+  struct afp_server     *m_pAfpServer;
+  struct afp_volume     *m_pAfpVol;
+  struct afp_url        *m_pAfpUrl;
+  struct libafpclient   *m_pAfpClient;
+  DllLibAfp             *m_pLibAfp;
+  bool                  m_bDllInited;
+};
+
+extern CAfpConnection gAfpConnection;
+
+namespace XFILE
+{
+class CAFPFile : public IFile
+{
+public:
+  CAFPFile();
+  virtual ~CAFPFile();
+  virtual void          Close();
+  virtual int64_t       Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual unsigned int  Read(void* lpBuf, int64_t uiBufSize);
+  virtual bool          Open(const CURL& url);
+  virtual bool          Exists(const CURL& url);
+  virtual int           Stat(const CURL& url, struct __stat64* buffer);
+  virtual int           Stat(struct __stat64* buffer);
+  virtual int64_t       GetLength();
+  virtual int64_t       GetPosition();
+  virtual int           Write(const void* lpBuf, int64_t uiBufSize);
+
+  virtual bool          OpenForWrite(const CURL& url, bool bOverWrite = false);
+  virtual bool          Delete(const CURL& url);
+  virtual bool          Rename(const CURL& url, const CURL& urlnew);
+  virtual int           GetChunkSize() {return 1;}
+  // implement iocontrol for seek_possible for preventing the stat in File class for
+  // getting this info ...
+  virtual int           IoControl(EIoControl request, void* param)
+                        { if (request == IOCTRL_SEEK_POSSIBLE) return 1;
+                          return -1;
+                        };
+
+protected:
+  bool                  IsValidFile(const CStdString& strFileName);
+
+  CURL                  m_url;
+  int64_t               m_fileSize;
+  off_t                 m_fileOffset; // current SEEK pointer
+  struct afp_file_info *m_pFp;
+  struct afp_volume    *m_pAfpVol;  
+};
+}
+#endif // _LINUX
+#endif // FILEAFP_H_
index cdac766..402b285 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "AddonsDirectory.h"
 #include "addons/AddonDatabase.h"
-#include "FactoryDirectory.h"
+#include "DirectoryFactory.h"
 #include "Directory.h"
 #include "DirectoryCache.h"
 #include "FileItem.h"
diff --git a/xbmc/filesystem/CDDAFile.cpp b/xbmc/filesystem/CDDAFile.cpp
new file mode 100644 (file)
index 0000000..408efe1
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "system.h"
+
+#ifdef HAS_DVD_DRIVE
+
+#include "CDDAFile.h"
+#include <sys/stat.h>
+#include "Util.h"
+#include "URL.h"
+#include "storage/MediaManager.h"
+#include "utils/log.h"
+#include "utils/URIUtils.h"
+
+using namespace MEDIA_DETECT;
+using namespace XFILE;
+
+CFileCDDA::CFileCDDA(void)
+{
+  m_pCdIo = NULL;
+  m_lsnStart = CDIO_INVALID_LSN;
+  m_lsnCurrent = CDIO_INVALID_LSN;
+  m_lsnEnd = CDIO_INVALID_LSN;
+  m_cdio = CLibcdio::GetInstance();
+}
+
+CFileCDDA::~CFileCDDA(void)
+{
+  Close();
+}
+
+bool CFileCDDA::Open(const CURL& url)
+{
+  CStdString strURL = url.GetWithoutFilename();
+
+  if (!g_mediaManager.IsDiscInDrive(strURL) || !IsValidFile(url))
+    return false;
+
+  // Open the dvd drive
+#ifdef _LINUX
+  m_pCdIo = m_cdio->cdio_open(g_mediaManager.TranslateDevicePath(strURL), DRIVER_UNKNOWN);
+#elif defined(_WIN32)
+  m_pCdIo = m_cdio->cdio_open_win32(g_mediaManager.TranslateDevicePath(strURL, true));
+#else
+  m_pCdIo = m_cdio->cdio_open_win32("D:");
+#endif
+  if (!m_pCdIo)
+  {
+    CLog::Log(LOGERROR, "file cdda: Opening the dvd drive failed");
+    return false;
+  }
+
+  int iTrack = GetTrackNum(url);
+
+  m_lsnStart = m_cdio->cdio_get_track_lsn(m_pCdIo, iTrack);
+  m_lsnEnd = m_cdio->cdio_get_track_last_lsn(m_pCdIo, iTrack);
+  m_lsnCurrent = m_lsnStart;
+
+  if (m_lsnStart == CDIO_INVALID_LSN || m_lsnEnd == CDIO_INVALID_LSN)
+  {
+    m_cdio->cdio_destroy(m_pCdIo);
+    m_pCdIo = NULL;
+    return false;
+  }
+
+  return true;
+}
+
+bool CFileCDDA::Exists(const CURL& url)
+{
+  if (!IsValidFile(url))
+    return false;
+
+  int iTrack = GetTrackNum(url);
+
+  if (!Open(url))
+    return false;
+
+  int iLastTrack = m_cdio->cdio_get_last_track_num(m_pCdIo);
+  if (iLastTrack == CDIO_INVALID_TRACK)
+    return false;
+
+  return (iTrack > 0 && iTrack <= iLastTrack);
+}
+
+int CFileCDDA::Stat(const CURL& url, struct __stat64* buffer)
+{
+  if (Open(url))
+  {
+    memset(buffer, 0, sizeof(struct __stat64));
+    buffer->st_size = GetLength();
+    buffer->st_mode = _S_IFREG;
+    Close();
+    return 0;
+  }
+  errno = ENOENT;
+  return -1;
+}
+
+unsigned int CFileCDDA::Read(void* lpBuf, int64_t uiBufSize)
+{
+  if (!m_pCdIo || !g_mediaManager.IsDiscInDrive())
+    return 0;
+
+  int iSectorCount = (int)uiBufSize / CDIO_CD_FRAMESIZE_RAW;
+
+  if (iSectorCount <= 0)
+    return 0;
+
+  // Are there enough sectors left to read
+  if (m_lsnCurrent + iSectorCount > m_lsnEnd)
+    iSectorCount = m_lsnEnd - m_lsnCurrent;
+
+  int iret = m_cdio->cdio_read_audio_sectors(m_pCdIo, lpBuf, m_lsnCurrent, iSectorCount);
+
+  if ( iret != DRIVER_OP_SUCCESS)
+  {
+    CLog::Log(LOGERROR, "file cdda: Reading %d sectors of audio data starting at lsn %d failed with error code %i", iSectorCount, m_lsnCurrent, iret);
+    return 0;
+  }
+
+  m_lsnCurrent += iSectorCount;
+
+  return iSectorCount*CDIO_CD_FRAMESIZE_RAW;
+}
+
+int64_t CFileCDDA::Seek(int64_t iFilePosition, int iWhence /*=SEEK_SET*/)
+{
+  if (!m_pCdIo)
+    return -1;
+
+  lsn_t lsnPosition = (int)iFilePosition / CDIO_CD_FRAMESIZE_RAW;
+
+  switch (iWhence)
+  {
+  case SEEK_SET:
+    // cur = pos
+    m_lsnCurrent = m_lsnStart + lsnPosition;
+    break;
+  case SEEK_CUR:
+    // cur += pos
+    m_lsnCurrent += lsnPosition;
+    break;
+  case SEEK_END:
+    // end += pos
+    m_lsnCurrent = m_lsnEnd + lsnPosition;
+    break;
+  default:
+    return -1;
+  }
+
+  return ((m_lsnCurrent -m_lsnStart)*CDIO_CD_FRAMESIZE_RAW);
+}
+
+void CFileCDDA::Close()
+{
+  if (m_pCdIo)
+  {
+    m_cdio->cdio_destroy(m_pCdIo);
+    m_pCdIo = NULL;
+  }
+}
+
+int64_t CFileCDDA::GetPosition()
+{
+  if (!m_pCdIo)
+    return 0;
+
+  return ((m_lsnCurrent -m_lsnStart)*CDIO_CD_FRAMESIZE_RAW);
+}
+
+int64_t CFileCDDA::GetLength()
+{
+  if (!m_pCdIo)
+    return 0;
+
+  return ((m_lsnEnd -m_lsnStart)*CDIO_CD_FRAMESIZE_RAW);
+}
+
+bool CFileCDDA::IsValidFile(const CURL& url)
+{
+  // Only .cdda files are supported
+  CStdString strExtension;
+  URIUtils::GetExtension(url.Get(), strExtension);
+  strExtension.MakeLower();
+
+  return (strExtension == ".cdda");
+}
+
+int CFileCDDA::GetTrackNum(const CURL& url)
+{
+  CStdString strFileName = url.Get();
+
+  // get track number from "cdda://local/01.cdda"
+  return atoi(strFileName.substr(13, strFileName.size() - 13 - 5).c_str());
+}
+
+#define SECTOR_COUNT 52 // max. sectors that can be read at once
+int CFileCDDA::GetChunkSize()
+{
+  return SECTOR_COUNT*CDIO_CD_FRAMESIZE_RAW;
+}
+
+#endif
+
diff --git a/xbmc/filesystem/CDDAFile.h b/xbmc/filesystem/CDDAFile.h
new file mode 100644 (file)
index 0000000..e10e517
--- /dev/null
@@ -0,0 +1,62 @@
+#pragma once
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "system.h" // for HAS_DVD_DRIVE
+
+#ifdef HAS_DVD_DRIVE
+
+#include "IFile.h"
+#include "storage/cdioSupport.h"
+
+namespace XFILE
+{
+class CFileCDDA : public IFile
+{
+public:
+  CFileCDDA(void);
+  virtual ~CFileCDDA(void);
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+  virtual int GetChunkSize();
+
+protected:
+  bool IsValidFile(const CURL& url);
+  int GetTrackNum(const CURL& url);
+
+protected:
+  CdIo_t* m_pCdIo;
+  lsn_t m_lsnStart;  // Start of m_iTrack in logical sector number
+  lsn_t m_lsnCurrent; // Position inside the track in logical sector number
+  lsn_t m_lsnEnd;   // End of m_iTrack in logical sector number
+  MEDIA_DETECT::CLibcdio* m_cdio;
+};
+}
+
+#endif
+
diff --git a/xbmc/filesystem/CacheCircular.cpp b/xbmc/filesystem/CacheCircular.cpp
deleted file mode 100644 (file)
index 1716927..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "threads/SystemClock.h"
-#include "system.h"
-#include "utils/log.h"
-#include "threads/SingleLock.h"
-#include "utils/TimeUtils.h"
-#include "CacheCircular.h"
-
-using namespace XFILE;
-
-CCacheCircular::CCacheCircular(size_t front, size_t back)
- : CCacheStrategy()
- , m_beg(0)
- , m_end(0)
- , m_cur(0)
- , m_buf(NULL)
- , m_size(front + back)
- , m_size_back(back)
-#ifdef _WIN32
- , m_handle(INVALID_HANDLE_VALUE)
-#endif
-{
-}
-
-CCacheCircular::~CCacheCircular()
-{
-  Close();
-}
-
-int CCacheCircular::Open()
-{
-#ifdef _WIN32
-  m_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, m_size, NULL);
-  if(m_handle == INVALID_HANDLE_VALUE)
-    return CACHE_RC_ERROR;
-  m_buf = (uint8_t*)MapViewOfFile(m_handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
-#else
-  m_buf = new uint8_t[m_size];
-#endif
-  if(m_buf == 0)
-    return CACHE_RC_ERROR;
-  m_beg = 0;
-  m_end = 0;
-  m_cur = 0;
-  return CACHE_RC_OK;
-}
-
-void CCacheCircular::Close()
-{
-#ifdef _WIN32
-  UnmapViewOfFile(m_buf);
-  CloseHandle(m_handle);
-  m_handle = INVALID_HANDLE_VALUE;
-#else
-  delete[] m_buf;
-#endif
-  m_buf = NULL;
-}
-
-/**
- * Function will write to m_buf at m_end % m_size location
- * it will write at maximum m_size, but it will only write
- * as much it can without wrapping around in the buffer
- *
- * It will always leave m_size_back of the backbuffer intact
- * but if the back buffer is less than that, that space is
- * usable to write.
- *
- * If back buffer is filled to an larger extent than
- * m_size_back, it will allow it to be overwritten
- * until only m_size_back data remains.
- *
- * The following always apply:
- *  * m_end <= m_cur <= m_end
- *  * m_end - m_beg <= m_size
- *
- * Multiple calls may be needed to fill buffer completely.
- */
-int CCacheCircular::WriteToCache(const char *buf, size_t len)
-{
-  CSingleLock lock(m_sync);
-
-  // where are we in the buffer
-  size_t pos   = m_end % m_size;
-  size_t back  = (size_t)(m_cur - m_beg);
-  size_t front = (size_t)(m_end - m_cur);
-
-  size_t limit = m_size - std::min(back, m_size_back) - front;
-  size_t wrap  = m_size - pos;
-
-  // limit by max forward size
-  if(len > limit)
-    len = limit;
-
-  // limit to wrap point
-  if(len > wrap)
-    len = wrap;
-
-  if(len == 0)
-    return 0;
-
-  // write the data
-  memcpy(m_buf + pos, buf, len);
-  m_end += len;
-
-  // drop history that was overwritten
-  if(m_end - m_beg > m_size)
-    m_beg = m_end - m_size;
-
-  m_written.Set();
-
-  return len;
-}
-
-/**
- * Reads data from cache. Will only read up till
- * the buffer wrap point. So multiple calls
- * may be needed to empty the whole cache
- */
-int CCacheCircular::ReadFromCache(char *buf, size_t len)
-{
-  CSingleLock lock(m_sync);
-
-  size_t pos   = m_cur % m_size;
-  size_t front = (size_t)(m_end - m_cur);
-  size_t avail = std::min(m_size - pos, front);
-
-  if(avail == 0)
-  {
-    if(IsEndOfInput())
-      return 0;
-    else
-      return CACHE_RC_WOULD_BLOCK;
-  }
-
-  if(len > avail)
-    len = avail;
-
-  if(len == 0)
-    return 0;
-
-  memcpy(buf, m_buf + pos, len);
-  m_cur += len;
-
-  m_space.Set();
-
-  return len;
-}
-
-int64_t CCacheCircular::WaitForData(unsigned int minumum, unsigned int millis)
-{
-  CSingleLock lock(m_sync);
-  uint64_t avail = m_end - m_cur;
-
-  if(millis == 0 || IsEndOfInput())
-    return avail;
-
-  if(minumum > m_size - m_size_back)
-    minumum = m_size - m_size_back;
-
-  XbmcThreads::EndTime endtime(millis);
-  while (!IsEndOfInput() && avail < minumum && !endtime.IsTimePast() )
-  {
-    lock.Leave();
-    m_written.WaitMSec(50); // may miss the deadline. shouldn't be a problem.
-    lock.Enter();
-    avail = m_end - m_cur;
-  }
-
-  return avail;
-}
-
-int64_t CCacheCircular::Seek(int64_t pos)
-{
-  CSingleLock lock(m_sync);
-
-  // if seek is a bit over what we have, try to wait a few seconds for the data to be available.
-  // we try to avoid a (heavy) seek on the source
-  if ((uint64_t)pos >= m_end && (uint64_t)pos < m_end + 100000)
-  {
-    lock.Leave();
-    WaitForData((size_t)(pos - m_cur), 5000);
-    lock.Enter();
-  }
-
-  if((uint64_t)pos >= m_beg && (uint64_t)pos <= m_end)
-  {
-    m_cur = pos;
-    return pos;
-  }
-
-  return CACHE_RC_ERROR;
-}
-
-void CCacheCircular::Reset(int64_t pos)
-{
-  CSingleLock lock(m_sync);
-  m_end = pos;
-  m_beg = pos;
-  m_cur = pos;
-}
-
diff --git a/xbmc/filesystem/CacheCircular.h b/xbmc/filesystem/CacheCircular.h
deleted file mode 100644 (file)
index 52981c6..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#ifndef CACHECIRCULAR_H
-#define CACHECIRCULAR_H
-
-#include "CacheStrategy.h"
-#include "threads/CriticalSection.h"
-#include "threads/Event.h"
-
-namespace XFILE {
-
-class CCacheCircular : public CCacheStrategy
-{
-public:
-    CCacheCircular(size_t front, size_t back);
-    virtual ~CCacheCircular();
-
-    virtual int Open() ;
-    virtual void Close();
-
-    virtual int WriteToCache(const char *buf, size_t len) ;
-    virtual int ReadFromCache(char *buf, size_t len) ;
-    virtual int64_t WaitForData(unsigned int minimum, unsigned int iMillis) ;
-
-    virtual int64_t Seek(int64_t pos) ;
-    virtual void Reset(int64_t pos) ;
-
-protected:
-    uint64_t          m_beg;       /**< index in file (not buffer) of beginning of valid data */
-    uint64_t          m_end;       /**< index in file (not buffer) of end of valid data */
-    uint64_t          m_cur;       /**< current reading index in file */
-    uint8_t          *m_buf;       /**< buffer holding data */
-    size_t            m_size;      /**< size of data buffer used (m_buf) */
-    size_t            m_size_back; /**< guaranteed size of back buffer (actual size can be smaller, or larger if front buffer doesn't need it) */
-    CCriticalSection  m_sync;
-    CEvent            m_written;
-#ifdef _WIN32
-    HANDLE            m_handle;
-#endif
-};
-
-} // namespace XFILE
-#endif
diff --git a/xbmc/filesystem/CacheMemBuffer.cpp b/xbmc/filesystem/CacheMemBuffer.cpp
deleted file mode 100644 (file)
index 65bd005..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#ifdef _LINUX
-#include "threads/SystemClock.h"
-#include "linux/PlatformDefs.h"
-#endif
-#include "settings/AdvancedSettings.h"
-#include "CacheMemBuffer.h"
-#include "utils/log.h"
-#include "threads/SingleLock.h"
-#include "utils/TimeUtils.h"
-
-#include <math.h>
-
-using namespace XFILE;
-
-#define SEEK_CHECK_RET(x) if (!(x)) return -1;
-
-CacheMemBuffer::CacheMemBuffer()
- : CCacheStrategy()
-{
-  m_nStartPosition = 0;
-  m_buffer.Create(g_advancedSettings.m_cacheMemBufferSize + 1);
-  m_HistoryBuffer.Create(g_advancedSettings.m_cacheMemBufferSize + 1);
-  m_forwardBuffer.Create(g_advancedSettings.m_cacheMemBufferSize + 1);
-}
-
-
-CacheMemBuffer::~CacheMemBuffer()
-{
-  m_buffer.Destroy();
-  m_HistoryBuffer.Destroy();
-  m_forwardBuffer.Destroy();
-}
-
-int CacheMemBuffer::Open()
-{
-  m_nStartPosition = 0;
-  m_buffer.Clear();
-  m_HistoryBuffer.Clear();
-  m_forwardBuffer.Clear();
-  return CACHE_RC_OK;
-}
-
-void CacheMemBuffer::Close()
-{
-  m_buffer.Clear();
-  m_HistoryBuffer.Clear();
-  m_forwardBuffer.Clear();
-}
-
-int CacheMemBuffer::WriteToCache(const char *pBuffer, size_t iSize)
-{
-  CSingleLock lock(m_sync);
-  unsigned int nToWrite = m_buffer.getMaxWriteSize() ;
-
-  // must also check the forward buffer.
-  // if we have leftovers from the previous seek - we need not read anymore until they are utilized
-  if (nToWrite == 0 || m_forwardBuffer.getMaxReadSize() > 0)
-    return 0;
-
-  if (nToWrite > iSize)
-    nToWrite = iSize;
-
-  if (!m_buffer.WriteData((char*)pBuffer, nToWrite))
-  {
-    CLog::Log(LOGWARNING,"%s, failed to write %d bytes to buffer. max buffer size: %d", __FUNCTION__, nToWrite, m_buffer.getMaxWriteSize());
-    nToWrite = 0;
-  }
-
-  m_written.Set();
-
-  return nToWrite;
-}
-
-int CacheMemBuffer::ReadFromCache(char *pBuffer, size_t iMaxSize)
-{
-  CSingleLock lock(m_sync);
-  if ( m_buffer.getMaxReadSize() == 0 ) {
-    return m_bEndOfInput ? 0 : CACHE_RC_WOULD_BLOCK;
-  }
-
-  int nRead = iMaxSize;
-  if ((size_t) m_buffer.getMaxReadSize() < iMaxSize)
-    nRead = m_buffer.getMaxReadSize();
-
-  if (nRead > 0)
-  {
-    if (!m_buffer.ReadData(pBuffer, nRead))
-    {
-      CLog::Log(LOGWARNING, "%s, failed to read %d bytes from buffer. max read size: %d", __FUNCTION__, nRead, m_buffer.getMaxReadSize());
-      return 0;
-    }
-
-    // copy to history so we can seek back
-    if ((int) m_HistoryBuffer.getMaxWriteSize() < nRead)
-      m_HistoryBuffer.SkipBytes(nRead);
-    m_HistoryBuffer.WriteData(pBuffer, nRead);
-
-    m_nStartPosition += nRead;
-  }
-
-  // check forward buffer and copy it when enough space is available
-  if (m_forwardBuffer.getMaxReadSize() > 0 && m_buffer.getMaxWriteSize() >= m_forwardBuffer.getMaxReadSize())
-  {
-    m_buffer.Append(m_forwardBuffer);
-    m_forwardBuffer.Clear();
-  }
-
-  if (nRead > 0)
-    m_space.Set();
-
-  return nRead;
-}
-
-int64_t CacheMemBuffer::WaitForData(unsigned int iMinAvail, unsigned int millis)
-{
-  if (millis == 0 || IsEndOfInput())
-    return m_buffer.getMaxReadSize();
-
-  XbmcThreads::EndTime endTime(millis);
-  while (!IsEndOfInput() && (unsigned int) m_buffer.getMaxReadSize() < iMinAvail && !endTime.IsTimePast() )
-    m_written.WaitMSec(50); // may miss the deadline. shouldn't be a problem.
-
-  return m_buffer.getMaxReadSize();
-}
-
-int64_t CacheMemBuffer::Seek(int64_t iFilePosition)
-{
-  CSingleLock lock(m_sync);
-
-  // if seek is a bit over what we have, try to wait a few seconds for the data to be available.
-  // we try to avoid a (heavy) seek on the source
-  if (iFilePosition > m_nStartPosition + m_buffer.getMaxReadSize() &&
-      iFilePosition < m_nStartPosition + m_buffer.getMaxReadSize() + 100000)
-  {
-    int nRequired = (int)(iFilePosition - (m_nStartPosition + m_buffer.getMaxReadSize()));
-    lock.Leave();
-    WaitForData(nRequired + 1, 5000);
-    lock.Enter();
-  }
-
-  // check if seek is inside the current buffer
-  if (iFilePosition >= m_nStartPosition && iFilePosition < m_nStartPosition + m_buffer.getMaxReadSize())
-  {
-    unsigned int nOffset = (unsigned int)(iFilePosition - m_nStartPosition);
-    // copy to history so we can seek back
-    if (m_HistoryBuffer.getMaxWriteSize() < nOffset)
-      m_HistoryBuffer.SkipBytes(nOffset);
-
-    if (!m_buffer.ReadData(m_HistoryBuffer, nOffset))
-    {
-      CLog::Log(LOGERROR, "%s, failed to copy %d bytes to history", __FUNCTION__, nOffset);
-    }
-
-    m_nStartPosition = iFilePosition;
-    m_space.Set();
-    return m_nStartPosition;
-  }
-
-  int64_t iHistoryStart = m_nStartPosition - m_HistoryBuffer.getMaxReadSize();
-  if (iFilePosition < m_nStartPosition && iFilePosition >= iHistoryStart)
-  {
-    CRingBuffer saveHist, saveUnRead;
-    int64_t nToSkip = iFilePosition - iHistoryStart;
-    SEEK_CHECK_RET(m_HistoryBuffer.ReadData(saveHist, (int)nToSkip));
-
-    SEEK_CHECK_RET(saveUnRead.Copy(m_buffer));
-
-    SEEK_CHECK_RET(m_buffer.Copy(m_HistoryBuffer));
-    int nSpace = m_buffer.getMaxWriteSize();
-    int nToCopy = saveUnRead.getMaxReadSize();
-
-    if (nToCopy < nSpace)
-      nSpace = nToCopy;
-
-    SEEK_CHECK_RET(saveUnRead.ReadData(m_buffer, nSpace));
-    nToCopy -= nSpace;
-    if (nToCopy > 0)
-      m_forwardBuffer.Copy(saveUnRead);
-
-    m_nStartPosition = iFilePosition;
-    m_space.Set();
-    return m_nStartPosition;
-  }
-
-  // seek outside the buffer. return error.
-  return CACHE_RC_ERROR;
-}
-
-void CacheMemBuffer::Reset(int64_t iSourcePosition)
-{
-  CSingleLock lock(m_sync);
-  m_nStartPosition = iSourcePosition;
-  m_buffer.Clear();
-  m_HistoryBuffer.Clear();
-  m_forwardBuffer.Clear();
-}
-
-
diff --git a/xbmc/filesystem/CacheMemBuffer.h b/xbmc/filesystem/CacheMemBuffer.h
deleted file mode 100644 (file)
index c2fc109..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#ifndef CACHEMEMBUFFER_H
-#define CACHEMEMBUFFER_H
-
-#include "CacheStrategy.h"
-#include "threads/CriticalSection.h"
-#include "threads/Event.h"
-#include "utils/RingBuffer.h"
-
-/**
-  @author Team XBMC
-*/
-namespace XFILE {
-
-class CacheMemBuffer : public CCacheStrategy
-{
-public:
-    CacheMemBuffer();
-    virtual ~CacheMemBuffer();
-
-    virtual int Open() ;
-    virtual void Close();
-
-    virtual int WriteToCache(const char *pBuffer, size_t iSize) ;
-    virtual int ReadFromCache(char *pBuffer, size_t iMaxSize) ;
-    virtual int64_t WaitForData(unsigned int iMinAvail, unsigned int iMillis) ;
-
-    virtual int64_t Seek(int64_t iFilePosition) ;
-    virtual void Reset(int64_t iSourcePosition) ;
-
-protected:
-    int64_t m_nStartPosition;
-    CRingBuffer m_buffer;
-    CRingBuffer m_HistoryBuffer;
-    CRingBuffer m_forwardBuffer; // for seek cases, to store data already read
-    CCriticalSection m_sync;
-    CEvent m_written;
-};
-
-} // namespace XFILE
-#endif
diff --git a/xbmc/filesystem/CircularCache.cpp b/xbmc/filesystem/CircularCache.cpp
new file mode 100644 (file)
index 0000000..30429d1
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "threads/SystemClock.h"
+#include "system.h"
+#include "utils/log.h"
+#include "threads/SingleLock.h"
+#include "utils/TimeUtils.h"
+#include "CircularCache.h"
+
+using namespace XFILE;
+
+CCircularCache::CCircularCache(size_t front, size_t back)
+ : CCacheStrategy()
+ , m_beg(0)
+ , m_end(0)
+ , m_cur(0)
+ , m_buf(NULL)
+ , m_size(front + back)
+ , m_size_back(back)
+#ifdef _WIN32
+ , m_handle(INVALID_HANDLE_VALUE)
+#endif
+{
+}
+
+CCircularCache::~CCircularCache()
+{
+  Close();
+}
+
+int CCircularCache::Open()
+{
+#ifdef _WIN32
+  m_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, m_size, NULL);
+  if(m_handle == INVALID_HANDLE_VALUE)
+    return CACHE_RC_ERROR;
+  m_buf = (uint8_t*)MapViewOfFile(m_handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
+#else
+  m_buf = new uint8_t[m_size];
+#endif
+  if(m_buf == 0)
+    return CACHE_RC_ERROR;
+  m_beg = 0;
+  m_end = 0;
+  m_cur = 0;
+  return CACHE_RC_OK;
+}
+
+void CCircularCache::Close()
+{
+#ifdef _WIN32
+  UnmapViewOfFile(m_buf);
+  CloseHandle(m_handle);
+  m_handle = INVALID_HANDLE_VALUE;
+#else
+  delete[] m_buf;
+#endif
+  m_buf = NULL;
+}
+
+/**
+ * Function will write to m_buf at m_end % m_size location
+ * it will write at maximum m_size, but it will only write
+ * as much it can without wrapping around in the buffer
+ *
+ * It will always leave m_size_back of the backbuffer intact
+ * but if the back buffer is less than that, that space is
+ * usable to write.
+ *
+ * If back buffer is filled to an larger extent than
+ * m_size_back, it will allow it to be overwritten
+ * until only m_size_back data remains.
+ *
+ * The following always apply:
+ *  * m_end <= m_cur <= m_end
+ *  * m_end - m_beg <= m_size
+ *
+ * Multiple calls may be needed to fill buffer completely.
+ */
+int CCircularCache::WriteToCache(const char *buf, size_t len)
+{
+  CSingleLock lock(m_sync);
+
+  // where are we in the buffer
+  size_t pos   = m_end % m_size;
+  size_t back  = (size_t)(m_cur - m_beg);
+  size_t front = (size_t)(m_end - m_cur);
+
+  size_t limit = m_size - std::min(back, m_size_back) - front;
+  size_t wrap  = m_size - pos;
+
+  // limit by max forward size
+  if(len > limit)
+    len = limit;
+
+  // limit to wrap point
+  if(len > wrap)
+    len = wrap;
+
+  if(len == 0)
+    return 0;
+
+  // write the data
+  memcpy(m_buf + pos, buf, len);
+  m_end += len;
+
+  // drop history that was overwritten
+  if(m_end - m_beg > m_size)
+    m_beg = m_end - m_size;
+
+  m_written.Set();
+
+  return len;
+}
+
+/**
+ * Reads data from cache. Will only read up till
+ * the buffer wrap point. So multiple calls
+ * may be needed to empty the whole cache
+ */
+int CCircularCache::ReadFromCache(char *buf, size_t len)
+{
+  CSingleLock lock(m_sync);
+
+  size_t pos   = m_cur % m_size;
+  size_t front = (size_t)(m_end - m_cur);
+  size_t avail = std::min(m_size - pos, front);
+
+  if(avail == 0)
+  {
+    if(IsEndOfInput())
+      return 0;
+    else
+      return CACHE_RC_WOULD_BLOCK;
+  }
+
+  if(len > avail)
+    len = avail;
+
+  if(len == 0)
+    return 0;
+
+  memcpy(buf, m_buf + pos, len);
+  m_cur += len;
+
+  m_space.Set();
+
+  return len;
+}
+
+int64_t CCircularCache::WaitForData(unsigned int minumum, unsigned int millis)
+{
+  CSingleLock lock(m_sync);
+  uint64_t avail = m_end - m_cur;
+
+  if(millis == 0 || IsEndOfInput())
+    return avail;
+
+  if(minumum > m_size - m_size_back)
+    minumum = m_size - m_size_back;
+
+  XbmcThreads::EndTime endtime(millis);
+  while (!IsEndOfInput() && avail < minumum && !endtime.IsTimePast() )
+  {
+    lock.Leave();
+    m_written.WaitMSec(50); // may miss the deadline. shouldn't be a problem.
+    lock.Enter();
+    avail = m_end - m_cur;
+  }
+
+  return avail;
+}
+
+int64_t CCircularCache::Seek(int64_t pos)
+{
+  CSingleLock lock(m_sync);
+
+  // if seek is a bit over what we have, try to wait a few seconds for the data to be available.
+  // we try to avoid a (heavy) seek on the source
+  if ((uint64_t)pos >= m_end && (uint64_t)pos < m_end + 100000)
+  {
+    lock.Leave();
+    WaitForData((size_t)(pos - m_cur), 5000);
+    lock.Enter();
+  }
+
+  if((uint64_t)pos >= m_beg && (uint64_t)pos <= m_end)
+  {
+    m_cur = pos;
+    return pos;
+  }
+
+  return CACHE_RC_ERROR;
+}
+
+void CCircularCache::Reset(int64_t pos)
+{
+  CSingleLock lock(m_sync);
+  m_end = pos;
+  m_beg = pos;
+  m_cur = pos;
+}
+
diff --git a/xbmc/filesystem/CircularCache.h b/xbmc/filesystem/CircularCache.h
new file mode 100644 (file)
index 0000000..391c3a2
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifndef CACHECIRCULAR_H
+#define CACHECIRCULAR_H
+
+#include "CacheStrategy.h"
+#include "threads/CriticalSection.h"
+#include "threads/Event.h"
+
+namespace XFILE {
+
+class CCircularCache : public CCacheStrategy
+{
+public:
+    CCircularCache(size_t front, size_t back);
+    virtual ~CCircularCache();
+
+    virtual int Open() ;
+    virtual void Close();
+
+    virtual int WriteToCache(const char *buf, size_t len) ;
+    virtual int ReadFromCache(char *buf, size_t len) ;
+    virtual int64_t WaitForData(unsigned int minimum, unsigned int iMillis) ;
+
+    virtual int64_t Seek(int64_t pos) ;
+    virtual void Reset(int64_t pos) ;
+
+protected:
+    uint64_t          m_beg;       /**< index in file (not buffer) of beginning of valid data */
+    uint64_t          m_end;       /**< index in file (not buffer) of end of valid data */
+    uint64_t          m_cur;       /**< current reading index in file */
+    uint8_t          *m_buf;       /**< buffer holding data */
+    size_t            m_size;      /**< size of data buffer used (m_buf) */
+    size_t            m_size_back; /**< guaranteed size of back buffer (actual size can be smaller, or larger if front buffer doesn't need it) */
+    CCriticalSection  m_sync;
+    CEvent            m_written;
+#ifdef _WIN32
+    HANDLE            m_handle;
+#endif
+};
+
+} // namespace XFILE
+#endif
diff --git a/xbmc/filesystem/CurlFile.cpp b/xbmc/filesystem/CurlFile.cpp
new file mode 100644 (file)
index 0000000..29ae694
--- /dev/null
@@ -0,0 +1,1400 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "CurlFile.h"
+#include "utils/URIUtils.h"
+#include "Util.h"
+#include "URL.h"
+#include "settings/AdvancedSettings.h"
+#include "settings/GUISettings.h"
+#include "settings/Settings.h"
+#include "File.h"
+
+#include <vector>
+#include <climits>
+
+#ifdef _LINUX
+#include <errno.h>
+#include <inttypes.h>
+#include "../linux/XFileUtils.h"
+#include "../linux/XTimeUtils.h"
+#include "../linux/ConvUtils.h"
+#endif
+
+#include "DllLibCurl.h"
+#include "ShoutcastFile.h"
+#include "SpecialProtocol.h"
+#include "utils/CharsetConverter.h"
+#include "utils/log.h"
+
+using namespace XFILE;
+using namespace XCURL;
+
+#define XMIN(a,b) ((a)<(b)?(a):(b))
+#define FITS_INT(a) (((a) <= INT_MAX) && ((a) >= INT_MIN))
+
+#define dllselect select
+
+// curl calls this routine to debug
+extern "C" int debug_callback(CURL_HANDLE *handle, curl_infotype info, char *output, size_t size, void *data)
+{
+  if (info == CURLINFO_DATA_IN || info == CURLINFO_DATA_OUT)
+    return 0;
+
+  // Only shown cURL debug into with loglevel DEBUG_SAMBA or higher
+  if( g_advancedSettings.m_logLevel < LOG_LEVEL_DEBUG_SAMBA )
+    return 0;
+
+  CStdString strLine;
+  strLine.append(output, size);
+  std::vector<CStdString> vecLines;
+  CUtil::Tokenize(strLine, vecLines, "\r\n");
+  std::vector<CStdString>::const_iterator it = vecLines.begin();
+
+  while (it != vecLines.end()) {
+    CLog::Log(LOGDEBUG, "Curl::Debug %s", (*it).c_str());
+    it++;
+  }
+  return 0;
+}
+
+/* curl calls this routine to get more data */
+extern "C" size_t write_callback(char *buffer,
+               size_t size,
+               size_t nitems,
+               void *userp)
+{
+  if(userp == NULL) return 0;
+
+  CCurlFile::CReadState *state = (CCurlFile::CReadState *)userp;
+  return state->WriteCallback(buffer, size, nitems);
+}
+
+extern "C" size_t header_callback(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+  CCurlFile::CReadState *state = (CCurlFile::CReadState *)stream;
+  return state->HeaderCallback(ptr, size, nmemb);
+}
+
+/* fix for silly behavior of realloc */
+static inline void* realloc_simple(void *ptr, size_t size)
+{
+  void *ptr2 = realloc(ptr, size);
+  if(ptr && !ptr2 && size > 0)
+  {
+    free(ptr);
+    return NULL;
+  }
+  else
+    return ptr2;
+}
+
+size_t CCurlFile::CReadState::HeaderCallback(void *ptr, size_t size, size_t nmemb)
+{
+  // clear any previous header
+  if(m_headerdone)
+  {
+    m_httpheader.Clear();
+    m_headerdone = false;
+  }
+
+  // libcurl doc says that this info is not always \0 terminated
+  char* strData = (char*)ptr;
+  int iSize = size * nmemb;
+
+  if (strData[iSize] != 0)
+  {
+    strData = (char*)malloc(iSize + 1);
+    strncpy(strData, (char*)ptr, iSize);
+    strData[iSize] = 0;
+  }
+  else strData = strdup((char*)ptr);
+
+  if(strcmp(strData, "\r\n") == 0)
+    m_headerdone = true;
+
+  m_httpheader.Parse(strData);
+
+  free(strData);
+
+  return iSize;
+}
+
+size_t CCurlFile::CReadState::WriteCallback(char *buffer, size_t size, size_t nitems)
+{
+  unsigned int amount = size * nitems;
+//  CLog::Log(LOGDEBUG, "CCurlFile::WriteCallback (%p) with %i bytes, readsize = %i, writesize = %i", this, amount, m_buffer.getMaxReadSize(), m_buffer.getMaxWriteSize() - m_overflowSize);
+  if (m_overflowSize)
+  {
+    // we have our overflow buffer - first get rid of as much as we can
+    unsigned int maxWriteable = XMIN((unsigned int)m_buffer.getMaxWriteSize(), m_overflowSize);
+    if (maxWriteable)
+    {
+      if (!m_buffer.WriteData(m_overflowBuffer, maxWriteable))
+        CLog::Log(LOGERROR, "Unable to write to buffer - what's up?");
+      if (m_overflowSize > maxWriteable)
+      { // still have some more - copy it down
+        memmove(m_overflowBuffer, m_overflowBuffer + maxWriteable, m_overflowSize - maxWriteable);
+      }
+      m_overflowSize -= maxWriteable;
+    }
+  }
+  // ok, now copy the data into our ring buffer
+  unsigned int maxWriteable = XMIN((unsigned int)m_buffer.getMaxWriteSize(), amount);
+  if (maxWriteable)
+  {
+    if (!m_buffer.WriteData(buffer, maxWriteable))
+    {
+      CLog::Log(LOGERROR, "%s - Unable to write to buffer with %i bytes - what's up?", __FUNCTION__, maxWriteable);
+    }
+    else
+    {
+      amount -= maxWriteable;
+      buffer += maxWriteable;
+    }
+  }
+  if (amount)
+  {
+//    CLog::Log(LOGDEBUG, "CCurlFile::WriteCallback(%p) not enough free space for %i bytes", (void*)this,  amount);
+
+    m_overflowBuffer = (char*)realloc_simple(m_overflowBuffer, amount + m_overflowSize);
+    if(m_overflowBuffer == NULL)
+    {
+      CLog::Log(LOGWARNING, "%s - Failed to grow overflow buffer from %i bytes to %i bytes", __FUNCTION__, m_overflowSize, amount + m_overflowSize);
+      return 0;
+    }
+    memcpy(m_overflowBuffer + m_overflowSize, buffer, amount);
+    m_overflowSize += amount;
+  }
+  return size * nitems;
+}
+
+CCurlFile::CReadState::CReadState()
+{
+  m_easyHandle = NULL;
+  m_multiHandle = NULL;
+  m_overflowBuffer = NULL;
+  m_overflowSize = 0;
+  m_filePos = 0;
+  m_fileSize = 0;
+  m_bufferSize = 0;
+  m_cancelled = false;
+  m_bFirstLoop = true;
+  m_headerdone = false;
+}
+
+CCurlFile::CReadState::~CReadState()
+{
+  Disconnect();
+
+  if(m_easyHandle)
+    g_curlInterface.easy_release(&m_easyHandle, &m_multiHandle);
+}
+
+bool CCurlFile::CReadState::Seek(int64_t pos)
+{
+  if(pos == m_filePos)
+    return true;
+
+  if(FITS_INT(pos - m_filePos) && m_buffer.SkipBytes((int)(pos - m_filePos)))
+  {
+    m_filePos = pos;
+    return true;
+  }
+
+  if(pos > m_filePos && pos < m_filePos + m_bufferSize)
+  {
+    int len = m_buffer.getMaxReadSize();
+    m_filePos += len;
+    m_buffer.SkipBytes(len);
+    if(!FillBuffer(m_bufferSize))
+    {
+      if(!m_buffer.SkipBytes(-len))
+        CLog::Log(LOGERROR, "%s - Failed to restore position after failed fill", __FUNCTION__);
+      else
+        m_filePos -= len;
+      return false;
+    }
+
+    if(!FITS_INT(pos - m_filePos) || !m_buffer.SkipBytes((int)(pos - m_filePos)))
+    {
+      CLog::Log(LOGERROR, "%s - Failed to skip to position after having filled buffer", __FUNCTION__);
+      if(!m_buffer.SkipBytes(-len))
+        CLog::Log(LOGERROR, "%s - Failed to restore position after failed seek", __FUNCTION__);
+      else
+        m_filePos -= len;
+      return false;
+    }
+    m_filePos = pos;
+    return true;
+  }
+  return false;
+}
+
+long CCurlFile::CReadState::Connect(unsigned int size)
+{
+  g_curlInterface.easy_setopt(m_easyHandle, CURLOPT_RESUME_FROM_LARGE, m_filePos);
+  g_curlInterface.multi_add_handle(m_multiHandle, m_easyHandle);
+
+  m_bufferSize = size;
+  m_buffer.Destroy();
+  m_buffer.Create(size * 3);
+  m_headerdone = false;
+
+  // read some data in to try and obtain the length
+  // maybe there's a better way to get this info??
+  m_stillRunning = 1;
+  if (!FillBuffer(1))
+  {
+    CLog::Log(LOGERROR, "CCurlFile::CReadState::Open, didn't get any data from stream.");
+    return -1;
+  }
+
+  double length;
+  if (CURLE_OK == g_curlInterface.easy_getinfo(m_easyHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &length))
+  {
+    if (length < 0)
+      length = 0.0;
+    m_fileSize = m_filePos + (int64_t)length;
+  }
+
+  long response;
+  if (CURLE_OK == g_curlInterface.easy_getinfo(m_easyHandle, CURLINFO_RESPONSE_CODE, &response))
+    return response;
+
+  return -1;
+}
+
+void CCurlFile::CReadState::Disconnect()
+{
+  if(m_multiHandle && m_easyHandle)
+    g_curlInterface.multi_remove_handle(m_multiHandle, m_easyHandle);
+
+  m_buffer.Clear();
+  free(m_overflowBuffer);
+  m_overflowBuffer = NULL;
+  m_overflowSize = 0;
+  m_filePos = 0;
+  m_fileSize = 0;
+  m_bufferSize = 0;
+}
+
+
+CCurlFile::~CCurlFile()
+{
+  if (m_opened)
+    Close();
+  delete m_state;
+  g_curlInterface.Unload();
+}
+
+CCurlFile::CCurlFile()
+{
+  g_curlInterface.Load(); // loads the curl dll and resolves exports etc.
+  m_curlAliasList = NULL;
+  m_curlHeaderList = NULL;
+  m_opened = false;
+  m_multisession  = true;
+  m_seekable = true;
+  m_useOldHttpVersion = false;
+  m_connecttimeout = 0;
+  m_lowspeedtime = 0;
+  m_ftpauth = "";
+  m_ftpport = "";
+  m_ftppasvip = false;
+  m_bufferSize = 32768;
+  m_binary = true;
+  m_postdata = "";
+  m_username = "";
+  m_password = "";
+  m_httpauth = "";
+  m_state = new CReadState();
+  m_skipshout = false;
+}
+
+//Has to be called before Open()
+void CCurlFile::SetBufferSize(unsigned int size)
+{
+  m_bufferSize = size;
+}
+
+void CCurlFile::Close()
+{
+  m_state->Disconnect();
+
+  m_url.Empty();
+  m_referer.Empty();
+  m_cookie.Empty();
+
+  /* cleanup */
+  if( m_curlAliasList )
+    g_curlInterface.slist_free_all(m_curlAliasList);
+  if( m_curlHeaderList )
+    g_curlInterface.slist_free_all(m_curlHeaderList);
+
+  m_curlAliasList = NULL;
+  m_curlHeaderList = NULL;
+  m_opened = false;
+}
+
+void CCurlFile::SetCommonOptions(CReadState* state)
+{
+  CURL_HANDLE* h = state->m_easyHandle;
+
+  g_curlInterface.easy_reset(h);
+
+  g_curlInterface.easy_setopt(h, CURLOPT_DEBUGFUNCTION, debug_callback);
+
+  if( g_advancedSettings.m_logLevel >= LOG_LEVEL_DEBUG )
+    g_curlInterface.easy_setopt(h, CURLOPT_VERBOSE, TRUE);
+  else
+    g_curlInterface.easy_setopt(h, CURLOPT_VERBOSE, FALSE);
+
+  g_curlInterface.easy_setopt(h, CURLOPT_WRITEDATA, state);
+  g_curlInterface.easy_setopt(h, CURLOPT_WRITEFUNCTION, write_callback);
+
+  // set username and password for current handle
+  if (m_username.length() > 0 && m_password.length() > 0)
+  {
+    CStdString userpwd = m_username + ":" + m_password;
+    g_curlInterface.easy_setopt(h, CURLOPT_USERPWD, userpwd.c_str());
+  }
+
+  // make sure headers are seperated from the data stream
+  g_curlInterface.easy_setopt(h, CURLOPT_WRITEHEADER, state);
+  g_curlInterface.easy_setopt(h, CURLOPT_HEADERFUNCTION, header_callback);
+  g_curlInterface.easy_setopt(h, CURLOPT_HEADER, FALSE);
+
+  g_curlInterface.easy_setopt(h, CURLOPT_FTP_USE_EPSV, 0); // turn off epsv
+
+  // Allow us to follow two redirects
+  g_curlInterface.easy_setopt(h, CURLOPT_FOLLOWLOCATION, TRUE);
+  g_curlInterface.easy_setopt(h, CURLOPT_MAXREDIRS, 5);
+
+  // Enable cookie engine for current handle to re-use them in future requests
+  CStdString strCookieFile;
+  CStdString strTempPath = CSpecialProtocol::TranslatePath(g_advancedSettings.m_cachePath);
+  URIUtils::AddFileToFolder(strTempPath, "cookies.dat", strCookieFile);
+
+  g_curlInterface.easy_setopt(h, CURLOPT_COOKIEFILE, strCookieFile.c_str());
+  g_curlInterface.easy_setopt(h, CURLOPT_COOKIEJAR, strCookieFile.c_str());
+
+  // Set custom cookie if requested
+  if (!m_cookie.IsEmpty())
+    g_curlInterface.easy_setopt(h, CURLOPT_COOKIE, m_cookie.c_str());
+
+  g_curlInterface.easy_setopt(h, CURLOPT_COOKIELIST, "FLUSH");
+
+  // When using multiple threads you should set the CURLOPT_NOSIGNAL option to
+  // TRUE for all handles. Everything will work fine except that timeouts are not
+  // honored during the DNS lookup - which you can work around by building libcurl
+  // with c-ares support. c-ares is a library that provides asynchronous name
+  // resolves. Unfortunately, c-ares does not yet support IPv6.
+  g_curlInterface.easy_setopt(h, CURLOPT_NOSIGNAL, TRUE);
+
+  // not interested in failed requests
+  g_curlInterface.easy_setopt(h, CURLOPT_FAILONERROR, 1);
+
+  // enable support for icecast / shoutcast streams
+  m_curlAliasList = g_curlInterface.slist_append(m_curlAliasList, "ICY 200 OK");
+  g_curlInterface.easy_setopt(h, CURLOPT_HTTP200ALIASES, m_curlAliasList);
+
+  // never verify peer, we don't have any certificates to do this
+  g_curlInterface.easy_setopt(h, CURLOPT_SSL_VERIFYPEER, 0);
+  g_curlInterface.easy_setopt(h, CURLOPT_SSL_VERIFYHOST, 0);
+
+  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_URL, m_url.c_str());
+  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TRANSFERTEXT, FALSE);
+
+  // setup POST data if it exists
+  if (!m_postdata.IsEmpty())
+  {
+    g_curlInterface.easy_setopt(h, CURLOPT_POST, 1 );
+    g_curlInterface.easy_setopt(h, CURLOPT_POSTFIELDSIZE, m_postdata.length());
+    g_curlInterface.easy_setopt(h, CURLOPT_POSTFIELDS, m_postdata.c_str());
+  }
+
+  // setup Referer header if needed
+  if (!m_referer.IsEmpty())
+    g_curlInterface.easy_setopt(h, CURLOPT_REFERER, m_referer.c_str());
+  else
+  {
+    g_curlInterface.easy_setopt(h, CURLOPT_REFERER, NULL);
+    g_curlInterface.easy_setopt(h, CURLOPT_AUTOREFERER, TRUE);
+  }
+
+  // setup any requested authentication
+  if( m_ftpauth.length() > 0 )
+  {
+    g_curlInterface.easy_setopt(h, CURLOPT_FTP_SSL, CURLFTPSSL_TRY);
+    if( m_ftpauth.Equals("any") )
+      g_curlInterface.easy_setopt(h, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_DEFAULT);
+    else if( m_ftpauth.Equals("ssl") )
+      g_curlInterface.easy_setopt(h, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_SSL);
+    else if( m_ftpauth.Equals("tls") )
+      g_curlInterface.easy_setopt(h, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_TLS);
+  }
+
+  // setup requested http authentication method
+  if(m_httpauth.length() > 0)
+  {
+    if( m_httpauth.Equals("any") )
+      g_curlInterface.easy_setopt(h, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+    else if( m_httpauth.Equals("anysafe") )
+      g_curlInterface.easy_setopt(h, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
+    else if( m_httpauth.Equals("digest") )
+      g_curlInterface.easy_setopt(h, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+    else if( m_httpauth.Equals("ntlm") )
+      g_curlInterface.easy_setopt(h, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
+  }
+
+  // allow passive mode for ftp
+  if( m_ftpport.length() > 0 )
+    g_curlInterface.easy_setopt(h, CURLOPT_FTPPORT, m_ftpport.c_str());
+  else
+    g_curlInterface.easy_setopt(h, CURLOPT_FTPPORT, NULL);
+
+  // allow curl to not use the ip address in the returned pasv response
+  if( m_ftppasvip )
+    g_curlInterface.easy_setopt(h, CURLOPT_FTP_SKIP_PASV_IP, 0);
+  else
+    g_curlInterface.easy_setopt(h, CURLOPT_FTP_SKIP_PASV_IP, 1);
+
+  // setup Content-Encoding if requested
+  if( m_contentencoding.length() > 0 )
+    g_curlInterface.easy_setopt(h, CURLOPT_ENCODING, m_contentencoding.c_str());
+
+  if (m_userAgent.length() > 0)
+    g_curlInterface.easy_setopt(h, CURLOPT_USERAGENT, m_userAgent.c_str());
+  else /* set some default agent as shoutcast doesn't return proper stuff otherwise */
+    g_curlInterface.easy_setopt(h, CURLOPT_USERAGENT, g_settings.m_userAgent.c_str());
+
+  if (m_useOldHttpVersion)
+    g_curlInterface.easy_setopt(h, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+  else
+    SetRequestHeader("Connection", "keep-alive");
+
+  if (g_advancedSettings.m_curlDisableIPV6)
+    g_curlInterface.easy_setopt(h, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+
+  if (m_proxy.length() > 0)
+  {
+    g_curlInterface.easy_setopt(h, CURLOPT_PROXY, m_proxy.c_str());
+    if (m_proxyuserpass.length() > 0)
+      g_curlInterface.easy_setopt(h, CURLOPT_PROXYUSERPWD, m_proxyuserpass.c_str());
+
+  }
+  if (m_customrequest.length() > 0)
+    g_curlInterface.easy_setopt(h, CURLOPT_CUSTOMREQUEST, m_customrequest.c_str());
+
+  if (m_connecttimeout == 0)
+    m_connecttimeout = g_advancedSettings.m_curlconnecttimeout;
+
+  // set our timeouts, we abort connection after m_timeout, and reads after no data for m_timeout seconds
+  g_curlInterface.easy_setopt(h, CURLOPT_CONNECTTIMEOUT, m_connecttimeout);
+
+  // We abort in case we transfer less than 1byte/second
+  g_curlInterface.easy_setopt(h, CURLOPT_LOW_SPEED_LIMIT, 1);
+
+  if (m_lowspeedtime == 0)
+    m_lowspeedtime = g_advancedSettings.m_curllowspeedtime;
+
+  // Set the lowspeed time very low as it seems Curl takes much longer to detect a lowspeed condition
+  g_curlInterface.easy_setopt(h, CURLOPT_LOW_SPEED_TIME, m_lowspeedtime);
+}
+
+void CCurlFile::SetRequestHeaders(CReadState* state)
+{
+  if(m_curlHeaderList)
+  {
+    g_curlInterface.slist_free_all(m_curlHeaderList);
+    m_curlHeaderList = NULL;
+  }
+
+  MAPHTTPHEADERS::iterator it;
+  for(it = m_requestheaders.begin(); it != m_requestheaders.end(); it++)
+  {
+    CStdString buffer = it->first + ": " + it->second;
+    m_curlHeaderList = g_curlInterface.slist_append(m_curlHeaderList, buffer.c_str());
+  }
+
+  // add user defined headers
+  if (m_curlHeaderList && state->m_easyHandle)
+    g_curlInterface.easy_setopt(state->m_easyHandle, CURLOPT_HTTPHEADER, m_curlHeaderList);
+
+}
+
+void CCurlFile::SetCorrectHeaders(CReadState* state)
+{
+  CHttpHeader& h = state->m_httpheader;
+  /* workaround for shoutcast server wich doesn't set content type on standard mp3 */
+  if( h.GetMimeType().IsEmpty() )
+  {
+    if( !h.GetValue("icy-notice1").IsEmpty()
+    || !h.GetValue("icy-name").IsEmpty()
+    || !h.GetValue("icy-br").IsEmpty() )
+    h.Parse("Content-Type: audio/mpeg\r\n");
+  }
+
+  /* hack for google video */
+  if ( h.GetMimeType().Equals("text/html")
+  &&  !h.GetValue("Content-Disposition").IsEmpty() )
+  {
+    CStdString strValue = h.GetValue("Content-Disposition");
+    if (strValue.Find("filename=") > -1 && strValue.Find(".flv") > -1)
+      h.Parse("Content-Type: video/flv\r\n");
+  }
+}
+
+void CCurlFile::ParseAndCorrectUrl(CURL &url2)
+{
+  CStdString strProtocol = url2.GetTranslatedProtocol();
+  url2.SetProtocol(strProtocol);
+
+  if( strProtocol.Equals("ftp")
+  ||  strProtocol.Equals("ftps") )
+  {
+    /* this is uggly, depending on from where   */
+    /* we get the link it may or may not be     */
+    /* url encoded. if handed from ftpdirectory */
+    /* it won't be so let's handle that case    */
+
+    CStdString partial, filename(url2.GetFileName());
+    CStdStringArray array;
+
+    /* our current client doesn't support utf8 */
+    g_charsetConverter.utf8ToStringCharset(filename);
+
+    /* TODO: create a tokenizer that doesn't skip empty's */
+    CUtil::Tokenize(filename, array, "/");
+    filename.Empty();
+    for(CStdStringArray::iterator it = array.begin(); it != array.end(); it++)
+    {
+      if(it != array.begin())
+        filename += "/";
+
+      partial = *it;
+      CURL::Encode(partial);
+      filename += partial;
+    }
+
+    /* make sure we keep slashes */
+    if(url2.GetFileName().Right(1) == "/")
+      filename += "/";
+
+    url2.SetFileName(filename);
+
+    CStdString options = url2.GetOptions().Mid(1);
+    options.TrimRight('/'); // hack for trailing slashes being added from source
+
+    m_ftpauth = "";
+    m_ftpport = "";
+    m_ftppasvip = false;
+
+    /* parse options given */
+    CUtil::Tokenize(options, array, "&");
+    for(CStdStringArray::iterator it = array.begin(); it != array.end(); it++)
+    {
+      CStdString name, value;
+      int pos = it->Find('=');
+      if(pos >= 0)
+      {
+        name = it->Left(pos);
+        value = it->Mid(pos+1, it->size());
+      }
+      else
+      {
+        name = (*it);
+        value = "";
+      }
+
+      if(name.Equals("auth"))
+      {
+        m_ftpauth = value;
+        if(m_ftpauth.IsEmpty())
+          m_ftpauth = "any";
+      }
+      else if(name.Equals("active"))
+      {
+        m_ftpport = value;
+        if(value.IsEmpty())
+          m_ftpport = "-";
+      }
+      else if(name.Equals("pasvip"))
+      {
+        if(value == "0")
+          m_ftppasvip = false;
+        else
+          m_ftppasvip = true;
+      }
+    }
+
+    /* ftp has no options */
+    url2.SetOptions("");
+  }
+  else if( strProtocol.Equals("http")
+       ||  strProtocol.Equals("https"))
+  {
+    if (g_guiSettings.GetBool("network.usehttpproxy") && m_proxy.IsEmpty())
+    {
+      m_proxy = "http://" + g_guiSettings.GetString("network.httpproxyserver");
+      m_proxy += ":" + g_guiSettings.GetString("network.httpproxyport");
+      if (g_guiSettings.GetString("network.httpproxyusername").length() > 0 && m_proxyuserpass.IsEmpty())
+      {
+        m_proxyuserpass = g_guiSettings.GetString("network.httpproxyusername");
+        m_proxyuserpass += ":" + g_guiSettings.GetString("network.httpproxypassword");
+      }
+      CLog::Log(LOGDEBUG, "Using proxy %s", m_proxy.c_str());
+    }
+
+    // get username and password
+    m_username = url2.GetUserName();
+    m_password = url2.GetPassWord();
+
+    // handle any protocol options
+    CStdString options = url2.GetProtocolOptions();
+    options.TrimRight('/'); // hack for trailing slashes being added from source
+    if (options.length() > 0)
+    {
+      // clear protocol options
+      url2.SetProtocolOptions("");
+      // set xbmc headers
+      CStdStringArray array;
+      CUtil::Tokenize(options, array, "&");
+      for(CStdStringArray::iterator it = array.begin(); it != array.end(); it++)
+      {
+        // parse name, value
+        CStdString name, value;
+        int pos = it->Find('=');
+        if(pos >= 0)
+        {
+          name = it->Left(pos);
+          value = it->Mid(pos+1, it->size());
+        }
+        else
+        {
+          name = (*it);
+          value = "";
+        }
+
+        // url decode value
+        CURL::Decode(value);
+
+        if(name.Equals("auth"))
+        {
+          m_httpauth = value;
+          if(m_httpauth.IsEmpty())
+            m_httpauth = "any";
+        }
+        else if (name.Equals("Referer"))
+          SetReferer(value);
+        else if (name.Equals("User-Agent"))
+          SetUserAgent(value);
+        else if (name.Equals("Cookie"))
+          SetCookie(value);
+        else if (name.Equals("Encoding"))
+          SetContentEncoding(value);
+        else if (name.Equals("noshout") && value.Equals("true"))
+          m_skipshout = true;
+        else
+          SetRequestHeader(name, value);
+      }
+    }
+  }
+
+  if (m_username.length() > 0 && m_password.length() > 0)
+    m_url = url2.GetWithoutUserDetails();
+  else
+    m_url = url2.Get();
+}
+
+bool CCurlFile::Post(const CStdString& strURL, const CStdString& strPostData, CStdString& strHTML)
+{
+  return Service(strURL, strPostData, strHTML);
+}
+
+bool CCurlFile::Get(const CStdString& strURL, CStdString& strHTML)
+{
+  return Service(strURL, "", strHTML);
+}
+
+bool CCurlFile::Service(const CStdString& strURL, const CStdString& strPostData, CStdString& strHTML)
+{
+  m_postdata = strPostData;
+  if (Open(strURL))
+  {
+    if (ReadData(strHTML))
+    {
+      Close();
+      return true;
+    }
+  }
+  Close();
+  return false;
+}
+
+bool CCurlFile::ReadData(CStdString& strHTML)
+{
+  int size_read = 0;
+  int data_size = 0;
+  strHTML = "";
+  char buffer[16384];
+  while( (size_read = Read(buffer, sizeof(buffer)-1) ) > 0 )
+  {
+    buffer[size_read] = 0;
+    strHTML.append(buffer, size_read);
+    data_size += size_read;
+  }
+  if (m_state->m_cancelled)
+    return false;
+  return true;
+}
+
+bool CCurlFile::Download(const CStdString& strURL, const CStdString& strFileName, LPDWORD pdwSize)
+{
+  CLog::Log(LOGINFO, "Download: %s->%s", strURL.c_str(), strFileName.c_str());
+
+  CStdString strData;
+  if (!Get(strURL, strData))
+    return false;
+
+  XFILE::CFile file;
+  if (!file.OpenForWrite(strFileName, true))
+  {
+    CLog::Log(LOGERROR, "Unable to open file %s: %u",
+    strFileName.c_str(), GetLastError());
+    return false;
+  }
+  if (strData.size())
+    file.Write(strData.c_str(), strData.size());
+  file.Close();
+
+  if (pdwSize != NULL)
+  {
+    *pdwSize = strData.size();
+  }
+
+  return true;
+}
+
+// Detect whether we are "online" or not! Very simple and dirty!
+bool CCurlFile::IsInternet(bool checkDNS /* = true */)
+{
+  CStdString strURL = "http://www.google.com";
+  if (!checkDNS)
+    strURL = "http://74.125.19.103"; // www.google.com ip
+
+  bool found = Exists(strURL);
+  Close();
+
+  return found;
+}
+
+void CCurlFile::Cancel()
+{
+  m_state->m_cancelled = true;
+  while (m_opened)
+    Sleep(1);
+}
+
+void CCurlFile::Reset()
+{
+  m_state->m_cancelled = false;
+}
+
+bool CCurlFile::Open(const CURL& url)
+{
+
+  m_opened = true;
+
+  CURL url2(url);
+  ParseAndCorrectUrl(url2);
+
+  CLog::Log(LOGDEBUG, "CurlFile::Open(%p) %s", (void*)this, m_url.c_str());
+
+  ASSERT(!(!m_state->m_easyHandle ^ !m_state->m_multiHandle));
+  if( m_state->m_easyHandle == NULL )
+    g_curlInterface.easy_aquire(url2.GetProtocol(), url2.GetHostName(), &m_state->m_easyHandle, &m_state->m_multiHandle );
+
+  // setup common curl options
+  SetCommonOptions(m_state);
+  SetRequestHeaders(m_state);
+
+  long response = m_state->Connect(m_bufferSize);
+  if( response < 0 || response >= 400)
+    return false;
+
+  SetCorrectHeaders(m_state);
+
+  // since we can't know the stream size up front if we're gzipped/deflated
+  // flag the stream with an unknown file size rather than the compressed
+  // file size.
+  if (m_contentencoding.size() > 0)
+    m_state->m_fileSize = 0;
+
+  // check if this stream is a shoutcast stream. sometimes checking the protocol line is not enough so examine other headers as well.
+  // shoutcast streams should be handled by FileShoutcast.
+  if ((m_state->m_httpheader.GetProtoLine().Left(3) == "ICY" || !m_state->m_httpheader.GetValue("icy-notice1").IsEmpty()
+     || !m_state->m_httpheader.GetValue("icy-name").IsEmpty()
+     || !m_state->m_httpheader.GetValue("icy-br").IsEmpty()) && !m_skipshout)
+  {
+    CLog::Log(LOGDEBUG,"CurlFile - file <%s> is a shoutcast stream. re-opening", m_url.c_str());
+    throw new CRedirectException(new CShoutcastFile);
+  }
+
+  m_multisession = false;
+  if(m_url.Left(5).Equals("http:") || m_url.Left(6).Equals("https:"))
+  {
+    m_multisession = true;
+    if(m_state->m_httpheader.GetValue("Server").Find("Portable SDK for UPnP devices") >= 0)
+    {
+      CLog::Log(LOGWARNING, "CurlFile - disabling multi session due to broken libupnp server");
+      m_multisession = false;
+    }
+  }
+
+  if(m_state->m_httpheader.GetValue("Transfer-Encoding").Equals("chunked"))
+    m_state->m_fileSize = 0;
+
+  m_seekable = false;
+  if(m_state->m_fileSize > 0)
+  {
+    m_seekable = true;
+
+    if(url2.GetProtocol().Equals("http")
+    || url2.GetProtocol().Equals("https"))
+    {
+      // if server says explicitly it can't seek, respect that
+      if(m_state->m_httpheader.GetValue("Accept-Ranges").Equals("none"))
+        m_seekable = false;
+    }
+  }
+
+  char* efurl;
+  if (CURLE_OK == g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_EFFECTIVE_URL,&efurl) && efurl)
+    m_url = efurl;
+
+  return true;
+}
+
+bool CCurlFile::CReadState::ReadString(char *szLine, int iLineLength)
+{
+  unsigned int want = (unsigned int)iLineLength;
+
+  if((m_fileSize == 0 || m_filePos < m_fileSize) && !FillBuffer(want))
+    return false;
+
+  // ensure only available data is considered
+  want = XMIN((unsigned int)m_buffer.getMaxReadSize(), want);
+
+  /* check if we finished prematurely */
+  if (!m_stillRunning && (m_fileSize == 0 || m_filePos != m_fileSize) && !want)
+  {
+    if (m_fileSize != 0)
+      CLog::Log(LOGWARNING, "%s - Transfer ended before entire file was retrieved pos %"PRId64", size %"PRId64, __FUNCTION__, m_filePos, m_fileSize);
+
+    return false;
+  }
+
+  char* pLine = szLine;
+  do
+  {
+    if (!m_buffer.ReadData(pLine, 1))
+      break;
+
+    pLine++;
+  } while (((pLine - 1)[0] != '\n') && ((unsigned int)(pLine - szLine) < want));
+  pLine[0] = 0;
+  m_filePos += (pLine - szLine);
+  return (bool)((pLine - szLine) > 0);
+}
+
+bool CCurlFile::Exists(const CURL& url)
+{
+  // if file is already running, get info from it
+  if( m_opened )
+  {
+    CLog::Log(LOGWARNING, "%s - Exist called on open file", __FUNCTION__);
+    return true;
+  }
+
+  CURL url2(url);
+  ParseAndCorrectUrl(url2);
+
+  ASSERT(m_state->m_easyHandle == NULL);
+  g_curlInterface.easy_aquire(url2.GetProtocol(), url2.GetHostName(), &m_state->m_easyHandle, NULL);
+
+  SetCommonOptions(m_state);
+  SetRequestHeaders(m_state);
+  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, 5);
+  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_NOBODY, 1);
+  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/
+
+  if(url2.GetProtocol() == "ftp")
+  {
+    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME, 1);
+    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD);
+  }
+
+  CURLcode result = g_curlInterface.easy_perform(m_state->m_easyHandle);
+  g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
+
+  if (result == CURLE_WRITE_ERROR || result == CURLE_OK)
+    return true;
+
+  errno = ENOENT;
+  return false;
+}
+
+int64_t CCurlFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  int64_t nextPos = m_state->m_filePos;
+  switch(iWhence)
+  {
+    case SEEK_SET:
+      nextPos = iFilePosition;
+      break;
+    case SEEK_CUR:
+      nextPos += iFilePosition;
+      break;
+    case SEEK_END:
+      if (m_state->m_fileSize)
+        nextPos = m_state->m_fileSize + iFilePosition;
+      else
+        return -1;
+      break;
+    default:
+      return -1;
+  }
+
+  // We can't seek beyond EOF
+  if (m_state->m_fileSize && nextPos > m_state->m_fileSize) return -1;
+
+  if(m_state->Seek(nextPos))
+    return nextPos;
+
+  if(!m_seekable)
+    return -1;
+
+  CReadState* oldstate = NULL;
+  if(m_multisession)
+  {
+    CURL url(m_url);
+    oldstate = m_state;
+    m_state = new CReadState();
+
+    g_curlInterface.easy_aquire(url.GetProtocol(), url.GetHostName(), &m_state->m_easyHandle, &m_state->m_multiHandle );
+
+    // setup common curl options
+    SetCommonOptions(m_state);
+  }
+  else
+    m_state->Disconnect();
+
+  /* caller might have changed some headers (needed for daap)*/
+  SetRequestHeaders(m_state);
+
+  m_state->m_filePos = nextPos;
+  if (oldstate)
+    m_state->m_fileSize = oldstate->m_fileSize;
+
+  long response = m_state->Connect(m_bufferSize);
+  if(response < 0 && (m_state->m_fileSize == 0 || m_state->m_fileSize != m_state->m_filePos))
+  {
+    m_seekable = false;
+    if(oldstate)
+    {
+      delete m_state;
+      m_state = oldstate;
+    }
+    return -1;
+  }
+
+  SetCorrectHeaders(m_state);
+  delete oldstate;
+
+  return m_state->m_filePos;
+}
+
+int64_t CCurlFile::GetLength()
+{
+  if (!m_opened) return 0;
+  return m_state->m_fileSize;
+}
+
+int64_t CCurlFile::GetPosition()
+{
+  if (!m_opened) return 0;
+  return m_state->m_filePos;
+}
+
+int CCurlFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  // if file is already running, get info from it
+  if( m_opened )
+  {
+    CLog::Log(LOGWARNING, "%s - Stat called on open file", __FUNCTION__);
+    if (buffer)
+    {
+      memset(buffer, 0, sizeof(struct __stat64));
+      buffer->st_size = GetLength();
+      buffer->st_mode = _S_IFREG;
+    }
+    return 0;
+  }
+
+  CURL url2(url);
+  ParseAndCorrectUrl(url2);
+
+  ASSERT(m_state->m_easyHandle == NULL);
+  g_curlInterface.easy_aquire(url2.GetProtocol(), url2.GetHostName(), &m_state->m_easyHandle, NULL);
+
+  SetCommonOptions(m_state);
+  SetRequestHeaders(m_state);
+  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, 5);
+  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_NOBODY, 1);
+  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/
+
+  if(url2.GetProtocol() == "ftp")
+  {
+    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME, 1);
+    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD);
+  }
+
+  CURLcode result = g_curlInterface.easy_perform(m_state->m_easyHandle);
+
+
+  if(result == CURLE_HTTP_RETURNED_ERROR)
+  {
+    long code;
+    if(g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_RESPONSE_CODE, &code) == CURLE_OK && code == 404 )
+      return -1;
+  }
+
+  if(result == CURLE_GOT_NOTHING 
+  || result == CURLE_HTTP_RETURNED_ERROR 
+  || result == CURLE_RECV_ERROR /* some silly shoutcast servers */ )
+  {
+    /* some http servers and shoutcast servers don't give us any data on a head request */
+    /* request normal and just fail out, it's their loss */
+    /* somehow curl doesn't reset CURLOPT_NOBODY properly so reset everything */
+    SetCommonOptions(m_state);
+    SetRequestHeaders(m_state);
+    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, 5);
+    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_RANGE, "0-0");
+    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/
+    result = g_curlInterface.easy_perform(m_state->m_easyHandle);
+  }
+
+  if( result == CURLE_HTTP_RANGE_ERROR )
+  {
+    /* crap can't use the range option, disable it and try again */
+    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_RANGE, NULL);
+    result = g_curlInterface.easy_perform(m_state->m_easyHandle);
+  }
+
+  if( result != CURLE_WRITE_ERROR && result != CURLE_OK )
+  {
+    g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
+    errno = ENOENT;
+    return -1;
+  }
+
+  double length;
+  if (CURLE_OK != g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &length) || length < 0.0)
+  {
+    if (url.GetProtocol() == "ftp")
+    {
+      g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
+      errno = ENOENT;
+      return -1;
+    }
+    else
+      length = 0.0;
+  }
+
+  SetCorrectHeaders(m_state);
+
+  if(buffer)
+  {
+    char *content;
+    if (CURLE_OK != g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_CONTENT_TYPE, &content))
+    {
+      g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
+      errno = ENOENT;
+      return -1;
+    }
+    else
+    {
+      memset(buffer, 0, sizeof(struct __stat64));
+      buffer->st_size = (int64_t)length;
+      if(content && strstr(content, "text/html")) //consider html files directories
+        buffer->st_mode = _S_IFDIR;
+      else
+        buffer->st_mode = _S_IFREG;
+    }
+  }
+  g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
+  return 0;
+}
+
+unsigned int CCurlFile::CReadState::Read(void* lpBuf, int64_t uiBufSize)
+{
+  /* only request 1 byte, for truncated reads (only if not eof) */
+  if((m_fileSize == 0 || m_filePos < m_fileSize) && !FillBuffer(1))
+    return 0;
+
+  /* ensure only available data is considered */
+  unsigned int want = (unsigned int)XMIN(m_buffer.getMaxReadSize(), uiBufSize);
+
+  /* xfer data to caller */
+  if (m_buffer.ReadData((char *)lpBuf, want))
+  {
+    m_filePos += want;
+    return want;
+  }
+
+  /* check if we finished prematurely */
+  if (!m_stillRunning && (m_fileSize == 0 || m_filePos != m_fileSize))
+  {
+    CLog::Log(LOGWARNING, "%s - Transfer ended before entire file was retrieved pos %"PRId64", size %"PRId64, __FUNCTION__, m_filePos, m_fileSize);
+    return 0;
+  }
+
+  return 0;
+}
+
+/* use to attempt to fill the read buffer up to requested number of bytes */
+bool CCurlFile::CReadState::FillBuffer(unsigned int want)
+{
+  int retry=0;
+  fd_set fdread;
+  fd_set fdwrite;
+  fd_set fdexcep;
+
+  // only attempt to fill buffer if transactions still running and buffer
+  // doesnt exceed required size already
+  while ((unsigned int)m_buffer.getMaxReadSize() < want && m_buffer.getMaxWriteSize() > 0 )
+  {
+    if (m_cancelled)
+      return false;
+
+    /* if there is data in overflow buffer, try to use that first */
+    if (m_overflowSize)
+    {
+      unsigned amount = XMIN((unsigned int)m_buffer.getMaxWriteSize(), m_overflowSize);
+      m_buffer.WriteData(m_overflowBuffer, amount);
+
+      if (amount < m_overflowSize)
+        memcpy(m_overflowBuffer, m_overflowBuffer+amount,m_overflowSize-amount);
+
+      m_overflowSize -= amount;
+      m_overflowBuffer = (char*)realloc_simple(m_overflowBuffer, m_overflowSize);
+      continue;
+    }
+
+    CURLMcode result = g_curlInterface.multi_perform(m_multiHandle, &m_stillRunning);
+    if (!m_stillRunning)
+    {
+      if (result == CURLM_OK)
+      {
+        /* if we still have stuff in buffer, we are fine */
+        if (m_buffer.getMaxReadSize())
+          return true;
+
+        /* verify that we are actually okey */
+        int msgs;
+        CURLcode CURLresult = CURLE_OK;
+        CURLMsg* msg;
+        while ((msg = g_curlInterface.multi_info_read(m_multiHandle, &msgs)))
+        {
+          if (msg->msg == CURLMSG_DONE)
+          {
+            if (msg->data.result == CURLE_OK)
+              return true;
+
+            CLog::Log(LOGWARNING, "%s: curl failed with code %i", __FUNCTION__, msg->data.result);
+
+            // We need to check the data.result here as we don't want to retry on every error
+            if ( (msg->data.result == CURLE_OPERATION_TIMEDOUT ||
+                  msg->data.result == CURLE_PARTIAL_FILE       ||
+                  msg->data.result == CURLE_RECV_ERROR)        &&
+                  !m_bFirstLoop)
+              CURLresult=msg->data.result;
+            else
+              return false;
+          }
+        }
+
+        // Don't retry, when we didn't "see" any error
+        if (CURLresult == CURLE_OK)
+          return false;
+
+        // Close handle
+        if (m_multiHandle && m_easyHandle)
+          g_curlInterface.multi_remove_handle(m_multiHandle, m_easyHandle);
+
+        // Reset all the stuff like we would in Disconnect()
+        m_buffer.Clear();
+        free(m_overflowBuffer);
+        m_overflowBuffer = NULL;
+        m_overflowSize = 0;
+
+        // If we got here something is wrong
+        if (++retry > g_advancedSettings.m_curlretries)
+        {
+          CLog::Log(LOGWARNING, "%s: Reconnect failed!", __FUNCTION__);
+          // Reset the rest of the variables like we would in Disconnect()
+          m_filePos = 0;
+          m_fileSize = 0;
+          m_bufferSize = 0;
+
+          return false;
+        }
+
+        CLog::Log(LOGDEBUG, "%s: Reconnect, (re)try %i", __FUNCTION__, retry);
+
+        // Connect + seek to current position (again)
+        g_curlInterface.easy_setopt(m_easyHandle, CURLOPT_RESUME_FROM_LARGE, m_filePos);
+        g_curlInterface.multi_add_handle(m_multiHandle, m_easyHandle);
+
+        // Return to the beginning of the loop:
+        continue;
+      }
+      return false;
+    }
+
+    // We've finished out first loop
+    if(m_bFirstLoop && m_buffer.getMaxReadSize() > 0)
+      m_bFirstLoop = false;
+
+    switch (result)
+    {
+      case CURLM_OK:
+      {
+        int maxfd = -1;
+        FD_ZERO(&fdread);
+        FD_ZERO(&fdwrite);
+        FD_ZERO(&fdexcep);
+
+        // get file descriptors from the transfers
+        g_curlInterface.multi_fdset(m_multiHandle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+        long timeout = 0;
+        if (CURLM_OK != g_curlInterface.multi_timeout(m_multiHandle, &timeout) || timeout == -1)
+          timeout = 200;
+
+        struct timeval t = { timeout / 1000, (timeout % 1000) * 1000 };
+
+        /* Wait until data is available or a timeout occurs.
+           We call dllselect(maxfd + 1, ...), specially in case of (maxfd == -1),
+           we call dllselect(0, ...), which is basically equal to sleep. */
+        if (SOCKET_ERROR == dllselect(maxfd + 1, &fdread, &fdwrite, &fdexcep, &t))
+        {
+          CLog::Log(LOGERROR, "%s - curl failed with socket error", __FUNCTION__);
+          return false;
+        }
+      }
+      break;
+      case CURLM_CALL_MULTI_PERFORM:
+      {
+        // we don't keep calling here as that can easily overwrite our buffer which we want to avoid
+        // docs says we should call it soon after, but aslong as we are reading data somewhere
+        // this aught to be soon enough. should stay in socket otherwise
+        continue;
+      }
+      break;
+      default:
+      {
+        CLog::Log(LOGERROR, "%s - curl multi perform failed with code %d, aborting", __FUNCTION__, result);
+        return false;
+      }
+      break;
+    }
+  }
+  return true;
+}
+
+void CCurlFile::ClearRequestHeaders()
+{
+  m_requestheaders.clear();
+}
+
+void CCurlFile::SetRequestHeader(CStdString header, CStdString value)
+{
+  m_requestheaders[header] = value;
+}
+
+void CCurlFile::SetRequestHeader(CStdString header, long value)
+{
+  CStdString buffer;
+  buffer.Format("%ld", value);
+  m_requestheaders[header] = buffer;
+}
+
+/* STATIC FUNCTIONS */
+bool CCurlFile::GetHttpHeader(const CURL &url, CHttpHeader &headers)
+{
+  try
+  {
+    CCurlFile file;
+    if(file.Stat(url, NULL) == 0)
+    {
+      headers = file.GetHttpHeader();
+      return true;
+    }
+    return false;
+  }
+  catch(...)
+  {
+    CLog::Log(LOGERROR, "%s - Exception thrown while trying to retrieve header url: %s", __FUNCTION__, url.Get().c_str());
+    return false;
+  }
+}
+
+bool CCurlFile::GetMimeType(const CURL &url, CStdString &content, CStdString useragent)
+{
+  CCurlFile file;
+  if (!useragent.IsEmpty())
+    file.SetUserAgent(useragent);
+
+  struct __stat64 buffer;
+  if( file.Stat(url, &buffer) == 0 )
+  {
+    if (buffer.st_mode == _S_IFDIR)
+      content = "x-directory/normal";
+    else
+      content = file.GetMimeType();
+    CLog::Log(LOGDEBUG, "CCurlFile::GetMimeType - %s -> %s", url.Get().c_str(), content.c_str());
+    return true;
+  }
+  CLog::Log(LOGDEBUG, "CCurlFile::GetMimeType - %s -> failed", url.Get().c_str());
+  content = "";
+  return false;
+}
+
+int CCurlFile::IoControl(EIoControl request, void* param)
+{
+  if(request == IOCTRL_SEEK_POSSIBLE)
+    return m_seekable ? 1 : 0;
+
+  return -1;
+}
diff --git a/xbmc/filesystem/CurlFile.h b/xbmc/filesystem/CurlFile.h
new file mode 100644 (file)
index 0000000..158e750
--- /dev/null
@@ -0,0 +1,173 @@
+#pragma once
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IFile.h"
+#include "utils/RingBuffer.h"
+#include <map>
+#include "utils/HttpHeader.h"
+
+namespace XCURL
+{
+  typedef void CURL_HANDLE;
+  typedef void CURLM;
+  struct curl_slist;
+}
+
+class CHttpHeader;
+
+namespace XFILE
+{
+  class CCurlFile : public IFile
+  {
+    public:
+      CCurlFile();
+      virtual ~CCurlFile();
+      virtual bool Open(const CURL& url);
+      virtual bool Exists(const CURL& url);
+      virtual int64_t  Seek(int64_t iFilePosition, int iWhence=SEEK_SET);
+      virtual int64_t GetPosition();
+      virtual int64_t  GetLength();
+      virtual int  Stat(const CURL& url, struct __stat64* buffer);
+      virtual void Close();
+      virtual bool ReadString(char *szLine, int iLineLength)     { return m_state->ReadString(szLine, iLineLength); }
+      virtual unsigned int Read(void* lpBuf, int64_t uiBufSize)  { return m_state->Read(lpBuf, uiBufSize); }
+      virtual CStdString GetMimeType()                           { return m_state->m_httpheader.GetMimeType(); }
+      virtual int IoControl(EIoControl request, void* param);
+
+      bool Post(const CStdString& strURL, const CStdString& strPostData, CStdString& strHTML);
+      bool Get(const CStdString& strURL, CStdString& strHTML);
+      bool ReadData(CStdString& strHTML);
+      bool Download(const CStdString& strURL, const CStdString& strFileName, LPDWORD pdwSize = NULL);
+      bool IsInternet(bool checkDNS = true);
+      void Cancel();
+      void Reset();
+      void SetUserAgent(CStdString sUserAgent)                   { m_userAgent = sUserAgent; }
+      void SetProxy(CStdString &proxy)                           { m_proxy = proxy; }
+      void SetProxyUserPass(CStdString &proxyuserpass)           { m_proxyuserpass = proxyuserpass; }
+      void SetCustomRequest(CStdString &request)                 { m_customrequest = request; }
+      void UseOldHttpVersion(bool bUse)                          { m_useOldHttpVersion = bUse; }
+      void SetContentEncoding(CStdString encoding)               { m_contentencoding = encoding; }
+      void SetTimeout(int connecttimeout)                        { m_connecttimeout = connecttimeout; }
+      void SetLowSpeedTime(int lowspeedtime)                     { m_lowspeedtime = lowspeedtime; }
+      void SetPostData(CStdString postdata)                      { m_postdata = postdata; }
+      void SetReferer(CStdString referer)                        { m_referer = referer; }
+      void SetCookie(CStdString cookie)                          { m_cookie = cookie; }
+      void SetMimeType(CStdString mimetype)                      { SetRequestHeader("Content-Type", m_mimetype); }
+      void SetRequestHeader(CStdString header, CStdString value);
+      void SetRequestHeader(CStdString header, long value);
+
+      void ClearRequestHeaders();
+      void SetBufferSize(unsigned int size);
+
+      const CHttpHeader& GetHttpHeader() { return m_state->m_httpheader; }
+
+      /* static function that will get content type of a file */
+      static bool GetHttpHeader(const CURL &url, CHttpHeader &headers);
+      static bool GetMimeType(const CURL &url, CStdString &content, CStdString useragent="");
+
+      class CReadState
+      {
+      public:
+          CReadState();
+          ~CReadState();
+          XCURL::CURL_HANDLE*    m_easyHandle;
+          XCURL::CURLM*          m_multiHandle;
+
+          CRingBuffer     m_buffer;           // our ringhold buffer
+          unsigned int    m_bufferSize;
+
+          char *          m_overflowBuffer;   // in the rare case we would overflow the above buffer
+          unsigned int    m_overflowSize;     // size of the overflow buffer
+          int             m_stillRunning;     // Is background url fetch still in progress
+          bool            m_cancelled;
+          int64_t         m_fileSize;
+          int64_t         m_filePos;
+          bool            m_bFirstLoop;
+
+          /* returned http header */
+          CHttpHeader m_httpheader;
+          bool        m_headerdone;
+
+          size_t WriteCallback(char *buffer, size_t size, size_t nitems);
+          size_t HeaderCallback(void *ptr, size_t size, size_t nmemb);
+
+          bool         Seek(int64_t pos);
+          unsigned int Read(void* lpBuf, int64_t uiBufSize);
+          bool         ReadString(char *szLine, int iLineLength);
+          bool         FillBuffer(unsigned int want);
+
+          long         Connect(unsigned int size);
+          void         Disconnect();
+      };
+
+    protected:
+      void ParseAndCorrectUrl(CURL &url);
+      void SetCommonOptions(CReadState* state);
+      void SetRequestHeaders(CReadState* state);
+      void SetCorrectHeaders(CReadState* state);
+      bool Service(const CStdString& strURL, const CStdString& strPostData, CStdString& strHTML);
+
+    private:
+      CReadState*     m_state;
+      unsigned int    m_bufferSize;
+
+      CStdString      m_url;
+      CStdString      m_userAgent;
+      CStdString      m_proxy;
+      CStdString      m_proxyuserpass;
+      CStdString      m_customrequest;
+      CStdString      m_contentencoding;
+      CStdString      m_ftpauth;
+      CStdString      m_ftpport;
+      CStdString      m_binary;
+      CStdString      m_postdata;
+      CStdString      m_referer;
+      CStdString      m_cookie;
+      CStdString      m_mimetype;
+      CStdString      m_username;
+      CStdString      m_password;
+      CStdString      m_httpauth;
+      bool            m_ftppasvip;
+      int             m_connecttimeout;
+      int             m_lowspeedtime;
+      bool            m_opened;
+      bool            m_useOldHttpVersion;
+      bool            m_seekable;
+      bool            m_multisession;
+      bool            m_skipshout;
+
+      CRingBuffer     m_buffer;           // our ringhold buffer
+      char *          m_overflowBuffer;   // in the rare case we would overflow the above buffer
+      unsigned int    m_overflowSize;     // size of the overflow buffer
+
+      int             m_stillRunning;     // Is background url fetch still in progress?
+
+      struct XCURL::curl_slist* m_curlAliasList;
+      struct XCURL::curl_slist* m_curlHeaderList;
+
+      typedef std::map<CStdString, CStdString> MAPHTTPHEADERS;
+      MAPHTTPHEADERS m_requestheaders;
+  };
+}
+
+
+
index ddb6183..492abcb 100644 (file)
@@ -18,7 +18,7 @@
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include "FileDAAP.h"
+#include "DAAPFile.h"
 #include "DAAPDirectory.h"
 #include "music/tags/MusicInfoTag.h"
 #include "FileItem.h"
diff --git a/xbmc/filesystem/DAAPFile.cpp b/xbmc/filesystem/DAAPFile.cpp
new file mode 100644 (file)
index 0000000..46b2220
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+* DAAP Support for XBMC
+* Copyright (c) 2004 Forza (Chris Barnett)
+* Portions Copyright (c) by the authors of libOpenDAAP
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "DAAPFile.h"
+#include "SectionLoader.h"
+#include "threads/SingleLock.h"
+#include "utils/log.h"
+#include <sys/stat.h>
+
+#include "lib/libXDAAP/private.h"
+
+using namespace XFILE;
+
+#define HEDAER_VERSION       "Client-DAAP-Version"
+#define HEADER_REQUESTID     "Client-DAAP-Request-ID"
+#define HEADER_VALIDATE      "Client-DAAP-Validation"
+#define HEADER_ACCESS_INDEX  "Client-DAAP-Access-Index"
+#define DAAP_USERAGENT       "iTunes/4.6 (Windows; N)"
+#define DAAP_PORT            3689
+
+extern "C"
+{
+/* prototype of function in LIBXDAAP to generate the has needed for requests */
+void GenerateHash(short version_major,
+                  const unsigned char *url, unsigned char hashSelect,
+                  unsigned char *outhash,
+                  int request_id);
+}
+
+CDaapClient g_DaapClient;
+
+CDaapClient::CDaapClient()
+{
+  m_pClient = NULL;
+  m_Status = DAAP_STATUS_error;
+
+  m_pArtistsHead = NULL;
+  m_iDatabase = 0;
+}
+CDaapClient::~CDaapClient()
+{
+
+}
+void CDaapClient::Release()
+{
+  m_mapHosts.clear();
+
+  if( m_pClient )
+  {
+    try
+    {
+      while( DAAP_Client_Release(m_pClient) != 0 ) {}
+    }
+    catch(...)
+    {
+      CLog::Log(LOGINFO, "CDaapClient::Disconnect - Unexpected exception");
+    }
+
+    m_pClient = NULL;
+  }
+}
+
+DAAP_SClientHost* CDaapClient::GetHost(const CStdString &strHost)
+{
+  //We need this section from now on
+  if( !CSectionLoader::IsLoaded("LIBXDAAP") ) CSectionLoader::Load("LIBXDAAP");
+  try
+  {
+
+    ITHOST it;
+    it = m_mapHosts.find(strHost);
+    if( it != m_mapHosts.end() )
+      return it->second;
+
+
+    if( !m_pClient )
+      m_pClient = DAAP_Client_Create((DAAP_fnClientStatus)StatusCallback, (void*)this);
+
+    DAAP_SClientHost* pHost = DAAP_Client_AddHost(m_pClient, (char *)strHost.c_str(), (char *)"A", (char *)"A");
+    if( !pHost )
+      throw("Unable to add host");
+
+    if( DAAP_ClientHost_Connect(pHost) != 0 )
+      throw("Unable to connect");
+
+    m_mapHosts[strHost] = pHost;
+
+    return pHost;
+
+  }
+  catch(char* err)
+  {
+    CLog::Log(LOGERROR, "CDaapClient::GetHost(%s) - %s", strHost.c_str(), err );
+    return NULL;
+  }
+  catch(...)
+  {
+    CLog::Log(LOGERROR, "CDaapClient::GetHost(%s) - Unknown Exception", strHost.c_str());
+    return NULL;
+  }
+
+}
+
+void CDaapClient::StatusCallback(DAAP_SClient *pClient, DAAP_Status status, int value, void* pContext)
+{
+  ((CDaapClient*)pContext)->m_Status = status;
+  switch(status)
+  {
+    case DAAP_STATUS_connecting:
+      CLog::Log(LOGINFO, "CDaapClient::Callback - Connecting");
+    case DAAP_STATUS_downloading:
+      CLog::Log(LOGINFO, "CDaapClient::Callback - Downlading");
+    case DAAP_STATUS_idle:
+      CLog::Log(LOGINFO, "CDaapClient::Callback - Idle");
+    default:
+      CLog::Log(LOGINFO, "CDaapClient::Callback - Status %d", status);
+  }
+}
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CDAAPFile::CDAAPFile()
+{
+  m_thisHost = NULL;
+  m_thisClient = NULL;
+
+  m_bOpened = false;
+}
+
+CDAAPFile::~CDAAPFile()
+{
+  Close();
+}
+
+
+
+//*********************************************************************************************
+bool CDAAPFile::Open(const CURL& url)
+{
+  CSingleLock lock(g_DaapClient);
+
+  if (m_bOpened) Close();
+
+  m_url = url;
+
+  CLog::Log(LOGDEBUG, "CDAAPFile::Open(%s)", url.GetFileName().c_str());
+  CStdString host = url.GetHostName();
+  if (url.HasPort())
+    host.Format("%s:%i",url.GetHostName(),url.GetPort());
+  m_thisHost = g_DaapClient.GetHost(host);
+  if (!m_thisHost)
+    return false;
+
+  /* get us a new request id */
+  int requestid = ++m_thisHost->request_id;
+
+  m_hashurl = "/" + m_url.GetFileName();
+  m_hashurl += m_url.GetOptions();
+
+  char hash[33] = {0};
+  GenerateHash(m_thisHost->version_major, (unsigned char*)(m_hashurl.c_str()), 2, (unsigned char*)hash, requestid);
+
+  m_curl.SetUserAgent(DAAP_USERAGENT);
+
+  //m_curl.SetRequestHeader(HEADER_VERSION, "3.0");
+  m_curl.SetRequestHeader(HEADER_REQUESTID, requestid);
+  m_curl.SetRequestHeader(HEADER_VALIDATE, CStdString(hash));
+  m_curl.SetRequestHeader(HEADER_ACCESS_INDEX, 2);
+
+  m_url.SetProtocol("http");
+  if(!m_url.HasPort())
+    m_url.SetPort(DAAP_PORT);
+
+
+  m_bOpened = true;
+
+  return m_curl.Open(m_url);
+}
+
+
+//*********************************************************************************************
+unsigned int CDAAPFile::Read(void *lpBuf, int64_t uiBufSize)
+{
+  return m_curl.Read(lpBuf, uiBufSize);
+}
+
+//*********************************************************************************************
+void CDAAPFile::Close()
+{
+  m_curl.Close();
+  m_bOpened = false;
+}
+
+//*********************************************************************************************
+int64_t CDAAPFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  CSingleLock lock(g_DaapClient);
+
+  int requestid = ++m_thisHost->request_id;
+
+  char hash[33] = {0};
+  GenerateHash(m_thisHost->version_major, (unsigned char*)(m_hashurl.c_str()), 2, (unsigned char*)hash, requestid);
+
+  m_curl.SetRequestHeader(HEADER_REQUESTID, requestid);
+  m_curl.SetRequestHeader(HEADER_VALIDATE, CStdString(hash));
+
+  return m_curl.Seek(iFilePosition, iWhence);
+}
+
+//*********************************************************************************************
+int64_t CDAAPFile::GetLength()
+{
+  return m_curl.GetLength();
+}
+
+//*********************************************************************************************
+int64_t CDAAPFile::GetPosition()
+{
+  return m_curl.GetPosition();
+}
+
+bool CDAAPFile::Exists(const CURL& url)
+{
+  return false;
+}
+
+int CDAAPFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  return -1;
+}
+
+int CDAAPFile::IoControl(EIoControl request, void* param)
+{
+  if(request == IOCTRL_SEEK_POSSIBLE)
+    return 1;
+
+  return -1;
+}
diff --git a/xbmc/filesystem/DAAPFile.h b/xbmc/filesystem/DAAPFile.h
new file mode 100644 (file)
index 0000000..e347bbe
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+* DAAP Support for XBMC
+* Copyright (c) 2004 Forza (Chris Barnett)
+* Portions Copyright (c) by the authors of libOpenDAAP
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+// FileDAAP.h: interface for the CDAAPFile class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_FILEDAAP_H___INCLUDED_)
+#define AFX_FILEDAAP_H___INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "lib/libXDAAP/client.h"
+#include "CurlFile.h"
+#include "URL.h"
+#include "threads/CriticalSection.h"
+
+class CDaapClient : public CCriticalSection
+{
+public:
+
+  CDaapClient();
+  ~CDaapClient();
+
+  DAAP_SClient *m_pClient;
+  DAAP_SClientHost* GetHost(const CStdString &srtHost);
+  std::map<CStdString, DAAP_SClientHost*> m_mapHosts;
+  typedef std::map<CStdString, DAAP_SClientHost*>::iterator ITHOST;
+
+  DAAP_Status m_Status;
+
+  //Buffers
+  int m_iDatabase;
+  void *m_pArtistsHead;
+
+  void Release();
+
+protected:
+  static void StatusCallback(DAAP_SClient *pClient, DAAP_Status status, int value, void* pContext);
+};
+
+extern CDaapClient g_DaapClient;
+
+
+#include "IFile.h"
+
+namespace XFILE
+{
+class CDAAPFile : public IFile
+{
+public:
+  CDAAPFile();
+  virtual ~CDAAPFile();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+  virtual int  IoControl(EIoControl request, void* param);
+
+protected:
+
+  bool StartStreaming();
+  bool StopStreaming();
+
+  int64_t m_fileSize; //holds full size
+  int64_t m_filePos; //holds current position in file
+
+
+  DAAP_SClient *m_thisClient;
+  DAAP_SClientHost *m_thisHost;
+  DAAP_ClientHost_Song m_song;
+
+  bool m_bOpened;
+
+  CStdString m_hashurl; // the url that should be used in hash calculation
+  CURL       m_url;     // the complete url we have connected too
+  CCurlFile  m_curl;
+};
+}
+
+#endif // !defined(AFX_FILEDAAP_H___INCLUDED_)
+
+
index 9a456c8..9bf42f3 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "DAVDirectory.h"
 #include "URL.h"
-#include "FileCurl.h"
+#include "CurlFile.h"
 #include "FileItem.h"
 #include "utils/RegExp.h"
 #include "utils/StringUtils.h"
@@ -168,7 +168,7 @@ void CDAVDirectory::ParseResponse(const TiXmlElement *pElement, CFileItem &item)
 
 bool CDAVDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
 {
-  CFileCurl dav;
+  CCurlFile dav;
   CURL url(strPath);
   CStdString strRequest = "PROPFIND";
 
@@ -251,7 +251,7 @@ bool CDAVDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items
 
 bool CDAVDirectory::Exists(const char* strPath)
 {
-  CFileCurl dav;
+  CCurlFile dav;
   CURL url(strPath);
   return dav.Exists(url);
 }
index 7510267..c761047 100644 (file)
@@ -20,8 +20,8 @@
  */
 
 #include "Directory.h"
-#include "FactoryDirectory.h"
-#include "FactoryFileDirectory.h"
+#include "DirectoryFactory.h"
+#include "FileDirectoryFactory.h"
 #ifndef _LINUX
 #include "utils/Win32Exception.h"
 #endif
@@ -123,7 +123,7 @@ bool CDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items, C
   try
   {
     CStdString realPath = URIUtils::SubstitutePath(strPath);
-    boost::shared_ptr<IDirectory> pDirectory(CFactoryDirectory::Create(realPath));
+    boost::shared_ptr<IDirectory> pDirectory(CDirectoryFactory::Create(realPath));
     if (!pDirectory.get())
       return false;
 
@@ -232,7 +232,7 @@ bool CDirectory::Create(const CStdString& strPath)
   try
   {
     CStdString realPath = URIUtils::SubstitutePath(strPath);
-    auto_ptr<IDirectory> pDirectory(CFactoryDirectory::Create(realPath));
+    auto_ptr<IDirectory> pDirectory(CDirectoryFactory::Create(realPath));
     if (pDirectory.get())
       if(pDirectory->Create(realPath.c_str()))
         return true;
@@ -256,7 +256,7 @@ bool CDirectory::Exists(const CStdString& strPath)
   try
   {
     CStdString realPath = URIUtils::SubstitutePath(strPath);
-    auto_ptr<IDirectory> pDirectory(CFactoryDirectory::Create(realPath));
+    auto_ptr<IDirectory> pDirectory(CDirectoryFactory::Create(realPath));
     if (pDirectory.get())
       return pDirectory->Exists(realPath.c_str());
   }
@@ -279,7 +279,7 @@ bool CDirectory::Remove(const CStdString& strPath)
   try
   {
     CStdString realPath = URIUtils::SubstitutePath(strPath);
-    auto_ptr<IDirectory> pDirectory(CFactoryDirectory::Create(realPath));
+    auto_ptr<IDirectory> pDirectory(CDirectoryFactory::Create(realPath));
     if (pDirectory.get())
       if(pDirectory->Remove(realPath.c_str()))
         return true;
@@ -305,7 +305,7 @@ void CDirectory::FilterFileDirectories(CFileItemList &items, const CStdString &m
     CFileItemPtr pItem=items[i];
     if ((!pItem->m_bIsFolder) && (!pItem->IsInternetStream()))
     {
-      auto_ptr<IFileDirectory> pDirectory(CFactoryFileDirectory::Create(pItem->GetPath(),pItem.get(),mask));
+      auto_ptr<IFileDirectory> pDirectory(CFileDirectoryFactory::Create(pItem->GetPath(),pItem.get(),mask));
       if (pDirectory.get())
         pItem->m_bIsFolder = true;
       else
diff --git a/xbmc/filesystem/DirectoryFactory.cpp b/xbmc/filesystem/DirectoryFactory.cpp
new file mode 100644 (file)
index 0000000..d7ba5a5
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#if (defined HAVE_CONFIG_H) && (!defined WIN32)
+  #include "config.h"
+#endif
+#include "system.h"
+#include "DirectoryFactory.h"
+#include "HDDirectory.h"
+#include "SpecialProtocolDirectory.h"
+#include "MultiPathDirectory.h"
+#include "StackDirectory.h"
+#include "FileDirectoryFactory.h"
+#include "PlaylistDirectory.h"
+#include "MusicDatabaseDirectory.h"
+#include "MusicSearchDirectory.h"
+#include "VideoDatabaseDirectory.h"
+#include "AddonsDirectory.h"
+#include "SourcesDirectory.h"
+#include "LastFMDirectory.h"
+#include "FTPDirectory.h"
+#include "HTTPDirectory.h"
+#include "DAVDirectory.h"
+#include "UDFDirectory.h"
+#include "Application.h"
+#include "addons/Addon.h"
+#include "utils/log.h"
+
+#ifdef HAS_FILESYSTEM_SMB
+#ifdef _WIN32
+#include "windows/WINSMBDirectory.h"
+#else
+#include "SMBDirectory.h"
+#endif
+#endif
+#ifdef HAS_FILESYSTEM_CDDA
+#include "CDDADirectory.h"
+#endif
+#include "PluginDirectory.h"
+#ifdef HAS_FILESYSTEM
+#include "ISO9660Directory.h"
+#ifdef HAS_FILESYSTEM_RTV
+#include "RTVDirectory.h"
+#endif
+#ifdef HAS_FILESYSTEM_DAAP
+#include "DAAPDirectory.h"
+#endif
+#endif
+#ifdef HAS_UPNP
+#include "UPnPDirectory.h"
+#endif
+#ifdef HAS_FILESYSTEM_SAP
+#include "SAPDirectory.h"
+#endif
+#ifdef HAS_FILESYSTEM_VTP
+#include "VTPDirectory.h"
+#endif
+#ifdef HAS_FILESYSTEM_HTSP
+#include "HTSPDirectory.h"
+#endif
+#include "ZipDirectory.h"
+#ifdef HAS_FILESYSTEM_RAR
+#include "RarDirectory.h"
+#endif
+#include "TuxBoxDirectory.h"
+#include "HDHomeRunDirectory.h"
+#include "SlingboxDirectory.h"
+#include "MythDirectory.h"
+#include "FileItem.h"
+#include "URL.h"
+#include "RSSDirectory.h"
+#ifdef HAS_ZEROCONF
+#include "ZeroconfDirectory.h"
+#endif
+#ifdef HAS_FILESYSTEM_SFTP
+#include "SFTPDirectory.h"
+#endif
+#ifdef HAS_FILESYSTEM_NFS
+#include "NFSDirectory.h"
+#endif
+#ifdef HAS_FILESYSTEM_AFP
+#include "AFPDirectory.h"
+#endif
+
+using namespace XFILE;
+
+/*!
+ \brief Create a IDirectory object of the share type specified in \e strPath .
+ \param strPath Specifies the share type to access, can be a share or share with path.
+ \return IDirectory object to access the directories on the share.
+ \sa IDirectory
+ */
+IDirectory* CDirectoryFactory::Create(const CStdString& strPath)
+{
+  CURL url(strPath);
+
+  CFileItem item(strPath, false);
+  IFileDirectory* pDir=CFileDirectoryFactory::Create(strPath, &item);
+  if (pDir)
+    return pDir;
+
+  CStdString strProtocol = url.GetProtocol();
+
+  if (strProtocol.size() == 0 || strProtocol == "file") return new CHDDirectory();
+  if (strProtocol == "special") return new CSpecialProtocolDirectory();
+  if (strProtocol == "sources") return new CSourcesDirectory();
+  if (strProtocol == "addons") return new CAddonsDirectory();
+#if defined(HAS_FILESYSTEM_CDDA) && defined(HAS_DVD_DRIVE)
+  if (strProtocol == "cdda") return new CCDDADirectory();
+#endif
+#ifdef HAS_FILESYSTEM
+  if (strProtocol == "iso9660") return new CISO9660Directory();
+#endif
+  if (strProtocol == "udf") return new CUDFDirectory();
+  if (strProtocol == "plugin") return new CPluginDirectory();
+  if (strProtocol == "zip") return new CZipDirectory();
+#ifdef HAS_FILESYSTEM_RAR
+  if (strProtocol == "rar") return new CRarDirectory();
+#endif
+  if (strProtocol == "multipath") return new CMultiPathDirectory();
+  if (strProtocol == "stack") return new CStackDirectory();
+  if (strProtocol == "playlistmusic") return new CPlaylistDirectory();
+  if (strProtocol == "playlistvideo") return new CPlaylistDirectory();
+  if (strProtocol == "musicdb") return new CMusicDatabaseDirectory();
+  if (strProtocol == "musicsearch") return new CMusicSearchDirectory();
+  if (strProtocol == "videodb") return new CVideoDatabaseDirectory();
+  if (strProtocol == "filereader")
+    return CDirectoryFactory::Create(url.GetFileName());
+
+  if( g_application.getNetwork().IsAvailable(true) )  // true to wait for the network (if possible)
+  {
+    if (strProtocol == "lastfm") return new CLastFMDirectory();
+    if (strProtocol == "tuxbox") return new CTuxBoxDirectory();
+    if (strProtocol == "ftp" ||  strProtocol == "ftpx" ||  strProtocol == "ftps") return new CFTPDirectory();
+    if (strProtocol == "http" || strProtocol == "https") return new CHTTPDirectory();
+    if (strProtocol == "dav" || strProtocol == "davs") return new CDAVDirectory();
+#ifdef HAS_FILESYSTEM_SFTP
+    if (strProtocol == "sftp" || strProtocol == "ssh") return new CSFTPDirectory();
+#endif
+#ifdef HAS_FILESYSTEM_SMB
+#ifdef _WIN32
+    if (strProtocol == "smb") return new CWINSMBDirectory();
+#else
+    if (strProtocol == "smb") return new CSMBDirectory();
+#endif
+#endif
+#ifdef HAS_FILESYSTEM
+#ifdef HAS_FILESYSTEM_DAAP
+    if (strProtocol == "daap") return new CDAAPDirectory();
+#endif
+#ifdef HAS_FILESYSTEM_RTV
+    if (strProtocol == "rtv") return new CRTVDirectory();
+#endif
+#endif
+#ifdef HAS_UPNP
+    if (strProtocol == "upnp") return new CUPnPDirectory();
+#endif
+    if (strProtocol == "hdhomerun") return new CHomeRunDirectory();
+    if (strProtocol == "sling") return new CSlingboxDirectory();
+    if (strProtocol == "myth") return new CMythDirectory();
+    if (strProtocol == "cmyth") return new CMythDirectory();
+    if (strProtocol == "rss") return new CRSSDirectory();
+#ifdef HAS_FILESYSTEM_SAP
+    if (strProtocol == "sap") return new CSAPDirectory();
+#endif
+#ifdef HAS_FILESYSTEM_VTP
+    if (strProtocol == "vtp") return new CVTPDirectory();
+#endif
+#ifdef HAS_FILESYSTEM_HTSP
+    if (strProtocol == "htsp") return new CHTSPDirectory();
+#endif
+#ifdef HAS_ZEROCONF
+    if (strProtocol == "zeroconf") return new CZeroconfDirectory();
+#endif
+#ifdef HAS_FILESYSTEM_NFS
+    if (strProtocol == "nfs") return new CNFSDirectory();
+#endif
+#ifdef HAS_FILESYSTEM_AFP
+      if (strProtocol == "afp") return new CAFPDirectory();
+#endif
+  }
+
+  CLog::Log(LOGWARNING, "%s - Unsupported protocol(%s) in %s", __FUNCTION__, strProtocol.c_str(), url.Get().c_str() );
+  return NULL;
+}
+
diff --git a/xbmc/filesystem/DirectoryFactory.h b/xbmc/filesystem/DirectoryFactory.h
new file mode 100644 (file)
index 0000000..6ff0776
--- /dev/null
@@ -0,0 +1,51 @@
+#pragma once
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IDirectory.h"
+
+namespace XFILE
+{
+/*!
+ \ingroup filesystem
+ \brief Get access to a directory of a file system.
+
+ The Factory can be used to create a directory object
+ for every file system accessable. \n
+ \n
+ Example:
+
+ \verbatim
+ CStdString strShare="iso9660://";
+
+ IDirectory* pDir=CDirectoryFactory::Create(strShare);
+ \endverbatim
+ The \e pDir pointer can be used to access a directory and retrieve it's content.
+
+ When different types of shares have to be accessed use CVirtualDirectory.
+ \sa IDirectory
+ */
+class CDirectoryFactory
+{
+public:
+  static IDirectory* Create(const CStdString& strPath);
+};
+}
diff --git a/xbmc/filesystem/DirectoryTuxBox.cpp b/xbmc/filesystem/DirectoryTuxBox.cpp
deleted file mode 100644 (file)
index 70d4392..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-
-#include "DirectoryTuxBox.h"
-#include "DirectoryCache.h"
-#include "FileCurl.h"
-#include "utils/HttpHeader.h"
-#include "utils/TuxBoxUtil.h"
-#include "URL.h"
-#include "tinyXML/tinyxml.h"
-#include "settings/AdvancedSettings.h"
-#include "FileItem.h"
-#include "utils/log.h"
-#include "utils/URIUtils.h"
-
-using namespace XFILE;
-
-CDirectoryTuxBox::CDirectoryTuxBox(void)
-{
-}
-
-CDirectoryTuxBox::~CDirectoryTuxBox(void)
-{
-}
-
-bool CDirectoryTuxBox::GetDirectory(const CStdString& strPath, CFileItemList &items)
-{
-  // so we know that we have enigma2
-  static bool enigma2 = false;
-  // Detect and delete slash at end
-  CStdString strRoot = strPath;
-  URIUtils::RemoveSlashAtEnd(strRoot);
-
-  //Get the request strings
-  CStdString strBQRequest;
-  CStdString strXMLRootString;
-  CStdString strXMLChildString;
-  if(!GetRootAndChildString(strRoot, strBQRequest, strXMLRootString, strXMLChildString))
-    return false;
-
-  //Set url Protocol
-  CURL url(strRoot);
-  CStdString strFilter;
-  CStdString protocol = url.GetProtocol();
-  CStdString strOptions = url.GetOptions();
-  url.SetProtocol("http");
-  bool bIsBouquet=false;
-
-  int ipoint = strOptions.Find("?path=");
-  if (ipoint >=0)
-  {
-    // send Zap!
-    return g_tuxbox.ZapToUrl(url, strOptions, ipoint);
-  }
-  else
-  {
-    ipoint = strOptions.Find("&reference=");
-    if (ipoint >=0 || enigma2)
-    {
-      //List reference
-      strFilter = strOptions.Right((strOptions.size()-(ipoint+11)));
-      bIsBouquet = false; //On Empty is Bouquet
-      if (enigma2)
-      {
-        CStdString strPort;
-        strPort.Format(":%i",url.GetPort());
-        if (strRoot.Right(strPort.GetLength()) != strPort) // If not root dir, enable Channels
-          strFilter = "e2"; // Disable Bouquets for Enigma2
-
-        GetRootAndChildStringEnigma2(strBQRequest, strXMLRootString, strXMLChildString);
-        url.SetOptions("");
-        url.SetFileName(strBQRequest);
-      }
-    }
-  }
-  if(strFilter.IsEmpty())
-  {
-    url.SetOptions(strBQRequest);
-    bIsBouquet = true;
-  }
-  //Open
-  CFileCurl http;
-  int iTryConnect = 0;
-  int iWaitTimer = 20;
-  bool result = false;
-
-  while (iTryConnect < 4)
-  {
-    http.SetTimeout(iWaitTimer);
-    if(http.Open(url))
-    {
-      //We are connected!
-      iTryConnect = 4;
-
-      // restore protocol
-      url.SetProtocol(protocol);
-
-      int size_read = 0;
-      int size_total = (int)http.GetLength();
-      int data_size = 0;
-      CStdString data;
-      data.reserve(size_total);
-
-      // read response from server into string buffer
-      char buffer[16384];
-      while ((size_read = http.Read(buffer, sizeof(buffer)-1)) > 0)
-      {
-        buffer[size_read] = 0;
-        data += buffer;
-        data_size += size_read;
-      }
-      http.Close();
-
-      // parse returned xml
-      TiXmlDocument doc;
-      data.Replace("></",">-</"); //FILL EMPTY ELEMENTS WITH "-"!
-      doc.Parse(data.c_str());
-      TiXmlElement *root = doc.RootElement();
-      if(root == NULL)
-      {
-        CLog::Log(LOGERROR, "%s - Unable to parse xml", __FUNCTION__);
-        CLog::Log(LOGERROR, "%s - Sample follows...\n%s", __FUNCTION__, data.c_str());
-        return false;
-      }
-      if( strXMLRootString.Equals(root->Value()) && bIsBouquet)
-      {
-        data.Empty();
-        if (enigma2)
-          result = g_tuxbox.ParseBouquetsEnigma2(root, items, url, strFilter, strXMLChildString);
-        else
-          result = g_tuxbox.ParseBouquets(root, items, url, strFilter, strXMLChildString);
-      }
-      else if( strXMLRootString.Equals(root->Value()) && !strFilter.IsEmpty() )
-      {
-        data.Empty();
-        if (enigma2)
-          result = g_tuxbox.ParseChannelsEnigma2(root, items, url, strFilter, strXMLChildString);
-        else
-          result = g_tuxbox.ParseChannels(root, items, url, strFilter, strXMLChildString);
-      }
-      else
-      {
-        CLog::Log(LOGERROR, "%s - Invalid root xml element for TuxBox", __FUNCTION__);
-        CLog::Log(LOGERROR, "%s - Sample follows...\n%s", __FUNCTION__, data.c_str());
-        data.Empty();
-        result = false;
-      }
-    }
-    else
-    {
-      CLog::Log(LOGERROR, "%s - Unable to get XML structure! Try count:%i, Wait Timer:%is",__FUNCTION__, iTryConnect, iWaitTimer);
-      iTryConnect++;
-      if (iTryConnect == 2) //try enigma2 instead of enigma1, best entrypoint here i thought
-      {        
-        enigma2 = true;
-        GetRootAndChildStringEnigma2(strBQRequest, strXMLRootString, strXMLChildString);
-        url.SetOptions("");
-        url.SetFileName(strBQRequest);
-//        iTryConnect = 0;
-        iWaitTimer = 20;
-      }
-      else
-        iWaitTimer = iWaitTimer+10;
-
-      result = false;
-      http.Close(); // Close old connections
-    }
-  }
-  items.SetContent("movies");
-  return result;
-}
-
-void CDirectoryTuxBox::GetRootAndChildStringEnigma2(CStdString& strBQRequest, CStdString& strXMLRootString, CStdString& strXMLChildString )
-{
-  // Allways take getallservices for Enigma2
-  strBQRequest = "web/getallservices"; //Bouquets and Channels
-  strXMLRootString.Format("e2servicelistrecursive");
-  strXMLChildString.Format("e2bouquet");
-}
-
-bool CDirectoryTuxBox::GetRootAndChildString(const CStdString strPath, CStdString& strBQRequest, CStdString& strXMLRootString, CStdString& strXMLChildString )
-{
-  //Advanced Settings: RootMode! Movies:
-  if(g_advancedSettings.m_iTuxBoxDefaultRootMenu == 3) //Movies! Fixed-> mode=3&submode=4
-  {
-    CLog::Log(LOGDEBUG, "%s - Default defined RootMenu : (3) Movies", __FUNCTION__);
-    strBQRequest = "xml/services?mode=3&submode=4";
-    strXMLRootString.Format("movies");
-    strXMLChildString.Format("service");
-  }
-  else if(g_advancedSettings.m_iTuxBoxDefaultRootMenu <= 0 || g_advancedSettings.m_iTuxBoxDefaultRootMenu == 1 ||
-    g_advancedSettings.m_iTuxBoxDefaultRootMenu > 4 )
-  {
-    //Falling Back to the Default RootMenu => 0 Bouquets
-    if(g_advancedSettings.m_iTuxBoxDefaultRootMenu < 0 || g_advancedSettings.m_iTuxBoxDefaultRootMenu > 4)
-    {
-      g_advancedSettings.m_iTuxBoxDefaultRootMenu = 0;
-    }
-
-    //Advanced Settings: SubMenu!
-    if(g_advancedSettings.m_bTuxBoxSubMenuSelection)
-    {
-      CLog::Log(LOGDEBUG, "%s SubMenu Channel Selection is Enabled! Requesting Submenu!", __FUNCTION__);
-      // DeActivated: Timing Problems, bug in TuxBox.. etc.!
-      bool bReqMoRe = true;
-      // Detect the RootMode !
-      if (strPath.Find("?mode=")>=0)
-      {
-        CStdString strMode;
-        bReqMoRe=false;
-        strMode = g_tuxbox.DetectSubMode(strPath, strXMLRootString, strXMLChildString);
-      }
-      if(bReqMoRe)
-      {
-        //PopUp Context and Request SubMode with root and child string
-        strBQRequest = g_tuxbox.GetSubMode(g_advancedSettings.m_iTuxBoxDefaultRootMenu, strXMLRootString, strXMLChildString);
-        if(strBQRequest.IsEmpty())
-        {
-          strBQRequest = "xml/services?mode=0&submode=4"; //Bouquets
-          strXMLRootString.Format("bouquets");
-          strXMLChildString.Format("bouquet");
-        }
-      }
-    }
-    else
-    {
-      //Advanced Settings: Set Default Subemnu
-      if(g_advancedSettings.m_iTuxBoxDefaultSubMenu == 1)
-      {
-        CLog::Log(LOGDEBUG, "%s - Default defined SubMenu : (1) Services", __FUNCTION__);
-        strBQRequest = "xml/services?mode=0&submode=1"; //Services
-        strXMLRootString.Format("services");
-        strXMLChildString.Format("service");
-      }
-      else if(g_advancedSettings.m_iTuxBoxDefaultSubMenu == 2)
-      {
-        CLog::Log(LOGDEBUG, "%s - Default defined SubMenu : (2) Satellites", __FUNCTION__);
-        strBQRequest = "xml/services?mode=0&submode=2"; //Satellites
-        strXMLRootString.Format("satellites");
-        strXMLChildString.Format("satellite");
-      }
-      else if(g_advancedSettings.m_iTuxBoxDefaultSubMenu == 3)
-      {
-        CLog::Log(LOGDEBUG, "%s - Default defined SubMenu : (3) Providers", __FUNCTION__);
-        strBQRequest = "xml/services?mode=0&submode=3"; //Providers
-        strXMLRootString.Format("providers");
-        strXMLChildString.Format("provider");
-      }
-      else
-      {
-        CLog::Log(LOGDEBUG, "%s - Default defined SubMenu : (4) Bouquets", __FUNCTION__);
-        strBQRequest = "xml/services?mode=0&submode=4"; //Bouquets
-        strXMLRootString.Format("bouquets");
-        strXMLChildString.Format("bouquet");
-      }
-    }
-  }
-  if(strBQRequest.IsEmpty() || strXMLRootString.IsEmpty() || strXMLChildString.IsEmpty())
-    return false;
-  else
-    return true;
-}
diff --git a/xbmc/filesystem/DirectoryTuxBox.h b/xbmc/filesystem/DirectoryTuxBox.h
deleted file mode 100644 (file)
index eb3f92b..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "IDirectory.h"
-
-class CURL;
-class TiXmlElement;
-
-namespace XFILE
-{
-  class CDirectoryTuxBox : public IDirectory
-  {
-    public:
-      CDirectoryTuxBox(void);
-      virtual ~CDirectoryTuxBox(void);
-      virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items);
-      virtual bool IsAllowed(const CStdString &strFile) const { return true; };
-      virtual DIR_CACHE_TYPE GetCacheType(const CStdString& strPath) const { return DIR_CACHE_ALWAYS; };
-    private:
-      bool GetRootAndChildString(const CStdString strPath, CStdString& strBQRequest, CStdString& strXMLRootString, CStdString& strXMLChildString );
-      void GetRootAndChildStringEnigma2(CStdString& strBQRequest, CStdString& strXMLRootString, CStdString& strXMLChildString );
-  };
-}
-
index 4b7ce40..461c6af 100644 (file)
@@ -23,7 +23,7 @@
 #include "FTPParse.h"
 #include "URL.h"
 #include "utils/URIUtils.h"
-#include "FileCurl.h"
+#include "CurlFile.h"
 #include "FileItem.h"
 #include "utils/StringUtils.h"
 #include "utils/CharsetConverter.h"
@@ -36,7 +36,7 @@ CFTPDirectory::~CFTPDirectory(void){}
 
 bool CFTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
 {
-  CFileCurl reader;
+  CCurlFile reader;
 
   CURL url(strPath);
 
@@ -101,7 +101,7 @@ bool CFTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items
 
 bool CFTPDirectory::Exists(const char* strPath)
 {
-  CFileCurl ftp;
+  CCurlFile ftp;
   CURL url(strPath);
   return ftp.Exists(url);
 }
index b9e2aa0..dc08889 100644 (file)
@@ -50,7 +50,7 @@ int CFTPParse::getFlagtryretr()
   return m_flagtryretr;
 }
 
-long CFTPParse::getSize()
+uint64_t CFTPParse::getSize()
 {
   return m_size;
 }
@@ -409,7 +409,7 @@ int CFTPParse::FTPParse(string str)
   if (unix_re.FullMatch(str, &type, &permissions, &link_count, &owner, &group, &size, &date, &name))
   {
     m_name = name;
-    m_size = strtol(size.c_str(), NULL, 0);
+    m_size = (uint64_t)strtod(size.c_str(), NULL);
     if (pcrecpp::RE("d").FullMatch(type))
       m_flagtrycwd = 1;
     if (pcrecpp::RE("-").FullMatch(type))
@@ -429,7 +429,7 @@ int CFTPParse::FTPParse(string str)
   if (netware_re.FullMatch(str, &type, &permissions, &owner, &size, &date, &name))
   {
     m_name = name;
-    m_size = strtol(size.c_str(), NULL, 0);
+    m_size = (uint64_t)strtod(size.c_str(), NULL);
     if (pcrecpp::RE("d").FullMatch(type))
       m_flagtrycwd = 1;
     if (pcrecpp::RE("-").FullMatch(type))
@@ -441,7 +441,7 @@ int CFTPParse::FTPParse(string str)
   if (netpresenz_re.FullMatch(str, &type, &permissions, &stuff, &size, &date, &name))
   {
     m_name = name;
-    m_size = strtol(size.c_str(), NULL, 0);
+    m_size = (uint64_t)strtod(size.c_str(), NULL);
     if (pcrecpp::RE("d").FullMatch(type))
       m_flagtrycwd = 1;
     if (pcrecpp::RE("-").FullMatch(type))
@@ -466,7 +466,7 @@ int CFTPParse::FTPParse(string str)
     pcrecpp::RE("(\\+|,)m(\\d+),").PartialMatch(facts, (void*)NULL, &date);
 
     m_name = name;
-    m_size = strtol(size.c_str(), NULL, 0);
+    m_size = (uint64_t)strtod(size.c_str(), NULL);
     if (pcrecpp::RE("/").FullMatch(type))
       m_flagtrycwd = 1;
     if (pcrecpp::RE("r").FullMatch(type))
@@ -503,7 +503,7 @@ int CFTPParse::FTPParse(string str)
     else
     {
       m_flagtryretr = 1;
-      m_size = strtol(size.c_str(), NULL, 0);
+      m_size = (uint64_t)strtod(size.c_str(), NULL);
     }
     setTime(date);
 
index 0e99b74..16e715c 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <string>
 #include <ctime>
+#include <stdint.h>
 
 using namespace std;
 
@@ -33,13 +34,13 @@ public:
   string getName();
   int getFlagtrycwd();
   int getFlagtryretr();
-  long getSize();
+  uint64_t getSize();
   time_t getTime();
 private:
   string m_name;            // not necessarily 0-terminated
   int m_flagtrycwd;         // 0 if cwd is definitely pointless, 1 otherwise
   int m_flagtryretr;        // 0 if retr is definitely pointless, 1 otherwise
-  long m_size;              // number of octets
+  uint64_t m_size;              // number of octets
   time_t m_time;            // modification time
   void setTime(string str); // Method used to set m_time from a string
   int getDayOfWeek(int month, int date, int year); // Method to get day of week
diff --git a/xbmc/filesystem/FactoryDirectory.cpp b/xbmc/filesystem/FactoryDirectory.cpp
deleted file mode 100644 (file)
index 6c627af..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#if (defined HAVE_CONFIG_H) && (!defined WIN32)
-  #include "config.h"
-#endif
-#include "system.h"
-#include "FactoryDirectory.h"
-#include "HDDirectory.h"
-#include "SpecialProtocolDirectory.h"
-#include "MultiPathDirectory.h"
-#include "StackDirectory.h"
-#include "FactoryFileDirectory.h"
-#include "PlaylistDirectory.h"
-#include "MusicDatabaseDirectory.h"
-#include "MusicSearchDirectory.h"
-#include "VideoDatabaseDirectory.h"
-#include "AddonsDirectory.h"
-#include "SourcesDirectory.h"
-#include "LastFMDirectory.h"
-#include "FTPDirectory.h"
-#include "HTTPDirectory.h"
-#include "DAVDirectory.h"
-#include "UDFDirectory.h"
-#include "Application.h"
-#include "addons/Addon.h"
-#include "utils/log.h"
-
-#ifdef HAS_FILESYSTEM_SMB
-#ifdef _WIN32
-#include "WINSMBDirectory.h"
-#else
-#include "SMBDirectory.h"
-#endif
-#endif
-#ifdef HAS_FILESYSTEM_CDDA
-#include "CDDADirectory.h"
-#endif
-#include "PluginDirectory.h"
-#ifdef HAS_FILESYSTEM
-#include "ISO9660Directory.h"
-#ifdef HAS_FILESYSTEM_RTV
-#include "RTVDirectory.h"
-#endif
-#ifdef HAS_FILESYSTEM_DAAP
-#include "DAAPDirectory.h"
-#endif
-#endif
-#ifdef HAS_UPNP
-#include "UPnPDirectory.h"
-#endif
-#ifdef HAS_FILESYSTEM_SAP
-#include "SAPDirectory.h"
-#endif
-#ifdef HAS_FILESYSTEM_VTP
-#include "VTPDirectory.h"
-#endif
-#ifdef HAS_FILESYSTEM_HTSP
-#include "HTSPDirectory.h"
-#endif
-#include "ZipDirectory.h"
-#ifdef HAS_FILESYSTEM_RAR
-#include "RarDirectory.h"
-#endif
-#include "DirectoryTuxBox.h"
-#include "HDHomeRun.h"
-#include "Slingbox.h"
-#include "MythDirectory.h"
-#include "FileItem.h"
-#include "URL.h"
-#include "RSSDirectory.h"
-#ifdef HAS_ZEROCONF
-#include "ZeroconfDirectory.h"
-#endif
-#ifdef HAS_FILESYSTEM_SFTP
-#include "SFTPDirectory.h"
-#endif
-#ifdef HAS_FILESYSTEM_NFS
-#include "NFSDirectory.h"
-#endif
-#ifdef HAS_FILESYSTEM_AFP
-#include "AFPDirectory.h"
-#endif
-
-using namespace XFILE;
-
-/*!
- \brief Create a IDirectory object of the share type specified in \e strPath .
- \param strPath Specifies the share type to access, can be a share or share with path.
- \return IDirectory object to access the directories on the share.
- \sa IDirectory
- */
-IDirectory* CFactoryDirectory::Create(const CStdString& strPath)
-{
-  CURL url(strPath);
-
-  CFileItem item(strPath, false);
-  IFileDirectory* pDir=CFactoryFileDirectory::Create(strPath, &item);
-  if (pDir)
-    return pDir;
-
-  CStdString strProtocol = url.GetProtocol();
-
-  if (strProtocol.size() == 0 || strProtocol == "file") return new CHDDirectory();
-  if (strProtocol == "special") return new CSpecialProtocolDirectory();
-  if (strProtocol == "sources") return new CSourcesDirectory();
-  if (strProtocol == "addons") return new CAddonsDirectory();
-#if defined(HAS_FILESYSTEM_CDDA) && defined(HAS_DVD_DRIVE)
-  if (strProtocol == "cdda") return new CCDDADirectory();
-#endif
-#ifdef HAS_FILESYSTEM
-  if (strProtocol == "iso9660") return new CISO9660Directory();
-#endif
-  if (strProtocol == "udf") return new CUDFDirectory();
-  if (strProtocol == "plugin") return new CPluginDirectory();
-  if (strProtocol == "zip") return new CZipDirectory();
-#ifdef HAS_FILESYSTEM_RAR
-  if (strProtocol == "rar") return new CRarDirectory();
-#endif
-  if (strProtocol == "multipath") return new CMultiPathDirectory();
-  if (strProtocol == "stack") return new CStackDirectory();
-  if (strProtocol == "playlistmusic") return new CPlaylistDirectory();
-  if (strProtocol == "playlistvideo") return new CPlaylistDirectory();
-  if (strProtocol == "musicdb") return new CMusicDatabaseDirectory();
-  if (strProtocol == "musicsearch") return new CMusicSearchDirectory();
-  if (strProtocol == "videodb") return new CVideoDatabaseDirectory();
-  if (strProtocol == "filereader")
-    return CFactoryDirectory::Create(url.GetFileName());
-
-  if( g_application.getNetwork().IsAvailable(true) )  // true to wait for the network (if possible)
-  {
-    if (strProtocol == "lastfm") return new CLastFMDirectory();
-    if (strProtocol == "tuxbox") return new CDirectoryTuxBox();
-    if (strProtocol == "ftp" ||  strProtocol == "ftpx" ||  strProtocol == "ftps") return new CFTPDirectory();
-    if (strProtocol == "http" || strProtocol == "https") return new CHTTPDirectory();
-    if (strProtocol == "dav" || strProtocol == "davs") return new CDAVDirectory();
-#ifdef HAS_FILESYSTEM_SFTP
-    if (strProtocol == "sftp" || strProtocol == "ssh") return new CSFTPDirectory();
-#endif
-#ifdef HAS_FILESYSTEM_SMB
-#ifdef _WIN32
-    if (strProtocol == "smb") return new CWINSMBDirectory();
-#else
-    if (strProtocol == "smb") return new CSMBDirectory();
-#endif
-#endif
-#ifdef HAS_FILESYSTEM
-#ifdef HAS_FILESYSTEM_DAAP
-    if (strProtocol == "daap") return new CDAAPDirectory();
-#endif
-#ifdef HAS_FILESYSTEM_RTV
-    if (strProtocol == "rtv") return new CRTVDirectory();
-#endif
-#endif
-#ifdef HAS_UPNP
-    if (strProtocol == "upnp") return new CUPnPDirectory();
-#endif
-    if (strProtocol == "hdhomerun") return new CDirectoryHomeRun();
-    if (strProtocol == "sling") return new CSlingboxDirectory();
-    if (strProtocol == "myth") return new CMythDirectory();
-    if (strProtocol == "cmyth") return new CMythDirectory();
-    if (strProtocol == "rss") return new CRSSDirectory();
-#ifdef HAS_FILESYSTEM_SAP
-    if (strProtocol == "sap") return new CSAPDirectory();
-#endif
-#ifdef HAS_FILESYSTEM_VTP
-    if (strProtocol == "vtp") return new CVTPDirectory();
-#endif
-#ifdef HAS_FILESYSTEM_HTSP
-    if (strProtocol == "htsp") return new CHTSPDirectory();
-#endif
-#ifdef HAS_ZEROCONF
-    if (strProtocol == "zeroconf") return new CZeroconfDirectory();
-#endif
-#ifdef HAS_FILESYSTEM_NFS
-    if (strProtocol == "nfs") return new CNFSDirectory();
-#endif
-#ifdef HAS_FILESYSTEM_AFP
-      if (strProtocol == "afp") return new CAFPDirectory();
-#endif
-  }
-
-  CLog::Log(LOGWARNING, "%s - Unsupported protocol(%s) in %s", __FUNCTION__, strProtocol.c_str(), url.Get().c_str() );
-  return NULL;
-}
-
diff --git a/xbmc/filesystem/FactoryDirectory.h b/xbmc/filesystem/FactoryDirectory.h
deleted file mode 100644 (file)
index f525917..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "IDirectory.h"
-
-namespace XFILE
-{
-/*!
- \ingroup filesystem
- \brief Get access to a directory of a file system.
-
- The Factory can be used to create a directory object
- for every file system accessable. \n
- \n
- Example:
-
- \verbatim
- CStdString strShare="iso9660://";
-
- IDirectory* pDir=CFactoryDirectory::Create(strShare);
- \endverbatim
- The \e pDir pointer can be used to access a directory and retrieve it's content.
-
- When different types of shares have to be accessed use CVirtualDirectory.
- \sa IDirectory
- */
-class CFactoryDirectory
-{
-public:
-  static IDirectory* Create(const CStdString& strPath);
-};
-}
diff --git a/xbmc/filesystem/FactoryFileDirectory.cpp b/xbmc/filesystem/FactoryFileDirectory.cpp
deleted file mode 100644 (file)
index 7b36b3a..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-
-#include "system.h"
-#include "Util.h"
-#include "utils/URIUtils.h"
-#include "FactoryFileDirectory.h"
-#ifdef HAS_FILESYSTEM
-#include "OGGFileDirectory.h"
-#include "NSFFileDirectory.h"
-#include "SIDFileDirectory.h"
-#include "ASAPFileDirectory.h"
-#include "RSSDirectory.h"
-#include "cores/paplayer/ASAPCodec.h"
-#endif
-#ifdef HAS_FILESYSTEM_RAR
-#include "RarDirectory.h"
-#endif
-#include "ZipDirectory.h"
-#include "SmartPlaylistDirectory.h"
-#include "playlists/SmartPlayList.h"
-#include "PlaylistFileDirectory.h"
-#include "playlists/PlayListFactory.h"
-#include "Directory.h"
-#include "File.h"
-#include "ZipManager.h"
-#include "settings/AdvancedSettings.h"
-#include "FileItem.h"
-
-using namespace XFILE;
-using namespace PLAYLIST;
-using namespace std;
-
-CFactoryFileDirectory::CFactoryFileDirectory(void)
-{}
-
-CFactoryFileDirectory::~CFactoryFileDirectory(void)
-{}
-
-// return NULL + set pItem->m_bIsFolder to remove it completely from list.
-IFileDirectory* CFactoryFileDirectory::Create(const CStdString& strPath, CFileItem* pItem, const CStdString& strMask)
-{
-  CStdString strExtension=URIUtils::GetExtension(strPath);
-  strExtension.MakeLower();
-
-#ifdef HAS_FILESYSTEM
-  if ((strExtension.Equals(".ogg") || strExtension.Equals(".oga")) && CFile::Exists(strPath))
-  {
-    IFileDirectory* pDir=new COGGFileDirectory;
-    //  Has the ogg file more than one bitstream?
-    if (pDir->ContainsFiles(strPath))
-    {
-      return pDir; // treat as directory
-    }
-
-    delete pDir;
-    return NULL;
-  }
-  if (strExtension.Equals(".nsf") && CFile::Exists(strPath))
-  {
-    IFileDirectory* pDir=new CNSFFileDirectory;
-    //  Has the nsf file more than one track?
-    if (pDir->ContainsFiles(strPath))
-      return pDir; // treat as directory
-
-    delete pDir;
-    return NULL;
-  }
-  if (strExtension.Equals(".sid") && CFile::Exists(strPath))
-  {
-    IFileDirectory* pDir=new CSIDFileDirectory;
-    //  Has the sid file more than one track?
-    if (pDir->ContainsFiles(strPath))
-      return pDir; // treat as directory
-
-    delete pDir;
-    return NULL;
-  }
-#ifdef HAS_ASAP_CODEC
-  if (ASAPCodec::IsSupportedFormat(strExtension) && CFile::Exists(strPath))
-  {
-    IFileDirectory* pDir=new CASAPFileDirectory;
-    //  Has the asap file more than one track?
-    if (pDir->ContainsFiles(strPath))
-      return pDir; // treat as directory
-
-    delete pDir;
-    return NULL;
-  }
-#endif
-
-  if (pItem->IsRSS())
-    return new CRSSDirectory();
-
-#endif
-  if (strExtension.Equals(".zip"))
-  {
-    CStdString strUrl;
-    URIUtils::CreateArchivePath(strUrl, "zip", strPath, "");
-
-    CFileItemList items;
-    CDirectory::GetDirectory(strUrl, items, strMask);
-    if (items.Size() == 0) // no files
-      pItem->m_bIsFolder = true;
-    else if (items.Size() == 1 && items[0]->m_idepth == 0)
-    {
-      // one STORED file - collapse it down
-      *pItem = *items[0];
-    }
-    else
-    { // compressed or more than one file -> create a zip dir
-      pItem->SetPath(strUrl);
-      return new CZipDirectory;
-    }
-    return NULL;
-  }
-  if (strExtension.Equals(".rar") || strExtension.Equals(".001"))
-  {
-    CStdString strUrl;
-    URIUtils::CreateArchivePath(strUrl, "rar", strPath, "");
-
-    vector<CStdString> tokens;
-    CUtil::Tokenize(strPath,tokens,".");
-    if (tokens.size() > 2)
-    {
-      if (strExtension.Equals(".001"))
-      {
-        if (tokens[tokens.size()-2].Equals("ts")) // .ts.001 - treat as a movie file to scratch some users itch
-          return NULL;
-      }
-      CStdString token = tokens[tokens.size()-2];
-      if (token.Left(4).CompareNoCase("part") == 0) // only list '.part01.rar'
-      {
-        // need this crap to avoid making mistakes - yeyh for the new rar naming scheme :/
-        struct __stat64 stat;
-        int digits = token.size()-4;
-        CStdString strNumber, strFormat;
-        strFormat.Format("part%%0%ii",digits);
-        strNumber.Format(strFormat.c_str(),1);
-        CStdString strPath2=strPath;
-        strPath2.Replace(token,strNumber);
-        if (atoi(token.substr(4).c_str()) > 1 && CFile::Stat(strPath2,&stat) == 0)
-        {
-          pItem->m_bIsFolder = true;
-          return NULL;
-        }
-      }
-    }
-
-    CFileItemList items;
-    CDirectory::GetDirectory(strUrl, items, strMask);
-    if (items.Size() == 0) // no files - hide this
-      pItem->m_bIsFolder = true;
-    else if (items.Size() == 1 && items[0]->m_idepth == 0x30)
-    {
-      // one STORED file - collapse it down
-      *pItem = *items[0];
-    }
-    else
-    {
-#ifdef HAS_FILESYSTEM_RAR
-      // compressed or more than one file -> create a rar dir
-      pItem->SetPath(strUrl);
-      return new CRarDirectory;
-#else
-      return NULL;
-#endif
-    }
-    return NULL;
-  }
-  if (strExtension.Equals(".xsp"))
-  { // XBMC Smart playlist - just XML renamed to XSP
-    // read the name of the playlist in
-    CSmartPlaylist playlist;
-    if (playlist.OpenAndReadName(strPath))
-    {
-      pItem->SetLabel(playlist.GetName());
-      pItem->SetLabelPreformated(true);
-    }
-    IFileDirectory* pDir=new CSmartPlaylistDirectory;
-    return pDir; // treat as directory
-  }
-  if (g_advancedSettings.m_playlistAsFolders && CPlayListFactory::IsPlaylist(strPath))
-  { // Playlist file
-    // currently we only return the directory if it contains
-    // more than one file.  Reason is that .pls and .m3u may be used
-    // for links to http streams etc.
-    IFileDirectory *pDir = new CPlaylistFileDirectory();
-    CFileItemList items;
-    if (pDir->GetDirectory(strPath, items))
-    {
-      if (items.Size() > 1)
-        return pDir;
-    }
-    delete pDir;
-    return NULL;
-  }
-  return NULL;
-}
-
diff --git a/xbmc/filesystem/FactoryFileDirectory.h b/xbmc/filesystem/FactoryFileDirectory.h
deleted file mode 100644 (file)
index d426430..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "IFileDirectory.h"
-
-class CFileItem;
-
-namespace XFILE
-{
-class CFactoryFileDirectory
-{
-public:
-  CFactoryFileDirectory(void);
-  virtual ~CFactoryFileDirectory(void);
-  static IFileDirectory* Create(const CStdString& strPath, CFileItem* pItem, const CStdString& strMask="");
-};
-}
index 080ed73..ec3f3c4 100644 (file)
@@ -827,8 +827,9 @@ bool CFile::SetHidden(const CStdString& fileName, bool hidden)
 int CFile::IoControl(EIoControl request, void* param)
 {
   int result = -1;
-  if (m_pFile)
-    result = m_pFile->IoControl(request, param);
+  if (m_pFile == NULL)
+    return -1;
+  result = m_pFile->IoControl(request, param);
 
   if(result == -1 && request == IOCTRL_SEEK_POSSIBLE)
   {
@@ -1034,17 +1035,3 @@ bool CFileStream::Open(const CStdString& filename)
 {
   return Open(CURL(URIUtils::SubstitutePath(filename)));
 }
-
-#ifdef _ARMEL
-char* CFileStream::ReadFile()
-{
-  if(!m_file)
-    return NULL;
-
-  int64_t length = m_file->GetLength();
-  char *str = new char[length+1];
-  m_file->Read(str, length);
-  str[length] = '\0';
-  return str;
-}
-#endif
index 29e4028..5240569 100644 (file)
@@ -148,9 +148,6 @@ public:
   void Close();
 
   int64_t GetLength();
-#ifdef _ARMEL
-  char*   ReadFile();
-#endif
 private:
   CFileStreamBuffer m_buffer;
   IFile*            m_file;
diff --git a/xbmc/filesystem/FileAFP.cpp b/xbmc/filesystem/FileAFP.cpp
deleted file mode 100644 (file)
index ff45413..0000000
+++ /dev/null
@@ -1,735 +0,0 @@
-/*
- *      Copyright (C) 2011 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-// FileAFP.cpp: implementation of the CFileAFP class.
-//
-//////////////////////////////////////////////////////////////////////
-#ifdef _LINUX
-#include "system.h"
-
-#if defined(HAS_FILESYSTEM_AFP)
-#include "FileAFP.h"
-#include "PasswordManager.h"
-#include "AFPDirectory.h"
-#include "Util.h"
-#include "settings/AdvancedSettings.h"
-#include "settings/GUISettings.h"
-#include "threads/SingleLock.h"
-#include "utils/log.h"
-#include "utils/TimeUtils.h"
-
-using namespace XFILE;
-
-#define AFP_MAX_READ_SIZE 131072
-
-CStdString URLEncode(const CStdString value)
-{
-  CStdString encoded(value);
-  CURL::Encode(encoded);
-  return encoded;
-}
-
-void AfpConnectionLog(void *priv, enum loglevels loglevel, int logtype, const char *message)
-{
-  if (!message) return;
-  CStdString msg = "LIBAFPCLIENT: " + CStdString(message);
-
-  switch(logtype)
-  {
-    case LOG_WARNING:
-      CLog::Log(LOGWARNING, "%s", msg.c_str());
-      break;
-    case LOG_ERR:
-      CLog::Log(LOGERROR, "%s", msg.c_str());
-      break;
-    default:
-      CLog::Log(LOGDEBUG, "%s", msg.c_str());
-      break;
-  }
-}
-
-CAfpConnection::CAfpConnection()
- : m_OpenConnections(0)
- , m_IdleTimeout(0)
- , m_pAfpServer(NULL)
- , m_pAfpVol(NULL)
- , m_pAfpUrl((struct afp_url*)malloc(sizeof(struct afp_url)))
- , m_pAfpClient((struct libafpclient*)malloc(sizeof(struct libafpclient)))
- , m_pLibAfp(new DllLibAfp())
- , m_bDllInited(false)
-{
-}
-
-CAfpConnection::~CAfpConnection()
-{
-  Disconnect();
-  free(m_pAfpClient);
-  free(m_pAfpUrl);
-  if (m_pLibAfp->IsLoaded())
-    m_pLibAfp->Unload();
-  delete m_pLibAfp;
-}
-
-bool CAfpConnection::initLib()
-{
-  if (!m_bDllInited)
-  {
-    if (m_pLibAfp->Load())
-    {
-      m_pAfpClient->unmount_volume = NULL;
-      m_pAfpClient->log_for_client = AfpConnectionLog;
-      m_pAfpClient->forced_ending_hook = NULL;
-      m_pAfpClient->scan_extra_fds = NULL;
-      m_pAfpClient->loop_started = NULL;
-
-      m_pLibAfp->libafpclient_register(m_pAfpClient);
-      m_pLibAfp->init_uams();
-      m_pLibAfp->afp_main_quick_startup(NULL);
-      CLog::Log(LOGDEBUG, "AFP: Supported UAMs: %s", m_pLibAfp->get_uam_names_list());
-      m_bDllInited = true;
-    }
-    else
-    {
-      CLog::Log(LOGERROR, "AFP: Error loading afpclient lib.");
-    }
-  }
-
-  return m_bDllInited;
-}
-
-//only unmount here - afpclient lib is not
-//stoppable (no afp_main_quick_shutdown as counter part
-//for afp_main_quick_startup)
-void CAfpConnection::Deinit()
-{
-  if(m_pAfpVol && m_pLibAfp->IsLoaded())
-  {
-    disconnectVolume();
-    Disconnect();
-    m_pAfpUrl->servername[0] = '\0';
-  }        
-}
-
-void CAfpConnection::Disconnect()
-{
-  CSingleLock lock(*this);
-  m_pAfpServer = NULL;
-}
-
-void CAfpConnection::disconnectVolume()
-{
-  if (m_pAfpVol)
-  {
-    // afp_unmount_volume(m_pAfpVol);
-    m_pLibAfp->afp_unmount_all_volumes(m_pAfpServer);
-    m_pAfpVol = NULL;
-  }
-}
-
-// taken from cmdline tool
-bool CAfpConnection::connectVolume(const char *volumename, struct afp_volume *&pVolume)
-{
-  bool ret = false;
-  if (strlen(volumename) != 0)
-  {
-    // Ah, we're not connected to a volume
-    unsigned int len = 0;
-    char mesg[1024];
-
-    if ((pVolume = m_pLibAfp->find_volume_by_name(m_pAfpServer, volumename)) == NULL)
-    {
-      CLog::Log(LOGDEBUG, "AFP: Could not find a volume called %s\n", volumename);
-    }
-    else
-    {
-      pVolume->mapping = AFP_MAPPING_LOGINIDS;
-      pVolume->extra_flags |= VOLUME_EXTRA_FLAGS_NO_LOCKING;
-
-      if (m_pLibAfp->afp_connect_volume(pVolume, m_pAfpServer, mesg, &len, 1024 ))
-      {
-        CLog::Log(LOGDEBUG, "AFP: Could not access volume %s (error: %s)\n", pVolume->volume_name, mesg);
-        pVolume = NULL;
-      }
-      else
-      {
-        CLog::Log(LOGDEBUG, "AFP: Connected to volume %s\n", pVolume->volume_name_printable);
-        ret = true;
-      }
-    }
-  }
-
-  return ret;
-}
-
-CStdString CAfpConnection::getAuthenticatedPath(const CURL &url)
-{
-  CURL authURL(url);
-  CStdString ret;
-  CPasswordManager::GetInstance().AuthenticateURL(authURL);
-  ret = authURL.Get();
-  return ret;
-}
-
-CAfpConnection::afpConnnectError CAfpConnection::Connect(const CURL& url)
-{
-  CSingleLock lock(*this);
-  struct afp_connection_request *conn_req = NULL;
-  struct afp_url tmpurl;
-  CURL nonConstUrl(getAuthenticatedPath(url)); // we need a editable copy of the url
-  bool serverChanged=false;
-
-  if (!initLib())
-    return AfpFailed;
-
-  m_pLibAfp->afp_default_url(&tmpurl);
-
-  // if hostname has changed - assume server changed
-  if (!nonConstUrl.GetHostName().Equals(m_pAfpUrl->servername, false)|| (m_pAfpServer && m_pAfpServer->connect_state == 0))
-  {
-    serverChanged = true;
-    Disconnect();
-  }
-
-  // if volume changed - also assume server changed (afpclient can't reuse old servobject it seems)
-  if (!nonConstUrl.GetShareName().Equals(m_pAfpUrl->volumename, false))
-  {
-   // no reusing of old server object possible with libafpclient it seems...
-    serverChanged = true;
-    Disconnect();
-  }
-
-  // first, try to parse the URL
-  if (m_pLibAfp->afp_parse_url(&tmpurl, nonConstUrl.Get().c_str(), 0) != 0)
-  {
-    // Okay, this isn't a real URL
-    CLog::Log(LOGDEBUG, "AFP: Could not parse url: %s!\n", nonConstUrl.Get().c_str());
-    return AfpFailed;
-  }
-  else // parsed sucessfull
-  {
-    // this is our current url object whe are connected to (at least we try)
-    *m_pAfpUrl = tmpurl;
-  }
-
-  // if no username and password is set - use no user authent uam
-  if (strlen(m_pAfpUrl->password) == 0 && strlen(m_pAfpUrl->username) == 0)
-  {
-    // try anonymous
-    strncpy(m_pAfpUrl->uamname, "No User Authent", sizeof(m_pAfpUrl->uamname));
-    CLog::Log(LOGDEBUG, "AFP: Using anonymous authentication.");
-  }
-  else if ((nonConstUrl.GetPassWord().IsEmpty() || nonConstUrl.GetUserName().IsEmpty()) && serverChanged)
-  {
-    // this is our current url object whe are connected to (at least we try)
-    return AfpAuth;
-  }
-
-  // we got a password in the url
-  if (!nonConstUrl.GetPassWord().IsEmpty())
-  {
-    // copy password because afp_parse_url just puts garbage into the password field :(
-    strncpy(m_pAfpUrl->password, nonConstUrl.GetPassWord().c_str(), 127);
-  }
-
-  // whe are not connected or we want to connect to another server
-  if (!m_pAfpServer || serverChanged)
-  {
-    // code from cmdline tool
-    conn_req = (struct afp_connection_request*)malloc(sizeof(struct afp_connection_request));
-    memset(conn_req, 0, sizeof(struct afp_connection_request));
-
-    conn_req->url = *m_pAfpUrl;
-    conn_req->url.requested_version = 31;
-
-    if (strlen(m_pAfpUrl->uamname)>0)
-    {
-      if ((conn_req->uam_mask = m_pLibAfp->find_uam_by_name(m_pAfpUrl->uamname)) == 0)
-      {
-        CLog::Log(LOGDEBUG, "AFP:I don't know about UAM %s\n", m_pAfpUrl->uamname);
-        m_pAfpUrl->volumename[0] = '\0';
-        m_pAfpUrl->servername[0] = '\0';
-        free(conn_req);
-        return AfpFailed;
-      }
-    }
-    else
-    {
-      conn_req->uam_mask = m_pLibAfp->default_uams_mask();
-    }
-
-    // try to connect
-#ifdef USE_CVS_AFPFS
-    if ((m_pAfpServer = m_pLibAfp->afp_wrap_server_full_connect(NULL, conn_req, NULL)) == NULL)
-#else
-    if ((m_pAfpServer = m_pLibAfp->afp_wrap_server_full_connect(NULL, conn_req)) == NULL)
-#endif
-    {
-      m_pAfpUrl->volumename[0] = '\0';
-      m_pAfpUrl->servername[0] = '\0';
-      free(conn_req);
-      CLog::Log(LOGERROR, "AFP: Error connecting to %s", url.Get().c_str());
-      return AfpFailed;
-    }
-    // success!
-    CLog::Log(LOGDEBUG, "AFP: Connected to server %s using UAM \"%s\"\n",
-      m_pAfpServer->server_name, m_pLibAfp->uam_bitmap_to_string(m_pAfpServer->using_uam));
-    // we don't need it after here ...
-    free(conn_req);
-  }
-
-  // if server changed reconnect volume
-  if (serverChanged)
-  {
-    connectVolume(m_pAfpUrl->volumename, m_pAfpVol); // connect new volume
-  }
-  return AfpOk;
-}
-
-int CAfpConnection::stat(const CURL &url, struct stat *statbuff)
-{
-  CSingleLock lock(*this);
-  CStdString strPath = gAfpConnection.GetPath(url);
-  struct afp_volume *pTmpVol = NULL;
-  struct afp_url tmpurl;
-  int iResult = -1;
-  CURL nonConstUrl(getAuthenticatedPath(url)); // we need a editable copy of the url
-
-  if (!initLib() || !m_pAfpServer)
-    return -1;
-
-  m_pLibAfp->afp_default_url(&tmpurl);
-
-  // first, try to parse the URL
-  if (m_pLibAfp->afp_parse_url(&tmpurl, nonConstUrl.Get().c_str(), 0) != 0)
-  {
-    // Okay, this isn't a real URL
-    CLog::Log(LOGDEBUG, "AFP: Could not parse url: %s!\n", nonConstUrl.Get().c_str());
-    return -1;
-  }
-
-  // if no username and password is set - use no user authent uam
-  if (strlen(tmpurl.password) == 0 && strlen(tmpurl.username) == 0)
-  {
-    // try anonymous
-    strncpy(tmpurl.uamname, "No User Authent", sizeof(tmpurl.uamname));
-    CLog::Log(LOGDEBUG, "AFP: Using anonymous authentication.");
-  }
-  else if ((nonConstUrl.GetPassWord().IsEmpty() || nonConstUrl.GetUserName().IsEmpty()))
-  {
-    // this is our current url object whe are connected to (at least we try)
-    return -1;
-  }
-
-  // we got a password in the url
-  if (!nonConstUrl.GetPassWord().IsEmpty())
-  {
-    // copy password because afp_parse_url just puts garbage into the password field :(
-    strncpy(tmpurl.password, nonConstUrl.GetPassWord().c_str(), 127);
-  }
-
-  // connect new volume
-  if(connectVolume(tmpurl.volumename, pTmpVol) && pTmpVol)
-  {
-    iResult = m_pLibAfp->afp_wrap_getattr(pTmpVol, strPath.c_str(), statbuff);
-    //unmount single volume crashs
-    //we will get rid of the mounted volume
-    //once the context is changed in connect function
-    //ppppooooorrrr!!
-    //m_pLibAfp->afp_unmount_volume(pTmpVol);
-  }
-  return iResult;
-}
-
-
-/* This is called from CApplication::ProcessSlow() and is used to tell if afp have been idle for too long */
-void CAfpConnection::CheckIfIdle()
-{
-  /* We check if there are open connections. This is done without a lock to not halt the mainthread. It should be thread safe as
-   worst case scenario is that m_OpenConnections could read 0 and then changed to 1 if this happens it will enter the if wich will lead to another check, wich is locked.  */
-  if (m_OpenConnections == 0 && m_pAfpVol != NULL)
-  { /* I've set the the maxiumum IDLE time to be 1 min and 30 sec. */
-    CSingleLock lock(*this);
-    if (m_OpenConnections == 0 /* check again - when locked */)
-    {
-      if (m_IdleTimeout > 0)
-      {
-        m_IdleTimeout--;
-      }
-      else
-      {
-        CLog::Log(LOGNOTICE, "AFP is idle. Closing the remaining connections.");
-        gAfpConnection.Deinit();
-      }
-    }
-  }
-}
-
-/* The following two function is used to keep track on how many Opened files/directories there are.
-needed for unloading the dylib*/
-void CAfpConnection::AddActiveConnection()
-{
-  CSingleLock lock(*this);
-  m_OpenConnections++;
-}
-
-void CAfpConnection::AddIdleConnection()
-{
-  CSingleLock lock(*this);
-  m_OpenConnections--;
-  /* If we close a file we reset the idle timer so that we don't have any wierd behaviours if a user
-   leaves the movie paused for a long while and then press stop */
-  m_IdleTimeout = 180;
-}
-
-CStdString CAfpConnection::GetPath(const CURL &url)
-{
-  struct afp_url tmpurl;
-  CStdString ret = "";
-
-  m_pLibAfp->afp_default_url(&tmpurl);
-
-  // First, try to parse the URL
-  if (m_pLibAfp->afp_parse_url(&tmpurl, url.Get().c_str(), 0) != 0 )
-  {
-    // Okay, this isn't a real URL
-    CLog::Log(LOGDEBUG, "AFP: Could not parse url.\n");
-  }
-  else
-  {
-    ret = CStdString(tmpurl.path);
-  }
-  return ret;
-}
-
-CAfpConnection gAfpConnection;
-
-CFileAFP::CFileAFP()
- : m_fileSize(0)
- , m_fileOffset(0)
- , m_pFp(NULL)
- , m_pAfpVol(NULL)
-{
-  gAfpConnection.AddActiveConnection();
-}
-
-CFileAFP::~CFileAFP()
-{
-  gAfpConnection.AddIdleConnection();
-  Close();
-}
-
-int64_t CFileAFP::GetPosition()
-{
-  if (m_pFp == NULL) return 0;
-  return m_fileOffset;
-}
-
-int64_t CFileAFP::GetLength()
-{
-  if (m_pFp == NULL) return 0;
-  return m_fileSize;
-}
-
-bool CFileAFP::Open(const CURL& url)
-{
-  Close();
-  // we can't open files like afp://file.f or afp://server/file.f
-  // if a file matches the if below return false, it can't exist on a afp share.
-  if (!IsValidFile(url.GetFileName()))
-  {
-    CLog::Log(LOGNOTICE, "FileAfp: Bad URL : '%s'", url.GetFileName().c_str());
-    return false;
-  }
-
-  CSingleLock lock(gAfpConnection);
-  if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume())
-    return false;
-  m_pAfpVol = gAfpConnection.GetVolume();
-
-  CStdString strPath = gAfpConnection.GetPath(url);
-
-  if (gAfpConnection.GetImpl()->afp_wrap_open(m_pAfpVol, strPath.c_str(), O_RDONLY, &m_pFp))
-  {
-    if (gAfpConnection.GetImpl()->afp_wrap_open(m_pAfpVol, URLEncode(strPath.c_str()).c_str(), O_RDONLY, &m_pFp))
-    {
-      // write error to logfile
-      CLog::Log(LOGINFO, "CFileAFP::Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strPath.c_str(), errno, strerror(errno));
-      return false;
-    }
-  }
-  
-  CLog::Log(LOGDEBUG,"CFileAFP::Open - opened %s, fd=%d",url.GetFileName().c_str(), m_pFp ? m_pFp->fileid:-1);
-  m_url = url;
-  
-#ifdef _LINUX
-  struct __stat64 tmpBuffer;
-#else
-  struct stat tmpBuffer;
-#endif  
-  if(Stat(&tmpBuffer))
-  {
-    m_url.Reset();
-    Close();
-    return false;
-  }
-
-  m_fileSize = tmpBuffer.st_size;
-  m_fileOffset = 0;
-  // We've successfully opened the file!
-  return true;
-}
-
-
-bool CFileAFP::Exists(const CURL& url)
-{
-  return Stat(url, NULL) == 0;
-}
-
-int CFileAFP::Stat(struct __stat64* buffer)
-{
-  if (m_pFp == NULL)
-    return -1;
-  return Stat(m_url, buffer);
-}
-
-// TODO - maybe check returncode!
-int CFileAFP::Stat(const CURL& url, struct __stat64* buffer)
-{
-  CSingleLock lock(gAfpConnection);
-  if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume())
-    return -1;
-
-  CStdString strPath = gAfpConnection.GetPath(url);
-
-  struct stat tmpBuffer = {0};
-  int iResult = gAfpConnection.GetImpl()->afp_wrap_getattr(gAfpConnection.GetVolume(), strPath.c_str(), &tmpBuffer);
-
-  if (buffer)
-  {
-    memset(buffer, 0, sizeof(struct __stat64));
-    buffer->st_dev   = tmpBuffer.st_dev;
-    buffer->st_ino   = tmpBuffer.st_ino;
-    buffer->st_mode  = tmpBuffer.st_mode;
-    buffer->st_nlink = tmpBuffer.st_nlink;
-    buffer->st_uid   = tmpBuffer.st_uid;
-    buffer->st_gid   = tmpBuffer.st_gid;
-    buffer->st_rdev  = tmpBuffer.st_rdev;
-    buffer->st_size  = tmpBuffer.st_size;
-    buffer->st_atime = tmpBuffer.st_atime;
-    buffer->st_mtime = tmpBuffer.st_mtime;
-    buffer->st_ctime = tmpBuffer.st_ctime;
-  }
-
-  return iResult;
-}
-
-unsigned int CFileAFP::Read(void *lpBuf, int64_t uiBufSize)
-{
-  CSingleLock lock(gAfpConnection);
-  if (m_pFp == NULL || !m_pAfpVol)
-    return 0;
-
-  if (uiBufSize > AFP_MAX_READ_SIZE)
-    uiBufSize = AFP_MAX_READ_SIZE;
-
-#ifdef USE_CVS_AFPFS
-  char *name = m_pFp->basename;
-#else
-  char *name = m_pFp->name;
-  if (strlen(name) == 0)
-    name = m_pFp->basename;
-
-#endif
-  int eof = 0;
-  int bytesRead = gAfpConnection.GetImpl()->afp_wrap_read(m_pAfpVol,
-    name, (char *)lpBuf,(size_t)uiBufSize, m_fileOffset, m_pFp, &eof);
-  if (bytesRead > 0)
-    m_fileOffset += bytesRead;
-
-  if (bytesRead < 0)
-  {
-    CLog::Log(LOGERROR, "%s - Error( %d, %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno));
-    return 0;
-  }
-
-  return (unsigned int)bytesRead;
-}
-
-int64_t CFileAFP::Seek(int64_t iFilePosition, int iWhence)
-{
-  off_t newOffset = m_fileOffset;
-  if (m_pFp == NULL) return -1;
-
-  switch(iWhence)
-  {
-    case SEEK_SET:
-      newOffset = iFilePosition;
-      break;
-    case SEEK_END:
-      newOffset = m_fileSize+iFilePosition;
-      break;
-    case SEEK_CUR:
-      newOffset += iFilePosition;
-      break;
-  }
-
-  if ( newOffset < 0 || newOffset > m_fileSize)
-  {
-    CLog::Log(LOGERROR, "%s - Error( %"PRId64")", __FUNCTION__, newOffset);
-    return -1;
-  }
-
-  m_fileOffset = newOffset;
-  return (int64_t)m_fileOffset;
-}
-
-void CFileAFP::Close()
-{
-  CSingleLock lock(gAfpConnection);
-  if (m_pFp != NULL && m_pAfpVol)
-  {
-    CLog::Log(LOGDEBUG, "CFileAFP::Close closing fd %d", m_pFp->fileid);
-#ifdef USE_CVS_AFPFS
-    char *name = m_pFp->basename;
-#else
-    char *name = m_pFp->name;
-    if (strlen(name) == 0)
-      name = m_pFp->basename;
-#endif
-    gAfpConnection.GetImpl()->afp_wrap_close(m_pAfpVol, name, m_pFp);
-    delete m_pFp;
-    m_pFp = NULL;
-    m_pAfpVol = NULL;
-  }
-}
-
-int CFileAFP::Write(const void* lpBuf, int64_t uiBufSize)
-{
-  CSingleLock lock(gAfpConnection);
-  if (m_pFp == NULL || !m_pAfpVol)
-   return -1;
-
-  int numberOfBytesWritten = 0;
-  uid_t uid;
-  gid_t gid;
-
-  // FIXME need a better way to get server's uid/gid
-  uid = getuid();
-  gid = getgid();
-#ifdef USE_CVS_AFPFS
-  char *name = m_pFp->basename;
-#else
-  char *name = m_pFp->name;
-  if (strlen(name) == 0)
-    name = m_pFp->basename;
-#endif
-  numberOfBytesWritten = gAfpConnection.GetImpl()->afp_wrap_write(m_pAfpVol,
-    name, (const char *)lpBuf, (size_t)uiBufSize, m_fileOffset, m_pFp, uid, gid);
-
-  return numberOfBytesWritten;
-}
-
-bool CFileAFP::Delete(const CURL& url)
-{
-  CSingleLock lock(gAfpConnection);
-  if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume())
-    return false;
-
-  CStdString strPath = gAfpConnection.GetPath(url);
-
-  int result = gAfpConnection.GetImpl()->afp_wrap_unlink(gAfpConnection.GetVolume(), strPath.c_str());
-
-  if (result != 0)
-    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno));
-
-  return (result == 0);
-}
-
-bool CFileAFP::Rename(const CURL& url, const CURL& urlnew)
-{
-  CSingleLock lock(gAfpConnection);
-  if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume())
-    return false;
-
-  CStdString strFile = gAfpConnection.GetPath(url);
-  CStdString strFileNew = gAfpConnection.GetPath(urlnew);
-
-  int result = gAfpConnection.GetImpl()->afp_wrap_rename(gAfpConnection.GetVolume(), strFile.c_str(), strFileNew.c_str());
-
-  if (result != 0)
-    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno));
-
-  return (result == 0);
-}
-
-bool CFileAFP::OpenForWrite(const CURL& url, bool bOverWrite)
-{
-
-  int ret = 0;
-  m_fileSize = 0;
-  m_fileOffset = 0;
-
-  Close();
-  CSingleLock lock(gAfpConnection);
-  if (gAfpConnection.Connect(url) != CAfpConnection::AfpOk || !gAfpConnection.GetVolume())
-    return false;
-
-  // we can't open files like afp://file.f or afp://server/file.f
-  // if a file matches the if below return false, it can't exist on a afp share.
-  if (!IsValidFile(url.GetFileName()))
-    return false;
-
-  m_pAfpVol = gAfpConnection.GetVolume();
-
-  CStdString strPath = gAfpConnection.GetPath(url);
-
-  if (bOverWrite)
-  {
-    CLog::Log(LOGWARNING, "FileAFP::OpenForWrite() called with overwriting enabled! - %s", strPath.c_str());
-    ret = gAfpConnection.GetImpl()->afp_wrap_creat(m_pAfpVol, strPath.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-  }
-
-  ret = gAfpConnection.GetImpl()->afp_wrap_open(m_pAfpVol, strPath.c_str(), O_RDWR, &m_pFp);
-
-  if (ret || m_pFp == NULL)
-  {
-    // write error to logfile
-    CLog::Log(LOGERROR, "CFileAFP::Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strPath.c_str(), errno, strerror(errno));
-    return false;
-  }
-
-  // We've successfully opened the file!
-  return true;
-}
-
-bool CFileAFP::IsValidFile(const CStdString& strFileName)
-{
-  if (strFileName.Find('/') == -1   || // doesn't have sharename
-      strFileName.Right(2)  == "/." || // not current folder
-      strFileName.Right(3)  == "/..")  // not parent folder
-  {
-    return false;
-  }
-
-  return true;
-}
-#endif // HAS_FILESYSTEM_AFP
-#endif // _LINUX
diff --git a/xbmc/filesystem/FileAFP.h b/xbmc/filesystem/FileAFP.h
deleted file mode 100644 (file)
index bf6e0f9..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *      Copyright (C) 2011 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-// FileAFP.h: interface for the CFileAFP class.
-#ifndef FILEAFP_H_
-#define FILEAFP_H_
-
-
-#ifdef _LINUX
-
-#include "IFile.h"
-#include "URL.h"
-#include "threads/CriticalSection.h"
-#include "DllLibAfp.h"
-
-// libafpclient includes
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-CStdString URLEncode(CStdString str);
-
-class CAfpConnection : public CCriticalSection
-{
-public:
-    enum eAfpConnectError
-    {
-      AfpOk     = 0,
-      AfpFailed = 1,
-      AfpAuth   = 2,
-    };
-    typedef enum eAfpConnectError afpConnnectError;
-
-   CAfpConnection();
-  ~CAfpConnection();
-
-  afpConnnectError      Connect(const CURL &url);
-  void                  Disconnect(void);
-  struct afp_server     *GetServer()    {return m_pAfpServer;}
-  struct afp_volume     *GetVolume()    {return m_pAfpVol;};
-  struct afp_url        *GetUrl()       {return m_pAfpUrl;};
-  CStdString            GetPath(const CURL &url);
-  DllLibAfp             *GetImpl()      {return m_pLibAfp;}
-  
-  const char            *GetConnectedIp() const { if(m_pAfpUrl) return m_pAfpUrl->servername;else return "";}
-  
-  //special stat which uses its own context
-  //needed for getting intervolume symlinks to work
-  //it uses the same global server connection
-  //but its own volume
-  int                   stat(const CURL &url, struct stat *statbuff);
-  
-  void AddActiveConnection();
-  void AddIdleConnection();
-  void CheckIfIdle();  
-  void Deinit();  
-
-private:
-  bool                  initLib(void);
-  bool                  connectVolume(const char *volumename, struct afp_volume *&pVolume);
-  void                  disconnectVolume(void);
-  CStdString            getAuthenticatedPath(const CURL &url);
-
-  int                   m_OpenConnections;
-  int                   m_IdleTimeout;
-  struct afp_server     *m_pAfpServer;
-  struct afp_volume     *m_pAfpVol;
-  struct afp_url        *m_pAfpUrl;
-  struct libafpclient   *m_pAfpClient;
-  DllLibAfp             *m_pLibAfp;
-  bool                  m_bDllInited;
-};
-
-extern CAfpConnection gAfpConnection;
-
-namespace XFILE
-{
-class CFileAFP : public IFile
-{
-public:
-  CFileAFP();
-  virtual ~CFileAFP();
-  virtual void          Close();
-  virtual int64_t       Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual unsigned int  Read(void* lpBuf, int64_t uiBufSize);
-  virtual bool          Open(const CURL& url);
-  virtual bool          Exists(const CURL& url);
-  virtual int           Stat(const CURL& url, struct __stat64* buffer);
-  virtual int           Stat(struct __stat64* buffer);
-  virtual int64_t       GetLength();
-  virtual int64_t       GetPosition();
-  virtual int           Write(const void* lpBuf, int64_t uiBufSize);
-
-  virtual bool          OpenForWrite(const CURL& url, bool bOverWrite = false);
-  virtual bool          Delete(const CURL& url);
-  virtual bool          Rename(const CURL& url, const CURL& urlnew);
-  virtual int           GetChunkSize() {return 1;}
-  // implement iocontrol for seek_possible for preventing the stat in File class for
-  // getting this info ...
-  virtual int           IoControl(EIoControl request, void* param)
-                        { if (request == IOCTRL_SEEK_POSSIBLE) return 1;
-                          return -1;
-                        };
-
-protected:
-  bool                  IsValidFile(const CStdString& strFileName);
-
-  CURL                  m_url;
-  int64_t               m_fileSize;
-  off_t                 m_fileOffset; // current SEEK pointer
-  struct afp_file_info *m_pFp;
-  struct afp_volume    *m_pAfpVol;  
-};
-}
-#endif // _LINUX
-#endif // FILEAFP_H_
diff --git a/xbmc/filesystem/FileCDDA.cpp b/xbmc/filesystem/FileCDDA.cpp
deleted file mode 100644 (file)
index bae2d87..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "system.h"
-
-#ifdef HAS_DVD_DRIVE
-
-#include "FileCDDA.h"
-#include <sys/stat.h>
-#include "Util.h"
-#include "URL.h"
-#include "storage/MediaManager.h"
-#include "utils/log.h"
-#include "utils/URIUtils.h"
-
-using namespace MEDIA_DETECT;
-using namespace XFILE;
-
-CFileCDDA::CFileCDDA(void)
-{
-  m_pCdIo = NULL;
-  m_lsnStart = CDIO_INVALID_LSN;
-  m_lsnCurrent = CDIO_INVALID_LSN;
-  m_lsnEnd = CDIO_INVALID_LSN;
-  m_cdio = CLibcdio::GetInstance();
-}
-
-CFileCDDA::~CFileCDDA(void)
-{
-  Close();
-}
-
-bool CFileCDDA::Open(const CURL& url)
-{
-  CStdString strURL = url.GetWithoutFilename();
-
-  if (!g_mediaManager.IsDiscInDrive(strURL) || !IsValidFile(url))
-    return false;
-
-  // Open the dvd drive
-#ifdef _LINUX
-  m_pCdIo = m_cdio->cdio_open(g_mediaManager.TranslateDevicePath(strURL), DRIVER_UNKNOWN);
-#elif defined(_WIN32)
-  m_pCdIo = m_cdio->cdio_open_win32(g_mediaManager.TranslateDevicePath(strURL, true));
-#else
-  m_pCdIo = m_cdio->cdio_open_win32("D:");
-#endif
-  if (!m_pCdIo)
-  {
-    CLog::Log(LOGERROR, "file cdda: Opening the dvd drive failed");
-    return false;
-  }
-
-  int iTrack = GetTrackNum(url);
-
-  m_lsnStart = m_cdio->cdio_get_track_lsn(m_pCdIo, iTrack);
-  m_lsnEnd = m_cdio->cdio_get_track_last_lsn(m_pCdIo, iTrack);
-  m_lsnCurrent = m_lsnStart;
-
-  if (m_lsnStart == CDIO_INVALID_LSN || m_lsnEnd == CDIO_INVALID_LSN)
-  {
-    m_cdio->cdio_destroy(m_pCdIo);
-    m_pCdIo = NULL;
-    return false;
-  }
-
-  return true;
-}
-
-bool CFileCDDA::Exists(const CURL& url)
-{
-  if (!IsValidFile(url))
-    return false;
-
-  int iTrack = GetTrackNum(url);
-
-  if (!Open(url))
-    return false;
-
-  int iLastTrack = m_cdio->cdio_get_last_track_num(m_pCdIo);
-  if (iLastTrack == CDIO_INVALID_TRACK)
-    return false;
-
-  return (iTrack > 0 && iTrack <= iLastTrack);
-}
-
-int CFileCDDA::Stat(const CURL& url, struct __stat64* buffer)
-{
-  if (Open(url))
-  {
-    memset(buffer, 0, sizeof(struct __stat64));
-    buffer->st_size = GetLength();
-    buffer->st_mode = _S_IFREG;
-    Close();
-    return 0;
-  }
-  errno = ENOENT;
-  return -1;
-}
-
-unsigned int CFileCDDA::Read(void* lpBuf, int64_t uiBufSize)
-{
-  if (!m_pCdIo || !g_mediaManager.IsDiscInDrive())
-    return 0;
-
-  int iSectorCount = (int)uiBufSize / CDIO_CD_FRAMESIZE_RAW;
-
-  if (iSectorCount <= 0)
-    return 0;
-
-  // Are there enough sectors left to read
-  if (m_lsnCurrent + iSectorCount > m_lsnEnd)
-    iSectorCount = m_lsnEnd - m_lsnCurrent;
-
-  int iret = m_cdio->cdio_read_audio_sectors(m_pCdIo, lpBuf, m_lsnCurrent, iSectorCount);
-
-  if ( iret != DRIVER_OP_SUCCESS)
-  {
-    CLog::Log(LOGERROR, "file cdda: Reading %d sectors of audio data starting at lsn %d failed with error code %i", iSectorCount, m_lsnCurrent, iret);
-    return 0;
-  }
-
-  m_lsnCurrent += iSectorCount;
-
-  return iSectorCount*CDIO_CD_FRAMESIZE_RAW;
-}
-
-int64_t CFileCDDA::Seek(int64_t iFilePosition, int iWhence /*=SEEK_SET*/)
-{
-  if (!m_pCdIo)
-    return -1;
-
-  lsn_t lsnPosition = (int)iFilePosition / CDIO_CD_FRAMESIZE_RAW;
-
-  switch (iWhence)
-  {
-  case SEEK_SET:
-    // cur = pos
-    m_lsnCurrent = m_lsnStart + lsnPosition;
-    break;
-  case SEEK_CUR:
-    // cur += pos
-    m_lsnCurrent += lsnPosition;
-    break;
-  case SEEK_END:
-    // end += pos
-    m_lsnCurrent = m_lsnEnd + lsnPosition;
-    break;
-  default:
-    return -1;
-  }
-
-  return ((m_lsnCurrent -m_lsnStart)*CDIO_CD_FRAMESIZE_RAW);
-}
-
-void CFileCDDA::Close()
-{
-  if (m_pCdIo)
-  {
-    m_cdio->cdio_destroy(m_pCdIo);
-    m_pCdIo = NULL;
-  }
-}
-
-int64_t CFileCDDA::GetPosition()
-{
-  if (!m_pCdIo)
-    return 0;
-
-  return ((m_lsnCurrent -m_lsnStart)*CDIO_CD_FRAMESIZE_RAW);
-}
-
-int64_t CFileCDDA::GetLength()
-{
-  if (!m_pCdIo)
-    return 0;
-
-  return ((m_lsnEnd -m_lsnStart)*CDIO_CD_FRAMESIZE_RAW);
-}
-
-bool CFileCDDA::IsValidFile(const CURL& url)
-{
-  // Only .cdda files are supported
-  CStdString strExtension;
-  URIUtils::GetExtension(url.Get(), strExtension);
-  strExtension.MakeLower();
-
-  return (strExtension == ".cdda");
-}
-
-int CFileCDDA::GetTrackNum(const CURL& url)
-{
-  CStdString strFileName = url.Get();
-
-  // get track number from "cdda://local/01.cdda"
-  return atoi(strFileName.substr(13, strFileName.size() - 13 - 5).c_str());
-}
-
-#define SECTOR_COUNT 52 // max. sectors that can be read at once
-int CFileCDDA::GetChunkSize()
-{
-  return SECTOR_COUNT*CDIO_CD_FRAMESIZE_RAW;
-}
-
-#endif
-
diff --git a/xbmc/filesystem/FileCDDA.h b/xbmc/filesystem/FileCDDA.h
deleted file mode 100644 (file)
index e10e517..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "system.h" // for HAS_DVD_DRIVE
-
-#ifdef HAS_DVD_DRIVE
-
-#include "IFile.h"
-#include "storage/cdioSupport.h"
-
-namespace XFILE
-{
-class CFileCDDA : public IFile
-{
-public:
-  CFileCDDA(void);
-  virtual ~CFileCDDA(void);
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-  virtual int GetChunkSize();
-
-protected:
-  bool IsValidFile(const CURL& url);
-  int GetTrackNum(const CURL& url);
-
-protected:
-  CdIo_t* m_pCdIo;
-  lsn_t m_lsnStart;  // Start of m_iTrack in logical sector number
-  lsn_t m_lsnCurrent; // Position inside the track in logical sector number
-  lsn_t m_lsnEnd;   // End of m_iTrack in logical sector number
-  MEDIA_DETECT::CLibcdio* m_cdio;
-};
-}
-
-#endif
-
index c6af9d0..9e94ce5 100644 (file)
@@ -26,7 +26,7 @@
 #include "File.h"
 #include "URL.h"
 
-#include "CacheCircular.h"
+#include "CircularCache.h"
 #include "threads/SingleLock.h"
 #include "utils/log.h"
 #include "utils/TimeUtils.h"
@@ -89,7 +89,7 @@ CFileCache::CFileCache()
    if (g_advancedSettings.m_cacheMemBufferSize == 0)
      m_pCache = new CSimpleFileCache();
    else
-     m_pCache = new CCacheCircular(g_advancedSettings.m_cacheMemBufferSize
+     m_pCache = new CCircularCache(g_advancedSettings.m_cacheMemBufferSize
                                  , std::max<unsigned int>( g_advancedSettings.m_cacheMemBufferSize / 4, 1024 * 1024));
    m_seekPossible = 0;
    m_cacheFull = false;
@@ -103,6 +103,7 @@ CFileCache::CFileCache(CCacheStrategy *pCache, bool bDeleteCache)
   m_readPos = 0;
   m_writePos = 0;
   m_nSeekResult = 0;
+  m_chunkSize = 0;
 }
 
 CFileCache::~CFileCache()
@@ -163,6 +164,7 @@ bool CFileCache::Open(const CURL& url)
 
   // check if source can seek
   m_seekPossible = m_source.IoControl(IOCTRL_SEEK_POSSIBLE, NULL);
+  m_chunkSize = CFile::GetChunkSize(m_source.GetChunkSize(), READ_CACHE_CHUNK_SIZE);
 
   m_readPos = 0;
   m_writePos = 0;
@@ -185,11 +187,8 @@ void CFileCache::Process()
     return;
   }
 
-  // setup read chunks size
-  int chunksize = CFile::GetChunkSize(m_source.GetChunkSize(), READ_CACHE_CHUNK_SIZE);
-
   // create our read buffer
-  auto_aptr<char> buffer(new char[chunksize]);
+  auto_aptr<char> buffer(new char[m_chunkSize]);
   if (buffer.get() == NULL)
   {
     CLog::Log(LOGERROR, "%s - failed to allocate read buffer", __FUNCTION__);
@@ -243,7 +242,7 @@ void CFileCache::Process()
       }
     }
 
-    int iRead = m_source.Read(buffer.get(), chunksize);
+    int iRead = m_source.Read(buffer.get(), m_chunkSize);
     if (iRead == 0)
     {
       CLog::Log(LOGINFO, "CFileCache::Process - Hit eof.");
@@ -393,13 +392,28 @@ int64_t CFileCache::Seek(int64_t iFilePosition, int iWhence)
     if (m_seekPossible == 0)
       return m_nSeekResult;
 
-    m_seekPos = iTarget;
+    /* never request closer to end than 2k, speeds up tag reading */
+    m_seekPos = std::min(iTarget, std::max((int64_t)0, m_source.GetLength() - m_chunkSize));
+
     m_seekEvent.Set();
     if (!m_seekEnded.Wait())
     {
       CLog::Log(LOGWARNING,"%s - seek to %"PRId64" failed.", __FUNCTION__, m_seekPos);
       return -1;
     }
+
+    /* wait for any remainin data */
+    if(m_seekPos < iTarget)
+    {
+      CLog::Log(LOGDEBUG,"%s - waiting for position %"PRId64".", __FUNCTION__, iTarget);
+      if(m_pCache->WaitForData((unsigned)(iTarget - m_seekPos), 10000) < iTarget - m_seekPos)
+      {
+        CLog::Log(LOGWARNING,"%s - failed to get remaining data", __FUNCTION__);
+        return -1;
+      }
+      m_pCache->Seek(iTarget);
+    }
+    m_readPos = iTarget;
     m_seekEvent.Reset();
   }
   else
index cbc3a62..5509f82 100644 (file)
@@ -73,6 +73,7 @@ namespace XFILE
     int64_t      m_seekPos;
     int64_t      m_readPos;
     int64_t      m_writePos;
+    unsigned     m_chunkSize;
     unsigned     m_writeRate;
     unsigned     m_writeRateActual;
     bool         m_cacheFull;
diff --git a/xbmc/filesystem/FileCurl.cpp b/xbmc/filesystem/FileCurl.cpp
deleted file mode 100644 (file)
index 58cf1bf..0000000
+++ /dev/null
@@ -1,1396 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "FileCurl.h"
-#include "utils/URIUtils.h"
-#include "Util.h"
-#include "URL.h"
-#include "settings/AdvancedSettings.h"
-#include "settings/GUISettings.h"
-#include "settings/Settings.h"
-#include "File.h"
-
-#include <vector>
-#include <climits>
-
-#ifdef _LINUX
-#include <errno.h>
-#include <inttypes.h>
-#include "../linux/XFileUtils.h"
-#include "../linux/XTimeUtils.h"
-#include "../linux/ConvUtils.h"
-#endif
-
-#include "DllLibCurl.h"
-#include "FileShoutcast.h"
-#include "SpecialProtocol.h"
-#include "utils/CharsetConverter.h"
-#include "utils/log.h"
-
-using namespace XFILE;
-using namespace XCURL;
-
-#define XMIN(a,b) ((a)<(b)?(a):(b))
-#define FITS_INT(a) (((a) <= INT_MAX) && ((a) >= INT_MIN))
-
-#define dllselect select
-
-// curl calls this routine to debug
-extern "C" int debug_callback(CURL_HANDLE *handle, curl_infotype info, char *output, size_t size, void *data)
-{
-  if (info == CURLINFO_DATA_IN || info == CURLINFO_DATA_OUT)
-    return 0;
-
-  // Only shown cURL debug into with loglevel DEBUG_SAMBA or higher
-  if( g_advancedSettings.m_logLevel < LOG_LEVEL_DEBUG_SAMBA )
-    return 0;
-
-  CStdString strLine;
-  strLine.append(output, size);
-  std::vector<CStdString> vecLines;
-  CUtil::Tokenize(strLine, vecLines, "\r\n");
-  std::vector<CStdString>::const_iterator it = vecLines.begin();
-
-  while (it != vecLines.end()) {
-    CLog::Log(LOGDEBUG, "Curl::Debug %s", (*it).c_str());
-    it++;
-  }
-  return 0;
-}
-
-/* curl calls this routine to get more data */
-extern "C" size_t write_callback(char *buffer,
-               size_t size,
-               size_t nitems,
-               void *userp)
-{
-  if(userp == NULL) return 0;
-
-  CFileCurl::CReadState *state = (CFileCurl::CReadState *)userp;
-  return state->WriteCallback(buffer, size, nitems);
-}
-
-extern "C" size_t header_callback(void *ptr, size_t size, size_t nmemb, void *stream)
-{
-  CFileCurl::CReadState *state = (CFileCurl::CReadState *)stream;
-  return state->HeaderCallback(ptr, size, nmemb);
-}
-
-/* fix for silly behavior of realloc */
-static inline void* realloc_simple(void *ptr, size_t size)
-{
-  void *ptr2 = realloc(ptr, size);
-  if(ptr && !ptr2 && size > 0)
-  {
-    free(ptr);
-    return NULL;
-  }
-  else
-    return ptr2;
-}
-
-size_t CFileCurl::CReadState::HeaderCallback(void *ptr, size_t size, size_t nmemb)
-{
-  // clear any previous header
-  if(m_headerdone)
-  {
-    m_httpheader.Clear();
-    m_headerdone = false;
-  }
-
-  // libcurl doc says that this info is not always \0 terminated
-  char* strData = (char*)ptr;
-  int iSize = size * nmemb;
-
-  if (strData[iSize] != 0)
-  {
-    strData = (char*)malloc(iSize + 1);
-    strncpy(strData, (char*)ptr, iSize);
-    strData[iSize] = 0;
-  }
-  else strData = strdup((char*)ptr);
-
-  if(strcmp(strData, "\r\n") == 0)
-    m_headerdone = true;
-
-  m_httpheader.Parse(strData);
-
-  free(strData);
-
-  return iSize;
-}
-
-size_t CFileCurl::CReadState::WriteCallback(char *buffer, size_t size, size_t nitems)
-{
-  unsigned int amount = size * nitems;
-//  CLog::Log(LOGDEBUG, "CFileCurl::WriteCallback (%p) with %i bytes, readsize = %i, writesize = %i", this, amount, m_buffer.getMaxReadSize(), m_buffer.getMaxWriteSize() - m_overflowSize);
-  if (m_overflowSize)
-  {
-    // we have our overflow buffer - first get rid of as much as we can
-    unsigned int maxWriteable = XMIN((unsigned int)m_buffer.getMaxWriteSize(), m_overflowSize);
-    if (maxWriteable)
-    {
-      if (!m_buffer.WriteData(m_overflowBuffer, maxWriteable))
-        CLog::Log(LOGERROR, "Unable to write to buffer - what's up?");
-      if (m_overflowSize > maxWriteable)
-      { // still have some more - copy it down
-        memmove(m_overflowBuffer, m_overflowBuffer + maxWriteable, m_overflowSize - maxWriteable);
-      }
-      m_overflowSize -= maxWriteable;
-    }
-  }
-  // ok, now copy the data into our ring buffer
-  unsigned int maxWriteable = XMIN((unsigned int)m_buffer.getMaxWriteSize(), amount);
-  if (maxWriteable)
-  {
-    if (!m_buffer.WriteData(buffer, maxWriteable))
-    {
-      CLog::Log(LOGERROR, "%s - Unable to write to buffer with %i bytes - what's up?", __FUNCTION__, maxWriteable);
-    }
-    else
-    {
-      amount -= maxWriteable;
-      buffer += maxWriteable;
-    }
-  }
-  if (amount)
-  {
-//    CLog::Log(LOGDEBUG, "CFileCurl::WriteCallback(%p) not enough free space for %i bytes", (void*)this,  amount);
-
-    m_overflowBuffer = (char*)realloc_simple(m_overflowBuffer, amount + m_overflowSize);
-    if(m_overflowBuffer == NULL)
-    {
-      CLog::Log(LOGWARNING, "%s - Failed to grow overflow buffer from %i bytes to %i bytes", __FUNCTION__, m_overflowSize, amount + m_overflowSize);
-      return 0;
-    }
-    memcpy(m_overflowBuffer + m_overflowSize, buffer, amount);
-    m_overflowSize += amount;
-  }
-  return size * nitems;
-}
-
-CFileCurl::CReadState::CReadState()
-{
-  m_easyHandle = NULL;
-  m_multiHandle = NULL;
-  m_overflowBuffer = NULL;
-  m_overflowSize = 0;
-  m_filePos = 0;
-  m_fileSize = 0;
-  m_bufferSize = 0;
-  m_cancelled = false;
-  m_bFirstLoop = true;
-  m_headerdone = false;
-}
-
-CFileCurl::CReadState::~CReadState()
-{
-  Disconnect();
-
-  if(m_easyHandle)
-    g_curlInterface.easy_release(&m_easyHandle, &m_multiHandle);
-}
-
-bool CFileCurl::CReadState::Seek(int64_t pos)
-{
-  if(pos == m_filePos)
-    return true;
-
-  if(FITS_INT(pos - m_filePos) && m_buffer.SkipBytes((int)(pos - m_filePos)))
-  {
-    m_filePos = pos;
-    return true;
-  }
-
-  if(pos > m_filePos && pos < m_filePos + m_bufferSize)
-  {
-    int len = m_buffer.getMaxReadSize();
-    m_filePos += len;
-    m_buffer.SkipBytes(len);
-    if(!FillBuffer(m_bufferSize))
-    {
-      if(!m_buffer.SkipBytes(-len))
-        CLog::Log(LOGERROR, "%s - Failed to restore position after failed fill", __FUNCTION__);
-      else
-        m_filePos -= len;
-      return false;
-    }
-
-    if(!FITS_INT(pos - m_filePos) || !m_buffer.SkipBytes((int)(pos - m_filePos)))
-    {
-      CLog::Log(LOGERROR, "%s - Failed to skip to position after having filled buffer", __FUNCTION__);
-      if(!m_buffer.SkipBytes(-len))
-        CLog::Log(LOGERROR, "%s - Failed to restore position after failed seek", __FUNCTION__);
-      else
-        m_filePos -= len;
-      return false;
-    }
-    m_filePos = pos;
-    return true;
-  }
-  return false;
-}
-
-long CFileCurl::CReadState::Connect(unsigned int size)
-{
-  g_curlInterface.easy_setopt(m_easyHandle, CURLOPT_RESUME_FROM_LARGE, m_filePos);
-  g_curlInterface.multi_add_handle(m_multiHandle, m_easyHandle);
-
-  m_bufferSize = size;
-  m_buffer.Destroy();
-  m_buffer.Create(size * 3);
-  m_headerdone = false;
-
-  // read some data in to try and obtain the length
-  // maybe there's a better way to get this info??
-  m_stillRunning = 1;
-  if (!FillBuffer(1))
-  {
-    CLog::Log(LOGERROR, "CFileCurl::CReadState::Open, didn't get any data from stream.");
-    return -1;
-  }
-
-  double length;
-  if (CURLE_OK == g_curlInterface.easy_getinfo(m_easyHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &length))
-  {
-    if (length < 0)
-      length = 0.0;
-    m_fileSize = m_filePos + (int64_t)length;
-  }
-
-  long response;
-  if (CURLE_OK == g_curlInterface.easy_getinfo(m_easyHandle, CURLINFO_RESPONSE_CODE, &response))
-    return response;
-
-  return -1;
-}
-
-void CFileCurl::CReadState::Disconnect()
-{
-  if(m_multiHandle && m_easyHandle)
-    g_curlInterface.multi_remove_handle(m_multiHandle, m_easyHandle);
-
-  m_buffer.Clear();
-  free(m_overflowBuffer);
-  m_overflowBuffer = NULL;
-  m_overflowSize = 0;
-  m_filePos = 0;
-  m_fileSize = 0;
-  m_bufferSize = 0;
-}
-
-
-CFileCurl::~CFileCurl()
-{
-  if (m_opened)
-    Close();
-  delete m_state;
-  g_curlInterface.Unload();
-}
-
-CFileCurl::CFileCurl()
-{
-  g_curlInterface.Load(); // loads the curl dll and resolves exports etc.
-  m_curlAliasList = NULL;
-  m_curlHeaderList = NULL;
-  m_opened = false;
-  m_multisession  = true;
-  m_seekable = true;
-  m_useOldHttpVersion = false;
-  m_connecttimeout = 0;
-  m_lowspeedtime = 0;
-  m_ftpauth = "";
-  m_ftpport = "";
-  m_ftppasvip = false;
-  m_bufferSize = 32768;
-  m_binary = true;
-  m_postdata = "";
-  m_username = "";
-  m_password = "";
-  m_httpauth = "";
-  m_state = new CReadState();
-  m_skipshout = false;
-}
-
-//Has to be called before Open()
-void CFileCurl::SetBufferSize(unsigned int size)
-{
-  m_bufferSize = size;
-}
-
-void CFileCurl::Close()
-{
-  m_state->Disconnect();
-
-  m_url.Empty();
-  m_referer.Empty();
-  m_cookie.Empty();
-
-  /* cleanup */
-  if( m_curlAliasList )
-    g_curlInterface.slist_free_all(m_curlAliasList);
-  if( m_curlHeaderList )
-    g_curlInterface.slist_free_all(m_curlHeaderList);
-
-  m_curlAliasList = NULL;
-  m_curlHeaderList = NULL;
-  m_opened = false;
-}
-
-void CFileCurl::SetCommonOptions(CReadState* state)
-{
-  CURL_HANDLE* h = state->m_easyHandle;
-
-  g_curlInterface.easy_reset(h);
-
-  g_curlInterface.easy_setopt(h, CURLOPT_DEBUGFUNCTION, debug_callback);
-
-  if( g_advancedSettings.m_logLevel >= LOG_LEVEL_DEBUG )
-    g_curlInterface.easy_setopt(h, CURLOPT_VERBOSE, TRUE);
-  else
-    g_curlInterface.easy_setopt(h, CURLOPT_VERBOSE, FALSE);
-
-  g_curlInterface.easy_setopt(h, CURLOPT_WRITEDATA, state);
-  g_curlInterface.easy_setopt(h, CURLOPT_WRITEFUNCTION, write_callback);
-
-  // set username and password for current handle
-  if (m_username.length() > 0 && m_password.length() > 0)
-  {
-    CStdString userpwd = m_username + ":" + m_password;
-    g_curlInterface.easy_setopt(h, CURLOPT_USERPWD, userpwd.c_str());
-  }
-
-  // make sure headers are seperated from the data stream
-  g_curlInterface.easy_setopt(h, CURLOPT_WRITEHEADER, state);
-  g_curlInterface.easy_setopt(h, CURLOPT_HEADERFUNCTION, header_callback);
-  g_curlInterface.easy_setopt(h, CURLOPT_HEADER, FALSE);
-
-  g_curlInterface.easy_setopt(h, CURLOPT_FTP_USE_EPSV, 0); // turn off epsv
-
-  // Allow us to follow two redirects
-  g_curlInterface.easy_setopt(h, CURLOPT_FOLLOWLOCATION, TRUE);
-  g_curlInterface.easy_setopt(h, CURLOPT_MAXREDIRS, 5);
-
-  // Enable cookie engine for current handle to re-use them in future requests
-  CStdString strCookieFile;
-  CStdString strTempPath = CSpecialProtocol::TranslatePath(g_advancedSettings.m_cachePath);
-  URIUtils::AddFileToFolder(strTempPath, "cookies.dat", strCookieFile);
-
-  g_curlInterface.easy_setopt(h, CURLOPT_COOKIEFILE, strCookieFile.c_str());
-  g_curlInterface.easy_setopt(h, CURLOPT_COOKIEJAR, strCookieFile.c_str());
-
-  // Set custom cookie if requested
-  if (!m_cookie.IsEmpty())
-    g_curlInterface.easy_setopt(h, CURLOPT_COOKIE, m_cookie.c_str());
-
-  g_curlInterface.easy_setopt(h, CURLOPT_COOKIELIST, "FLUSH");
-
-  // When using multiple threads you should set the CURLOPT_NOSIGNAL option to
-  // TRUE for all handles. Everything will work fine except that timeouts are not
-  // honored during the DNS lookup - which you can work around by building libcurl
-  // with c-ares support. c-ares is a library that provides asynchronous name
-  // resolves. Unfortunately, c-ares does not yet support IPv6.
-  g_curlInterface.easy_setopt(h, CURLOPT_NOSIGNAL, TRUE);
-
-  // not interested in failed requests
-  g_curlInterface.easy_setopt(h, CURLOPT_FAILONERROR, 1);
-
-  // enable support for icecast / shoutcast streams
-  m_curlAliasList = g_curlInterface.slist_append(m_curlAliasList, "ICY 200 OK");
-  g_curlInterface.easy_setopt(h, CURLOPT_HTTP200ALIASES, m_curlAliasList);
-
-  // never verify peer, we don't have any certificates to do this
-  g_curlInterface.easy_setopt(h, CURLOPT_SSL_VERIFYPEER, 0);
-  g_curlInterface.easy_setopt(h, CURLOPT_SSL_VERIFYHOST, 0);
-
-  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_URL, m_url.c_str());
-  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TRANSFERTEXT, FALSE);
-
-  // setup POST data if it exists
-  if (!m_postdata.IsEmpty())
-  {
-    g_curlInterface.easy_setopt(h, CURLOPT_POST, 1 );
-    g_curlInterface.easy_setopt(h, CURLOPT_POSTFIELDSIZE, m_postdata.length());
-    g_curlInterface.easy_setopt(h, CURLOPT_POSTFIELDS, m_postdata.c_str());
-  }
-
-  // setup Referer header if needed
-  if (!m_referer.IsEmpty())
-    g_curlInterface.easy_setopt(h, CURLOPT_REFERER, m_referer.c_str());
-  else
-  {
-    g_curlInterface.easy_setopt(h, CURLOPT_REFERER, NULL);
-    g_curlInterface.easy_setopt(h, CURLOPT_AUTOREFERER, TRUE);
-  }
-
-  // setup any requested authentication
-  if( m_ftpauth.length() > 0 )
-  {
-    g_curlInterface.easy_setopt(h, CURLOPT_FTP_SSL, CURLFTPSSL_TRY);
-    if( m_ftpauth.Equals("any") )
-      g_curlInterface.easy_setopt(h, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_DEFAULT);
-    else if( m_ftpauth.Equals("ssl") )
-      g_curlInterface.easy_setopt(h, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_SSL);
-    else if( m_ftpauth.Equals("tls") )
-      g_curlInterface.easy_setopt(h, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_TLS);
-  }
-
-  // setup requested http authentication method
-  if(m_httpauth.length() > 0)
-  {
-    if( m_httpauth.Equals("any") )
-      g_curlInterface.easy_setopt(h, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
-    else if( m_httpauth.Equals("anysafe") )
-      g_curlInterface.easy_setopt(h, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
-    else if( m_httpauth.Equals("digest") )
-      g_curlInterface.easy_setopt(h, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
-    else if( m_httpauth.Equals("ntlm") )
-      g_curlInterface.easy_setopt(h, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
-  }
-
-  // allow passive mode for ftp
-  if( m_ftpport.length() > 0 )
-    g_curlInterface.easy_setopt(h, CURLOPT_FTPPORT, m_ftpport.c_str());
-  else
-    g_curlInterface.easy_setopt(h, CURLOPT_FTPPORT, NULL);
-
-  // allow curl to not use the ip address in the returned pasv response
-  if( m_ftppasvip )
-    g_curlInterface.easy_setopt(h, CURLOPT_FTP_SKIP_PASV_IP, 0);
-  else
-    g_curlInterface.easy_setopt(h, CURLOPT_FTP_SKIP_PASV_IP, 1);
-
-  // setup Content-Encoding if requested
-  if( m_contentencoding.length() > 0 )
-    g_curlInterface.easy_setopt(h, CURLOPT_ENCODING, m_contentencoding.c_str());
-
-  if (m_userAgent.length() > 0)
-    g_curlInterface.easy_setopt(h, CURLOPT_USERAGENT, m_userAgent.c_str());
-  else /* set some default agent as shoutcast doesn't return proper stuff otherwise */
-    g_curlInterface.easy_setopt(h, CURLOPT_USERAGENT, g_settings.m_userAgent.c_str());
-
-  if (m_useOldHttpVersion)
-    g_curlInterface.easy_setopt(h, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
-  else
-    SetRequestHeader("Connection", "keep-alive");
-
-  if (g_advancedSettings.m_curlDisableIPV6)
-    g_curlInterface.easy_setopt(h, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
-
-  if (m_proxy.length() > 0)
-  {
-    g_curlInterface.easy_setopt(h, CURLOPT_PROXY, m_proxy.c_str());
-    if (m_proxyuserpass.length() > 0)
-      g_curlInterface.easy_setopt(h, CURLOPT_PROXYUSERPWD, m_proxyuserpass.c_str());
-
-  }
-  if (m_customrequest.length() > 0)
-    g_curlInterface.easy_setopt(h, CURLOPT_CUSTOMREQUEST, m_customrequest.c_str());
-
-  if (m_connecttimeout == 0)
-    m_connecttimeout = g_advancedSettings.m_curlconnecttimeout;
-
-  // set our timeouts, we abort connection after m_timeout, and reads after no data for m_timeout seconds
-  g_curlInterface.easy_setopt(h, CURLOPT_CONNECTTIMEOUT, m_connecttimeout);
-
-  // We abort in case we transfer less than 1byte/second
-  g_curlInterface.easy_setopt(h, CURLOPT_LOW_SPEED_LIMIT, 1);
-
-  if (m_lowspeedtime == 0)
-    m_lowspeedtime = g_advancedSettings.m_curllowspeedtime;
-
-  // Set the lowspeed time very low as it seems Curl takes much longer to detect a lowspeed condition
-  g_curlInterface.easy_setopt(h, CURLOPT_LOW_SPEED_TIME, m_lowspeedtime);
-}
-
-void CFileCurl::SetRequestHeaders(CReadState* state)
-{
-  if(m_curlHeaderList)
-  {
-    g_curlInterface.slist_free_all(m_curlHeaderList);
-    m_curlHeaderList = NULL;
-  }
-
-  MAPHTTPHEADERS::iterator it;
-  for(it = m_requestheaders.begin(); it != m_requestheaders.end(); it++)
-  {
-    CStdString buffer = it->first + ": " + it->second;
-    m_curlHeaderList = g_curlInterface.slist_append(m_curlHeaderList, buffer.c_str());
-  }
-
-  // add user defined headers
-  if (m_curlHeaderList && state->m_easyHandle)
-    g_curlInterface.easy_setopt(state->m_easyHandle, CURLOPT_HTTPHEADER, m_curlHeaderList);
-
-}
-
-void CFileCurl::SetCorrectHeaders(CReadState* state)
-{
-  CHttpHeader& h = state->m_httpheader;
-  /* workaround for shoutcast server wich doesn't set content type on standard mp3 */
-  if( h.GetMimeType().IsEmpty() )
-  {
-    if( !h.GetValue("icy-notice1").IsEmpty()
-    || !h.GetValue("icy-name").IsEmpty()
-    || !h.GetValue("icy-br").IsEmpty() )
-    h.Parse("Content-Type: audio/mpeg\r\n");
-  }
-
-  /* hack for google video */
-  if ( h.GetMimeType().Equals("text/html")
-  &&  !h.GetValue("Content-Disposition").IsEmpty() )
-  {
-    CStdString strValue = h.GetValue("Content-Disposition");
-    if (strValue.Find("filename=") > -1 && strValue.Find(".flv") > -1)
-      h.Parse("Content-Type: video/flv\r\n");
-  }
-}
-
-void CFileCurl::ParseAndCorrectUrl(CURL &url2)
-{
-  CStdString strProtocol = url2.GetTranslatedProtocol();
-  url2.SetProtocol(strProtocol);
-
-  if( strProtocol.Equals("ftp")
-  ||  strProtocol.Equals("ftps") )
-  {
-    /* this is uggly, depending on from where   */
-    /* we get the link it may or may not be     */
-    /* url encoded. if handed from ftpdirectory */
-    /* it won't be so let's handle that case    */
-
-    CStdString partial, filename(url2.GetFileName());
-    CStdStringArray array;
-
-    /* our current client doesn't support utf8 */
-    g_charsetConverter.utf8ToStringCharset(filename);
-
-    /* TODO: create a tokenizer that doesn't skip empty's */
-    CUtil::Tokenize(filename, array, "/");
-    filename.Empty();
-    for(CStdStringArray::iterator it = array.begin(); it != array.end(); it++)
-    {
-      if(it != array.begin())
-        filename += "/";
-
-      partial = *it;
-      CURL::Encode(partial);
-      filename += partial;
-    }
-
-    /* make sure we keep slashes */
-    if(url2.GetFileName().Right(1) == "/")
-      filename += "/";
-
-    url2.SetFileName(filename);
-
-    CStdString options = url2.GetOptions().Mid(1);
-    options.TrimRight('/'); // hack for trailing slashes being added from source
-
-    m_ftpauth = "";
-    m_ftpport = "";
-    m_ftppasvip = false;
-
-    /* parse options given */
-    CUtil::Tokenize(options, array, "&");
-    for(CStdStringArray::iterator it = array.begin(); it != array.end(); it++)
-    {
-      CStdString name, value;
-      int pos = it->Find('=');
-      if(pos >= 0)
-      {
-        name = it->Left(pos);
-        value = it->Mid(pos+1, it->size());
-      }
-      else
-      {
-        name = (*it);
-        value = "";
-      }
-
-      if(name.Equals("auth"))
-      {
-        m_ftpauth = value;
-        if(m_ftpauth.IsEmpty())
-          m_ftpauth = "any";
-      }
-      else if(name.Equals("active"))
-      {
-        m_ftpport = value;
-        if(value.IsEmpty())
-          m_ftpport = "-";
-      }
-      else if(name.Equals("pasvip"))
-      {
-        if(value == "0")
-          m_ftppasvip = false;
-        else
-          m_ftppasvip = true;
-      }
-    }
-
-    /* ftp has no options */
-    url2.SetOptions("");
-  }
-  else if( strProtocol.Equals("http")
-       ||  strProtocol.Equals("https"))
-  {
-    if (g_guiSettings.GetBool("network.usehttpproxy") && m_proxy.IsEmpty())
-    {
-      m_proxy = "http://" + g_guiSettings.GetString("network.httpproxyserver");
-      m_proxy += ":" + g_guiSettings.GetString("network.httpproxyport");
-      if (g_guiSettings.GetString("network.httpproxyusername").length() > 0 && m_proxyuserpass.IsEmpty())
-      {
-        m_proxyuserpass = g_guiSettings.GetString("network.httpproxyusername");
-        m_proxyuserpass += ":" + g_guiSettings.GetString("network.httpproxypassword");
-      }
-      CLog::Log(LOGDEBUG, "Using proxy %s", m_proxy.c_str());
-    }
-
-    // get username and password
-    m_username = url2.GetUserName();
-    m_password = url2.GetPassWord();
-
-    // handle any protocol options
-    CStdString options = url2.GetProtocolOptions();
-    options.TrimRight('/'); // hack for trailing slashes being added from source
-    if (options.length() > 0)
-    {
-      // clear protocol options
-      url2.SetProtocolOptions("");
-      // set xbmc headers
-      CStdStringArray array;
-      CUtil::Tokenize(options, array, "&");
-      for(CStdStringArray::iterator it = array.begin(); it != array.end(); it++)
-      {
-        // parse name, value
-        CStdString name, value;
-        int pos = it->Find('=');
-        if(pos >= 0)
-        {
-          name = it->Left(pos);
-          value = it->Mid(pos+1, it->size());
-        }
-        else
-        {
-          name = (*it);
-          value = "";
-        }
-
-        // url decode value
-        CURL::Decode(value);
-
-        if(name.Equals("auth"))
-        {
-          m_httpauth = value;
-          if(m_httpauth.IsEmpty())
-            m_httpauth = "any";
-        }
-        else if (name.Equals("Referer"))
-          SetReferer(value);
-        else if (name.Equals("User-Agent"))
-          SetUserAgent(value);
-        else if (name.Equals("Cookie"))
-          SetCookie(value);
-        else if (name.Equals("Encoding"))
-          SetContentEncoding(value);
-        else if (name.Equals("noshout") && value.Equals("true"))
-          m_skipshout = true;
-        else
-          SetRequestHeader(name, value);
-      }
-    }
-  }
-
-  if (m_username.length() > 0 && m_password.length() > 0)
-    m_url = url2.GetWithoutUserDetails();
-  else
-    m_url = url2.Get();
-}
-
-bool CFileCurl::Post(const CStdString& strURL, const CStdString& strPostData, CStdString& strHTML)
-{
-  return Service(strURL, strPostData, strHTML);
-}
-
-bool CFileCurl::Get(const CStdString& strURL, CStdString& strHTML)
-{
-  return Service(strURL, "", strHTML);
-}
-
-bool CFileCurl::Service(const CStdString& strURL, const CStdString& strPostData, CStdString& strHTML)
-{
-  m_postdata = strPostData;
-  if (Open(strURL))
-  {
-    if (ReadData(strHTML))
-    {
-      Close();
-      return true;
-    }
-  }
-  Close();
-  return false;
-}
-
-bool CFileCurl::ReadData(CStdString& strHTML)
-{
-  int size_read = 0;
-  int data_size = 0;
-  strHTML = "";
-  char buffer[16384];
-  while( (size_read = Read(buffer, sizeof(buffer)-1) ) > 0 )
-  {
-    buffer[size_read] = 0;
-    strHTML.append(buffer, size_read);
-    data_size += size_read;
-  }
-  if (m_state->m_cancelled)
-    return false;
-  return true;
-}
-
-bool CFileCurl::Download(const CStdString& strURL, const CStdString& strFileName, LPDWORD pdwSize)
-{
-  CLog::Log(LOGINFO, "Download: %s->%s", strURL.c_str(), strFileName.c_str());
-
-  CStdString strData;
-  if (!Get(strURL, strData))
-    return false;
-
-  XFILE::CFile file;
-  if (!file.OpenForWrite(strFileName, true))
-  {
-    CLog::Log(LOGERROR, "Unable to open file %s: %u",
-    strFileName.c_str(), GetLastError());
-    return false;
-  }
-  if (strData.size())
-    file.Write(strData.c_str(), strData.size());
-  file.Close();
-
-  if (pdwSize != NULL)
-  {
-    *pdwSize = strData.size();
-  }
-
-  return true;
-}
-
-// Detect whether we are "online" or not! Very simple and dirty!
-bool CFileCurl::IsInternet(bool checkDNS /* = true */)
-{
-  CStdString strURL = "http://www.google.com";
-  if (!checkDNS)
-    strURL = "http://74.125.19.103"; // www.google.com ip
-
-  bool found = Exists(strURL);
-  Close();
-
-  return found;
-}
-
-void CFileCurl::Cancel()
-{
-  m_state->m_cancelled = true;
-  while (m_opened)
-    Sleep(1);
-}
-
-void CFileCurl::Reset()
-{
-  m_state->m_cancelled = false;
-}
-
-bool CFileCurl::Open(const CURL& url)
-{
-
-  m_opened = true;
-
-  CURL url2(url);
-  ParseAndCorrectUrl(url2);
-
-  CLog::Log(LOGDEBUG, "FileCurl::Open(%p) %s", (void*)this, m_url.c_str());
-
-  ASSERT(!(!m_state->m_easyHandle ^ !m_state->m_multiHandle));
-  if( m_state->m_easyHandle == NULL )
-    g_curlInterface.easy_aquire(url2.GetProtocol(), url2.GetHostName(), &m_state->m_easyHandle, &m_state->m_multiHandle );
-
-  // setup common curl options
-  SetCommonOptions(m_state);
-  SetRequestHeaders(m_state);
-
-  long response = m_state->Connect(m_bufferSize);
-  if( response < 0 || response >= 400)
-    return false;
-
-  SetCorrectHeaders(m_state);
-
-  // since we can't know the stream size up front if we're gzipped/deflated
-  // flag the stream with an unknown file size rather than the compressed
-  // file size.
-  if (m_contentencoding.size() > 0)
-    m_state->m_fileSize = 0;
-
-  // check if this stream is a shoutcast stream. sometimes checking the protocol line is not enough so examine other headers as well.
-  // shoutcast streams should be handled by FileShoutcast.
-  if ((m_state->m_httpheader.GetProtoLine().Left(3) == "ICY" || !m_state->m_httpheader.GetValue("icy-notice1").IsEmpty()
-     || !m_state->m_httpheader.GetValue("icy-name").IsEmpty()
-     || !m_state->m_httpheader.GetValue("icy-br").IsEmpty()) && !m_skipshout)
-  {
-    CLog::Log(LOGDEBUG,"FileCurl - file <%s> is a shoutcast stream. re-opening", m_url.c_str());
-    throw new CRedirectException(new CFileShoutcast);
-  }
-
-  m_multisession = false;
-  if(m_url.Left(5).Equals("http:") || m_url.Left(6).Equals("https:"))
-  {
-    m_multisession = true;
-    if(m_state->m_httpheader.GetValue("Server").Find("Portable SDK for UPnP devices") >= 0)
-    {
-      CLog::Log(LOGWARNING, "FileCurl - disabling multi session due to broken libupnp server");
-      m_multisession = false;
-    }
-  }
-
-  if(m_state->m_httpheader.GetValue("Transfer-Encoding").Equals("chunked"))
-    m_state->m_fileSize = 0;
-
-  m_seekable = false;
-  if(m_state->m_fileSize > 0)
-  {
-    m_seekable = true;
-
-    if(url2.GetProtocol().Equals("http")
-    || url2.GetProtocol().Equals("https"))
-    {
-      // if server says explicitly it can't seek, respect that
-      if(m_state->m_httpheader.GetValue("Accept-Ranges").Equals("none"))
-        m_seekable = false;
-    }
-  }
-
-  char* efurl;
-  if (CURLE_OK == g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_EFFECTIVE_URL,&efurl) && efurl)
-    m_url = efurl;
-
-  return true;
-}
-
-bool CFileCurl::CReadState::ReadString(char *szLine, int iLineLength)
-{
-  unsigned int want = (unsigned int)iLineLength;
-
-  if((m_fileSize == 0 || m_filePos < m_fileSize) && !FillBuffer(want))
-    return false;
-
-  // ensure only available data is considered
-  want = XMIN((unsigned int)m_buffer.getMaxReadSize(), want);
-
-  /* check if we finished prematurely */
-  if (!m_stillRunning && (m_fileSize == 0 || m_filePos != m_fileSize) && !want)
-  {
-    if (m_fileSize != 0)
-      CLog::Log(LOGWARNING, "%s - Transfer ended before entire file was retrieved pos %"PRId64", size %"PRId64, __FUNCTION__, m_filePos, m_fileSize);
-
-    return false;
-  }
-
-  char* pLine = szLine;
-  do
-  {
-    if (!m_buffer.ReadData(pLine, 1))
-      break;
-
-    pLine++;
-  } while (((pLine - 1)[0] != '\n') && ((unsigned int)(pLine - szLine) < want));
-  pLine[0] = 0;
-  m_filePos += (pLine - szLine);
-  return (bool)((pLine - szLine) > 0);
-}
-
-bool CFileCurl::Exists(const CURL& url)
-{
-  // if file is already running, get info from it
-  if( m_opened )
-  {
-    CLog::Log(LOGWARNING, "%s - Exist called on open file", __FUNCTION__);
-    return true;
-  }
-
-  CURL url2(url);
-  ParseAndCorrectUrl(url2);
-
-  ASSERT(m_state->m_easyHandle == NULL);
-  g_curlInterface.easy_aquire(url2.GetProtocol(), url2.GetHostName(), &m_state->m_easyHandle, NULL);
-
-  SetCommonOptions(m_state);
-  SetRequestHeaders(m_state);
-  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, 5);
-  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_NOBODY, 1);
-  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/
-
-  if(url2.GetProtocol() == "ftp")
-  {
-    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME, 1);
-    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD);
-  }
-
-  CURLcode result = g_curlInterface.easy_perform(m_state->m_easyHandle);
-  g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
-
-  if (result == CURLE_WRITE_ERROR || result == CURLE_OK)
-    return true;
-
-  errno = ENOENT;
-  return false;
-}
-
-int64_t CFileCurl::Seek(int64_t iFilePosition, int iWhence)
-{
-  int64_t nextPos = m_state->m_filePos;
-  switch(iWhence)
-  {
-    case SEEK_SET:
-      nextPos = iFilePosition;
-      break;
-    case SEEK_CUR:
-      nextPos += iFilePosition;
-      break;
-    case SEEK_END:
-      if (m_state->m_fileSize)
-        nextPos = m_state->m_fileSize + iFilePosition;
-      else
-        return -1;
-      break;
-    default:
-      return -1;
-  }
-
-  // We can't seek beyond EOF
-  if (m_state->m_fileSize && nextPos > m_state->m_fileSize) return -1;
-
-  if(m_state->Seek(nextPos))
-    return nextPos;
-
-  if(!m_seekable)
-    return -1;
-
-  CReadState* oldstate = NULL;
-  if(m_multisession)
-  {
-    CURL url(m_url);
-    oldstate = m_state;
-    m_state = new CReadState();
-
-    g_curlInterface.easy_aquire(url.GetProtocol(), url.GetHostName(), &m_state->m_easyHandle, &m_state->m_multiHandle );
-
-    // setup common curl options
-    SetCommonOptions(m_state);
-  }
-  else
-    m_state->Disconnect();
-
-  /* caller might have changed some headers (needed for daap)*/
-  SetRequestHeaders(m_state);
-
-  m_state->m_filePos = nextPos;
-  if (oldstate)
-    m_state->m_fileSize = oldstate->m_fileSize;
-
-  long response = m_state->Connect(m_bufferSize);
-  if(response < 0 && (m_state->m_fileSize == 0 || m_state->m_fileSize != m_state->m_filePos))
-  {
-    m_seekable = false;
-    if(oldstate)
-    {
-      delete m_state;
-      m_state = oldstate;
-    }
-    return -1;
-  }
-
-  SetCorrectHeaders(m_state);
-  delete oldstate;
-
-  return m_state->m_filePos;
-}
-
-int64_t CFileCurl::GetLength()
-{
-  if (!m_opened) return 0;
-  return m_state->m_fileSize;
-}
-
-int64_t CFileCurl::GetPosition()
-{
-  if (!m_opened) return 0;
-  return m_state->m_filePos;
-}
-
-int CFileCurl::Stat(const CURL& url, struct __stat64* buffer)
-{
-  // if file is already running, get info from it
-  if( m_opened )
-  {
-    CLog::Log(LOGWARNING, "%s - Stat called on open file", __FUNCTION__);
-    if (buffer)
-    {
-      memset(buffer, 0, sizeof(struct __stat64));
-      buffer->st_size = GetLength();
-      buffer->st_mode = _S_IFREG;
-    }
-    return 0;
-  }
-
-  CURL url2(url);
-  ParseAndCorrectUrl(url2);
-
-  ASSERT(m_state->m_easyHandle == NULL);
-  g_curlInterface.easy_aquire(url2.GetProtocol(), url2.GetHostName(), &m_state->m_easyHandle, NULL);
-
-  SetCommonOptions(m_state);
-  SetRequestHeaders(m_state);
-  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, 5);
-  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_NOBODY, 1);
-  g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/
-
-  if(url2.GetProtocol() == "ftp")
-  {
-    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME, 1);
-    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD);
-  }
-
-  CURLcode result = g_curlInterface.easy_perform(m_state->m_easyHandle);
-
-
-  if(result == CURLE_HTTP_RETURNED_ERROR)
-  {
-    long code;
-    if(g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_RESPONSE_CODE, &code) == CURLE_OK && code == 404 )
-      return -1;
-  }
-
-  if(result == CURLE_GOT_NOTHING 
-  || result == CURLE_HTTP_RETURNED_ERROR 
-  || result == CURLE_RECV_ERROR /* some silly shoutcast servers */ )
-  {
-    /* some http servers and shoutcast servers don't give us any data on a head request */
-    /* request normal and just fail out, it's their loss */
-    /* somehow curl doesn't reset CURLOPT_NOBODY properly so reset everything */
-    SetCommonOptions(m_state);
-    SetRequestHeaders(m_state);
-    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, 5);
-    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_RANGE, "0-0");
-    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/
-    result = g_curlInterface.easy_perform(m_state->m_easyHandle);
-  }
-
-  if( result == CURLE_HTTP_RANGE_ERROR )
-  {
-    /* crap can't use the range option, disable it and try again */
-    g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_RANGE, NULL);
-    result = g_curlInterface.easy_perform(m_state->m_easyHandle);
-  }
-
-  if( result != CURLE_WRITE_ERROR && result != CURLE_OK )
-  {
-    g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
-    errno = ENOENT;
-    return -1;
-  }
-
-  double length;
-  if (CURLE_OK != g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &length) || length < 0.0)
-  {
-    if (url.GetProtocol() == "ftp")
-    {
-      g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
-      errno = ENOENT;
-      return -1;
-    }
-    else
-      length = 0.0;
-  }
-
-  SetCorrectHeaders(m_state);
-
-  if(buffer)
-  {
-    char *content;
-    if (CURLE_OK != g_curlInterface.easy_getinfo(m_state->m_easyHandle, CURLINFO_CONTENT_TYPE, &content))
-    {
-      g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
-      errno = ENOENT;
-      return -1;
-    }
-    else
-    {
-      memset(buffer, 0, sizeof(struct __stat64));
-      buffer->st_size = (int64_t)length;
-      if(content && strstr(content, "text/html")) //consider html files directories
-        buffer->st_mode = _S_IFDIR;
-      else
-        buffer->st_mode = _S_IFREG;
-    }
-  }
-  g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
-  return 0;
-}
-
-unsigned int CFileCurl::CReadState::Read(void* lpBuf, int64_t uiBufSize)
-{
-  /* only request 1 byte, for truncated reads (only if not eof) */
-  if((m_fileSize == 0 || m_filePos < m_fileSize) && !FillBuffer(1))
-    return 0;
-
-  /* ensure only available data is considered */
-  unsigned int want = (unsigned int)XMIN(m_buffer.getMaxReadSize(), uiBufSize);
-
-  /* xfer data to caller */
-  if (m_buffer.ReadData((char *)lpBuf, want))
-  {
-    m_filePos += want;
-    return want;
-  }
-
-  /* check if we finished prematurely */
-  if (!m_stillRunning && (m_fileSize == 0 || m_filePos != m_fileSize))
-  {
-    CLog::Log(LOGWARNING, "%s - Transfer ended before entire file was retrieved pos %"PRId64", size %"PRId64, __FUNCTION__, m_filePos, m_fileSize);
-    return 0;
-  }
-
-  return 0;
-}
-
-/* use to attempt to fill the read buffer up to requested number of bytes */
-bool CFileCurl::CReadState::FillBuffer(unsigned int want)
-{
-  int retry=0;
-  fd_set fdread;
-  fd_set fdwrite;
-  fd_set fdexcep;
-
-  // only attempt to fill buffer if transactions still running and buffer
-  // doesnt exceed required size already
-  while ((unsigned int)m_buffer.getMaxReadSize() < want && m_buffer.getMaxWriteSize() > 0 )
-  {
-    if (m_cancelled)
-      return false;
-
-    /* if there is data in overflow buffer, try to use that first */
-    if (m_overflowSize)
-    {
-      unsigned amount = XMIN((unsigned int)m_buffer.getMaxWriteSize(), m_overflowSize);
-      m_buffer.WriteData(m_overflowBuffer, amount);
-
-      if (amount < m_overflowSize)
-        memcpy(m_overflowBuffer, m_overflowBuffer+amount,m_overflowSize-amount);
-
-      m_overflowSize -= amount;
-      m_overflowBuffer = (char*)realloc_simple(m_overflowBuffer, m_overflowSize);
-      continue;
-    }
-
-    CURLMcode result = g_curlInterface.multi_perform(m_multiHandle, &m_stillRunning);
-    if (!m_stillRunning)
-    {
-      if (result == CURLM_OK)
-      {
-        /* if we still have stuff in buffer, we are fine */
-        if (m_buffer.getMaxReadSize())
-          return true;
-
-        /* verify that we are actually okey */
-        int msgs;
-        CURLcode CURLresult = CURLE_OK;
-        CURLMsg* msg;
-        while ((msg = g_curlInterface.multi_info_read(m_multiHandle, &msgs)))
-        {
-          if (msg->msg == CURLMSG_DONE)
-          {
-            if (msg->data.result == CURLE_OK)
-              return true;
-
-            CLog::Log(LOGWARNING, "%s: curl failed with code %i", __FUNCTION__, msg->data.result);
-
-            // We need to check the data.result here as we don't want to retry on every error
-            if ( (msg->data.result == CURLE_OPERATION_TIMEDOUT ||
-                  msg->data.result == CURLE_PARTIAL_FILE       ||
-                  msg->data.result == CURLE_RECV_ERROR)        &&
-                  !m_bFirstLoop)
-              CURLresult=msg->data.result;
-            else
-              return false;
-          }
-        }
-
-        // Don't retry, when we didn't "see" any error
-        if (CURLresult == CURLE_OK)
-          return false;
-
-        // Close handle
-        if (m_multiHandle && m_easyHandle)
-          g_curlInterface.multi_remove_handle(m_multiHandle, m_easyHandle);
-
-        // Reset all the stuff like we would in Disconnect()
-        m_buffer.Clear();
-        free(m_overflowBuffer);
-        m_overflowBuffer = NULL;
-        m_overflowSize = 0;
-
-        // If we got here something is wrong
-        if (++retry > g_advancedSettings.m_curlretries)
-        {
-          CLog::Log(LOGWARNING, "%s: Reconnect failed!", __FUNCTION__);
-          // Reset the rest of the variables like we would in Disconnect()
-          m_filePos = 0;
-          m_fileSize = 0;
-          m_bufferSize = 0;
-
-          return false;
-        }
-
-        CLog::Log(LOGDEBUG, "%s: Reconnect, (re)try %i", __FUNCTION__, retry);
-
-        // Connect + seek to current position (again)
-        g_curlInterface.easy_setopt(m_easyHandle, CURLOPT_RESUME_FROM_LARGE, m_filePos);
-        g_curlInterface.multi_add_handle(m_multiHandle, m_easyHandle);
-
-        // Return to the beginning of the loop:
-        continue;
-      }
-      return false;
-    }
-
-    // We've finished out first loop
-    if(m_bFirstLoop && m_buffer.getMaxReadSize() > 0)
-      m_bFirstLoop = false;
-
-    switch (result)
-    {
-      case CURLM_OK:
-      {
-        int maxfd = -1;
-        FD_ZERO(&fdread);
-        FD_ZERO(&fdwrite);
-        FD_ZERO(&fdexcep);
-
-        // get file descriptors from the transfers
-        g_curlInterface.multi_fdset(m_multiHandle, &fdread, &fdwrite, &fdexcep, &maxfd);
-
-        long timeout = 0;
-        if (CURLM_OK != g_curlInterface.multi_timeout(m_multiHandle, &timeout) || timeout == -1)
-          timeout = 200;
-
-        struct timeval t = { timeout / 1000, (timeout % 1000) * 1000 };
-
-        /* Wait until data is available or a timeout occurs.
-           We call dllselect(maxfd + 1, ...), specially in case of (maxfd == -1),
-           we call dllselect(0, ...), which is basically equal to sleep. */
-        if (SOCKET_ERROR == dllselect(maxfd + 1, &fdread, &fdwrite, &fdexcep, &t))
-        {
-          CLog::Log(LOGERROR, "%s - curl failed with socket error", __FUNCTION__);
-          return false;
-        }
-      }
-      break;
-      case CURLM_CALL_MULTI_PERFORM:
-      {
-        // we don't keep calling here as that can easily overwrite our buffer which we want to avoid
-        // docs says we should call it soon after, but aslong as we are reading data somewhere
-        // this aught to be soon enough. should stay in socket otherwise
-        continue;
-      }
-      break;
-      default:
-      {
-        CLog::Log(LOGERROR, "%s - curl multi perform failed with code %d, aborting", __FUNCTION__, result);
-        return false;
-      }
-      break;
-    }
-  }
-  return true;
-}
-
-void CFileCurl::ClearRequestHeaders()
-{
-  m_requestheaders.clear();
-}
-
-void CFileCurl::SetRequestHeader(CStdString header, CStdString value)
-{
-  m_requestheaders[header] = value;
-}
-
-void CFileCurl::SetRequestHeader(CStdString header, long value)
-{
-  CStdString buffer;
-  buffer.Format("%ld", value);
-  m_requestheaders[header] = buffer;
-}
-
-/* STATIC FUNCTIONS */
-bool CFileCurl::GetHttpHeader(const CURL &url, CHttpHeader &headers)
-{
-  try
-  {
-    CFileCurl file;
-    if(file.Stat(url, NULL) == 0)
-    {
-      headers = file.GetHttpHeader();
-      return true;
-    }
-    return false;
-  }
-  catch(...)
-  {
-    CLog::Log(LOGERROR, "%s - Exception thrown while trying to retrieve header url: %s", __FUNCTION__, url.Get().c_str());
-    return false;
-  }
-}
-
-bool CFileCurl::GetMimeType(const CURL &url, CStdString &content, CStdString useragent)
-{
-   CFileCurl file;
-   if (!useragent.IsEmpty())
-     file.SetUserAgent(useragent);
-
-   if( file.Stat(url, NULL) == 0 )
-   {
-     content = file.GetMimeType();
-     CLog::Log(LOGDEBUG, "CFileCurl::GetMimeType - %s -> %s", url.Get().c_str(), content.c_str());
-     return true;
-   }
-   CLog::Log(LOGDEBUG, "CFileCurl::GetMimeType - %s -> failed", url.Get().c_str());
-   content = "";
-   return false;
-}
-
-int CFileCurl::IoControl(EIoControl request, void* param)
-{
-  if(request == IOCTRL_SEEK_POSSIBLE)
-    return m_seekable ? 1 : 0;
-
-  return -1;
-}
diff --git a/xbmc/filesystem/FileCurl.h b/xbmc/filesystem/FileCurl.h
deleted file mode 100644 (file)
index 126f7bf..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "IFile.h"
-#include "utils/RingBuffer.h"
-#include <map>
-#include "utils/HttpHeader.h"
-
-namespace XCURL
-{
-  typedef void CURL_HANDLE;
-  typedef void CURLM;
-  struct curl_slist;
-}
-
-class CHttpHeader;
-
-namespace XFILE
-{
-  class CFileCurl : public IFile
-  {
-    public:
-      CFileCurl();
-      virtual ~CFileCurl();
-      virtual bool Open(const CURL& url);
-      virtual bool Exists(const CURL& url);
-      virtual int64_t  Seek(int64_t iFilePosition, int iWhence=SEEK_SET);
-      virtual int64_t GetPosition();
-      virtual int64_t  GetLength();
-      virtual int  Stat(const CURL& url, struct __stat64* buffer);
-      virtual void Close();
-      virtual bool ReadString(char *szLine, int iLineLength)     { return m_state->ReadString(szLine, iLineLength); }
-      virtual unsigned int Read(void* lpBuf, int64_t uiBufSize)  { return m_state->Read(lpBuf, uiBufSize); }
-      virtual CStdString GetMimeType()                           { return m_state->m_httpheader.GetMimeType(); }
-      virtual int IoControl(EIoControl request, void* param);
-
-      bool Post(const CStdString& strURL, const CStdString& strPostData, CStdString& strHTML);
-      bool Get(const CStdString& strURL, CStdString& strHTML);
-      bool ReadData(CStdString& strHTML);
-      bool Download(const CStdString& strURL, const CStdString& strFileName, LPDWORD pdwSize = NULL);
-      bool IsInternet(bool checkDNS = true);
-      void Cancel();
-      void Reset();
-      void SetUserAgent(CStdString sUserAgent)                   { m_userAgent = sUserAgent; }
-      void SetProxy(CStdString &proxy)                           { m_proxy = proxy; }
-      void SetProxyUserPass(CStdString &proxyuserpass)           { m_proxyuserpass = proxyuserpass; }
-      void SetCustomRequest(CStdString &request)                 { m_customrequest = request; }
-      void UseOldHttpVersion(bool bUse)                          { m_useOldHttpVersion = bUse; }
-      void SetContentEncoding(CStdString encoding)               { m_contentencoding = encoding; }
-      void SetTimeout(int connecttimeout)                        { m_connecttimeout = connecttimeout; }
-      void SetLowSpeedTime(int lowspeedtime)                     { m_lowspeedtime = lowspeedtime; }
-      void SetPostData(CStdString postdata)                      { m_postdata = postdata; }
-      void SetReferer(CStdString referer)                        { m_referer = referer; }
-      void SetCookie(CStdString cookie)                          { m_cookie = cookie; }
-      void SetMimeType(CStdString mimetype)                      { SetRequestHeader("Content-Type", m_mimetype); }
-      void SetRequestHeader(CStdString header, CStdString value);
-      void SetRequestHeader(CStdString header, long value);
-
-      void ClearRequestHeaders();
-      void SetBufferSize(unsigned int size);
-
-      const CHttpHeader& GetHttpHeader() { return m_state->m_httpheader; }
-
-      /* static function that will get content type of a file */
-      static bool GetHttpHeader(const CURL &url, CHttpHeader &headers);
-      static bool GetMimeType(const CURL &url, CStdString &content, CStdString useragent="");
-
-      class CReadState
-      {
-      public:
-          CReadState();
-          ~CReadState();
-          XCURL::CURL_HANDLE*    m_easyHandle;
-          XCURL::CURLM*          m_multiHandle;
-
-          CRingBuffer     m_buffer;           // our ringhold buffer
-          unsigned int    m_bufferSize;
-
-          char *          m_overflowBuffer;   // in the rare case we would overflow the above buffer
-          unsigned int    m_overflowSize;     // size of the overflow buffer
-          int             m_stillRunning;     // Is background url fetch still in progress
-          bool            m_cancelled;
-          int64_t         m_fileSize;
-          int64_t         m_filePos;
-          bool            m_bFirstLoop;
-
-          /* returned http header */
-          CHttpHeader m_httpheader;
-          bool        m_headerdone;
-
-          size_t WriteCallback(char *buffer, size_t size, size_t nitems);
-          size_t HeaderCallback(void *ptr, size_t size, size_t nmemb);
-
-          bool         Seek(int64_t pos);
-          unsigned int Read(void* lpBuf, int64_t uiBufSize);
-          bool         ReadString(char *szLine, int iLineLength);
-          bool         FillBuffer(unsigned int want);
-
-          long         Connect(unsigned int size);
-          void         Disconnect();
-      };
-
-    protected:
-      void ParseAndCorrectUrl(CURL &url);
-      void SetCommonOptions(CReadState* state);
-      void SetRequestHeaders(CReadState* state);
-      void SetCorrectHeaders(CReadState* state);
-      bool Service(const CStdString& strURL, const CStdString& strPostData, CStdString& strHTML);
-
-    private:
-      CReadState*     m_state;
-      unsigned int    m_bufferSize;
-
-      CStdString      m_url;
-      CStdString      m_userAgent;
-      CStdString      m_proxy;
-      CStdString      m_proxyuserpass;
-      CStdString      m_customrequest;
-      CStdString      m_contentencoding;
-      CStdString      m_ftpauth;
-      CStdString      m_ftpport;
-      CStdString      m_binary;
-      CStdString      m_postdata;
-      CStdString      m_referer;
-      CStdString      m_cookie;
-      CStdString      m_mimetype;
-      CStdString      m_username;
-      CStdString      m_password;
-      CStdString      m_httpauth;
-      bool            m_ftppasvip;
-      int             m_connecttimeout;
-      int             m_lowspeedtime;
-      bool            m_opened;
-      bool            m_useOldHttpVersion;
-      bool            m_seekable;
-      bool            m_multisession;
-      bool            m_skipshout;
-
-      CRingBuffer     m_buffer;           // our ringhold buffer
-      char *          m_overflowBuffer;   // in the rare case we would overflow the above buffer
-      unsigned int    m_overflowSize;     // size of the overflow buffer
-
-      int             m_stillRunning;     // Is background url fetch still in progress?
-
-      struct XCURL::curl_slist* m_curlAliasList;
-      struct XCURL::curl_slist* m_curlHeaderList;
-
-      typedef std::map<CStdString, CStdString> MAPHTTPHEADERS;
-      MAPHTTPHEADERS m_requestheaders;
-  };
-}
-
-
-
diff --git a/xbmc/filesystem/FileDAAP.cpp b/xbmc/filesystem/FileDAAP.cpp
deleted file mode 100644 (file)
index 0f8b522..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
-* DAAP Support for XBMC
-* Copyright (c) 2004 Forza (Chris Barnett)
-* Portions Copyright (c) by the authors of libOpenDAAP
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "FileDAAP.h"
-#include "SectionLoader.h"
-#include "threads/SingleLock.h"
-#include "utils/log.h"
-#include <sys/stat.h>
-
-#include "lib/libXDAAP/private.h"
-
-using namespace XFILE;
-
-#define HEDAER_VERSION       "Client-DAAP-Version"
-#define HEADER_REQUESTID     "Client-DAAP-Request-ID"
-#define HEADER_VALIDATE      "Client-DAAP-Validation"
-#define HEADER_ACCESS_INDEX  "Client-DAAP-Access-Index"
-#define DAAP_USERAGENT       "iTunes/4.6 (Windows; N)"
-#define DAAP_PORT            3689
-
-extern "C"
-{
-/* prototype of function in LIBXDAAP to generate the has needed for requests */
-void GenerateHash(short version_major,
-                  const unsigned char *url, unsigned char hashSelect,
-                  unsigned char *outhash,
-                  int request_id);
-}
-
-CDaapClient g_DaapClient;
-
-CDaapClient::CDaapClient()
-{
-  m_pClient = NULL;
-  m_Status = DAAP_STATUS_error;
-
-  m_pArtistsHead = NULL;
-  m_iDatabase = 0;
-}
-CDaapClient::~CDaapClient()
-{
-
-}
-void CDaapClient::Release()
-{
-  m_mapHosts.clear();
-
-  if( m_pClient )
-  {
-    try
-    {
-      while( DAAP_Client_Release(m_pClient) != 0 ) {}
-    }
-    catch(...)
-    {
-      CLog::Log(LOGINFO, "CDaapClient::Disconnect - Unexpected exception");
-    }
-
-    m_pClient = NULL;
-  }
-}
-
-DAAP_SClientHost* CDaapClient::GetHost(const CStdString &strHost)
-{
-  //We need this section from now on
-  if( !CSectionLoader::IsLoaded("LIBXDAAP") ) CSectionLoader::Load("LIBXDAAP");
-  try
-  {
-
-    ITHOST it;
-    it = m_mapHosts.find(strHost);
-    if( it != m_mapHosts.end() )
-      return it->second;
-
-
-    if( !m_pClient )
-      m_pClient = DAAP_Client_Create((DAAP_fnClientStatus)StatusCallback, (void*)this);
-
-    DAAP_SClientHost* pHost = DAAP_Client_AddHost(m_pClient, (char *)strHost.c_str(), (char *)"A", (char *)"A");
-    if( !pHost )
-      throw("Unable to add host");
-
-    if( DAAP_ClientHost_Connect(pHost) != 0 )
-      throw("Unable to connect");
-
-    m_mapHosts[strHost] = pHost;
-
-    return pHost;
-
-  }
-  catch(char* err)
-  {
-    CLog::Log(LOGERROR, "CDaapClient::GetHost(%s) - %s", strHost.c_str(), err );
-    return NULL;
-  }
-  catch(...)
-  {
-    CLog::Log(LOGERROR, "CDaapClient::GetHost(%s) - Unknown Exception", strHost.c_str());
-    return NULL;
-  }
-
-}
-
-void CDaapClient::StatusCallback(DAAP_SClient *pClient, DAAP_Status status, int value, void* pContext)
-{
-  ((CDaapClient*)pContext)->m_Status = status;
-  switch(status)
-  {
-    case DAAP_STATUS_connecting:
-      CLog::Log(LOGINFO, "CDaapClient::Callback - Connecting");
-    case DAAP_STATUS_downloading:
-      CLog::Log(LOGINFO, "CDaapClient::Callback - Downlading");
-    case DAAP_STATUS_idle:
-      CLog::Log(LOGINFO, "CDaapClient::Callback - Idle");
-    default:
-      CLog::Log(LOGINFO, "CDaapClient::Callback - Status %d", status);
-  }
-}
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-CFileDAAP::CFileDAAP()
-{
-  m_thisHost = NULL;
-  m_thisClient = NULL;
-
-  m_bOpened = false;
-}
-
-CFileDAAP::~CFileDAAP()
-{
-  Close();
-}
-
-
-
-//*********************************************************************************************
-bool CFileDAAP::Open(const CURL& url)
-{
-  CSingleLock lock(g_DaapClient);
-
-  if (m_bOpened) Close();
-
-  m_url = url;
-
-  CLog::Log(LOGDEBUG, "CFileDAAP::Open(%s)", url.GetFileName().c_str());
-  CStdString host = url.GetHostName();
-  if (url.HasPort())
-    host.Format("%s:%i",url.GetHostName(),url.GetPort());
-  m_thisHost = g_DaapClient.GetHost(host);
-  if (!m_thisHost)
-    return false;
-
-  /* get us a new request id */
-  int requestid = ++m_thisHost->request_id;
-
-  m_hashurl = "/" + m_url.GetFileName();
-  m_hashurl += m_url.GetOptions();
-
-  char hash[33] = {0};
-  GenerateHash(m_thisHost->version_major, (unsigned char*)(m_hashurl.c_str()), 2, (unsigned char*)hash, requestid);
-
-  m_curl.SetUserAgent(DAAP_USERAGENT);
-
-  //m_curl.SetRequestHeader(HEADER_VERSION, "3.0");
-  m_curl.SetRequestHeader(HEADER_REQUESTID, requestid);
-  m_curl.SetRequestHeader(HEADER_VALIDATE, CStdString(hash));
-  m_curl.SetRequestHeader(HEADER_ACCESS_INDEX, 2);
-
-  m_url.SetProtocol("http");
-  if(!m_url.HasPort())
-    m_url.SetPort(DAAP_PORT);
-
-
-  m_bOpened = true;
-
-  return m_curl.Open(m_url);
-}
-
-
-//*********************************************************************************************
-unsigned int CFileDAAP::Read(void *lpBuf, int64_t uiBufSize)
-{
-  return m_curl.Read(lpBuf, uiBufSize);
-}
-
-//*********************************************************************************************
-void CFileDAAP::Close()
-{
-  m_curl.Close();
-  m_bOpened = false;
-}
-
-//*********************************************************************************************
-int64_t CFileDAAP::Seek(int64_t iFilePosition, int iWhence)
-{
-  CSingleLock lock(g_DaapClient);
-
-  int requestid = ++m_thisHost->request_id;
-
-  char hash[33] = {0};
-  GenerateHash(m_thisHost->version_major, (unsigned char*)(m_hashurl.c_str()), 2, (unsigned char*)hash, requestid);
-
-  m_curl.SetRequestHeader(HEADER_REQUESTID, requestid);
-  m_curl.SetRequestHeader(HEADER_VALIDATE, CStdString(hash));
-
-  return m_curl.Seek(iFilePosition, iWhence);
-}
-
-//*********************************************************************************************
-int64_t CFileDAAP::GetLength()
-{
-  return m_curl.GetLength();
-}
-
-//*********************************************************************************************
-int64_t CFileDAAP::GetPosition()
-{
-  return m_curl.GetPosition();
-}
-
-bool CFileDAAP::Exists(const CURL& url)
-{
-  return false;
-}
-
-int CFileDAAP::Stat(const CURL& url, struct __stat64* buffer)
-{
-  return -1;
-}
-
-int CFileDAAP::IoControl(EIoControl request, void* param)
-{
-  if(request == IOCTRL_SEEK_POSSIBLE)
-    return 1;
-
-  return -1;
-}
diff --git a/xbmc/filesystem/FileDAAP.h b/xbmc/filesystem/FileDAAP.h
deleted file mode 100644 (file)
index efa6f15..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-* DAAP Support for XBMC
-* Copyright (c) 2004 Forza (Chris Barnett)
-* Portions Copyright (c) by the authors of libOpenDAAP
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-// FileDAAP.h: interface for the CFileDAAP class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#if !defined(AFX_FILEDAAP_H___INCLUDED_)
-#define AFX_FILEDAAP_H___INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include "lib/libXDAAP/client.h"
-#include "FileCurl.h"
-#include "URL.h"
-#include "threads/CriticalSection.h"
-
-class CDaapClient : public CCriticalSection
-{
-public:
-
-  CDaapClient();
-  ~CDaapClient();
-
-  DAAP_SClient *m_pClient;
-  DAAP_SClientHost* GetHost(const CStdString &srtHost);
-  std::map<CStdString, DAAP_SClientHost*> m_mapHosts;
-  typedef std::map<CStdString, DAAP_SClientHost*>::iterator ITHOST;
-
-  DAAP_Status m_Status;
-
-  //Buffers
-  int m_iDatabase;
-  void *m_pArtistsHead;
-
-  void Release();
-
-protected:
-  static void StatusCallback(DAAP_SClient *pClient, DAAP_Status status, int value, void* pContext);
-};
-
-extern CDaapClient g_DaapClient;
-
-
-#include "IFile.h"
-
-namespace XFILE
-{
-class CFileDAAP : public IFile
-{
-public:
-  CFileDAAP();
-  virtual ~CFileDAAP();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-  virtual int  IoControl(EIoControl request, void* param);
-
-protected:
-
-  bool StartStreaming();
-  bool StopStreaming();
-
-  int64_t m_fileSize; //holds full size
-  int64_t m_filePos; //holds current position in file
-
-
-  DAAP_SClient *m_thisClient;
-  DAAP_SClientHost *m_thisHost;
-  DAAP_ClientHost_Song m_song;
-
-  bool m_bOpened;
-
-  CStdString m_hashurl; // the url that should be used in hash calculation
-  CURL       m_url;     // the complete url we have connected too
-  CFileCurl  m_curl;
-};
-}
-
-#endif // !defined(AFX_FILEDAAP_H___INCLUDED_)
-
-
diff --git a/xbmc/filesystem/FileDirectoryFactory.cpp b/xbmc/filesystem/FileDirectoryFactory.cpp
new file mode 100644 (file)
index 0000000..843691b
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "system.h"
+#include "Util.h"
+#include "utils/URIUtils.h"
+#include "FileDirectoryFactory.h"
+#ifdef HAS_FILESYSTEM
+#include "OGGFileDirectory.h"
+#include "NSFFileDirectory.h"
+#include "SIDFileDirectory.h"
+#include "ASAPFileDirectory.h"
+#include "RSSDirectory.h"
+#include "cores/paplayer/ASAPCodec.h"
+#endif
+#ifdef HAS_FILESYSTEM_RAR
+#include "RarDirectory.h"
+#endif
+#include "ZipDirectory.h"
+#include "SmartPlaylistDirectory.h"
+#include "playlists/SmartPlayList.h"
+#include "PlaylistFileDirectory.h"
+#include "playlists/PlayListFactory.h"
+#include "Directory.h"
+#include "File.h"
+#include "ZipManager.h"
+#include "settings/AdvancedSettings.h"
+#include "FileItem.h"
+
+using namespace XFILE;
+using namespace PLAYLIST;
+using namespace std;
+
+CFileDirectoryFactory::CFileDirectoryFactory(void)
+{}
+
+CFileDirectoryFactory::~CFileDirectoryFactory(void)
+{}
+
+// return NULL + set pItem->m_bIsFolder to remove it completely from list.
+IFileDirectory* CFileDirectoryFactory::Create(const CStdString& strPath, CFileItem* pItem, const CStdString& strMask)
+{
+  CStdString strExtension=URIUtils::GetExtension(strPath);
+  strExtension.MakeLower();
+
+#ifdef HAS_FILESYSTEM
+  if ((strExtension.Equals(".ogg") || strExtension.Equals(".oga")) && CFile::Exists(strPath))
+  {
+    IFileDirectory* pDir=new COGGFileDirectory;
+    //  Has the ogg file more than one bitstream?
+    if (pDir->ContainsFiles(strPath))
+    {
+      return pDir; // treat as directory
+    }
+
+    delete pDir;
+    return NULL;
+  }
+  if (strExtension.Equals(".nsf") && CFile::Exists(strPath))
+  {
+    IFileDirectory* pDir=new CNSFFileDirectory;
+    //  Has the nsf file more than one track?
+    if (pDir->ContainsFiles(strPath))
+      return pDir; // treat as directory
+
+    delete pDir;
+    return NULL;
+  }
+  if (strExtension.Equals(".sid") && CFile::Exists(strPath))
+  {
+    IFileDirectory* pDir=new CSIDFileDirectory;
+    //  Has the sid file more than one track?
+    if (pDir->ContainsFiles(strPath))
+      return pDir; // treat as directory
+
+    delete pDir;
+    return NULL;
+  }
+#ifdef HAS_ASAP_CODEC
+  if (ASAPCodec::IsSupportedFormat(strExtension) && CFile::Exists(strPath))
+  {
+    IFileDirectory* pDir=new CASAPFileDirectory;
+    //  Has the asap file more than one track?
+    if (pDir->ContainsFiles(strPath))
+      return pDir; // treat as directory
+
+    delete pDir;
+    return NULL;
+  }
+#endif
+
+  if (pItem->IsRSS())
+    return new CRSSDirectory();
+
+#endif
+  if (strExtension.Equals(".zip"))
+  {
+    CStdString strUrl;
+    URIUtils::CreateArchivePath(strUrl, "zip", strPath, "");
+
+    CFileItemList items;
+    CDirectory::GetDirectory(strUrl, items, strMask);
+    if (items.Size() == 0) // no files
+      pItem->m_bIsFolder = true;
+    else if (items.Size() == 1 && items[0]->m_idepth == 0)
+    {
+      // one STORED file - collapse it down
+      *pItem = *items[0];
+    }
+    else
+    { // compressed or more than one file -> create a zip dir
+      pItem->SetPath(strUrl);
+      return new CZipDirectory;
+    }
+    return NULL;
+  }
+  if (strExtension.Equals(".rar") || strExtension.Equals(".001"))
+  {
+    CStdString strUrl;
+    URIUtils::CreateArchivePath(strUrl, "rar", strPath, "");
+
+    vector<CStdString> tokens;
+    CUtil::Tokenize(strPath,tokens,".");
+    if (tokens.size() > 2)
+    {
+      if (strExtension.Equals(".001"))
+      {
+        if (tokens[tokens.size()-2].Equals("ts")) // .ts.001 - treat as a movie file to scratch some users itch
+          return NULL;
+      }
+      CStdString token = tokens[tokens.size()-2];
+      if (token.Left(4).CompareNoCase("part") == 0) // only list '.part01.rar'
+      {
+        // need this crap to avoid making mistakes - yeyh for the new rar naming scheme :/
+        struct __stat64 stat;
+        int digits = token.size()-4;
+        CStdString strNumber, strFormat;
+        strFormat.Format("part%%0%ii",digits);
+        strNumber.Format(strFormat.c_str(),1);
+        CStdString strPath2=strPath;
+        strPath2.Replace(token,strNumber);
+        if (atoi(token.substr(4).c_str()) > 1 && CFile::Stat(strPath2,&stat) == 0)
+        {
+          pItem->m_bIsFolder = true;
+          return NULL;
+        }
+      }
+    }
+
+    CFileItemList items;
+    CDirectory::GetDirectory(strUrl, items, strMask);
+    if (items.Size() == 0) // no files - hide this
+      pItem->m_bIsFolder = true;
+    else if (items.Size() == 1 && items[0]->m_idepth == 0x30)
+    {
+      // one STORED file - collapse it down
+      *pItem = *items[0];
+    }
+    else
+    {
+#ifdef HAS_FILESYSTEM_RAR
+      // compressed or more than one file -> create a rar dir
+      pItem->SetPath(strUrl);
+      return new CRarDirectory;
+#else
+      return NULL;
+#endif
+    }
+    return NULL;
+  }
+  if (strExtension.Equals(".xsp"))
+  { // XBMC Smart playlist - just XML renamed to XSP
+    // read the name of the playlist in
+    CSmartPlaylist playlist;
+    if (playlist.OpenAndReadName(strPath))
+    {
+      pItem->SetLabel(playlist.GetName());
+      pItem->SetLabelPreformated(true);
+    }
+    IFileDirectory* pDir=new CSmartPlaylistDirectory;
+    return pDir; // treat as directory
+  }
+  if (g_advancedSettings.m_playlistAsFolders && CPlayListFactory::IsPlaylist(strPath))
+  { // Playlist file
+    // currently we only return the directory if it contains
+    // more than one file.  Reason is that .pls and .m3u may be used
+    // for links to http streams etc.
+    IFileDirectory *pDir = new CPlaylistFileDirectory();
+    CFileItemList items;
+    if (pDir->GetDirectory(strPath, items))
+    {
+      if (items.Size() > 1)
+        return pDir;
+    }
+    delete pDir;
+    return NULL;
+  }
+  return NULL;
+}
+
diff --git a/xbmc/filesystem/FileDirectoryFactory.h b/xbmc/filesystem/FileDirectoryFactory.h
new file mode 100644 (file)
index 0000000..4c816ef
--- /dev/null
@@ -0,0 +1,36 @@
+#pragma once
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IFileDirectory.h"
+
+class CFileItem;
+
+namespace XFILE
+{
+class CFileDirectoryFactory
+{
+public:
+  CFileDirectoryFactory(void);
+  virtual ~CFileDirectoryFactory(void);
+  static IFileDirectory* Create(const CStdString& strPath, CFileItem* pItem, const CStdString& strMask="");
+};
+}
index d9e1349..e4b26f3 100644 (file)
 #endif
 #include "system.h"
 #include "FileFactory.h"
-#include "FileHD.h"
-#include "FileCurl.h"
-#include "FileShoutcast.h"
-#include "FileLastFM.h"
-#include "FileFileReader.h"
+#include "HDFile.h"
+#include "CurlFile.h"
+#include "ShoutcastFile.h"
+#include "LastFMFile.h"
+#include "FileReaderFile.h"
 #ifdef HAS_FILESYSTEM_SMB
 #ifdef _WIN32
-#include "WINFileSmb.h"
+#include "windows/WINFileSmb.h"
 #else
-#include "FileSmb.h"
+#include "SmbFile.h"
 #endif
 #endif
 #ifdef HAS_FILESYSTEM_CDDA
-#include "FileCDDA.h"
+#include "CDDAFile.h"
 #endif
 #ifdef HAS_FILESYSTEM
-#include "FileISO.h"
+#include "ISOFile.h"
 #ifdef HAS_FILESYSTEM_RTV
-#include "FileRTV.h"
+#include "RTVFile.h"
 #endif
 #ifdef HAS_FILESYSTEM_DAAP
-#include "FileDAAP.h"
+#include "DAAPFile.h"
 #endif
 #endif
 #ifdef HAS_FILESYSTEM_SAP
 #ifdef HAS_FILESYSTEM_VTP
 #include "VTPFile.h"
 #endif
-#include "FileZip.h"
+#include "ZipFile.h"
 #ifdef HAS_FILESYSTEM_RAR
-#include "FileRar.h"
+#include "RarFile.h"
 #endif
 #ifdef HAS_FILESYSTEM_SFTP
-#include "FileSFTP.h"
+#include "SFTPFile.h"
 #endif
 #ifdef HAS_FILESYSTEM_NFS
-#include "FileNFS.h"
+#include "NFSFile.h"
 #endif
 #ifdef HAS_FILESYSTEM_AFP
-#include "FileAFP.h"
+#include "AFPFile.h"
 #endif
-#include "FileUPnP.h"
+#include "UPnPFile.h"
 #include "PipesManager.h"
-#include "FilePipe.h"
-#include "FileMusicDatabase.h"
-#include "FileSpecialProtocol.h"
+#include "PipeFile.h"
+#include "MusicDatabaseFile.h"
+#include "SpecialProtocolFile.h"
 #include "MultiPathFile.h"
-#include "FileTuxBox.h"
-#include "FileUDF.h"
+#include "TuxBoxFile.h"
+#include "UDFFile.h"
 #include "MythFile.h"
-#include "HDHomeRun.h"
-#include "Slingbox.h"
+#include "HDHomeRunFile.h"
+#include "SlingboxFile.h"
 #include "Application.h"
 #include "URL.h"
 #include "utils/log.h"
@@ -104,23 +104,23 @@ IFile* CFileFactory::CreateLoader(const CURL& url)
   CStdString strProtocol = url.GetProtocol();
   strProtocol.MakeLower();
 
-  if (strProtocol == "zip") return new CFileZip();
+  if (strProtocol == "zip") return new CZipFile();
 #ifdef HAS_FILESYSTEM_RAR
-  else if (strProtocol == "rar") return new CFileRar();
+  else if (strProtocol == "rar") return new CRarFile();
 #endif
-  else if (strProtocol == "musicdb") return new CFileMusicDatabase();
+  else if (strProtocol == "musicdb") return new CMusicDatabaseFile();
   else if (strProtocol == "videodb") return NULL;
-  else if (strProtocol == "special") return new CFileSpecialProtocol();
+  else if (strProtocol == "special") return new CSpecialProtocolFile();
   else if (strProtocol == "multipath") return new CMultiPathFile();
-  else if (strProtocol == "file" || strProtocol.IsEmpty()) return new CFileHD();
-  else if (strProtocol == "filereader") return new CFileFileReader();
+  else if (strProtocol == "file" || strProtocol.IsEmpty()) return new CHDFile();
+  else if (strProtocol == "filereader") return new CFileReaderFile();
 #if defined(HAS_FILESYSTEM_CDDA) && defined(HAS_DVD_DRIVE)
   else if (strProtocol == "cdda") return new CFileCDDA();
 #endif
 #ifdef HAS_FILESYSTEM
-  else if (strProtocol == "iso9660") return new CFileISO();
+  else if (strProtocol == "iso9660") return new CISOFile();
 #endif
-  else if(strProtocol == "udf") return new CFileUDF();
+  else if(strProtocol == "udf") return new CUDFFile();
 
   if( g_application.getNetwork().IsAvailable() )
   {
@@ -131,14 +131,14 @@ IFile* CFileFactory::CreateLoader(const CURL& url)
     ||  strProtocol == "ftp"
     ||  strProtocol == "ftpx"
     ||  strProtocol == "ftps"
-    ||  strProtocol == "rss") return new CFileCurl();
+    ||  strProtocol == "rss") return new CCurlFile();
 #ifdef HAS_FILESYSTEM_SFTP
-    else if (strProtocol == "sftp" || strProtocol == "ssh") return new CFileSFTP();
+    else if (strProtocol == "sftp" || strProtocol == "ssh") return new CSFTPFile();
 #endif
-    else if (strProtocol == "shout") return new CFileShoutcast();
-    else if (strProtocol == "lastfm") return new CFileLastFM();
-    else if (strProtocol == "tuxbox") return new CFileTuxBox();
-    else if (strProtocol == "hdhomerun") return new CFileHomeRun();
+    else if (strProtocol == "shout") return new CShoutcastFile();
+    else if (strProtocol == "lastfm") return new CLastFMFile();
+    else if (strProtocol == "tuxbox") return new CTuxBoxFile();
+    else if (strProtocol == "hdhomerun") return new CHomeRunFile();
     else if (strProtocol == "sling") return new CSlingboxFile();
     else if (strProtocol == "myth") return new CMythFile();
     else if (strProtocol == "cmyth") return new CMythFile();
@@ -146,15 +146,15 @@ IFile* CFileFactory::CreateLoader(const CURL& url)
 #ifdef _WIN32
     else if (strProtocol == "smb") return new CWINFileSMB();
 #else
-    else if (strProtocol == "smb") return new CFileSMB();
+    else if (strProtocol == "smb") return new CSmbFile();
 #endif
 #endif
 #ifdef HAS_FILESYSTEM
 #ifdef HAS_FILESYSTEM_RTV
-    else if (strProtocol == "rtv") return new CFileRTV();
+    else if (strProtocol == "rtv") return new CRTVFile();
 #endif
 #ifdef HAS_FILESYSTEM_DAAP
-    else if (strProtocol == "daap") return new CFileDAAP();
+    else if (strProtocol == "daap") return new CDAAPFile();
 #endif
 #endif
 #ifdef HAS_FILESYSTEM_SAP
@@ -164,13 +164,13 @@ IFile* CFileFactory::CreateLoader(const CURL& url)
     else if (strProtocol == "vtp") return new CVTPFile();
 #endif
 #ifdef HAS_FILESYSTEM_NFS
-    else if (strProtocol == "nfs") return new CFileNFS();
+    else if (strProtocol == "nfs") return new CNFSFile();
 #endif
 #ifdef HAS_FILESYSTEM_AFP
-    else if (strProtocol == "afp") return new CFileAFP();
+    else if (strProtocol == "afp") return new CAFPFile();
 #endif
-    else if (strProtocol == "pipe") return new CFilePipe();    
-    else if (strProtocol == "upnp") return new CFileUPnP();
+    else if (strProtocol == "pipe") return new CPipeFile();    
+    else if (strProtocol == "upnp") return new CUPnPFile();
   }
 
   CLog::Log(LOGWARNING, "%s - Unsupported protocol(%s) in %s", __FUNCTION__, strProtocol.c_str(), url.Get().c_str() );
diff --git a/xbmc/filesystem/FileFileReader.cpp b/xbmc/filesystem/FileFileReader.cpp
deleted file mode 100644 (file)
index 1579939..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * XBMC Media Center
- * Copyright (c) 2002 Frodo
- * Portions Copyright (c) by the authors of ffmpeg and xvid
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-#include "FileFileReader.h"
-#include "URL.h"
-
-using namespace XFILE;
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-//*********************************************************************************************
-CFileFileReader::CFileFileReader()
-{
-}
-
-//*********************************************************************************************
-CFileFileReader::~CFileFileReader()
-{
-  Close();
-}
-
-//*********************************************************************************************
-bool CFileFileReader::Open(const CURL& url)
-{
-  CStdString strURL = url.Get();
-  strURL = strURL.Mid(13);
-  return m_reader.Open(strURL,READ_CACHED);
-}
-
-bool CFileFileReader::Exists(const CURL& url)
-{
-  return CFile::Exists(url.Get().Mid(13));
-}
-
-int CFileFileReader::Stat(const CURL& url, struct __stat64* buffer)
-{
-  return CFile::Stat(url.Get().Mid(13),buffer);
-}
-
-
-//*********************************************************************************************
-bool CFileFileReader::OpenForWrite(const CURL& url, bool bOverWrite)
-{
-  return false;
-}
-
-//*********************************************************************************************
-unsigned int CFileFileReader::Read(void *lpBuf, int64_t uiBufSize)
-{
-  return m_reader.Read(lpBuf,uiBufSize);
-}
-
-//*********************************************************************************************
-int CFileFileReader::Write(const void *lpBuf, int64_t uiBufSize)
-{
-  return 0;
-}
-
-//*********************************************************************************************
-void CFileFileReader::Close()
-{
-  m_reader.Close();
-}
-
-//*********************************************************************************************
-int64_t CFileFileReader::Seek(int64_t iFilePosition, int iWhence)
-{
-  return m_reader.Seek(iFilePosition,iWhence);
-}
-
-//*********************************************************************************************
-int64_t CFileFileReader::GetLength()
-{
-  return m_reader.GetLength();
-}
-
-//*********************************************************************************************
-int64_t CFileFileReader::GetPosition()
-{
-  return m_reader.GetPosition();
-}
-
-
diff --git a/xbmc/filesystem/FileFileReader.h b/xbmc/filesystem/FileFileReader.h
deleted file mode 100644 (file)
index b9c9234..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#pragma once
-/*
- * XBMC Media Center
- * Copyright (c) 2002 Frodo
- * Portions Copyright (c) by the authors of ffmpeg and xvid
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "File.h"
-
-namespace XFILE
-{
-class CFileFileReader : public IFile
-{
-public:
-  CFileFileReader();
-  virtual ~CFileFileReader();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int Write(const void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-
-  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
-  protected:
-  CFile m_reader;
-};
-
-}
-
-
diff --git a/xbmc/filesystem/FileHD.cpp b/xbmc/filesystem/FileHD.cpp
deleted file mode 100644 (file)
index 4380797..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * XBMC Media Center
- * Copyright (c) 2002 Frodo
- * Portions Copyright (c) by the authors of ffmpeg and xvid
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "system.h"
-#include "FileHD.h"
-#include "Util.h"
-#include "URL.h"
-#include "utils/AliasShortcutUtils.h"
-#ifdef _LINUX
-#include "XHandle.h"
-#endif
-
-#include <sys/stat.h>
-#ifdef _LINUX
-#include <sys/ioctl.h>
-#else
-#include <io.h>
-#include "utils/CharsetConverter.h"
-#include "utils/URIUtils.h"
-#endif
-#include "utils/log.h"
-
-
-using namespace XFILE;
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-//*********************************************************************************************
-CFileHD::CFileHD()
-    : m_hFile(INVALID_HANDLE_VALUE)
-{}
-
-//*********************************************************************************************
-CFileHD::~CFileHD()
-{
-  if (m_hFile != INVALID_HANDLE_VALUE) Close();
-}
-//*********************************************************************************************
-CStdString CFileHD::GetLocal(const CURL &url)
-{
-  CStdString path( url.GetFileName() );
-
-  if( url.GetProtocol().Equals("file", false) )
-  {
-    // file://drive[:]/path
-    // file:///drive:/path
-    CStdString host( url.GetHostName() );
-
-    if(host.size() > 0)
-    {
-      if(host.Right(1) == ":")
-        path = host + "/" + path;
-      else
-        path = host + ":/" + path;
-    }
-  }
-
-#ifndef _LINUX
-  path.Replace('/', '\\');
-#endif
-
-  if (IsAliasShortcut(path))
-    TranslateAliasShortcut(path);
-
-  return path;
-}
-
-//*********************************************************************************************
-bool CFileHD::Open(const CURL& url)
-{
-  CStdString strFile = GetLocal(url);
-
-#ifdef _WIN32
-  CStdStringW strWFile;
-  g_charsetConverter.utf8ToW(strFile, strWFile, false);
-  m_hFile.attach(CreateFileW(strWFile.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL));
-#else
-  m_hFile.attach(CreateFile(strFile.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL));
-#endif
-  if (!m_hFile.isValid()) return false;
-
-  m_i64FilePos = 0;
-  m_i64FileLen = 0;
-
-  return true;
-}
-
-bool CFileHD::Exists(const CURL& url)
-{
-  struct __stat64 buffer;
-  CStdString strFile = GetLocal(url);
-
-#ifdef _WIN32
-  CStdStringW strWFile;
-  URIUtils::RemoveSlashAtEnd(strFile);
-  g_charsetConverter.utf8ToW(strFile, strWFile, false);
-  return (_wstat64(strWFile.c_str(), &buffer)==0);
-#else
-  return (_stat64(strFile.c_str(), &buffer)==0);
-#endif
-}
-
-int CFileHD::Stat(struct __stat64* buffer)
-{
-#ifdef _LINUX
-  return _fstat64((*m_hFile).fd, buffer);
-#else
-  // Duplicate the handle, as retrieving and closing a matching crt handle closes the crt handle AND the original Windows handle.
-  HANDLE hFileDup;
-  if (0 == DuplicateHandle(GetCurrentProcess(), (HANDLE)m_hFile, GetCurrentProcess(), &hFileDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
-  {
-    CLog::Log(LOGERROR, __FUNCTION__" - DuplicateHandle()");
-    return -1;
-  }
-
-  int fd;
-  fd = _open_osfhandle((intptr_t)((HANDLE)hFileDup), 0);
-  if (fd == -1)
-  {
-    CLog::Log(LOGERROR, "Stat: fd == -1");
-    return -1;
-  }
-  int result = _fstat64(fd, buffer);
-  _close(fd);
-  return result;
-#endif
-}
-
-int CFileHD::Stat(const CURL& url, struct __stat64* buffer)
-{
-  CStdString strFile = GetLocal(url);
-
-#ifdef _WIN32
-  CStdStringW strWFile;
-  // win32 can only stat root drives with a slash at the end
-  if(strFile.length() == 2 && strFile[1] ==':')
-    URIUtils::AddSlashAtEnd(strFile);
-  /* _wstat64 calls FindFirstFileEx. According to MSDN, the path should not end in a trailing backslash.
-    Remove it before calling _wstat64 */
-  if (strFile.length() > 3 && URIUtils::HasSlashAtEnd(strFile))
-    URIUtils::RemoveSlashAtEnd(strFile);
-  g_charsetConverter.utf8ToW(strFile, strWFile, false);
-  return _wstat64(strWFile.c_str(), buffer);
-#else
-  return _stat64(strFile.c_str(), buffer);
-#endif
-}
-
-bool CFileHD::SetHidden(const CURL &url, bool hidden)
-{
-#ifdef _WIN32
-  CStdStringW path;
-  g_charsetConverter.utf8ToW(GetLocal(url), path, false);
-  DWORD attributes = hidden ? FILE_ATTRIBUTE_HIDDEN : FILE_ATTRIBUTE_NORMAL;
-  if (SetFileAttributesW(path.c_str(), attributes))
-    return true;
-#endif
-  return false;
-}
-
-//*********************************************************************************************
-bool CFileHD::OpenForWrite(const CURL& url, bool bOverWrite)
-{
-  // make sure it's a legal FATX filename (we are writing to the harddisk)
-  CStdString strPath = GetLocal(url);
-
-#ifdef _WIN32
-  CStdStringW strWPath;
-  g_charsetConverter.utf8ToW(strPath, strWPath, false);
-  m_hFile.attach(CreateFileW(strWPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
-#else
-  m_hFile.attach(CreateFile(strPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
-#endif
-  if (!m_hFile.isValid())
-    return false;
-
-  m_i64FilePos = 0;
-  Seek(0, SEEK_SET);
-
-  return true;
-}
-
-//*********************************************************************************************
-unsigned int CFileHD::Read(void *lpBuf, int64_t uiBufSize)
-{
-  if (!m_hFile.isValid()) return 0;
-  DWORD nBytesRead;
-  if ( ReadFile((HANDLE)m_hFile, lpBuf, (DWORD)uiBufSize, &nBytesRead, NULL) )
-  {
-    m_i64FilePos += nBytesRead;
-    return nBytesRead;
-  }
-  return 0;
-}
-
-//*********************************************************************************************
-int CFileHD::Write(const void *lpBuf, int64_t uiBufSize)
-{
-  if (!m_hFile.isValid())
-    return 0;
-
-  DWORD nBytesWriten;
-  if ( WriteFile((HANDLE)m_hFile, (void*) lpBuf, (DWORD)uiBufSize, &nBytesWriten, NULL) )
-    return nBytesWriten;
-
-  return 0;
-}
-
-//*********************************************************************************************
-void CFileHD::Close()
-{
-  m_hFile.reset();
-}
-
-//*********************************************************************************************
-int64_t CFileHD::Seek(int64_t iFilePosition, int iWhence)
-{
-  LARGE_INTEGER lPos, lNewPos;
-  lPos.QuadPart = iFilePosition;
-  int bSuccess;
-
-  switch (iWhence)
-  {
-  case SEEK_SET:
-    bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_BEGIN);
-    break;
-
-  case SEEK_CUR:
-    bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_CURRENT);
-    break;
-
-  case SEEK_END:
-    bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_END);
-    break;
-
-  default:
-    return -1;
-  }
-  if (bSuccess)
-  {
-    m_i64FilePos = lNewPos.QuadPart;
-    return m_i64FilePos;
-  }
-  else
-    return -1;
-}
-
-//*********************************************************************************************
-int64_t CFileHD::GetLength()
-{
-  if(m_i64FileLen <= m_i64FilePos || m_i64FileLen == 0)
-  {
-    LARGE_INTEGER i64Size;
-    if(GetFileSizeEx((HANDLE)m_hFile, &i64Size))
-      m_i64FileLen = i64Size.QuadPart;
-    else
-      CLog::Log(LOGERROR, "CFileHD::GetLength - GetFileSizeEx failed with error %d", GetLastError());
-  }
-  return m_i64FileLen;
-}
-
-//*********************************************************************************************
-int64_t CFileHD::GetPosition()
-{
-  return m_i64FilePos;
-}
-
-bool CFileHD::Delete(const CURL& url)
-{
-  CStdString strFile=GetLocal(url);
-
-#ifdef _WIN32
-  CStdStringW strWFile;
-  g_charsetConverter.utf8ToW(strFile, strWFile, false);
-  return ::DeleteFileW(strWFile.c_str()) ? true : false;
-#else
-  return ::DeleteFile(strFile.c_str()) ? true : false;
-#endif
-}
-
-bool CFileHD::Rename(const CURL& url, const CURL& urlnew)
-{
-  CStdString strFile=GetLocal(url);
-  CStdString strNewFile=GetLocal(urlnew);
-
-#ifdef _WIN32
-  CStdStringW strWFile;
-  CStdStringW strWNewFile;
-  g_charsetConverter.utf8ToW(strFile, strWFile, false);
-  g_charsetConverter.utf8ToW(strNewFile, strWNewFile, false);
-  return ::MoveFileW(strWFile.c_str(), strWNewFile.c_str()) ? true : false;
-#else
-  return ::MoveFile(strFile.c_str(), strNewFile.c_str()) ? true : false;
-#endif
-}
-
-void CFileHD::Flush()
-{
-  ::FlushFileBuffers(m_hFile);
-}
-
-int CFileHD::IoControl(EIoControl request, void* param)
-{
-#ifdef _LINUX
-  if(request == IOCTRL_NATIVE && param)
-  {
-    SNativeIoControl* s = (SNativeIoControl*)param;
-    return ioctl((*m_hFile).fd, s->request, s->param);
-  }
-#endif
-  return -1;
-}
diff --git a/xbmc/filesystem/FileHD.h b/xbmc/filesystem/FileHD.h
deleted file mode 100644 (file)
index 84f7db8..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * XBMC Media Center
- * Copyright (c) 2002 Frodo
- * Portions Copyright (c) by the authors of ffmpeg and xvid
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-// FileHD.h: interface for the CFileHD class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#if !defined(AFX_FILEHD_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_)
-#define AFX_FILEHD_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include "IFile.h"
-#include "utils/AutoPtrHandle.h"
-
-namespace XFILE
-{
-class CFileHD : public IFile
-{
-public:
-  CFileHD();
-  virtual ~CFileHD();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-  virtual int Stat(struct __stat64* buffer);
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int Write(const void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-  virtual void Flush();
-
-  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
-
-  virtual bool Delete(const CURL& url);
-  virtual bool Rename(const CURL& url, const CURL& urlnew);
-  virtual bool SetHidden(const CURL& url, bool hidden);
-
-  virtual int IoControl(EIoControl request, void* param);
-protected:
-  CStdString GetLocal(const CURL &url); /* crate a properly format path from an url */
-  AUTOPTR::CAutoPtrHandle m_hFile;
-  int64_t m_i64FilePos;
-  int64_t m_i64FileLen;
-};
-
-}
-#endif // !defined(AFX_FILEHD_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_)
diff --git a/xbmc/filesystem/FileISO.cpp b/xbmc/filesystem/FileISO.cpp
deleted file mode 100644 (file)
index 61f047f..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
-* XBMC Media Center
-* Copyright (c) 2002 Frodo
-* Portions Copyright (c) by the authors of ffmpeg and xvid
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "FileISO.h"
-#include "URL.h"
-#include "iso9660.h"
-
-#include <sys/stat.h>
-
-using namespace std;
-using namespace XFILE;
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-//*********************************************************************************************
-CFileISO::CFileISO()
-{
-  m_bOpened = false;
-}
-
-//*********************************************************************************************
-CFileISO::~CFileISO()
-{
-  if (m_bOpened)
-  {
-    Close();
-  }
-}
-//*********************************************************************************************
-bool CFileISO::Open(const CURL& url)
-{
-  string strFName = "\\";
-  strFName += url.GetFileName();
-  for (int i = 0; i < (int)strFName.size(); ++i )
-  {
-    if (strFName[i] == '/') strFName[i] = '\\';
-  }
-  m_hFile = m_isoReader.OpenFile((char*)strFName.c_str());
-  if (m_hFile == INVALID_HANDLE_VALUE)
-  {
-    m_bOpened = false;
-    return false;
-  }
-
-  m_bOpened = true;
-  return true;
-}
-
-//*********************************************************************************************
-unsigned int CFileISO::Read(void *lpBuf, int64_t uiBufSize)
-{
-  if (!m_bOpened) return 0;
-  char *pData = (char *)lpBuf;
-
-  if (m_cache.getSize() > 0)
-  {
-    long lTotalBytesRead = 0;
-    while (uiBufSize > 0)
-    {
-      if (m_cache.getMaxReadSize() )
-      {
-        long lBytes2Read = m_cache.getMaxReadSize();
-        if (lBytes2Read > uiBufSize) lBytes2Read = (long)uiBufSize;
-        m_cache.ReadData(pData, lBytes2Read );
-        uiBufSize -= lBytes2Read ;
-        pData += lBytes2Read;
-        lTotalBytesRead += lBytes2Read ;
-      }
-
-      if (m_cache.getMaxWriteSize() > 5000)
-      {
-        byte buffer[5000];
-        long lBytesRead = m_isoReader.ReadFile( m_hFile, buffer, sizeof(buffer));
-        if (lBytesRead > 0)
-          m_cache.WriteData((char*)buffer, lBytesRead);
-        else
-          return 0;
-      }
-    }
-    return lTotalBytesRead;
-  }
-  int iResult = m_isoReader.ReadFile( m_hFile, (byte*)pData, (long)uiBufSize);
-  if (iResult == -1)
-    return 0;
-  return iResult;
-}
-
-//*********************************************************************************************
-void CFileISO::Close()
-{
-  if (!m_bOpened) return ;
-  m_isoReader.CloseFile( m_hFile);
-}
-
-//*********************************************************************************************
-int64_t CFileISO::Seek(int64_t iFilePosition, int iWhence)
-{
-  if (!m_bOpened) return -1;
-  int64_t lNewPos = m_isoReader.Seek(m_hFile, iFilePosition, iWhence);
-  if(lNewPos >= 0)
-    m_cache.Clear();
-  return lNewPos;
-}
-
-//*********************************************************************************************
-int64_t CFileISO::GetLength()
-{
-  if (!m_bOpened) return -1;
-  return m_isoReader.GetFileSize(m_hFile);
-}
-
-//*********************************************************************************************
-int64_t CFileISO::GetPosition()
-{
-  if (!m_bOpened) return -1;
-  return m_isoReader.GetFilePosition(m_hFile);
-}
-
-bool CFileISO::Exists(const CURL& url)
-{
-  string strFName = "\\";
-  strFName += url.GetFileName();
-  for (int i = 0; i < (int)strFName.size(); ++i )
-  {
-    if (strFName[i] == '/') strFName[i] = '\\';
-  }
-  m_hFile = m_isoReader.OpenFile((char*)strFName.c_str());
-  if (m_hFile == INVALID_HANDLE_VALUE)
-    return false;
-
-  m_isoReader.CloseFile(m_hFile);
-  return true;
-}
-
-int CFileISO::Stat(const CURL& url, struct __stat64* buffer)
-{
-  string strFName = "\\";
-  strFName += url.GetFileName();
-  for (int i = 0; i < (int)strFName.size(); ++i )
-  {
-    if (strFName[i] == '/') strFName[i] = '\\';
-  }
-  m_hFile = m_isoReader.OpenFile((char*)strFName.c_str());
-  if (m_hFile != INVALID_HANDLE_VALUE)
-  {
-    memset(buffer, 0, sizeof(struct __stat64));
-    buffer->st_size = m_isoReader.GetFileSize(m_hFile);
-    buffer->st_mode = _S_IFREG;
-    m_isoReader.CloseFile(m_hFile);
-    return 0;
-  }
-  errno = ENOENT;
-  return -1;
-}
diff --git a/xbmc/filesystem/FileISO.h b/xbmc/filesystem/FileISO.h
deleted file mode 100644 (file)
index 8fec921..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-* XBMC Media Center
-* Copyright (c) 2002 Frodo
-* Portions Copyright (c) by the authors of ffmpeg and xvid
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-// FileISO.h: interface for the CFileISO class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#if !defined(AFX_FILEISO_H__C2FB9C6D_3319_4182_AB45_65E57EFAC8D1__INCLUDED_)
-#define AFX_FILEISO_H__C2FB9C6D_3319_4182_AB45_65E57EFAC8D1__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include "IFile.h"
-#include "utils/RingBuffer.h"
-
-namespace XFILE
-{
-
-class CFileISO : public IFile
-{
-public:
-  CFileISO();
-  virtual ~CFileISO();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-protected:
-  bool m_bOpened;
-  HANDLE m_hFile;
-  CRingBuffer m_cache;
-};
-}
-
-#endif // !defined(AFX_FILEISO_H__C2FB9C6D_3319_4182_AB45_65E57EFAC8D1__INCLUDED_)
diff --git a/xbmc/filesystem/FileLastFM.cpp b/xbmc/filesystem/FileLastFM.cpp
deleted file mode 100644 (file)
index d1c4cbd..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "FileLastFM.h"
-
-namespace XFILE
-{
-
-CFileLastFM::CFileLastFM() : CFileCurl()
-{
-  SetUserAgent("");
-  SetBufferSize(8192);
-}
-
-CFileLastFM::~CFileLastFM()
-{
-}
-
-}
-
diff --git a/xbmc/filesystem/FileLastFM.h b/xbmc/filesystem/FileLastFM.h
deleted file mode 100644 (file)
index b12839e..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "FileCurl.h"
-#include "utils/RingBuffer.h"
-
-namespace XFILE
-{
-
-  class CFileLastFM : public CFileCurl
-  {
-  public:
-    CFileLastFM();
-    virtual ~CFileLastFM();
-  protected:
-  };
-
-}
diff --git a/xbmc/filesystem/FileMusicDatabase.cpp b/xbmc/filesystem/FileMusicDatabase.cpp
deleted file mode 100644 (file)
index 5273d4f..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "FileMusicDatabase.h"
-#include "music/MusicDatabase.h"
-#include "URL.h"
-#include "utils/StringUtils.h"
-#include "utils/URIUtils.h"
-
-#include <sys/stat.h>
-
-using namespace XFILE;
-
-CFileMusicDatabase::CFileMusicDatabase(void)
-{
-}
-
-CFileMusicDatabase::~CFileMusicDatabase(void)
-{
-  Close();
-}
-
-CStdString CFileMusicDatabase::TranslateUrl(const CURL& url)
-{
-  CMusicDatabase musicDatabase;
-  if (!musicDatabase.Open())
-    return "";
-
-  CStdString strFileName=URIUtils::GetFileName(url.Get());
-  CStdString strExtension;
-  URIUtils::GetExtension(strFileName, strExtension);
-  URIUtils::RemoveExtension(strFileName);
-
-  if (!StringUtils::IsNaturalNumber(strFileName))
-    return "";
-
-  long idSong=atol(strFileName.c_str());
-
-  CSong song;
-  if (!musicDatabase.GetSongById(idSong, song))
-    return "";
-
-  CStdString strExtensionFromDb;
-  URIUtils::GetExtension(song.strFileName, strExtensionFromDb);
-
-  if (!strExtensionFromDb.Equals(strExtension))
-    return "";
-
-  return song.strFileName;
-}
-
-bool CFileMusicDatabase::Open(const CURL& url)
-{
-  return m_file.Open(TranslateUrl(url));
-}
-
-bool CFileMusicDatabase::Exists(const CURL& url)
-{
-  return !TranslateUrl(url).IsEmpty();
-}
-
-int CFileMusicDatabase::Stat(const CURL& url, struct __stat64* buffer)
-{
-  return m_file.Stat(TranslateUrl(url), buffer);
-}
-
-unsigned int CFileMusicDatabase::Read(void* lpBuf, int64_t uiBufSize)
-{
-  return m_file.Read(lpBuf, uiBufSize);
-}
-
-int64_t CFileMusicDatabase::Seek(int64_t iFilePosition, int iWhence /*=SEEK_SET*/)
-{
-  return m_file.Seek(iFilePosition, iWhence);
-}
-
-void CFileMusicDatabase::Close()
-{
-  m_file.Close();
-}
-
-int64_t CFileMusicDatabase::GetPosition()
-{
-  return m_file.GetPosition();
-}
-
-int64_t CFileMusicDatabase::GetLength()
-{
-  return m_file.GetLength();
-}
-
diff --git a/xbmc/filesystem/FileMusicDatabase.h b/xbmc/filesystem/FileMusicDatabase.h
deleted file mode 100644 (file)
index 3d890bb..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "File.h"
-
-namespace XFILE
-{
-class CFileMusicDatabase : public IFile
-{
-public:
-  CFileMusicDatabase(void);
-  virtual ~CFileMusicDatabase(void);
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-
-  static CStdString TranslateUrl(const CURL& url);
-protected:
-  CFile m_file;
-};
-}
diff --git a/xbmc/filesystem/FileNFS.cpp b/xbmc/filesystem/FileNFS.cpp
deleted file mode 100644 (file)
index 271c363..0000000
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- *      Copyright (C) 2011 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-// FileNFS.cpp: implementation of the CFileNFS class.
-//
-//////////////////////////////////////////////////////////////////////
-#include "system.h"
-
-#ifdef HAS_FILESYSTEM_NFS
-#include "DllLibNfs.h"
-#include "FileNFS.h"
-#include "threads/SingleLock.h"
-#include "utils/log.h"
-#include "utils/URIUtils.h"
-#include "network/DNSNameCache.h"
-#include "threads/SystemClock.h"
-
-#include <nfsc/libnfs-raw-mount.h>
-
-#ifdef TARGET_WINDOWS
-#include <fcntl.h>
-#include <sys\stat.h>
-#endif
-
-//KEEP_ALIVE_TIMEOUT is decremented every half a second
-//480 * 0.5s == 240s == 4mins
-//so when no read was done for 4mins and files are open
-//do the nfs keep alive for the open files
-#define KEEP_ALIVE_TIMEOUT 480
-
-//4 mins cached context timeout
-#define CONTEXT_TIMEOUT 240000
-
-//return codes for getContextForExport
-#define CONTEXT_INVALID  0    //getcontext failed
-#define CONTEXT_NEW      1    //new context created
-#define CONTEXT_CACHED   2    //context cached and therefore already mounted (no new mount needed)
-
-using namespace XFILE;
-
-CNfsConnection::CNfsConnection()
-: m_pNfsContext(NULL)
-, m_exportPath("")
-, m_hostName("")
-, m_resolvedHostName("")
-, m_readChunkSize(0)
-, m_writeChunkSize(0)
-, m_OpenConnections(0)
-, m_IdleTimeout(0)
-, m_pLibNfs(new DllLibNfs())
-{
-}
-
-CNfsConnection::~CNfsConnection()
-{
-  Deinit();
-  delete m_pLibNfs;
-}
-
-void CNfsConnection::resolveHost(const CURL &url)
-{ 
-  //resolve if hostname has changed
-  CDNSNameCache::Lookup(url.GetHostName(), m_resolvedHostName);
-}
-
-std::list<CStdString> CNfsConnection::GetExportList(const CURL &url)
-{
-    std::list<CStdString> retList;
-
-    if(HandleDyLoad())
-    {
-      struct exportnode *exportlist, *tmp;
-      exportlist = m_pLibNfs->mount_getexports(m_resolvedHostName);
-      tmp = exportlist;
-
-      for(tmp = exportlist; tmp!=NULL; tmp=tmp->ex_next)
-      {
-        retList.push_back(CStdString(tmp->ex_dir));
-      }      
-
-      gNfsConnection.GetImpl()->mount_free_export_list(exportlist);
-    }
-    
-    return retList;
-}
-
-bool CNfsConnection::HandleDyLoad()
-{
-  bool ret = true;
-  
-  if(!m_pLibNfs->IsLoaded())
-  {
-    if(!m_pLibNfs->Load())
-    {
-      CLog::Log(LOGERROR,"NFS: Error loading libnfs (%s).",__FUNCTION__);    
-      ret = false; //fatal
-    }    
-  }
-  return ret;
-}
-
-void CNfsConnection::clearMembers()
-{
-    m_exportPath.clear();
-    m_hostName.clear();
-    m_exportList.clear();
-    m_writeChunkSize = 0;
-    m_readChunkSize = 0;  
-    m_pNfsContext = NULL;
-    m_KeepAliveTimeouts.clear();
-}
-
-void CNfsConnection::destroyOpenContexts()
-{
-  for(tOpenContextMap::iterator it = m_openContextMap.begin();it!=m_openContextMap.end();it++)
-  {
-    m_pLibNfs->nfs_destroy_context(it->second.pContext);
-  }
-  m_openContextMap.clear();
-}
-
-struct nfs_context *CNfsConnection::getContextFromMap(const CStdString &exportname)
-{
-  struct nfs_context *pRet = NULL;
-
-  tOpenContextMap::iterator it = m_openContextMap.find(exportname.c_str());
-  if(it != m_openContextMap.end())
-  {
-    //check if context has timed out already
-    uint64_t now = XbmcThreads::SystemClockMillis();
-    if((now - it->second.lastAccessedTime) < CONTEXT_TIMEOUT)
-    {
-      //its not timedout yet
-      //refresh access time of that
-      //context and return it
-      CLog::Log(LOGDEBUG, "NFS: Refreshing context for %s, old: %"PRId64", new: %"PRId64, exportname.c_str(), it->second.lastAccessedTime, now);
-      it->second.lastAccessedTime = now;
-      pRet = it->second.pContext;
-    }
-    else 
-    {
-      //context is timed out
-      //destroy it and return NULL
-      CLog::Log(LOGDEBUG, "NFS: Old context timed out - destroying it");
-      m_pLibNfs->nfs_destroy_context(it->second.pContext);
-    }
-  }
-  return pRet;
-}
-
-int CNfsConnection::getContextForExport(const CStdString &exportname)
-{
-  int ret = CONTEXT_INVALID; 
-    
-  if(HandleDyLoad())
-  {
-    clearMembers();  
-    
-    m_pNfsContext = getContextFromMap(exportname);
-
-    if(!m_pNfsContext)
-    {
-      CLog::Log(LOGDEBUG,"NFS: Context for %s not open - get a new context.", exportname.c_str());
-      m_pNfsContext = m_pLibNfs->nfs_init_context();
-    
-      if(!m_pNfsContext) 
-      {
-        CLog::Log(LOGERROR,"NFS: Error initcontext in getContextForExport.");
-      }
-      else 
-      {
-        struct contextTimeout tmp;
-        tmp.pContext = m_pNfsContext;
-        tmp.lastAccessedTime = XbmcThreads::SystemClockMillis();
-        m_openContextMap[exportname] = tmp; //add context to list of all contexts      
-        ret = CONTEXT_NEW;
-      }
-    }
-    else
-    {
-      ret = CONTEXT_CACHED;
-      CLog::Log(LOGDEBUG,"NFS: Using cached context.");
-    }
-  }
-  return ret;
-}
-
-bool CNfsConnection::splitUrlIntoExportAndPath(const CURL& url, CStdString &exportPath, CStdString &relativePath)
-{
-    bool ret = false;
-    
-    //refresh exportlist if empty or hostname change
-    if(m_exportList.empty() || !url.GetHostName().Equals(m_hostName,false))
-    {
-      m_exportList = GetExportList(url);
-    }
-
-    if(!m_exportList.empty())
-    {
-      relativePath = "";
-      exportPath = "";
-      
-      CStdString path = url.GetFileName();
-      
-      //GetFileName returns path without leading "/"
-      //but we need it because the export paths start with "/"
-      //and path.Find(*it) wouldn't work else
-      if(!path.empty() && path[0] != '/')
-      {
-        path = "/" + path;
-      }
-      
-      std::list<CStdString>::iterator it;
-      
-      for(it=m_exportList.begin();it!=m_exportList.end();it++)
-      {
-        //if path starts with the current export path
-        if( path.Find(*it) ==  0 )
-        {
-          exportPath = *it;
-          relativePath = "//" + path.Right((path.length()-1) - exportPath.length());
-          ret = true;
-          break;          
-        }
-      }
-    }
-    return ret;
-}
-
-bool CNfsConnection::Connect(const CURL& url, CStdString &relativePath)
-{
-  CSingleLock lock(*this);
-  bool ret = false;
-  int nfsRet = 0;
-  CStdString exportPath = "";
-
-  resolveHost(url);
-  ret = splitUrlIntoExportAndPath(url, exportPath, relativePath);
-  
-  if(ret && (!exportPath.Equals(m_exportPath,true) || !url.GetHostName().Equals(m_hostName,false)) )
-  {
-    int contextRet = getContextForExport(url.GetHostName() + exportPath);
-    
-    if(contextRet == CONTEXT_INVALID)//we need a new context because sharename or hostname has changed
-    {
-      return false;
-    }
-    
-    if(contextRet == CONTEXT_NEW) //new context was created - we need to mount it
-    {
-      //we connect to the directory of the path. This will be the "root" path of this connection then.
-      //So all fileoperations are relative to this mountpoint...
-      nfsRet = m_pLibNfs->nfs_mount(m_pNfsContext, m_resolvedHostName.c_str(), exportPath.c_str());
-
-      if(nfsRet != 0) 
-      {
-        CLog::Log(LOGERROR,"NFS: Failed to mount nfs share: %s (%s)\n", exportPath.c_str(), m_pLibNfs->nfs_get_error(m_pNfsContext));
-        return false;
-      }
-      CLog::Log(LOGDEBUG,"NFS: Connected to server %s and export %s\n", url.GetHostName().c_str(), exportPath.c_str());
-    }
-    m_exportPath = exportPath;
-    m_hostName = url.GetHostName();
-    //read chunksize only works after mount
-    m_readChunkSize = m_pLibNfs->nfs_get_readmax(m_pNfsContext);
-    m_writeChunkSize = m_pLibNfs->nfs_get_writemax(m_pNfsContext);
-
-    if(contextRet == CONTEXT_NEW)
-    {
-      CLog::Log(LOGDEBUG,"NFS: chunks: r/w %i/%i\n", (int)m_readChunkSize,(int)m_writeChunkSize);          
-    }
-  }
-  return ret; 
-}
-
-void CNfsConnection::Deinit()
-{
-  if(m_pNfsContext && m_pLibNfs->IsLoaded())
-  {
-    destroyOpenContexts();
-    m_pNfsContext = NULL;
-    m_pLibNfs->Unload();    
-  }        
-  clearMembers();
-}
-
-/* This is called from CApplication::ProcessSlow() and is used to tell if nfs have been idle for too long */
-void CNfsConnection::CheckIfIdle()
-{
-  /* We check if there are open connections. This is done without a lock to not halt the mainthread. It should be thread safe as
-   worst case scenario is that m_OpenConnections could read 0 and then changed to 1 if this happens it will enter the if wich will lead to another check, wich is locked.  */
-  if (m_OpenConnections == 0 && m_pNfsContext != NULL)
-  { /* I've set the the maxiumum IDLE time to be 1 min and 30 sec. */
-    CSingleLock lock(*this);
-    if (m_OpenConnections == 0 /* check again - when locked */)
-    {
-      if (m_IdleTimeout > 0)
-      {
-        m_IdleTimeout--;
-      }
-      else
-      {
-        CLog::Log(LOGNOTICE, "NFS is idle. Closing the remaining connections.");
-        gNfsConnection.Deinit();
-      }
-    }
-  }
-  
-  if( m_pNfsContext != NULL )
-  {
-    //handle keep alive on opened files
-    for( tFileKeepAliveMap::iterator it = m_KeepAliveTimeouts.begin();it!=m_KeepAliveTimeouts.end();it++)
-    {
-      CSingleLock lock(keepAliveLock);
-      if(it->second > 0)
-      {
-        it->second--;
-      }
-      else
-      {
-        lock.Leave();
-        keepAlive(it->first);
-        //reset timeout
-        resetKeepAlive(it->first);
-      }
-    }
-  }
-}
-
-//remove file handle from keep alive list on file close
-void CNfsConnection::removeFromKeepAliveList(struct nfsfh  *_pFileHandle)
-{
-  CSingleLock lock(keepAliveLock);
-  m_KeepAliveTimeouts.erase(_pFileHandle);
-}
-
-//reset timeouts on read
-void CNfsConnection::resetKeepAlive(struct nfsfh  *_pFileHandle)
-{
-  CSingleLock lock(keepAliveLock);
-  //adds new keys - refreshs existing ones  
-  m_KeepAliveTimeouts[_pFileHandle] = KEEP_ALIVE_TIMEOUT;
-}
-
-//keep alive the filehandles nfs connection
-//by blindly doing a read 32bytes - seek back to where
-//we were before
-void CNfsConnection::keepAlive(struct nfsfh  *_pFileHandle)
-{
-  off64_t offset = 0;
-  char buffer[32];
-  CLog::Log(LOGNOTICE, "NFS: sending keep alive after %i s.",KEEP_ALIVE_TIMEOUT/2);
-  CSingleLock lock(*this);
-  m_pLibNfs->nfs_lseek(m_pNfsContext, _pFileHandle, 0, SEEK_CUR, &offset);
-  m_pLibNfs->nfs_read(m_pNfsContext, _pFileHandle, 32, buffer);
-  m_pLibNfs->nfs_lseek(m_pNfsContext, _pFileHandle, offset, SEEK_SET, &offset);
-}
-
-int CNfsConnection::stat(const CURL &url, struct stat *statbuff)
-{
-  CSingleLock lock(*this);
-  int nfsRet = 0;
-  CStdString exportPath;
-  CStdString relativePath;
-  struct nfs_context *pTmpContext = NULL;
-  
-  if(!HandleDyLoad())
-  {
-    return -1;
-  }
-  
-  resolveHost(url);
-  
-  if(splitUrlIntoExportAndPath(url, exportPath, relativePath))
-  {    
-    pTmpContext = m_pLibNfs->nfs_init_context();
-    
-    if(pTmpContext)
-    {  
-      //we connect to the directory of the path. This will be the "root" path of this connection then.
-      //So all fileoperations are relative to this mountpoint...
-      nfsRet = m_pLibNfs->nfs_mount(pTmpContext, m_resolvedHostName.c_str(), exportPath.c_str());
-      
-      if(nfsRet == 0) 
-      {
-        nfsRet = m_pLibNfs->nfs_stat(pTmpContext, relativePath.c_str(), statbuff);      
-      }
-      else
-      {
-        CLog::Log(LOGERROR,"NFS: Failed to mount nfs share: %s (%s)\n", exportPath.c_str(), m_pLibNfs->nfs_get_error(m_pNfsContext));
-      }
-      
-      m_pLibNfs->nfs_destroy_context(pTmpContext);
-      CLog::Log(LOGDEBUG,"NFS: Connected to server %s and export %s in tmpContext\n", url.GetHostName().c_str(), exportPath.c_str());
-    }
-  }
-  return nfsRet;
-}
-
-/* The following two function is used to keep track on how many Opened files/directories there are.
-needed for unloading the dylib*/
-void CNfsConnection::AddActiveConnection()
-{
-  CSingleLock lock(*this);
-  m_OpenConnections++;
-}
-
-void CNfsConnection::AddIdleConnection()
-{
-  CSingleLock lock(*this);
-  m_OpenConnections--;
-  /* If we close a file we reset the idle timer so that we don't have any wierd behaviours if a user
-   leaves the movie paused for a long while and then press stop */
-  m_IdleTimeout = 180;
-}
-
-CNfsConnection gNfsConnection;
-
-CFileNFS::CFileNFS()
-: m_fileSize(0)
-, m_pFileHandle(NULL)
-, m_pNfsContext(NULL)
-{
-  gNfsConnection.AddActiveConnection();
-}
-
-CFileNFS::~CFileNFS()
-{
-  Close();
-  gNfsConnection.AddIdleConnection();
-}
-
-int64_t CFileNFS::GetPosition()
-{
-  int ret = 0;
-  off64_t offset = 0;
-  CSingleLock lock(gNfsConnection);
-  
-  if (gNfsConnection.GetNfsContext() == NULL || m_pFileHandle == NULL) return 0;
-  
-  ret = (int)gNfsConnection.GetImpl()->nfs_lseek(gNfsConnection.GetNfsContext(), m_pFileHandle, 0, SEEK_CUR, &offset);
-  
-  if (ret < 0) 
-  {
-    CLog::Log(LOGERROR, "NFS: Failed to lseek(%s)",gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
-  }
-  return offset;
-}
-
-int64_t CFileNFS::GetLength()
-{
-  if (m_pFileHandle == NULL) return 0;
-  return m_fileSize;
-}
-
-bool CFileNFS::Open(const CURL& url)
-{
-  int ret = 0;
-  Close();
-  // we can't open files like nfs://file.f or nfs://server/file.f
-  // if a file matches the if below return false, it can't exist on a nfs share.
-  if (!IsValidFile(url.GetFileName()))
-  {
-    CLog::Log(LOGNOTICE,"NFS: Bad URL : '%s'",url.GetFileName().c_str());
-    return false;
-  }
-  
-  CStdString filename = "";
-   
-  CSingleLock lock(gNfsConnection);
-  
-  if(!gNfsConnection.Connect(url, filename))
-    return false;
-  
-  m_pNfsContext = gNfsConnection.GetNfsContext(); 
-  
-  ret = gNfsConnection.GetImpl()->nfs_open(m_pNfsContext, filename.c_str(), O_RDONLY, &m_pFileHandle);
-  
-  if (ret != 0) 
-  {
-    CLog::Log(LOGINFO, "CFileNFS::Open: Unable to open file : '%s'  error : '%s'", url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
-    return false;
-  } 
-  
-  CLog::Log(LOGDEBUG,"CFileNFS::Open - opened %s",url.GetFileName().c_str());
-  m_url=url;
-  
-  struct __stat64 tmpBuffer;
-
-  if( Stat(&tmpBuffer) )
-  {
-    m_url.Reset();
-    Close();
-    return false;
-  }
-  
-  m_fileSize = tmpBuffer.st_size;//cache the size of this file
-  // We've successfully opened the file!
-  return true;
-}
-
-
-bool CFileNFS::Exists(const CURL& url)
-{
-  return Stat(url,NULL) == 0;
-}
-
-int CFileNFS::Stat(struct __stat64* buffer)
-{
-  return Stat(m_url,buffer);
-}
-
-
-int CFileNFS::Stat(const CURL& url, struct __stat64* buffer)
-{
-  int ret = 0;
-  CSingleLock lock(gNfsConnection);
-  CStdString filename = "";
-  
-  if(!gNfsConnection.Connect(url,filename))
-    return -1;
-   
-
-  struct stat tmpBuffer = {0};
-
-  ret = gNfsConnection.GetImpl()->nfs_stat(gNfsConnection.GetNfsContext(), filename.c_str(), &tmpBuffer);
-  
-  //if buffer == NULL we where called from Exists - in that case don't spam the log with errors
-  if (ret != 0 && buffer != NULL) 
-  {
-    CLog::Log(LOGERROR, "NFS: Failed to stat(%s) %s\n", url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
-    ret = -1;
-  }
-  else
-  {  
-    if(buffer)
-    {
-      memset(buffer, 0, sizeof(struct __stat64));
-      buffer->st_dev = tmpBuffer.st_dev;
-      buffer->st_ino = tmpBuffer.st_ino;
-      buffer->st_mode = tmpBuffer.st_mode;
-      buffer->st_nlink = tmpBuffer.st_nlink;
-      buffer->st_uid = tmpBuffer.st_uid;
-      buffer->st_gid = tmpBuffer.st_gid;
-      buffer->st_rdev = tmpBuffer.st_rdev;
-      buffer->st_size = tmpBuffer.st_size;
-      buffer->st_atime = tmpBuffer.st_atime;
-      buffer->st_mtime = tmpBuffer.st_mtime;
-      buffer->st_ctime = tmpBuffer.st_ctime;
-    }
-  }
-  return ret;
-}
-
-unsigned int CFileNFS::Read(void *lpBuf, int64_t uiBufSize)
-{
-  int numberOfBytesRead = 0;
-  CSingleLock lock(gNfsConnection);
-  
-  if (m_pFileHandle == NULL || m_pNfsContext == NULL ) return 0;
-
-  numberOfBytesRead = gNfsConnection.GetImpl()->nfs_read(m_pNfsContext, m_pFileHandle, (size_t)uiBufSize, (char *)lpBuf);  
-
-  lock.Leave();//no need to keep the connection lock after that
-  
-  gNfsConnection.resetKeepAlive(m_pFileHandle);//triggers keep alive timer reset for this filehandle
-  
-  //something went wrong ...
-  if (numberOfBytesRead < 0) 
-  {
-    CLog::Log(LOGERROR, "%s - Error( %d, %s )", __FUNCTION__, numberOfBytesRead, gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
-    return 0;
-  }
-  return (unsigned int)numberOfBytesRead;
-}
-
-int64_t CFileNFS::Seek(int64_t iFilePosition, int iWhence)
-{
-  int ret = 0;
-  off64_t offset = 0;
-
-  CSingleLock lock(gNfsConnection);  
-  if (m_pFileHandle == NULL || m_pNfsContext == NULL) return -1;
-  
-  ret = (int)gNfsConnection.GetImpl()->nfs_lseek(m_pNfsContext, m_pFileHandle, iFilePosition, iWhence, &offset);
-  if (ret < 0) 
-  {
-    CLog::Log(LOGERROR, "%s - Error( seekpos: %"PRId64", whence: %i, fsize: %"PRId64", %s)", __FUNCTION__, iFilePosition, iWhence, m_fileSize, gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
-    return -1;
-  }
-  return (int64_t)offset;
-}
-
-void CFileNFS::Close()
-{
-  CSingleLock lock(gNfsConnection);
-  
-  if (m_pFileHandle != NULL && m_pNfsContext != NULL)
-  {
-    int ret = 0;
-    CLog::Log(LOGDEBUG,"CFileNFS::Close closing file %s", m_url.GetFileName().c_str());
-    ret = gNfsConnection.GetImpl()->nfs_close(m_pNfsContext, m_pFileHandle);
-    gNfsConnection.removeFromKeepAliveList(m_pFileHandle);
-        
-         if (ret < 0) 
-    {
-      CLog::Log(LOGERROR, "Failed to close(%s) - %s\n", m_url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
-    }
-    m_pFileHandle = NULL;
-    m_pNfsContext = NULL;    
-    m_fileSize = 0;
-  }
-}
-
-//this was a bitch!
-//for nfs write to work we have to write chunked
-//otherwise this could crash on big files
-int CFileNFS::Write(const void* lpBuf, int64_t uiBufSize)
-{
-  int numberOfBytesWritten = 0;
-  int writtenBytes = 0;
-  int64_t leftBytes = uiBufSize;
-  //clamp max write chunksize to 32kb - fixme - this might be superfluious with future libnfs versions
-  int64_t chunkSize = gNfsConnection.GetMaxWriteChunkSize() > 32768 ? 32768 : gNfsConnection.GetMaxWriteChunkSize();
-  
-  CSingleLock lock(gNfsConnection);
-  
-  if (m_pFileHandle == NULL || m_pNfsContext == NULL) return -1;
-  
-  //write as long as some bytes are left to be written
-  while( leftBytes )
-  {
-    //the last chunk could be smalle than chunksize
-    if(leftBytes < chunkSize)
-    {
-      chunkSize = leftBytes;//write last chunk with correct size
-    }
-    //write chunk
-    writtenBytes = gNfsConnection.GetImpl()->nfs_write(m_pNfsContext,
-                                  m_pFileHandle, 
-                                  (size_t)chunkSize, 
-                                  (char *)lpBuf + numberOfBytesWritten);
-    //decrease left bytes
-    leftBytes-= writtenBytes;
-    //increase overall written bytes
-    numberOfBytesWritten += writtenBytes;
-        
-    //danger - something went wrong
-    if (writtenBytes < 0) 
-    {
-      CLog::Log(LOGERROR, "Failed to pwrite(%s) %s\n", m_url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));        
-      break;
-    }     
-  }
-  //return total number of written bytes
-  return numberOfBytesWritten;
-}
-
-bool CFileNFS::Delete(const CURL& url)
-{
-  int ret = 0;
-  CSingleLock lock(gNfsConnection);
-  CStdString filename = "";
-  
-  if(!gNfsConnection.Connect(url, filename))
-    return false;
-  
-  
-  ret = gNfsConnection.GetImpl()->nfs_unlink(gNfsConnection.GetNfsContext(), filename.c_str());
-  
-  if(ret != 0)
-  {
-    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
-  }
-  return (ret == 0);
-}
-
-bool CFileNFS::Rename(const CURL& url, const CURL& urlnew)
-{
-  int ret = 0;
-  CSingleLock lock(gNfsConnection);
-  CStdString strFile = "";
-  
-  if(!gNfsConnection.Connect(url,strFile))
-    return false;
-  
-  CStdString strFileNew;
-  CStdString strDummy;
-  gNfsConnection.splitUrlIntoExportAndPath(urlnew, strDummy, strFileNew);
-  
-  ret = gNfsConnection.GetImpl()->nfs_rename(gNfsConnection.GetNfsContext() , strFile.c_str(), strFileNew.c_str());
-  
-  if(ret != 0)
-  {
-    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
-  } 
-  return (ret == 0);
-}
-
-bool CFileNFS::OpenForWrite(const CURL& url, bool bOverWrite)
-{ 
-  int ret = 0;
-  // we can't open files like nfs://file.f or nfs://server/file.f
-  // if a file matches the if below return false, it can't exist on a nfs share.
-  if (!IsValidFile(url.GetFileName())) return false;
-  
-  Close();
-  CSingleLock lock(gNfsConnection);
-  CStdString filename = "";
-  
-  if(!gNfsConnection.Connect(url,filename))
-    return false;
-  
-  m_pNfsContext = gNfsConnection.GetNfsContext();
-  
-  if (bOverWrite)
-  {
-    CLog::Log(LOGWARNING, "FileNFS::OpenForWrite() called with overwriting enabled! - %s", filename.c_str());
-    //create file with proper permissions
-    ret = gNfsConnection.GetImpl()->nfs_creat(m_pNfsContext, filename.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, &m_pFileHandle);    
-    //if file was created the file handle isn't valid ... so close it and open later
-    if(ret == 0)
-    {
-      gNfsConnection.GetImpl()->nfs_close(m_pNfsContext,m_pFileHandle);
-    }
-  }
-
-  ret = gNfsConnection.GetImpl()->nfs_open(m_pNfsContext, filename.c_str(), O_RDWR, &m_pFileHandle);
-  
-  if (ret || m_pFileHandle == NULL)
-  {
-    // write error to logfile
-    CLog::Log(LOGERROR, "CFileNFS::Open: Unable to open file : '%s' error : '%s'", filename.c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
-    return false;
-  }
-  m_url=url;
-  
-  struct __stat64 tmpBuffer = {0};
-
-  //only stat if file was not created
-  if(!bOverWrite) 
-  {
-    if(Stat(&tmpBuffer))
-    {
-      m_url.Reset();
-      Close();
-      return false;
-    }
-    m_fileSize = tmpBuffer.st_size;//cache filesize of this file    
-  }
-  else//file was created - filesize is zero
-  {
-    m_fileSize = 0;    
-  }
-  
-  // We've successfully opened the file!
-  return true;
-}
-
-bool CFileNFS::IsValidFile(const CStdString& strFileName)
-{
-  if (strFileName.Find('/') == -1 || /* doesn't have sharename */
-      strFileName.Right(2) == "/." || /* not current folder */
-      strFileName.Right(3) == "/..")  /* not parent folder */
-    return false;
-  return true;
-}
-#endif//HAS_FILESYSTEM_NFS
-
diff --git a/xbmc/filesystem/FileNFS.h b/xbmc/filesystem/FileNFS.h
deleted file mode 100644 (file)
index ca42686..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *      Copyright (C) 2011 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-// FileNFS.h: interface for the CFileNFS class.
-#ifndef FILENFS_H_
-#define FILENFS_H_
-
-#include "IFile.h"
-#include "URL.h"
-#include "threads/CriticalSection.h"
-#include <list>
-#include "SectionLoader.h"
-#include <map>
-
-#ifdef TARGET_WINDOWS
-#define S_IRGRP 0
-#define S_IROTH 0
-#define S_IWUSR _S_IWRITE
-#define S_IRUSR _S_IREAD
-#define        S_IFLNK 0120000
-
-#define S_ISBLK(m) (0)
-#define S_ISSOCK(m) (0)
-#define S_ISLNK(m) ((m & S_IFLNK) != 0)
-#define S_ISCHR(m) ((m & _S_IFCHR) != 0)
-#define S_ISDIR(m) ((m & _S_IFDIR) != 0)
-#define S_ISFIFO(m) ((m & _S_IFIFO) != 0)
-#define S_ISREG(m) ((m & _S_IFREG) != 0)
-#endif
-
-class DllLibNfs;
-
-class CNfsConnection : public CCriticalSection
-{     
-public:
-  typedef std::map<struct nfsfh  *, unsigned int> tFileKeepAliveMap;  
-
-  struct contextTimeout
-  {
-    struct nfs_context *pContext;
-    uint64_t lastAccessedTime;
-  };
-
-  typedef std::map<std::string, struct contextTimeout> tOpenContextMap;    
-  
-  CNfsConnection();
-  ~CNfsConnection();
-  bool Connect(const CURL &url, CStdString &relativePath);
-  struct nfs_context *GetNfsContext(){return m_pNfsContext;}
-  size_t            GetMaxReadChunkSize(){return m_readChunkSize;}
-  size_t            GetMaxWriteChunkSize(){return m_writeChunkSize;} 
-  DllLibNfs        *GetImpl(){return m_pLibNfs;}
-  std::list<CStdString> GetExportList(const CURL &url);
-  //this functions splits the url into the exportpath (feed to mount) and the rest of the path
-  //relative to the mounted export
-  bool splitUrlIntoExportAndPath(const CURL& url, CStdString &exportPath, CStdString &relativePath);
-  
-  //special stat which uses its own context
-  //needed for getting intervolume symlinks to work
-  int stat(const CURL &url, struct stat *statbuff);
-
-  void AddActiveConnection();
-  void AddIdleConnection();
-  void CheckIfIdle();
-  void Deinit();
-  bool HandleDyLoad();//loads the lib if needed
-  //adds the filehandle to the keep alive list or resets
-  //the timeout for this filehandle if already in list
-  void resetKeepAlive(struct nfsfh  *_pFileHandle);
-  //removes file handle from keep alive list
-  void removeFromKeepAliveList(struct nfsfh  *_pFileHandle);  
-  
-  const CStdString& GetConnectedIp() const {return m_resolvedHostName;}
-  const CStdString& GetConnectedExport() const {return m_exportPath;}
-
-private:
-  struct nfs_context *m_pNfsContext;//current nfs context
-  CStdString m_exportPath;//current connected export path
-  CStdString m_hostName;//current connected host
-  CStdString m_resolvedHostName;//current connected host - as ip
-  size_t m_readChunkSize;//current read chunksize of connected server
-  size_t m_writeChunkSize;//current write chunksize of connected server
-  int m_OpenConnections;//number of open connections
-  unsigned int m_IdleTimeout;//timeout for idle connection close and dyunload
-  tFileKeepAliveMap m_KeepAliveTimeouts;//mapping filehandles to its idle timeout
-  tOpenContextMap m_openContextMap;//unique map for tracking all open contexts
-  DllLibNfs *m_pLibNfs;//the lib
-  std::list<CStdString> m_exportList;//list of exported pathes of current connected servers
-  CCriticalSection keepAliveLock;
-  void clearMembers();
-  struct nfs_context *getContextFromMap(const CStdString &exportname);
-  int  getContextForExport(const CStdString &exportname);//get context for given export and add to open contexts map - sets m_pNfsContext (my return a already mounted cached context)
-  void destroyOpenContexts();
-  void resolveHost(const CURL &url);//resolve hostname by dnslookup
-  void keepAlive(struct nfsfh  *_pFileHandle);
-};
-
-extern CNfsConnection gNfsConnection;
-
-namespace XFILE
-{
-  class CFileNFS : public IFile
-  {
-  public:
-    CFileNFS();
-    virtual ~CFileNFS();
-    virtual void Close();
-    virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-    virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-    virtual bool Open(const CURL& url);
-    virtual bool Exists(const CURL& url);
-    virtual int Stat(const CURL& url, struct __stat64* buffer);
-    virtual int Stat(struct __stat64* buffer);
-    virtual int64_t GetLength();
-    virtual int64_t GetPosition();
-    virtual int Write(const void* lpBuf, int64_t uiBufSize);
-    //implement iocontrol for seek_possible for preventing the stat in File class for
-    //getting this info ...
-    virtual int IoControl(EIoControl request, void* param){ if(request == IOCTRL_SEEK_POSSIBLE) return 1;return -1;};    
-    virtual int  GetChunkSize() {return 1;}
-    
-    virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
-    virtual bool Delete(const CURL& url);
-    virtual bool Rename(const CURL& url, const CURL& urlnew);    
-  protected:
-    CURL m_url;
-    bool IsValidFile(const CStdString& strFileName);
-    int64_t m_fileSize;
-    struct nfsfh  *m_pFileHandle;
-    struct nfs_context *m_pNfsContext;//current nfs context    
-  };
-}
-#endif // FILENFS_H_
-
-
diff --git a/xbmc/filesystem/FilePipe.cpp b/xbmc/filesystem/FilePipe.cpp
deleted file mode 100644 (file)
index 1a55336..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- *      Copyright (C) 2011 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "FilePipe.h"
-#include "threads/SingleLock.h"
-#include "PipesManager.h"
-#include "utils/StringUtils.h"
-
-using namespace XFILE;
-
-CFilePipe::CFilePipe() : m_pos(0), m_length(-1), m_pipe(NULL)
-{
-}
-
-CFilePipe::~CFilePipe()
-{
-  Close();
-}
-
-int64_t CFilePipe::GetPosition()
-{
-  return m_pos;
-}
-
-int64_t CFilePipe::GetLength()
-{
-  return m_length;
-}
-
-void CFilePipe::SetLength(int64_t len)
-{
-  m_length = len;
-}
-
-bool CFilePipe::Open(const CURL& url)
-{
-  CStdString name = url.Get();
-  m_pipe = PipesManager::GetInstance().OpenPipe(name);
-  if (m_pipe)
-    m_pipe->AddListener(this);
-  return (m_pipe != NULL);
-}
-
-bool CFilePipe::Exists(const CURL& url)
-{
-  CStdString name = url.Get();
-  return PipesManager::GetInstance().Exists(name);
-}
-
-int CFilePipe::Stat(const CURL& url, struct __stat64* buffer)
-{
-  return -1;
-}
-
-int CFilePipe::Stat(struct __stat64* buffer)
-{
-  memset(buffer,0,sizeof(struct __stat64));
-  buffer->st_size = m_length;
-  return 0;
-}
-
-unsigned int CFilePipe::Read(void* lpBuf, int64_t uiBufSize)
-{
-  if (!m_pipe)
-    return -1;
-  
-  return m_pipe->Read((char *)lpBuf,(int)uiBufSize,INFINITE);
-}
-
-int CFilePipe::Write(const void* lpBuf, int64_t uiBufSize)
-{
-  if (!m_pipe)
-    return -1;
-  
-  return (int)(m_pipe->Write((const char *)lpBuf,(int)uiBufSize,INFINITE)); // its not the size. its bool. either all was written or not.
-}
-
-void CFilePipe::SetEof()
-{
-  if (!m_pipe)
-    return ;
-  m_pipe->SetEof();
-}
-
-bool CFilePipe::IsEof()
-{
-  if (!m_pipe)
-    return true;
-  return m_pipe->IsEof();
-}
-
-bool CFilePipe::IsEmpty()
-{
-  if (!m_pipe)
-    return true;
-  return m_pipe->IsEmpty();
-}
-
-int64_t CFilePipe::Seek(int64_t iFilePosition, int iWhence)
-{
-  return -1;
-}
-
-void CFilePipe::Close()
-{
-  if (m_pipe)
-  {
-    m_pipe->RemoveListener(this);
-    PipesManager::GetInstance().ClosePipe(m_pipe);    
-  }
-  m_pipe = NULL;
-}
-
-bool CFilePipe::IsClosed()
-{
-  return (m_pipe == NULL);
-}
-
-void CFilePipe::Flush()
-{
-  if (m_pipe)
-    m_pipe->Flush();
-}
-
-bool CFilePipe::OpenForWrite(const CURL& url, bool bOverWrite)
-{
-  CStdString name = url.Get();
-
-  m_pipe = PipesManager::GetInstance().CreatePipe(name);
-  if (m_pipe)
-    m_pipe->AddListener(this);
-  return (m_pipe != NULL);
-}
-
-bool CFilePipe::Delete(const CURL& url)
-{
-  return false;
-}
-
-bool CFilePipe::Rename(const CURL& url, const CURL& urlnew)
-{
-  return false;
-}
-
-int CFilePipe::IoControl(int request, void* param)
-{
-  return -1;
-}
-
-CStdString CFilePipe::GetName() const
-{
-  if (!m_pipe)
-    return StringUtils::EmptyString;
-  return m_pipe->GetName();
-}
-
-void CFilePipe::OnPipeOverFlow()
-{
-  CSingleLock lock(m_lock);
-  for (size_t l=0; l<m_listeners.size(); l++)
-    m_listeners[l]->OnPipeOverFlow();
-}
-
-__int64        CFilePipe::GetAvailableRead()
-{
-  return m_pipe->GetAvailableRead();
-}
-
-void CFilePipe::OnPipeUnderFlow()
-{
-  for (size_t l=0; l<m_listeners.size(); l++)
-    m_listeners[l]->OnPipeUnderFlow();
-}
-
-void CFilePipe::AddListener(IPipeListener *l)
-{
-  CSingleLock lock(m_lock);
-  for (size_t i=0; i<m_listeners.size(); i++)
-  {
-    if (m_listeners[i] == l)
-      return;
-  }
-  m_listeners.push_back(l);
-}
-
-void CFilePipe::RemoveListener(IPipeListener *l)
-{
-  CSingleLock lock(m_lock);
-  std::vector<XFILE::IPipeListener *>::iterator i = m_listeners.begin();
-  while(i != m_listeners.end())
-  {
-    if ( (*i) == l)
-      i = m_listeners.erase(i);
-    else
-      i++;
-  }
-}
-
-void CFilePipe::SetOpenThreashold(int threashold)
-{
-  m_pipe->SetOpenThreashold(threashold);
-}
-
diff --git a/xbmc/filesystem/FilePipe.h b/xbmc/filesystem/FilePipe.h
deleted file mode 100644 (file)
index 01a0957..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * XBMC Media Center
- * Copyright (c) 2002 Frodo
- * Portions Copyright (c) by the authors of ffmpeg and xvid
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-// FilePipe.h: interface for the CFilePipe class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#if !defined(AFX_FILEPIPE_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_)
-#define AFX_FILEPIPE_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include "IFile.h"
-#include "utils/AutoPtrHandle.h"
-#include "utils/StdString.h"
-#include "threads/Event.h"
-#include "threads/CriticalSection.h"
-#include "utils/RingBuffer.h"
-#include "PipesManager.h"
-
-namespace XFILE
-{
-  
-class CFilePipe : public IFile, public IPipeListener
-{
-public:
-  CFilePipe();
-  virtual ~CFilePipe();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-  virtual void SetLength(int64_t len);
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-  virtual int Stat(struct __stat64* buffer);
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int Write(const void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-  virtual void Flush();
-  virtual __int64      GetAvailableRead();
-
-  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
-
-  virtual bool Delete(const CURL& url);
-  virtual bool Rename(const CURL& url, const CURL& urlnew);
-  virtual int IoControl(int request, void* param);
-  
-  CStdString GetName() const;
-  
-  virtual void OnPipeOverFlow();
-  virtual void OnPipeUnderFlow();
-
-  void AddListener(IPipeListener *l);
-  void RemoveListener(IPipeListener *l);
-
-  void SetEof();
-  bool IsEof();
-  bool IsEmpty();
-  bool IsClosed();
-  
-  void SetOpenThreashold(int threashold);
-
-protected:
-  int64_t m_pos;
-  int64_t m_length;
-  
-  XFILE::Pipe *m_pipe;
-  
-  CCriticalSection m_lock;
-  std::vector<XFILE::IPipeListener *> m_listeners;
-};
-
-}
-#endif // !defined(AFX_FILEPIPE_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_)
diff --git a/xbmc/filesystem/FileRTV.cpp b/xbmc/filesystem/FileRTV.cpp
deleted file mode 100644 (file)
index edcf6ea..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-// FileRTV.cpp: implementation of the CFileRTV class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#include "FileRTV.h"
-#include "SectionLoader.h"
-#include "URL.h"
-#include "utils/log.h"
-#include <errno.h>
-#include <sys/stat.h>
-#ifdef _WIN32
-#include "PlatformDefs.h" //for PRIdS
-#endif
-extern "C"
-{
-#include "lib/libRTV/interface.h"
-}
-
-
-using namespace XFILE;
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-CFileRTV::CFileRTV()
-{
-  CSectionLoader::Load("LIBRTV");
-  m_filePos = 0;
-  m_fileSize = 0;
-  m_bOpened = false;
-  m_rtvd = NULL;
-}
-
-CFileRTV::~CFileRTV()
-{
-  Close();
-  CSectionLoader::Unload("LIBRTV");
-}
-
-//*********************************************************************************************
-bool CFileRTV::Open(const char* strHostName, const char* strFileName, int iport)
-{
-  // Close any existing connection
-  if (m_bOpened) Close();
-
-  m_bOpened = false;
-
-  // Set up global variables.  Don't set m_filePos to 0 because we use it to SEEK!
-  m_fileSize = 0;
-  m_rtvd = NULL;
-  strcpy(m_hostName, strHostName);
-  strcpy(m_fileName, strFileName);
-  m_iport = iport;
-
-  // Allow for ReplayTVs on ports other than 80
-  CStdString strHostAndPort;
-  strHostAndPort = strHostName;
-  if (iport)
-  {
-    char buffer[10];
-    strHostAndPort += ':';
-    strHostAndPort += itoa(iport, buffer, 10);
-  }
-
-  // Get the file size of strFileName.  If size is 0 or negative, file doesn't exist so exit.
-  u64 size;
-  size = rtv_get_filesize(strHostAndPort.c_str(), strFileName);
-  if (!size)
-  {
-    CLog::Log(LOGERROR, "%s - Failed to get filesize of %s on %s", __FUNCTION__, strHostName, strFileName);
-    return false;
-  }
-  m_fileSize = size;
-
-  // Open a connection to strFileName stating at position m_filePos
-  // Store the handle to the connection in m_rtvd.  Exit if handle invalid.
-  m_rtvd = rtv_open_file(strHostAndPort.c_str(), strFileName, m_filePos);
-  if (!m_rtvd)
-  {
-    CLog::Log(LOGERROR, "%s - Failed to open %s on %s", __FUNCTION__, strHostName, strFileName);
-    return false;
-  }
-  m_bOpened = true;
-
-  CLog::Log(LOGDEBUG, "%s - Opened %s on %s, Size %"PRIu64", Position %"PRIu64"", __FUNCTION__, strHostName, strFileName, m_fileSize, m_filePos);
-  return true;
-}
-
-bool CFileRTV::Open(const CURL& url)
-{
-  return Open(url.GetHostName(), url.GetFileName(), url.GetPort());
-}
-
-bool CFileRTV::Exists(const CURL& url)
-{
-  return true;
-}
-
-int CFileRTV::Stat(const CURL& url, struct __stat64* buffer)
-{
-  errno = ENOENT;
-  return -1;
-}
-
-//*********************************************************************************************
-unsigned int CFileRTV::Read(void *lpBuf, int64_t uiBufSize)
-{
-  size_t lenread;
-
-  // Don't read if no connection is open!
-  if (!m_bOpened) return 0;
-
-  // Read uiBufSize bytes from the m_rtvd connection
-  lenread = rtv_read_file(m_rtvd, (char *) lpBuf, (size_t) uiBufSize);
-
-  CLog::Log(LOGDEBUG, "%s - Requested %"PRIdS", Recieved %"PRIdS"", __FUNCTION__, (size_t)uiBufSize, lenread);
-
-  // Some extra checking so library behaves
-  if(m_filePos + lenread > m_fileSize)
-  {
-    CLog::Log(LOGWARNING, "%s - RTV library read passed filesize, returning last chunk", __FUNCTION__);
-    lenread = (size_t)(m_fileSize - m_filePos);
-    m_filePos = m_fileSize;
-    return lenread;
-  }
-
-  // Increase the file position by the number of bytes we just read
-  m_filePos += lenread;
-
-  // Return the number of bytes we just read
-  return lenread;
-}
-
-//*********************************************************************************************
-void CFileRTV::Close()
-{
-  m_bOpened = false;
-
-  // Only try to close a valid handle!
-  if (m_rtvd)
-  {
-    rtv_close_file(m_rtvd);
-  }
-  m_rtvd = NULL;
-}
-
-//*********************************************************************************************
-int64_t CFileRTV::Seek(int64_t iFilePosition, int iWhence)
-{
-  UINT64 newpos;
-
-  if (!m_bOpened) return 0;
-  switch (iWhence)
-  {
-  case SEEK_SET:
-    // cur = pos
-    newpos = iFilePosition;
-    break;
-  case SEEK_CUR:
-    // cur += pos
-    newpos = m_filePos + iFilePosition;
-    break;
-  case SEEK_END:
-    // end += pos
-    newpos = m_fileSize + iFilePosition;
-    break;
-  default:
-    return -1;
-  }
-  // Return offset from beginning
-  if (newpos > m_fileSize) newpos = m_fileSize;
-
-  // NEW CODE
-  // If the new file position is different from the old, then we must SEEK there!
-  if (m_filePos != newpos)
-  {
-    m_filePos = newpos;
-    Open(m_hostName, m_fileName, m_iport);
-  }
-
-  // OLD CODE
-  // Below is old code that may be useful again.  For some reason I'm not sure of, XBMC
-  // does a few seeks to the beginning and end of the stream before it ever starts playing.
-  // When used instead of the code above, this code seeks only after playing begins.
-  // Theoretically, this saves some time because it prevents needless re-opening of the
-  // connection to the RTV, but in practice it seems to be the same.
-  //m_filePos = newpos;
-
-  //if (m_rtvd->firstReadDone && iWhence == SEEK_SET) {
-  // Open(NULL, NULL, m_hostName, m_fileName, m_iport, true);
-  //}
-
-  // Return the new file position after the seek
-  return m_filePos;
-}
-
-//*********************************************************************************************
-int64_t CFileRTV::GetLength()
-{
-  if (!m_bOpened) return 0;
-  return m_fileSize;
-}
-
-//*********************************************************************************************
-int64_t CFileRTV::GetPosition()
-{
-  if (!m_bOpened) return 0;
-  return m_filePos;
-}
diff --git a/xbmc/filesystem/FileRTV.h b/xbmc/filesystem/FileRTV.h
deleted file mode 100644 (file)
index 40c5ae8..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-// FileRTV.h: interface for the CFileRTV class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#if !defined(AFX_FILERTV_H___INCLUDED_)
-#define AFX_FILERTV_H___INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include "IFile.h"
-
-typedef struct rtv_data * RTVD;
-
-namespace XFILE
-{
-
-class CFileRTV : public IFile
-{
-public:
-  CFileRTV();
-  virtual ~CFileRTV();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-  virtual bool Open(const CURL& url);
-  bool Open(const char* strHostName, const char* strFileName, int iport);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-protected:
-  uint64_t m_fileSize;
-  uint64_t m_filePos;
-  char m_hostName[255];
-  char m_fileName[255];
-  int m_iport;
-private:
-  RTVD m_rtvd;
-  bool m_bOpened;
-
-};
-}
-
-#endif // !defined(AFX_FILERTV_H___INCLUDED_)
diff --git a/xbmc/filesystem/FileRar.cpp b/xbmc/filesystem/FileRar.cpp
deleted file mode 100644 (file)
index 9c87a35..0000000
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "system.h"
-#include "FileRar.h"
-#include <sys/stat.h>
-#include "Util.h"
-#include "utils/CharsetConverter.h"
-#include "utils/URIUtils.h"
-#include "URL.h"
-#include "Directory.h"
-#include "RarManager.h"
-#include "settings/AdvancedSettings.h"
-#include "FileItem.h"
-#include "utils/log.h"
-#include "UnrarXLib/rar.hpp"
-
-#ifndef _LINUX
-#include <process.h>
-#endif
-
-using namespace XFILE;
-using namespace std;
-
-#define SEEKTIMOUT 30000
-
-#ifdef HAS_FILESYSTEM_RAR
-CFileRarExtractThread::CFileRarExtractThread() : hRunning(true), hQuit(true)
-{
-  m_pArc = NULL;
-  m_pCmd = NULL;
-  m_pExtract = NULL;
-  StopThread();
-  Create();
-}
-
-CFileRarExtractThread::~CFileRarExtractThread()
-{
-  hQuit.Set();
-  AbortableWait(hRestart);
-  StopThread();
-}
-
-void CFileRarExtractThread::Start(Archive* pArc, CommandData* pCmd, CmdExtract* pExtract, int iSize)
-{
-  m_pArc = pArc;
-  m_pCmd = pCmd;
-  m_pExtract = pExtract;
-  m_iSize = iSize;
-
-  m_pExtract->GetDataIO().hBufferFilled = new CEvent;
-  m_pExtract->GetDataIO().hBufferEmpty = new CEvent;
-  m_pExtract->GetDataIO().hSeek = new CEvent(true);
-  m_pExtract->GetDataIO().hSeekDone = new CEvent;
-  m_pExtract->GetDataIO().hQuit = new CEvent(true);
-
-  hRunning.Set();
-  hRestart.Set();
-}
-
-void CFileRarExtractThread::OnStartup()
-{
-}
-
-void CFileRarExtractThread::OnExit()
-{
-}
-
-void CFileRarExtractThread::Process()
-{
-  while (AbortableWait(hQuit,1) != WAIT_SIGNALED)
-  {
-    if (AbortableWait(hRestart,1) == WAIT_SIGNALED)
-    {
-      bool Repeat = false;
-      try
-      {
-        m_pExtract->ExtractCurrentFile(m_pCmd,*m_pArc,m_iSize,Repeat);
-      }
-      catch (int rarErrCode)
-      {
-        CLog::Log(LOGERROR,"filerar CFileRarExtractThread::Process failed. CmdExtract::ExtractCurrentFile threw a UnrarXLib error code of %d",rarErrCode);
-      }
-      catch (...)
-      {
-        CLog::Log(LOGERROR,"filerar CFileRarExtractThread::Process failed. CmdExtract::ExtractCurrentFile threw an Unknown exception");
-      }
-
-      hRunning.Reset();
-    }
-  }
-  hRestart.Set();
-}
-#endif
-
-CFileRar::CFileRar()
-{
-  m_strCacheDir.Empty();
-  m_strRarPath.Empty();
-  m_strPassword.Empty();
-  m_strPathInRar.Empty();
-  m_bFileOptions = 0;
-#ifdef HAS_FILESYSTEM_RAR
-  m_pArc = NULL;
-  m_pCmd = NULL;
-  m_pExtract = NULL;
-  m_pExtractThread = NULL;
-#endif
-  m_szBuffer = NULL;
-  m_szStartOfBuffer = NULL;
-  m_iDataInBuffer = 0;
-  m_bUseFile = false;
-  m_bOpen = false;
-  m_bSeekable = true;
-}
-
-CFileRar::~CFileRar()
-{
-#ifdef HAS_FILESYSTEM_RAR
-  if (!m_bOpen)
-    return;
-
-  if (m_bUseFile)
-  {
-    m_File.Close();
-    g_RarManager.ClearCachedFile(m_strRarPath,m_strPathInRar);
-  }
-  else
-  {
-    CleanUp();
-    if (m_pExtractThread)
-    {
-      delete m_pExtractThread;
-      m_pExtractThread = NULL;
-    }
-  }
-#endif
-}
-
-bool CFileRar::Open(const CURL& url)
-{
-  InitFromUrl(url);
-  CFileItemList items;
-  g_RarManager.GetFilesInRar(items,m_strRarPath,false);
-  int i;
-  for (i=0;i<items.Size();++i)
-  {
-    if (items[i]->GetLabel() == m_strPathInRar)
-      break;
-  }
-
-  if (i<items.Size())
-  {
-    if (items[i]->m_idepth == 0x30) // stored
-    {
-      if (!OpenInArchive())
-        return false;
-
-      m_iFileSize = items[i]->m_dwSize;
-      m_bOpen = true;
-
-      // perform 'noidx' check
-      CFileInfo* pFile = g_RarManager.GetFileInRar(m_strRarPath,m_strPathInRar);
-      if (pFile)
-      {
-        if (pFile->m_iIsSeekable == -1)
-        {
-          if (Seek(-1,SEEK_END) == -1)
-          {
-            m_bSeekable = false;
-            pFile->m_iIsSeekable = 0;
-          }
-        }
-        else
-          m_bSeekable = (pFile->m_iIsSeekable == 1);
-      }
-      return true;
-    }
-    else
-    {
-      CFileInfo* info = g_RarManager.GetFileInRar(m_strRarPath,m_strPathInRar);
-      if ((!info || !CFile::Exists(info->m_strCachedPath)) && m_bFileOptions & EXFILE_NOCACHE)
-        return false;
-      m_bUseFile = true;
-      CStdString strPathInCache;
-
-      if (!g_RarManager.CacheRarredFile(strPathInCache, m_strRarPath, m_strPathInRar,
-                                        EXFILE_AUTODELETE | m_bFileOptions, m_strCacheDir,
-                                        items[i]->m_dwSize))
-      {
-        CLog::Log(LOGERROR,"filerar::open failed to cache file %s",m_strPathInRar.c_str());
-        return false;
-      }
-
-      if (!m_File.Open( strPathInCache ))
-      {
-        CLog::Log(LOGERROR,"filerar::open failed to open file in cache: %s",strPathInCache.c_str());
-        return false;
-      }
-
-      m_bOpen = true;
-      return true;
-    }
-  }
-  return false;
-}
-
-bool CFileRar::Exists(const CURL& url)
-{
-  InitFromUrl(url);
-  bool bResult;
-
-  if (!g_RarManager.IsFileInRar(bResult, m_strRarPath, m_strPathInRar))
-    return false;
-
-  return bResult;
-}
-
-int CFileRar::Stat(const CURL& url, struct __stat64* buffer)
-{
-  memset(buffer, 0, sizeof(struct __stat64));
-  if (Open(url))
-  {
-    buffer->st_size = GetLength();
-    buffer->st_mode = _S_IFREG;
-    Close();
-    errno = 0;
-    return 0;
-  }
-
-  if (CDirectory::Exists(url.Get()))
-  {
-    buffer->st_mode = _S_IFDIR;
-    return 0;
-  }
-
-  errno = ENOENT;
-  return -1;
-}
-
-bool CFileRar::OpenForWrite(const CURL& url)
-{
-  return false;
-}
-
-unsigned int CFileRar::Read(void *lpBuf, int64_t uiBufSize)
-{
-#ifdef HAS_FILESYSTEM_RAR
-  if (!m_bOpen)
-    return 0;
-
-  if (m_bUseFile)
-    return m_File.Read(lpBuf,uiBufSize);
-
-  if (m_iFilePosition >= GetLength()) // we are done
-    return 0;
-
-  if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(5000) )
-  {
-    CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
-    return 0;
-  }
-
-
-  byte* pBuf = (byte*)lpBuf;
-  int64_t uicBufSize = uiBufSize;
-  if (m_iDataInBuffer > 0)
-  {
-    int64_t iCopy = uiBufSize<m_iDataInBuffer?uiBufSize:m_iDataInBuffer;
-    memcpy(lpBuf,m_szStartOfBuffer,size_t(iCopy));
-    m_szStartOfBuffer += iCopy;
-    m_iDataInBuffer -= int(iCopy);
-    pBuf += iCopy;
-    uicBufSize -= iCopy;
-    m_iFilePosition += iCopy;
-  }
-
-  while ((uicBufSize > 0) && m_iFilePosition < GetLength() )
-  {
-    if (m_iDataInBuffer <= 0)
-    {
-      m_pExtract->GetDataIO().SetUnpackToMemory(m_szBuffer,MAXWINMEMSIZE);
-      m_szStartOfBuffer = m_szBuffer;
-      m_iBufferStart = m_iFilePosition;
-    }
-
-    m_pExtract->GetDataIO().hBufferFilled->Set();
-    m_pExtract->GetDataIO().hBufferEmpty->Wait();
-
-    if (m_pExtract->GetDataIO().NextVolumeMissing)
-      break;
-
-    m_iDataInBuffer = MAXWINMEMSIZE-m_pExtract->GetDataIO().UnpackToMemorySize;
-
-    if (m_iDataInBuffer == 0)
-      break;
-
-    if (m_iDataInBuffer > uicBufSize)
-    {
-      memcpy(pBuf,m_szStartOfBuffer,int(uicBufSize));
-      m_szStartOfBuffer += uicBufSize;
-      pBuf += int(uicBufSize);
-      m_iFilePosition += uicBufSize;
-      m_iDataInBuffer -= int(uicBufSize);
-      uicBufSize = 0;
-    }
-    else
-    {
-      memcpy(pBuf,m_szStartOfBuffer,size_t(m_iDataInBuffer));
-      m_iFilePosition += m_iDataInBuffer;
-      m_szStartOfBuffer += m_iDataInBuffer;
-      uicBufSize -= m_iDataInBuffer;
-      pBuf += m_iDataInBuffer;
-      m_iDataInBuffer = 0;
-    }
-  }
-
-  m_pExtract->GetDataIO().hBufferEmpty->Set();
-
-  return static_cast<unsigned int>(uiBufSize-uicBufSize);
-#else
-  return 0;
-#endif
-}
-
-unsigned int CFileRar::Write(void *lpBuf, int64_t uiBufSize)
-{
-  return 0;
-}
-
-void CFileRar::Close()
-{
-#ifdef HAS_FILESYSTEM_RAR
-  if (!m_bOpen)
-    return;
-
-  if (m_bUseFile)
-  {
-    m_File.Close();
-    g_RarManager.ClearCachedFile(m_strRarPath,m_strPathInRar);
-    m_bOpen = false;
-  }
-  else
-  {
-    CleanUp();
-    if (m_pExtractThread)
-    {
-      delete m_pExtractThread;
-      m_pExtractThread = NULL;
-    }
-    m_bOpen = false;
-  }
-#endif
-}
-
-int64_t CFileRar::Seek(int64_t iFilePosition, int iWhence)
-{
-#ifdef HAS_FILESYSTEM_RAR
-  if (!m_bOpen)
-    return -1;
-
-  if (!m_bSeekable)
-    return -1;
-
-  if (m_bUseFile)
-    return m_File.Seek(iFilePosition,iWhence);
-
-  if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(SEEKTIMOUT) )
-  {
-    CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
-    return -1;
-  }
-
-  m_pExtract->GetDataIO().hBufferEmpty->Set();
-
-  switch (iWhence)
-  {
-    case SEEK_CUR:
-      if (iFilePosition == 0)
-        return m_iFilePosition; // happens sometimes
-
-      iFilePosition += m_iFilePosition;
-      break;
-    case SEEK_END:
-      if (iFilePosition == 0) // do not seek to end
-      {
-        m_iFilePosition = this->GetLength();
-        m_iDataInBuffer = 0;
-        m_iBufferStart = this->GetLength();
-
-        return this->GetLength();
-      }
-
-      iFilePosition += GetLength();
-    case SEEK_SET:
-      break;
-    default:
-      return -1;
-  }
-
-  if (iFilePosition > this->GetLength())
-    return -1;
-
-  if (iFilePosition == m_iFilePosition) // happens a lot
-    return m_iFilePosition;
-
-  if ((iFilePosition >= m_iBufferStart) && (iFilePosition < m_iBufferStart+MAXWINMEMSIZE)
-                                        && (m_iDataInBuffer > 0)) // we are within current buffer
-  {
-    m_iDataInBuffer = MAXWINMEMSIZE-(iFilePosition-m_iBufferStart);
-    m_szStartOfBuffer = m_szBuffer+MAXWINMEMSIZE-m_iDataInBuffer;
-    m_iFilePosition = iFilePosition;
-
-    return m_iFilePosition;
-  }
-
-  if (iFilePosition < m_iBufferStart )
-  {
-    CleanUp();
-    if (!OpenInArchive())
-      return -1;
-
-    if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(SEEKTIMOUT) )
-    {
-      CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
-      return -1;
-    }
-    m_pExtract->GetDataIO().hBufferEmpty->Set();
-    m_pExtract->GetDataIO().m_iSeekTo = iFilePosition;
-  }
-  else
-    m_pExtract->GetDataIO().m_iSeekTo = iFilePosition;
-
-  m_pExtract->GetDataIO().SetUnpackToMemory(m_szBuffer,MAXWINMEMSIZE);
-  m_pExtract->GetDataIO().hSeek->Set();
-  m_pExtract->GetDataIO().hBufferFilled->Set();
-  if( !m_pExtract->GetDataIO().hSeekDone->WaitMSec(SEEKTIMOUT))
-  {
-    CLog::Log(LOGERROR, "%s - Timeout waiting for seek to finish", __FUNCTION__);
-    return -1;
-  }
-
-  if (m_pExtract->GetDataIO().NextVolumeMissing)
-  {
-    m_iFilePosition = m_iFileSize;
-    return -1;
-  }
-
-  if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(SEEKTIMOUT) )
-  {
-    CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
-    return -1;
-  }
-  m_iDataInBuffer = m_pExtract->GetDataIO().m_iSeekTo; // keep data
-  m_iBufferStart = m_pExtract->GetDataIO().m_iStartOfBuffer;
-  m_szStartOfBuffer = m_szBuffer+MAXWINMEMSIZE-m_iDataInBuffer;
-  m_iFilePosition = iFilePosition;
-
-  return m_iFilePosition;
-#else
-  return -1;
-#endif
-}
-
-int64_t CFileRar::GetLength()
-{
-  if (!m_bOpen)
-    return 0;
-
-  if (m_bUseFile)
-    return m_File.GetLength();
-
-  return m_iFileSize;
-}
-
-int64_t CFileRar::GetPosition()
-{
-  if (!m_bOpen)
-    return -1;
-
-  if (m_bUseFile)
-    return m_File.GetPosition();
-
-  return m_iFilePosition;
-}
-
-int CFileRar::Write(const void* lpBuf, int64_t uiBufSize)
-{
-  return -1;
-}
-
-void CFileRar::Flush()
-{
-  if (m_bUseFile)
-    m_File.Flush();
-}
-
-void CFileRar::InitFromUrl(const CURL& url)
-{
-  m_strCacheDir = g_advancedSettings.m_cachePath;//url.GetDomain();
-  URIUtils::AddSlashAtEnd(m_strCacheDir);
-  m_strRarPath = url.GetHostName();
-  m_strPassword = url.GetUserName();
-  m_strPathInRar = url.GetFileName();
-
-  vector<CStdString> options;
-  CUtil::Tokenize(url.GetOptions().Mid(1), options, "&");
-
-  m_bFileOptions = 0;
-
-  for( vector<CStdString>::iterator it = options.begin();it != options.end(); it++)
-  {
-    int iEqual = (*it).Find('=');
-    if( iEqual >= 0 )
-    {
-      CStdString strOption = (*it).Left(iEqual);
-      CStdString strValue = (*it).Mid(iEqual+1);
-
-      if( strOption.Equals("flags") )
-        m_bFileOptions = atoi(strValue.c_str());
-      else if( strOption.Equals("cache") )
-        m_strCacheDir = strValue;
-    }
-  }
-
-}
-
-void CFileRar::CleanUp()
-{
-#ifdef HAS_FILESYSTEM_RAR
-  try
-  {
-    if (m_pExtractThread)
-    {
-      if (m_pExtractThread->hRunning.WaitMSec(1))
-      {
-        m_pExtract->GetDataIO().hQuit->Set();
-        while (m_pExtractThread->hRunning.WaitMSec(1))
-          Sleep(1);
-      }
-      delete m_pExtract->GetDataIO().hBufferFilled;
-      delete m_pExtract->GetDataIO().hBufferEmpty;
-      delete m_pExtract->GetDataIO().hSeek;
-      delete m_pExtract->GetDataIO().hSeekDone;
-      delete m_pExtract->GetDataIO().hQuit;
-    }
-    if (m_pExtract)
-    {
-      delete m_pExtract;
-      m_pExtract = NULL;
-    }
-    if (m_pArc)
-    {
-      delete m_pArc;
-      m_pArc = NULL;
-    }
-    if (m_pCmd)
-    {
-      delete m_pCmd;
-      m_pCmd = NULL;
-    }
-    if (m_szBuffer)
-    {
-      delete[] m_szBuffer;
-      m_szBuffer = NULL;
-      m_szStartOfBuffer = NULL;
-    }
-  }
-  catch (int rarErrCode)
-  {
-    CLog::Log(LOGERROR,"filerar failed in UnrarXLib while deleting CFileRar with an UnrarXLib error code of %d",rarErrCode);
-  }
-  catch (...)
-  {
-    CLog::Log(LOGERROR,"filerar failed in UnrarXLib while deleting CFileRar with an Unknown exception");
-  }
-#endif
-}
-
-bool CFileRar::OpenInArchive()
-{
-#ifdef HAS_FILESYSTEM_RAR
-  try
-  {
-    int iHeaderSize;
-
-    InitCRC();
-
-    m_pCmd = new CommandData;
-    if (!m_pCmd)
-    {
-      CleanUp();
-      return false;
-    }
-
-    // Set the arguments for the extract command
-    strcpy(m_pCmd->Command, "X");
-
-    m_pCmd->AddArcName(const_cast<char*>(m_strRarPath.c_str()),NULL);
-
-    strncpy(m_pCmd->ExtrPath, m_strCacheDir.c_str(), sizeof (m_pCmd->ExtrPath) - 2);
-    m_pCmd->ExtrPath[sizeof (m_pCmd->ExtrPath) - 2] = 0;
-    AddEndSlash(m_pCmd->ExtrPath);
-
-    // Set password for encrypted archives
-    if ((m_strPassword.size() > 0) &&
-        (m_strPassword.size() < sizeof (m_pCmd->Password)))
-    {
-      strcpy(m_pCmd->Password, m_strPassword.c_str());
-    }
-
-    m_pCmd->ParseDone();
-
-    // Open the archive
-    m_pArc = new Archive(m_pCmd);
-    if (!m_pArc)
-    {
-      CleanUp();
-      return false;
-    }
-    if (!m_pArc->WOpen(m_strRarPath.c_str(),NULL))
-    {
-      CleanUp();
-      return false;
-    }
-    if (!(m_pArc->IsOpened() && m_pArc->IsArchive(true)))
-    {
-      CleanUp();
-      return false;
-    }
-
-    m_pExtract = new CmdExtract;
-    if (!m_pExtract)
-    {
-      CleanUp();
-      return false;
-    }
-    m_pExtract->GetDataIO().SetUnpackToMemory(m_szBuffer,0);
-    m_pExtract->GetDataIO().SetCurrentCommand(*(m_pCmd->Command));
-    struct FindData FD;
-    if (FindFile::FastFind(m_strRarPath.c_str(),NULL,&FD))
-      m_pExtract->GetDataIO().TotalArcSize+=FD.Size;
-    m_pExtract->ExtractArchiveInit(m_pCmd,*m_pArc);
-
-    while (true)
-    {
-      if ((iHeaderSize = m_pArc->ReadHeader()) <= 0)
-      {
-        CleanUp();
-        return false;
-      }
-
-      if (m_pArc->GetHeaderType() == FILE_HEAD)
-      {
-        CStdString strFileName;
-
-        if (m_pArc->NewLhd.FileNameW && wcslen(m_pArc->NewLhd.FileNameW) > 0)
-        {
-          g_charsetConverter.wToUTF8(m_pArc->NewLhd.FileNameW, strFileName);
-        }
-        else
-        {
-          g_charsetConverter.unknownToUTF8(m_pArc->NewLhd.FileName, strFileName);
-        }
-
-        /* replace back slashes into forward slashes */
-        /* this could get us into troubles, file could two different files, one with / and one with \ */
-        strFileName.Replace('\\', '/');
-
-        if (strFileName == m_strPathInRar)
-        {
-          break;
-        }
-      }
-
-      m_pArc->SeekToNext();
-    }
-
-    m_szBuffer = new byte[MAXWINMEMSIZE];
-    m_szStartOfBuffer = m_szBuffer;
-    m_pExtract->GetDataIO().SetUnpackToMemory(m_szBuffer,0);
-    m_iDataInBuffer = -1;
-    m_iFilePosition = 0;
-    m_iBufferStart = 0;
-
-    delete m_pExtractThread;
-    m_pExtractThread = new CFileRarExtractThread();
-    m_pExtractThread->Start(m_pArc,m_pCmd,m_pExtract,iHeaderSize);
-
-    return true;
-  }
-  catch (int rarErrCode)
-  {
-    CLog::Log(LOGERROR,"filerar failed in UnrarXLib while CFileRar::OpenInArchive with an UnrarXLib error code of %d",rarErrCode);
-    return false;
-  }
-  catch (...)
-  {
-    CLog::Log(LOGERROR,"filerar failed in UnrarXLib while CFileRar::OpenInArchive with an Unknown exception");
-    return false;
-  }
-#else
-  return false;
-#endif
-}
-
diff --git a/xbmc/filesystem/FileRar.h b/xbmc/filesystem/FileRar.h
deleted file mode 100644 (file)
index 83941dc..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-// FileRar.h: interface for the CFileRar class.
-
-#pragma once
-#ifndef FILERAR_H_
-#define FILERAR_H_
-
-#include "File.h"
-#include "threads/Thread.h"
-#include "threads/Event.h"
-
-class CmdExtract;
-class CommandData;
-class Archive;
-
-namespace XFILE
-{
-#ifdef HAS_FILESYSTEM_RAR
-  class CFileRarExtractThread : public CThread
-  {
-  public:
-    CFileRarExtractThread();
-    ~CFileRarExtractThread();
-
-    void Start(Archive* pArc, CommandData* pCmd, CmdExtract* pExtract, int iSize);
-
-    virtual void OnStartup();
-    virtual void OnExit();
-    virtual void Process();
-
-    CEvent hRunning;
-    CEvent hRestart;
-    CEvent hQuit;
-
-  protected:
-    Archive* m_pArc;
-    CommandData* m_pCmd;
-    CmdExtract* m_pExtract;
-    int m_iSize;
-  };
-#endif
-
-  class CFileRar : public IFile
-  {
-  public:
-    CFileRar();
-    CFileRar(bool bSeekable); // used for caching files
-    virtual ~CFileRar();
-    virtual int64_t       GetPosition();
-    virtual int64_t       GetLength();
-    virtual bool          Open(const CURL& url);
-    virtual bool          Exists(const CURL& url);
-    virtual int           Stat(const CURL& url, struct __stat64* buffer);
-    virtual unsigned int  Read(void* lpBuf, int64_t uiBufSize);
-    virtual int           Write(const void* lpBuf, int64_t uiBufSize);
-    virtual int64_t       Seek(int64_t iFilePosition, int iWhence=SEEK_SET);
-    virtual void          Close();
-    virtual void          Flush();
-
-    virtual bool          OpenForWrite(const CURL& url);
-    unsigned int          Write(void *lpBuf, int64_t uiBufSize);
-
-  protected:
-    CStdString m_strCacheDir;
-    CStdString m_strRarPath;
-    CStdString m_strPassword;
-    CStdString m_strPathInRar;
-    BYTE m_bFileOptions;
-    void Init();
-    void InitFromUrl(const CURL& url);
-    bool OpenInArchive();
-    void CleanUp();
-
-    int64_t m_iFilePosition;
-    int64_t m_iFileSize;
-    // rar stuff
-    bool m_bUseFile;
-    bool m_bOpen;
-    bool m_bSeekable;
-    CFile m_File; // for packed source
-#ifdef HAS_FILESYSTEM_RAR
-    Archive* m_pArc;
-    CommandData* m_pCmd;
-    CmdExtract* m_pExtract;
-    CFileRarExtractThread* m_pExtractThread;
-#endif
-    byte* m_szBuffer;
-    byte* m_szStartOfBuffer;
-    int64_t m_iDataInBuffer;
-    int64_t m_iBufferStart;
-  };
-
-}
-
-#endif  // FILERAR_H_
-
diff --git a/xbmc/filesystem/FileReaderFile.cpp b/xbmc/filesystem/FileReaderFile.cpp
new file mode 100644 (file)
index 0000000..2da9d57
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * XBMC Media Center
+ * Copyright (c) 2002 Frodo
+ * Portions Copyright (c) by the authors of ffmpeg and xvid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#include "FileReaderFile.h"
+#include "URL.h"
+
+using namespace XFILE;
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+//*********************************************************************************************
+CFileReaderFile::CFileReaderFile()
+{
+}
+
+//*********************************************************************************************
+CFileReaderFile::~CFileReaderFile()
+{
+  Close();
+}
+
+//*********************************************************************************************
+bool CFileReaderFile::Open(const CURL& url)
+{
+  CStdString strURL = url.Get();
+  strURL = strURL.Mid(13);
+  return m_reader.Open(strURL,READ_CACHED);
+}
+
+bool CFileReaderFile::Exists(const CURL& url)
+{
+  return CFile::Exists(url.Get().Mid(13));
+}
+
+int CFileReaderFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  return CFile::Stat(url.Get().Mid(13),buffer);
+}
+
+
+//*********************************************************************************************
+bool CFileReaderFile::OpenForWrite(const CURL& url, bool bOverWrite)
+{
+  return false;
+}
+
+//*********************************************************************************************
+unsigned int CFileReaderFile::Read(void *lpBuf, int64_t uiBufSize)
+{
+  return m_reader.Read(lpBuf,uiBufSize);
+}
+
+//*********************************************************************************************
+int CFileReaderFile::Write(const void *lpBuf, int64_t uiBufSize)
+{
+  return 0;
+}
+
+//*********************************************************************************************
+void CFileReaderFile::Close()
+{
+  m_reader.Close();
+}
+
+//*********************************************************************************************
+int64_t CFileReaderFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  return m_reader.Seek(iFilePosition,iWhence);
+}
+
+//*********************************************************************************************
+int64_t CFileReaderFile::GetLength()
+{
+  return m_reader.GetLength();
+}
+
+//*********************************************************************************************
+int64_t CFileReaderFile::GetPosition()
+{
+  return m_reader.GetPosition();
+}
+
+
diff --git a/xbmc/filesystem/FileReaderFile.h b/xbmc/filesystem/FileReaderFile.h
new file mode 100644 (file)
index 0000000..9ad8c9b
--- /dev/null
@@ -0,0 +1,48 @@
+#pragma once
+/*
+ * XBMC Media Center
+ * Copyright (c) 2002 Frodo
+ * Portions Copyright (c) by the authors of ffmpeg and xvid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "File.h"
+
+namespace XFILE
+{
+class CFileReaderFile : public IFile
+{
+public:
+  CFileReaderFile();
+  virtual ~CFileReaderFile();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int Write(const void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+
+  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
+  protected:
+  CFile m_reader;
+};
+
+}
+
+
diff --git a/xbmc/filesystem/FileSFTP.cpp b/xbmc/filesystem/FileSFTP.cpp
deleted file mode 100644 (file)
index 36c622e..0000000
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- *      Copyright (C) 2005-2010 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-
-#include "threads/SystemClock.h"
-#include "FileSFTP.h"
-#ifdef HAS_FILESYSTEM_SFTP
-#include "threads/SingleLock.h"
-#include "utils/log.h"
-#include "utils/TimeUtils.h"
-#include "utils/Variant.h"
-#include "Util.h"
-#include <fcntl.h>
-#include <sstream>
-
-#ifdef _WIN32
-#pragma comment(lib, "ssh.lib")
-#endif
-
-#ifdef _MSC_VER
-#define O_RDONLY _O_RDONLY
-#endif
-
-using namespace XFILE;
-using namespace std;
-
-
-static CStdString CorrectPath(const CStdString path)
-{
-  if(path == "~" || path.Left(2) == "~/")
-    return "./" + path.Mid(2);
-  else
-    return "/" + path;
-}
-
-CSFTPSession::CSFTPSession(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password)
-{
-  CLog::Log(LOGINFO, "SFTPSession: Creating new session on host '%s:%d' with user '%s'", host.c_str(), port, username.c_str());
-  CSingleLock lock(m_critSect);
-  if (!Connect(host, port, username, password))
-    Disconnect();
-
-  m_LastActive = XbmcThreads::SystemClockMillis();
-}
-
-CSFTPSession::~CSFTPSession()
-{
-  CSingleLock lock(m_critSect);
-  Disconnect();
-}
-
-sftp_file CSFTPSession::CreateFileHande(const CStdString &file)
-{
-  if (m_connected)
-  {
-    CSingleLock lock(m_critSect);
-    m_LastActive = XbmcThreads::SystemClockMillis();
-    sftp_file handle = sftp_open(m_sftp_session, CorrectPath(file).c_str(), O_RDONLY, 0);
-    if (handle)
-    {
-      sftp_file_set_blocking(handle);
-      return handle;
-    }
-    else
-      CLog::Log(LOGERROR, "SFTPSession: Was connected but couldn't create filehandle\n");
-  }
-  else
-    CLog::Log(LOGERROR, "SFTPSession: Not connected and can't create file handle");
-
-  return NULL;
-}
-
-void CSFTPSession::CloseFileHandle(sftp_file handle)
-{
-  CSingleLock lock(m_critSect);
-  sftp_close(handle);
-}
-
-bool CSFTPSession::GetDirectory(const CStdString &base, const CStdString &folder, CFileItemList &items)
-{
-  if (m_connected)
-  {
-    sftp_dir dir = NULL;
-
-    {
-      CSingleLock lock(m_critSect);
-      m_LastActive = XbmcThreads::SystemClockMillis();
-      dir = sftp_opendir(m_sftp_session, CorrectPath(folder).c_str());
-    }
-
-    if (dir)
-    {
-      bool read = true;
-      while (read)
-      {
-        sftp_attributes attributes = NULL;
-
-        {
-          CSingleLock lock(m_critSect);
-          read = sftp_dir_eof(dir) == 0;
-          attributes = sftp_readdir(m_sftp_session, dir);
-        }
-
-        if (attributes && (attributes->name == NULL || strcmp(attributes->name, "..") == 0 || strcmp(attributes->name, ".") == 0))
-        {
-          CSingleLock lock(m_critSect);
-          sftp_attributes_free(attributes);
-          continue;
-        }
-        
-        if (attributes)
-        {
-          CStdString itemName = attributes->name;
-          CStdString localPath = folder;
-          localPath.append(itemName);
-
-          if (attributes->type == SSH_FILEXFER_TYPE_SYMLINK)
-          {
-            CSingleLock lock(m_critSect);
-            sftp_attributes_free(attributes);
-            attributes = sftp_stat(m_sftp_session, CorrectPath(localPath).c_str());
-            if (attributes == NULL)
-              continue;
-          }
-
-          CFileItemPtr pItem(new CFileItem);
-          pItem->SetLabel(itemName);
-
-          if (itemName[0] == '.')
-            pItem->SetProperty("file:hidden", true);
-
-          if (attributes->flags & SSH_FILEXFER_ATTR_ACMODTIME)
-            pItem->m_dateTime = attributes->mtime;
-
-          if (attributes->type & SSH_FILEXFER_TYPE_DIRECTORY)
-          {
-            localPath.append("/");
-            pItem->m_bIsFolder = true;
-            pItem->m_dwSize = 0;
-          }
-          else
-          {
-            pItem->m_dwSize = attributes->size;
-          }
-
-          pItem->SetPath(base + localPath);
-          items.Add(pItem);
-
-          {
-            CSingleLock lock(m_critSect);
-            sftp_attributes_free(attributes);
-          }
-        }
-        else
-          read = false;
-      }
-
-      {
-        CSingleLock lock(m_critSect);
-        sftp_closedir(dir);
-      }
-
-      return true;
-    }
-  }
-  else
-    CLog::Log(LOGERROR, "SFTPSession: Not connected, can't list directory");
-
-  return false;
-}
-
-bool CSFTPSession::Exists(const char *path)
-{
-  bool exists = false;
-  CSingleLock lock(m_critSect);
-  if(m_connected)
-  {
-    sftp_attributes attributes = sftp_stat(m_sftp_session, CorrectPath(path).c_str());
-    exists = attributes != NULL;
-
-    if (attributes)
-      sftp_attributes_free(attributes);
-  }
-  return exists;
-}
-
-int CSFTPSession::Stat(const char *path, struct __stat64* buffer)
-{
-  CSingleLock lock(m_critSect);
-  if(m_connected)
-  {
-    m_LastActive = XbmcThreads::SystemClockMillis();
-    sftp_attributes attributes = sftp_stat(m_sftp_session, CorrectPath(path).c_str());
-
-    if (attributes)
-    {
-      memset(buffer, 0, sizeof(struct __stat64));
-      buffer->st_size = attributes->size;
-      buffer->st_mtime = attributes->mtime;
-      buffer->st_atime = attributes->atime;
-
-      sftp_attributes_free(attributes);
-      return 0;
-    }
-    else
-    {
-      CLog::Log(LOGERROR, "SFTPSession: STAT - Failed to get attributes");
-      return -1;
-    }
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "SFTPSession: STAT - Not connected");
-    return -1;
-  }
-}
-
-int CSFTPSession::Seek(sftp_file handle, uint64_t position)
-{
-  CSingleLock lock(m_critSect);
-  m_LastActive = XbmcThreads::SystemClockMillis();
-  return sftp_seek64(handle, position);
-}
-
-int CSFTPSession::Read(sftp_file handle, void *buffer, size_t length)
-{
-  CSingleLock lock(m_critSect);
-  m_LastActive = XbmcThreads::SystemClockMillis();
-  return sftp_read(handle, buffer, length);
-}
-
-int64_t CSFTPSession::GetPosition(sftp_file handle)
-{
-  CSingleLock lock(m_critSect);
-  m_LastActive = XbmcThreads::SystemClockMillis();
-  return sftp_tell64(handle);
-}
-
-bool CSFTPSession::IsIdle()
-{
-  return (XbmcThreads::SystemClockMillis() - m_LastActive) > 90000;
-}
-
-bool CSFTPSession::VerifyKnownHost(ssh_session session)
-{
-  switch (ssh_is_server_known(session))
-  {
-    case SSH_SERVER_KNOWN_OK:
-      return true;
-    case SSH_SERVER_KNOWN_CHANGED:
-      CLog::Log(LOGERROR, "SFTPSession: Server that was known has changed");
-      return false;
-    case SSH_SERVER_FOUND_OTHER:
-      CLog::Log(LOGERROR, "SFTPSession: The host key for this server was not found but an other type of key exists. An attacker might change the default server key to confuse your client into thinking the key does not exist");
-      return false;
-    case SSH_SERVER_FILE_NOT_FOUND:
-      CLog::Log(LOGINFO, "SFTPSession: Server file was not found, creating a new one");
-    case SSH_SERVER_NOT_KNOWN:
-      CLog::Log(LOGINFO, "SFTPSession: Server unkown, we trust it for now");
-      if (ssh_write_knownhost(session) < 0)
-      {
-        CLog::Log(LOGERROR, "CSFTPSession: Failed to save host '%s'", strerror(errno));
-        return false;
-      }
-
-      return true;
-    case SSH_SERVER_ERROR:
-      CLog::Log(LOGERROR, "SFTPSession: Failed to verify host '%s'", ssh_get_error(session));
-      return false;
-  }
-
-  return false;
-}
-
-bool CSFTPSession::Connect(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password)
-{
-  int timeout     = SFTP_TIMEOUT;
-  m_connected     = false;
-  m_session       = NULL;
-  m_sftp_session  = NULL;
-
-  m_session=ssh_new();
-  if (m_session == NULL)
-  {
-    CLog::Log(LOGERROR, "SFTPSession: Failed to initialize session");
-    return false;
-  }
-
-#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,4,0)
-  if (ssh_options_set(m_session, SSH_OPTIONS_USER, username.c_str()) < 0)
-  {
-    CLog::Log(LOGERROR, "SFTPSession: Failed to set username '%s' for session", username.c_str());
-    return false;
-  }
-
-  if (ssh_options_set(m_session, SSH_OPTIONS_HOST, host.c_str()) < 0)
-  {
-    CLog::Log(LOGERROR, "SFTPSession: Failed to set host '%s' for session", host.c_str());
-    return false;
-  }
-
-  if (ssh_options_set(m_session, SSH_OPTIONS_PORT, &port) < 0)
-  {
-    CLog::Log(LOGERROR, "SFTPSession: Failed to set port '%d' for session", port);
-    return false;
-  }
-
-  ssh_options_set(m_session, SSH_OPTIONS_LOG_VERBOSITY, 0);
-  ssh_options_set(m_session, SSH_OPTIONS_TIMEOUT, &timeout);  
-#else
-  SSH_OPTIONS* options = ssh_options_new();
-
-  if (ssh_options_set_username(options, username.c_str()) < 0)
-  {
-    CLog::Log(LOGERROR, "SFTPSession: Failed to set username '%s' for session", username.c_str());
-    return false;
-  }
-
-  if (ssh_options_set_host(options, host.c_str()) < 0)
-  {
-    CLog::Log(LOGERROR, "SFTPSession: Failed to set host '%s' for session", host.c_str());
-    return false;
-  }
-
-  if (ssh_options_set_port(options, port) < 0)
-  {
-    CLog::Log(LOGERROR, "SFTPSession: Failed to set port '%d' for session", port);
-    return false;
-  }
-  
-  ssh_options_set_timeout(options, timeout, 0);
-
-  ssh_options_set_log_verbosity(options, 0);
-
-  ssh_set_options(m_session, options);
-#endif
-
-  if(ssh_connect(m_session))
-  {
-    CLog::Log(LOGERROR, "SFTPSession: Failed to connect '%s'", ssh_get_error(m_session));
-    return false;
-  }
-
-  if (!VerifyKnownHost(m_session))
-    return false;
-
-
-  int noAuth = SSH_AUTH_DENIED;
-  if ((noAuth = ssh_userauth_none(m_session, NULL)) == SSH_AUTH_ERROR)
-  {
-    CLog::Log(LOGERROR, "SFTPSession: Failed to authenticate via guest '%s'", ssh_get_error(m_session));
-    return false;
-  }
-
-  int method = ssh_auth_list(m_session);
-
-  // Try to authenticate with public key first
-  int publicKeyAuth = SSH_AUTH_DENIED;
-  if (method & SSH_AUTH_METHOD_PUBLICKEY && (publicKeyAuth = ssh_userauth_autopubkey(m_session, NULL)) == SSH_AUTH_ERROR)
-  {
-    CLog::Log(LOGERROR, "SFTPSession: Failed to authenticate via publickey '%s'", ssh_get_error(m_session));
-    return false;
-  }
-
-  // Try to authenticate with password
-  int passwordAuth = SSH_AUTH_DENIED;
-  if (method & SSH_AUTH_METHOD_PASSWORD && publicKeyAuth != SSH_AUTH_SUCCESS && (passwordAuth = ssh_userauth_password(m_session, username.c_str(), password.c_str())) == SSH_AUTH_ERROR)
-  {
-    CLog::Log(LOGERROR, "SFTPSession: Failed to authenticate via password '%s'", ssh_get_error(m_session));
-    return false;
-  }
-
-  if (noAuth == SSH_AUTH_SUCCESS || publicKeyAuth == SSH_AUTH_SUCCESS || passwordAuth == SSH_AUTH_SUCCESS)
-  {
-    m_sftp_session = sftp_new(m_session);
-
-    if (m_sftp_session == NULL)
-    {
-      CLog::Log(LOGERROR, "SFTPSession: Failed to initialize channel '%s'", ssh_get_error(m_session));
-      return false;
-    }
-
-    if (sftp_init(m_sftp_session))
-    {
-      CLog::Log(LOGERROR, "SFTPSession: Failed to initialize sftp '%s'", ssh_get_error(m_session));
-      return false;
-    }
-
-    m_connected = true;
-  }
-
-  return m_connected;
-}
-
-void CSFTPSession::Disconnect()
-{
-  if (m_sftp_session)
-    sftp_free(m_sftp_session);
-
-  if (m_session)
-    ssh_disconnect(m_session);
-
-  m_sftp_session = NULL;
-  m_session = NULL;
-}
-
-CCriticalSection CSFTPSessionManager::m_critSect;
-map<CStdString, CSFTPSessionPtr> CSFTPSessionManager::sessions;
-
-CSFTPSessionPtr CSFTPSessionManager::CreateSession(const CURL &url)
-{
-  string username = url.GetUserName().c_str();
-  string password = url.GetPassWord().c_str();
-  string hostname = url.GetHostName().c_str();
-  unsigned int port = url.HasPort() ? url.GetPort() : 22;
-
-  return CSFTPSessionManager::CreateSession(hostname, port, username, password);
-}
-
-CSFTPSessionPtr CSFTPSessionManager::CreateSession(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password)
-{
-  // Convert port number to string
-  stringstream itoa;
-  itoa << port;
-  CStdString portstr = itoa.str();
-
-  CSingleLock lock(m_critSect);
-  CStdString key = username + ":" + password + "@" + host + ":" + portstr;
-  CSFTPSessionPtr ptr = sessions[key];
-  if (ptr == NULL)
-  {
-    ptr = CSFTPSessionPtr(new CSFTPSession(host, port, username, password));
-    sessions[key] = ptr;
-  }
-
-  return ptr;
-}
-
-void CSFTPSessionManager::ClearOutIdleSessions()
-{
-  CSingleLock lock(m_critSect);
-  for(map<CStdString, CSFTPSessionPtr>::iterator iter = sessions.begin(); iter != sessions.end();)
-  {
-    if (iter->second->IsIdle())
-      sessions.erase(iter++);
-    else
-      iter++;
-  }
-}
-
-void CSFTPSessionManager::DisconnectAllSessions()
-{
-  CSingleLock lock(m_critSect);
-  sessions.clear();
-}
-
-CFileSFTP::CFileSFTP()
-{
-  m_sftp_handle = NULL;
-}
-
-CFileSFTP::~CFileSFTP()
-{
-  Close();
-}
-
-bool CFileSFTP::Open(const CURL& url)
-{
-  m_session = CSFTPSessionManager::CreateSession(url);
-  if (m_session)
-  {
-    m_file = url.GetFileName().c_str();
-    m_sftp_handle = m_session->CreateFileHande(m_file);
-
-    return (m_sftp_handle != NULL);
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "SFTPFile: Failed to allocate session");
-    return false;
-  }
-}
-
-void CFileSFTP::Close()
-{
-  if (m_session && m_sftp_handle)
-  {
-    m_session->CloseFileHandle(m_sftp_handle);
-    m_sftp_handle = NULL;
-    m_session = CSFTPSessionPtr();
-  }
-}
-
-int64_t CFileSFTP::Seek(int64_t iFilePosition, int iWhence)
-{
-  if (m_session && m_sftp_handle)
-  {
-    uint64_t position = 0;
-    if (iWhence == SEEK_SET)
-      position = iFilePosition;
-    else if (iWhence == SEEK_CUR)
-      position = GetPosition() + iFilePosition;
-    else if (iWhence == SEEK_END)
-      position = GetLength() + iFilePosition;
-
-    if (m_session->Seek(m_sftp_handle, position) == 0)
-      return GetPosition();
-    else
-      return -1;
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "SFTPFile: Can't seek without a filehandle");
-    return -1;
-  }
-}
-
-unsigned int CFileSFTP::Read(void* lpBuf, int64_t uiBufSize)
-{
-  if (m_session && m_sftp_handle)
-  {
-    int rc = m_session->Read(m_sftp_handle, lpBuf, (size_t)uiBufSize);
-
-    if (rc >= 0)
-      return rc;
-    else
-      CLog::Log(LOGERROR, "SFTPFile: Failed to read %i", rc);
-  }
-  else
-    CLog::Log(LOGERROR, "SFTPFile: Can't read without a filehandle");
-
-  return 0;
-}
-
-bool CFileSFTP::Exists(const CURL& url)
-{
-  CSFTPSessionPtr session = CSFTPSessionManager::CreateSession(url);
-  if (session)
-    return session->Exists(url.GetFileName().c_str());
-  else
-  {
-    CLog::Log(LOGERROR, "SFTPFile: Failed to create session to check exists");
-    return false;
-  }
-}
-
-int CFileSFTP::Stat(const CURL& url, struct __stat64* buffer)
-{
-  CSFTPSessionPtr session = CSFTPSessionManager::CreateSession(url);
-  if (session)
-    return session->Stat(url.GetFileName().c_str(), buffer);
-  else
-  {
-    CLog::Log(LOGERROR, "SFTPFile: Failed to create session to stat");
-    return -1;
-  }
-}
-
-int CFileSFTP::Stat(struct __stat64* buffer)
-{
-  if (m_session)
-    return m_session->Stat(m_file.c_str(), buffer);
-
-  CLog::Log(LOGERROR, "SFTPFile: Can't stat without a session");
-  return -1;
-}
-
-int64_t CFileSFTP::GetLength()
-{
-  struct __stat64 buffer;
-  if (Stat(&buffer) != 0)
-    return 0;
-  else
-  {
-    int64_t length = buffer.st_size;
-    return length;
-  }
-}
-
-int64_t CFileSFTP::GetPosition()
-{
-  if (m_session && m_sftp_handle)
-    return m_session->GetPosition(m_sftp_handle);
-
-  CLog::Log(LOGERROR, "SFTPFile: Can't get position without a filehandle");
-  return 0;
-}
-
-int CFileSFTP::IoControl(EIoControl request, void* param)
-{
-  if(request == IOCTRL_SEEK_POSSIBLE)
-    return 1;
-
-  return -1;
-}
-
-#endif
diff --git a/xbmc/filesystem/FileSFTP.h b/xbmc/filesystem/FileSFTP.h
deleted file mode 100644 (file)
index 1ff25ba..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2010 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-
-#include "system.h"
-#ifdef HAS_FILESYSTEM_SFTP
-#include "IFile.h"
-#include "URL.h"
-#include "FileItem.h"
-#include "threads/CriticalSection.h"
-
-#include <libssh/libssh.h>
-#include <libssh/sftp.h>
-#include <string>
-#include <map>
-#include <boost/shared_ptr.hpp>
-
-#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0,3,2)
-#define ssh_session SSH_SESSION
-#endif
-
-#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0,4,0)
-#define sftp_file SFTP_FILE*
-#define sftp_session SFTP_SESSION*
-#define sftp_attributes SFTP_ATTRIBUTES*
-#define sftp_dir SFTP_DIR*
-#define ssh_session ssh_session*
-#endif
-
-//five secs timeout for SFTP
-#define SFTP_TIMEOUT 5
-
-class CSFTPSession
-{
-public:
-  CSFTPSession(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password);
-  virtual ~CSFTPSession();
-
-  sftp_file CreateFileHande(const CStdString &file);
-  void CloseFileHandle(sftp_file handle);
-  bool GetDirectory(const CStdString &base, const CStdString &folder, CFileItemList &items);
-  bool Exists(const char *path);
-  int Stat(const char *path, struct __stat64* buffer);
-  int Seek(sftp_file handle, uint64_t position);
-  int Read(sftp_file handle, void *buffer, size_t length);
-  int64_t GetPosition(sftp_file handle);
-  bool IsIdle();
-private:
-  bool VerifyKnownHost(ssh_session session);
-  bool Connect(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password);
-  void Disconnect();
-  CCriticalSection m_critSect;
-
-  bool m_connected;
-  ssh_session  m_session;
-  sftp_session m_sftp_session;
-  int m_LastActive;
-};
-
-typedef boost::shared_ptr<CSFTPSession> CSFTPSessionPtr;
-
-class CSFTPSessionManager
-{
-public:
-  static CSFTPSessionPtr CreateSession(const CURL &url);
-  static CSFTPSessionPtr CreateSession(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password);
-  static void ClearOutIdleSessions();
-  static void DisconnectAllSessions();
-private:
-  static CCriticalSection m_critSect;
-  static std::map<CStdString, CSFTPSessionPtr> sessions;
-};
-
-namespace XFILE
-{
-  class CFileSFTP : public IFile
-  {
-  public:
-    CFileSFTP();
-    virtual ~CFileSFTP();
-    virtual void Close();
-    virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-    virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-    virtual bool Open(const CURL& url);
-    virtual bool Exists(const CURL& url);
-    virtual int Stat(const CURL& url, struct __stat64* buffer);
-    virtual int Stat(struct __stat64* buffer);
-    virtual int64_t GetLength();
-    virtual int64_t GetPosition();
-    virtual int     GetChunkSize() {return 1;};
-    virtual int     IoControl(EIoControl request, void* param);
-  private:
-    CStdString m_file;
-    CSFTPSessionPtr m_session;
-    sftp_file m_sftp_handle;
-  };
-}
-#endif
diff --git a/xbmc/filesystem/FileShoutcast.cpp b/xbmc/filesystem/FileShoutcast.cpp
deleted file mode 100644 (file)
index 79fa6ac..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-
-// FileShoutcast.cpp: implementation of the CFileShoutcast class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#include "threads/SystemClock.h"
-#include "system.h"
-#include "Application.h"
-#include "FileShoutcast.h"
-#include "settings/GUISettings.h"
-#include "guilib/GUIWindowManager.h"
-#include "URL.h"
-#include "utils/RegExp.h"
-#include "utils/HTMLUtil.h"
-#include "utils/CharsetConverter.h"
-#include "utils/TimeUtils.h"
-#include "GUIInfoManager.h"
-#include "utils/log.h"
-
-using namespace XFILE;
-using namespace MUSIC_INFO;
-
-CFileShoutcast::CFileShoutcast()
-{
-  m_lastTime = XbmcThreads::SystemClockMillis();
-  m_discarded = 0;
-  m_currint = 0;
-  m_buffer = NULL;
-}
-
-CFileShoutcast::~CFileShoutcast()
-{
-  Close();
-}
-
-int64_t CFileShoutcast::GetPosition()
-{
-  return m_file.GetPosition()-m_discarded;
-}
-
-int64_t CFileShoutcast::GetLength()
-{
-  return 0;
-}
-
-bool CFileShoutcast::Open(const CURL& url)
-{
-  CURL url2(url);
-  url2.SetProtocolOptions("noshout=true&Icy-MetaData=1");
-  url2.SetProtocol("http");
-
-  bool result=false;
-  if ((result=m_file.Open(url2.Get())))
-  {
-    m_tag.SetTitle(m_file.GetHttpHeader().GetValue("icy-name"));
-    if (m_tag.GetTitle().IsEmpty())
-      m_tag.SetTitle(m_file.GetHttpHeader().GetValue("ice-name")); // icecast
-    m_tag.SetGenre(m_file.GetHttpHeader().GetValue("icy-genre"));
-    if (m_tag.GetGenre().IsEmpty())
-      m_tag.SetGenre(m_file.GetHttpHeader().GetValue("ice-genre")); // icecast
-    m_tag.SetLoaded(true);
-    g_infoManager.SetCurrentSongTag(m_tag);
-  }
-  m_metaint = atoi(m_file.GetHttpHeader().GetValue("icy-metaint").c_str());
-  if (!m_metaint)
-    m_metaint = -1;
-  m_buffer = new char[16*255];
-
-  return result;
-}
-
-unsigned int CFileShoutcast::Read(void* lpBuf, int64_t uiBufSize)
-{
-  if (m_currint >= m_metaint && m_metaint > 0)
-  {
-    unsigned char header;
-    m_file.Read(&header,1);
-    ReadTruncated(m_buffer, header*16);
-    ExtractTagInfo(m_buffer);
-    m_discarded += header*16+1;
-    m_currint = 0;
-  }
-  if (XbmcThreads::SystemClockMillis() - m_lastTime > 500)
-  {
-    m_lastTime = XbmcThreads::SystemClockMillis();
-    g_infoManager.SetCurrentSongTag(m_tag);
-  }
-
-  unsigned int toRead;
-  if (m_metaint > 0)
-    toRead = std::min((unsigned int)uiBufSize,(unsigned int)m_metaint-m_currint);
-  else
-    toRead = std::min((unsigned int)uiBufSize,(unsigned int)16*255);
-  toRead = m_file.Read(lpBuf,toRead);
-  m_currint += toRead;
-  return toRead;
-}
-
-int64_t CFileShoutcast::Seek(int64_t iFilePosition, int iWhence)
-{
-  return -1;
-}
-
-void CFileShoutcast::Close()
-{
-  delete[] m_buffer;
-  m_file.Close();
-}
-
-void CFileShoutcast::ExtractTagInfo(const char* buf)
-{
-  CStdString strBuffer = buf;
-  g_charsetConverter.unknownToUTF8(strBuffer);
-
-  CStdStringW wBuffer, wConverted;
-  g_charsetConverter.utf8ToW(strBuffer, wBuffer, false);
-  HTML::CHTMLUtil::ConvertHTMLToW(wBuffer, wConverted);
-  g_charsetConverter.wToUTF8(wConverted, strBuffer);
-
-  CRegExp reTitle(true);
-  reTitle.RegComp("StreamTitle=\'(.*?)\';");
-
-  if (reTitle.RegFind(strBuffer.c_str()) != -1)
-    m_tag.SetTitle(reTitle.GetReplaceString("\\1"));
-}
-
-void CFileShoutcast::ReadTruncated(char* buf2, int size)
-{
-  char* buf = buf2;
-  while (size > 0)
-  {
-    int read = m_file.Read(buf,size);
-    size -= read;
-    buf += read;
-  }
-}
-
diff --git a/xbmc/filesystem/FileShoutcast.h b/xbmc/filesystem/FileShoutcast.h
deleted file mode 100644 (file)
index bdd93ec..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-// FileShoutcast.h: interface for the CFileShoutcast class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-#include "IFile.h"
-#include "FileCurl.h"
-#include "utils/StdString.h"
-#include "music/tags/MusicInfoTag.h"
-
-namespace XFILE
-{
-class CFileShoutcast : public IFile
-{
-public:
-  CFileShoutcast();
-  virtual ~CFileShoutcast();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url) { return true;};
-  virtual int Stat(const CURL& url, struct __stat64* buffer) { errno = ENOENT; return -1; };
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-protected:
-  void ExtractTagInfo(const char* buf);
-  void ReadTruncated(char* buf2, int size);
-
-  unsigned int m_lastTime;
-  CFileCurl m_file;
-  int m_metaint;
-  int m_discarded; // data used for tags
-  int m_currint;
-  char* m_buffer; // buffer used for tags
-  MUSIC_INFO::CMusicInfoTag m_tag;
-};
-}
-
diff --git a/xbmc/filesystem/FileSmb.cpp b/xbmc/filesystem/FileSmb.cpp
deleted file mode 100644 (file)
index f1d7416..0000000
+++ /dev/null
@@ -1,777 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-// FileSmb.cpp: implementation of the CFileSMB class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#include "system.h"
-#include "FileSmb.h"
-#include "PasswordManager.h"
-#include "SMBDirectory.h"
-#include "Util.h"
-#include <libsmbclient.h>
-#include "settings/AdvancedSettings.h"
-#include "settings/GUISettings.h"
-#include "threads/SingleLock.h"
-#include "utils/log.h"
-#include "utils/TimeUtils.h"
-
-using namespace XFILE;
-
-void xb_smbc_log(const char* msg)
-{
-  CLog::Log(LOGINFO, "%s%s", "smb: ", msg);
-}
-
-void xb_smbc_auth(const char *srv, const char *shr, char *wg, int wglen,
-                  char *un, int unlen, char *pw, int pwlen)
-{
-  return ;
-}
-
-smbc_get_cached_srv_fn orig_cache;
-
-SMBCSRV* xb_smbc_cache(SMBCCTX* c, const char* server, const char* share, const char* workgroup, const char* username)
-{
-  return orig_cache(c, server, share, workgroup, username);
-}
-
-CSMB::CSMB()
-{
-#ifdef TARGET_POSIX
-  m_IdleTimeout = 0;
-#endif
-  m_context = NULL;
-  smbc_init(xb_smbc_auth, 0);
-}
-
-CSMB::~CSMB()
-{
-  Deinit();
-}
-
-void CSMB::Deinit()
-{
-  CSingleLock lock(*this);
-
-  /* samba goes loco if deinited while it has some files opened */
-  if (m_context)
-  {
-    try
-    {
-      smbc_set_context(NULL);
-      smbc_free_context(m_context, 1);
-    }
-#ifdef TARGET_WINDOWS
-    catch(win32_exception e)
-    {
-      e.writelog(__FUNCTION__);
-    }
-    m_IdleTimeout = 180;
-#else
-    catch(...)
-    {
-      CLog::Log(LOGERROR,"exception on CSMB::Deinit. errno: %d", errno);
-    }
-#endif
-    m_context = NULL;
-  }
-}
-
-void CSMB::Init()
-{
-  CSingleLock lock(*this);
-  if (!m_context)
-  {
-#ifdef TARGET_POSIX
-    // Create ~/.smb/smb.conf. This file is used by libsmbclient.
-    // http://us1.samba.org/samba/docs/man/manpages-3/libsmbclient.7.html
-    // http://us1.samba.org/samba/docs/man/manpages-3/smb.conf.5.html
-    char smb_conf[MAX_PATH];
-    sprintf(smb_conf, "%s/.smb", getenv("HOME"));
-    mkdir(smb_conf, 0755);
-    sprintf(smb_conf, "%s/.smb/smb.conf", getenv("HOME"));
-    FILE* f = fopen(smb_conf, "w");
-    if (f != NULL)
-    {
-      fprintf(f, "[global]\n");
-
-      // make sure we're not acting like a server
-      fprintf(f, "\tpreferred master = no\n");
-      fprintf(f, "\tlocal master = no\n");
-      fprintf(f, "\tdomain master = no\n");
-
-      // use the weaker LANMAN password hash in order to be compatible with older servers
-      fprintf(f, "\tclient lanman auth = yes\n");
-      fprintf(f, "\tlanman auth = yes\n");
-
-      fprintf(f, "\tsocket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");      
-      fprintf(f, "\tlock directory = %s/.smb/\n", getenv("HOME"));
-
-      // set wins server if there's one. name resolve order defaults to 'lmhosts host wins bcast'.
-      // if no WINS server has been specified the wins method will be ignored.
-      if ( g_guiSettings.GetString("smb.winsserver").length() > 0 && !g_guiSettings.GetString("smb.winsserver").Equals("0.0.0.0") )
-      {
-        fprintf(f, "\twins server = %s\n", g_guiSettings.GetString("smb.winsserver").c_str());
-        fprintf(f, "\tname resolve order = bcast wins host\n");
-      }
-      else
-        fprintf(f, "\tname resolve order = bcast host\n");
-
-      // use user-configured charset. if no charset is specified,
-      // samba tries to use charset 850 but falls back to ASCII in case it is not available
-      if (g_advancedSettings.m_sambadoscodepage.length() > 0)
-        fprintf(f, "\tdos charset = %s\n", g_advancedSettings.m_sambadoscodepage.c_str());
-
-      // if no workgroup string is specified, samba will use the default value 'WORKGROUP'
-      if ( g_guiSettings.GetString("smb.workgroup").length() > 0 )
-        fprintf(f, "\tworkgroup = %s\n", g_guiSettings.GetString("smb.workgroup").c_str());
-      fclose(f);
-    }
-#endif
-
-#ifdef TARGET_WINDOWS
-    // set the log function
-    set_log_callback(xb_smbc_log);
-#endif
-
-    // setup our context
-    m_context = smbc_new_context();
-#ifdef DEPRECATED_SMBC_INTERFACE
-    smbc_setDebug(m_context, g_advancedSettings.m_logLevel == LOG_LEVEL_DEBUG_SAMBA ? 10 : 0);
-    smbc_setFunctionAuthData(m_context, xb_smbc_auth);
-    orig_cache = smbc_getFunctionGetCachedServer(m_context);
-    smbc_setFunctionGetCachedServer(m_context, xb_smbc_cache);
-    smbc_setOptionOneSharePerServer(m_context, false);
-    smbc_setOptionBrowseMaxLmbCount(m_context, 0);
-    smbc_setTimeout(m_context, g_advancedSettings.m_sambaclienttimeout * 1000);
-#else
-    m_context->debug = g_advancedSettings.m_logLevel == LOG_LEVEL_DEBUG_SAMBA ? 10 : 0;
-    m_context->callbacks.auth_fn = xb_smbc_auth;
-    orig_cache = m_context->callbacks.get_cached_srv_fn;
-    m_context->callbacks.get_cached_srv_fn = xb_smbc_cache;
-    m_context->options.one_share_per_server = false;
-    m_context->options.browse_max_lmb_count = 0;
-    m_context->timeout = g_advancedSettings.m_sambaclienttimeout * 1000;
-#endif
-
-    // initialize samba and do some hacking into the settings
-    if (smbc_init_context(m_context))
-    {
-      /* setup old interface to use this context */
-      smbc_set_context(m_context);
-
-#ifdef TARGET_WINDOWS
-      // if a wins-server is set, we have to change name resolve order to
-      if ( g_guiSettings.GetString("smb.winsserver").length() > 0 && !g_guiSettings.GetString("smb.winsserver").Equals("0.0.0.0") )
-      {
-        lp_do_parameter( -1, "wins server", g_guiSettings.GetString("smb.winsserver").c_str());
-        lp_do_parameter( -1, "name resolve order", "bcast wins host");
-      }
-      else
-        lp_do_parameter( -1, "name resolve order", "bcast host");
-
-      if (g_advancedSettings.m_sambadoscodepage.length() > 0)
-        lp_do_parameter( -1, "dos charset", g_advancedSettings.m_sambadoscodepage.c_str());
-      else
-        lp_do_parameter( -1, "dos charset", "CP850");
-#endif
-    }
-    else
-    {
-      smbc_free_context(m_context, 1);
-      m_context = NULL;
-    }
-  }
-#ifdef TARGET_POSIX
-  m_IdleTimeout = 180;
-#endif
-}
-
-void CSMB::Purge()
-{
-#ifdef TARGET_WINDOWS
-  CSingleLock lock(*this);
-  smbc_purge();
-#endif
-}
-
-/*
- * For each new connection samba creates a new session
- * But this is not what we want, we just want to have one session at the time
- * This means that we have to call smbc_purge() if samba created a new session
- * Samba will create a new session when:
- * - connecting to another server
- * - connecting to another share on the same server (share, not a different folder!)
- *
- * We try to avoid lot's of purge commands because it slow samba down.
- */
-void CSMB::PurgeEx(const CURL& url)
-{
-  CSingleLock lock(*this);
-  CStdString strShare = url.GetFileName().substr(0, url.GetFileName().Find('/'));
-
-#ifdef TARGET_WINDOWS
-  if (m_strLastShare.length() > 0 && (m_strLastShare != strShare || m_strLastHost != url.GetHostName()))
-    smbc_purge();
-#endif
-
-  m_strLastShare = strShare;
-  m_strLastHost = url.GetHostName();
-}
-
-CStdString CSMB::URLEncode(const CURL &url)
-{
-  /* due to smb wanting encoded urls we have to build it manually */
-
-  CStdString flat = "smb://";
-
-  if(url.GetDomain().length() > 0)
-  {
-    flat += URLEncode(url.GetDomain());
-    flat += ";";
-  }
-
-  /* samba messes up of password is set but no username is set. don't know why yet */
-  /* probably the url parser that goes crazy */
-  if(url.GetUserName().length() > 0 /* || url.GetPassWord().length() > 0 */)
-  {
-    flat += URLEncode(url.GetUserName());
-    flat += ":";
-    flat += URLEncode(url.GetPassWord());
-    flat += "@";
-  }
-  flat += URLEncode(url.GetHostName());
-
-  /* okey sadly since a slash is an invalid name we have to tokenize */
-  std::vector<CStdString> parts;
-  std::vector<CStdString>::iterator it;
-  CUtil::Tokenize(url.GetFileName(), parts, "/");
-  for( it = parts.begin(); it != parts.end(); it++ )
-  {
-    flat += "/";
-    flat += URLEncode((*it));
-  }
-
-  /* okey options should go here, thou current samba doesn't support any */
-
-  return flat;
-}
-
-CStdString CSMB::URLEncode(const CStdString &value)
-{
-  CStdString encoded(value);
-  CURL::Encode(encoded);
-  return encoded;
-}
-
-#ifdef TARGET_WINDOWS
-DWORD CSMB::ConvertUnixToNT(int error)
-{
-  DWORD nt_error;
-  if (error == ENODEV || error == ENETUNREACH || error == WSAETIMEDOUT) nt_error = NT_STATUS_INVALID_COMPUTER_NAME;
-  else if(error == WSAECONNREFUSED || error == WSAECONNABORTED) nt_error = NT_STATUS_CONNECTION_REFUSED;
-  else nt_error = map_nt_error_from_unix(error);
-
-  return nt_error;
-}
-#endif
-
-#ifdef TARGET_POSIX
-/* This is called from CApplication::ProcessSlow() and is used to tell if smbclient have been idle for too long */
-void CSMB::CheckIfIdle()
-{
-/* We check if there are open connections. This is done without a lock to not halt the mainthread. It should be thread safe as
-   worst case scenario is that m_OpenConnections could read 0 and then changed to 1 if this happens it will enter the if wich will lead to another check, wich is locked.  */
-  if (m_OpenConnections == 0)
-  { /* I've set the the maxiumum IDLE time to be 1 min and 30 sec. */
-    CSingleLock lock(*this);
-    if (m_OpenConnections == 0 /* check again - when locked */ && m_context != NULL)
-    {
-      if (m_IdleTimeout > 0)
-         {
-        m_IdleTimeout--;
-      }
-         else
-         {
-        CLog::Log(LOGNOTICE, "Samba is idle. Closing the remaining connections");
-        smb.Deinit();
-      }
-    }
-  }
-}
-
-void CSMB::SetActivityTime()
-{
-  /* Since we get called every 500ms from ProcessSlow we limit the tick count to 180 */
-  /* That means we have 2 ticks per second which equals 180/2 == 90 seconds */
-  m_IdleTimeout = 180;
-}
-
-/* The following two function is used to keep track on how many Opened files/directories there are.
-   This makes the idle timer not count if a movie is paused for example */
-void CSMB::AddActiveConnection()
-{
-  CSingleLock lock(*this);
-  m_OpenConnections++;
-}
-void CSMB::AddIdleConnection()
-{
-  CSingleLock lock(*this);
-  m_OpenConnections--;
-  /* If we close a file we reset the idle timer so that we don't have any wierd behaviours if a user
-     leaves the movie paused for a long while and then press stop */
-  m_IdleTimeout = 180;
-}
-#endif
-
-CSMB smb;
-
-CFileSMB::CFileSMB()
-{
-  smb.Init();
-  m_fd = -1;
-#ifdef TARGET_POSIX
-  smb.AddActiveConnection();
-#endif
-}
-
-CFileSMB::~CFileSMB()
-{
-  Close();
-#ifdef TARGET_POSIX
-  smb.AddIdleConnection();
-#endif
-}
-
-int64_t CFileSMB::GetPosition()
-{
-  if (m_fd == -1) return 0;
-  smb.Init();
-  CSingleLock lock(smb);
-  int64_t pos = smbc_lseek(m_fd, 0, SEEK_CUR);
-  if ( pos < 0 )
-    return 0;
-  return pos;
-}
-
-int64_t CFileSMB::GetLength()
-{
-  if (m_fd == -1) return 0;
-  return m_fileSize;
-}
-
-bool CFileSMB::Open(const CURL& url)
-{
-  Close();
-
-  // we can't open files like smb://file.f or smb://server/file.f
-  // if a file matches the if below return false, it can't exist on a samba share.
-  if (!IsValidFile(url.GetFileName()))
-  {
-      CLog::Log(LOGNOTICE,"FileSmb->Open: Bad URL : '%s'",url.GetFileName().c_str());
-      return false;
-  }
-  m_url = url;
-
-  // opening a file to another computer share will create a new session
-  // when opening smb://server xbms will try to find folder.jpg in all shares
-  // listed, which will create lot's of open sessions.
-
-  CStdString strFileName;
-  m_fd = OpenFile(url, strFileName);
-
-  CLog::Log(LOGDEBUG,"CFileSMB::Open - opened %s, fd=%d",url.GetFileName().c_str(), m_fd);
-  if (m_fd == -1)
-  {
-    // write error to logfile
-#ifdef TARGET_WINDOWS
-    int nt_error = smb.ConvertUnixToNT(errno);
-    CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' nt_err : '%x' error : '%s'", strFileName.c_str(), errno, nt_error, get_friendly_nt_error_msg(nt_error));
-#else
-    CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strFileName.c_str(), errno, strerror(errno));
-#endif
-    return false;
-  }
-
-  CSingleLock lock(smb);
-#ifdef TARGET_WINDOWS
-  struct __stat64 tmpBuffer = {0};
-#else
-  struct stat tmpBuffer;
-#endif
-  if (smbc_stat(strFileName, &tmpBuffer) < 0)
-  {
-    smbc_close(m_fd);
-    m_fd = -1;
-    return false;
-  }
-
-  m_fileSize = tmpBuffer.st_size;
-
-  int64_t ret = smbc_lseek(m_fd, 0, SEEK_SET);
-  if ( ret < 0 )
-  {
-    smbc_close(m_fd);
-    m_fd = -1;
-    return false;
-  }
-  // We've successfully opened the file!
-  return true;
-}
-
-
-/// \brief Checks authentication against SAMBA share. Reads password cache created in CSMBDirectory::OpenDir().
-/// \param strAuth The SMB style path
-/// \return SMB file descriptor
-/*
-int CFileSMB::OpenFile(CStdString& strAuth)
-{
-  int fd = -1;
-
-  CStdString strPath = g_passwordManager.GetSMBAuthFilename(strAuth);
-
-  fd = smbc_open(strPath.c_str(), O_RDONLY, 0);
-  // TODO: Run a loop here that prompts for our username/password as appropriate?
-  // We have the ability to run a file (eg from a button action) without browsing to
-  // the directory first.  In the case of a password protected share that we do
-  // not have the authentication information for, the above smbc_open() will have
-  // returned negative, and the file will not be opened.  While this is not a particular
-  // likely scenario, we might want to implement prompting for the password in this case.
-  // The code from SMBDirectory can be used for this.
-  if(fd >= 0)
-    strAuth = strPath;
-
-  return fd;
-}
-*/
-
-int CFileSMB::OpenFile(const CURL &url, CStdString& strAuth)
-{
-  int fd = -1;
-  smb.Init();
-
-  strAuth = GetAuthenticatedPath(url);
-  CStdString strPath = strAuth;
-
-  {
-    CSingleLock lock(smb);
-    fd = smbc_open(strPath.c_str(), O_RDONLY, 0);
-  }
-
-  // file open failed, try to open the directory to force authentication
-#ifdef TARGET_WINDOWS
-  if (fd < 0 && smb.ConvertUnixToNT(errno) == NT_STATUS_ACCESS_DENIED)
-#else
-  if (fd < 0 && errno == EACCES)
-#endif
-  {
-    CURL urlshare(url);
-
-    /* just replace the filename with the sharename */
-    urlshare.SetFileName(url.GetShareName());
-
-    CSMBDirectory smbDir;
-    // TODO: Currently we always allow prompting on files.  This may need to
-    // change in the future as background scanners are more prolific.
-    smbDir.SetAllowPrompting(true);
-    fd = smbDir.Open(urlshare);
-
-    // directory open worked, try opening the file again
-    if (fd >= 0)
-    {
-      CSingleLock lock(smb);
-      // close current directory filehandle
-      // dont need to purge since its the same server and share
-      smbc_closedir(fd);
-
-      // set up new filehandle (as CFileSMB::Open does)
-      strPath = GetAuthenticatedPath(url);
-
-      fd = smbc_open(strPath.c_str(), O_RDONLY, 0);
-    }
-  }
-
-  if (fd >= 0)
-    strAuth = strPath;
-
-  return fd;
-}
-
-bool CFileSMB::Exists(const CURL& url)
-{
-  // we can't open files like smb://file.f or smb://server/file.f
-  // if a file matches the if below return false, it can't exist on a samba share.
-  if (!IsValidFile(url.GetFileName())) return false;
-
-  smb.Init();
-  CStdString strFileName = GetAuthenticatedPath(url);
-
-#ifdef TARGET_WINDOWS
-  struct __stat64 info;
-#else
-  struct stat info;
-#endif
-
-  CSingleLock lock(smb);
-  int iResult = smbc_stat(strFileName, &info);
-
-  if (iResult < 0) return false;
-  return true;
-}
-
-int CFileSMB::Stat(struct __stat64* buffer)
-{
-  if (m_fd == -1)
-    return -1;
-
-#ifdef TARGET_WINDOWS
-  struct __stat64 tmpBuffer = {0};
-#else
-  struct stat tmpBuffer = {0};
-#endif
-
-  CSingleLock lock(smb);
-  int iResult = smbc_fstat(m_fd, &tmpBuffer);
-
-  memset(buffer, 0, sizeof(struct __stat64));
-  buffer->st_dev = tmpBuffer.st_dev;
-  buffer->st_ino = tmpBuffer.st_ino;
-  buffer->st_mode = tmpBuffer.st_mode;
-  buffer->st_nlink = tmpBuffer.st_nlink;
-  buffer->st_uid = tmpBuffer.st_uid;
-  buffer->st_gid = tmpBuffer.st_gid;
-  buffer->st_rdev = tmpBuffer.st_rdev;
-  buffer->st_size = tmpBuffer.st_size;
-  buffer->st_atime = tmpBuffer.st_atime;
-  buffer->st_mtime = tmpBuffer.st_mtime;
-  buffer->st_ctime = tmpBuffer.st_ctime;
-
-  return iResult;
-}
-
-int CFileSMB::Stat(const CURL& url, struct __stat64* buffer)
-{
-  smb.Init();
-  CStdString strFileName = GetAuthenticatedPath(url);
-  CSingleLock lock(smb);
-
-#ifdef TARGET_WINDOWS
-  struct __stat64 tmpBuffer = {0};
-#else
-  struct stat tmpBuffer = {0};
-#endif
-  int iResult = smbc_stat(strFileName, &tmpBuffer);
-
-  memset(buffer, 0, sizeof(struct __stat64));
-  buffer->st_dev = tmpBuffer.st_dev;
-  buffer->st_ino = tmpBuffer.st_ino;
-  buffer->st_mode = tmpBuffer.st_mode;
-  buffer->st_nlink = tmpBuffer.st_nlink;
-  buffer->st_uid = tmpBuffer.st_uid;
-  buffer->st_gid = tmpBuffer.st_gid;
-  buffer->st_rdev = tmpBuffer.st_rdev;
-  buffer->st_size = tmpBuffer.st_size;
-  buffer->st_atime = tmpBuffer.st_atime;
-  buffer->st_mtime = tmpBuffer.st_mtime;
-  buffer->st_ctime = tmpBuffer.st_ctime;
-
-  return iResult;
-}
-
-unsigned int CFileSMB::Read(void *lpBuf, int64_t uiBufSize)
-{
-  if (m_fd == -1) return 0;
-  CSingleLock lock(smb); // Init not called since it has to be "inited" by now
-#ifdef TARGET_POSIX
-  smb.SetActivityTime();
-#endif
-  /* work around stupid bug in samba */
-  /* some samba servers has a bug in it where the */
-  /* 17th bit will be ignored in a request of data */
-  /* this can lead to a very small return of data */
-  /* also worse, a request of exactly 64k will return */
-  /* as if eof, client has a workaround for windows */
-  /* thou it seems other servers are affected too */
-  if( uiBufSize >= 64*1024-2 )
-    uiBufSize = 64*1024-2;
-
-  int bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize);
-
-  if ( bytesRead < 0 && errno == EINVAL )
-  {
-    CLog::Log(LOGERROR, "%s - Error( %d, %d, %s ) - Retrying", __FUNCTION__, bytesRead, errno, strerror(errno));
-    bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize);
-  }
-
-  if ( bytesRead < 0 )
-  {
-#ifdef TARGET_WINDOWS
-    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
-#else
-    CLog::Log(LOGERROR, "%s - Error( %d, %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno));
-#endif
-    return 0;
-  }
-
-  return (unsigned int)bytesRead;
-}
-
-int64_t CFileSMB::Seek(int64_t iFilePosition, int iWhence)
-{
-  if (m_fd == -1) return -1;
-
-  CSingleLock lock(smb); // Init not called since it has to be "inited" by now
-#ifdef TARGET_POSIX
-  smb.SetActivityTime();
-#endif
-  int64_t pos = smbc_lseek(m_fd, iFilePosition, iWhence);
-
-  if ( pos < 0 )
-  {
-#ifdef TARGET_WINDOWS
-    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
-#else
-    CLog::Log(LOGERROR, "%s - Error( %"PRId64", %d, %s )", __FUNCTION__, pos, errno, strerror(errno));
-#endif
-    return -1;
-  }
-
-  return (int64_t)pos;
-}
-
-void CFileSMB::Close()
-{
-  if (m_fd != -1)
-  {
-    CLog::Log(LOGDEBUG,"CFileSMB::Close closing fd %d", m_fd);
-    CSingleLock lock(smb);
-    smbc_close(m_fd);
-  }
-  m_fd = -1;
-}
-
-int CFileSMB::Write(const void* lpBuf, int64_t uiBufSize)
-{
-  if (m_fd == -1) return -1;
-  DWORD dwNumberOfBytesWritten = 0;
-
-  // lpBuf can be safely casted to void* since xmbc_write will only read from it.
-  smb.Init();
-  CSingleLock lock(smb);
-  dwNumberOfBytesWritten = smbc_write(m_fd, (void*)lpBuf, (DWORD)uiBufSize);
-
-  return (int)dwNumberOfBytesWritten;
-}
-
-bool CFileSMB::Delete(const CURL& url)
-{
-  smb.Init();
-  CStdString strFile = GetAuthenticatedPath(url);
-
-  CSingleLock lock(smb);
-
-  int result = smbc_unlink(strFile.c_str());
-
-  if(result != 0)
-#ifdef TARGET_WINDOWS
-    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
-#else
-    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno));
-#endif
-
-  return (result == 0);
-}
-
-bool CFileSMB::Rename(const CURL& url, const CURL& urlnew)
-{
-  smb.Init();
-  CStdString strFile = GetAuthenticatedPath(url);
-  CStdString strFileNew = GetAuthenticatedPath(urlnew);
-  CSingleLock lock(smb);
-
-  int result = smbc_rename(strFile.c_str(), strFileNew.c_str());
-
-  if(result != 0)
-#ifdef TARGET_WINDOWS
-    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
-#else
-    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno));
-#endif
-
-  return (result == 0);
-}
-
-bool CFileSMB::OpenForWrite(const CURL& url, bool bOverWrite)
-{
-  m_fileSize = 0;
-
-  Close();
-  smb.Init();
-  // we can't open files like smb://file.f or smb://server/file.f
-  // if a file matches the if below return false, it can't exist on a samba share.
-  if (!IsValidFile(url.GetFileName())) return false;
-
-  CStdString strFileName = GetAuthenticatedPath(url);
-  CSingleLock lock(smb);
-
-  if (bOverWrite)
-  {
-    CLog::Log(LOGWARNING, "FileSmb::OpenForWrite() called with overwriting enabled! - %s", strFileName.c_str());
-    m_fd = smbc_creat(strFileName.c_str(), 0);
-  }
-  else
-  {
-    m_fd = smbc_open(strFileName.c_str(), O_RDWR, 0);
-  }
-
-  if (m_fd == -1)
-  {
-    // write error to logfile
-#ifdef TARGET_WINDOWS
-    int nt_error = map_nt_error_from_unix(errno);
-    CLog::Log(LOGERROR, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' nt_err : '%x' error : '%s'", strFileName.c_str(), errno, nt_error, get_friendly_nt_error_msg(nt_error));
-#else
-    CLog::Log(LOGERROR, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strFileName.c_str(), errno, strerror(errno));
-#endif
-    return false;
-  }
-
-  // We've successfully opened the file!
-  return true;
-}
-
-bool CFileSMB::IsValidFile(const CStdString& strFileName)
-{
-  if (strFileName.Find('/') == -1 || /* doesn't have sharename */
-      strFileName.Right(2) == "/." || /* not current folder */
-      strFileName.Right(3) == "/..")  /* not parent folder */
-      return false;
-  return true;
-}
-
-CStdString CFileSMB::GetAuthenticatedPath(const CURL &url)
-{
-  CURL authURL(url);
-  CPasswordManager::GetInstance().AuthenticateURL(authURL);
-  return smb.URLEncode(authURL);
-}
diff --git a/xbmc/filesystem/FileSmb.h b/xbmc/filesystem/FileSmb.h
deleted file mode 100644 (file)
index 4068199..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-// FileSmb.h: interface for the CFileSMB class.
-
-//
-
-//////////////////////////////////////////////////////////////////////
-
-
-
-#if !defined(AFX_FILESMB_H__2C4AB5BC_0742_458D_95EA_E9C77BA5663D__INCLUDED_)
-
-#define AFX_FILESMB_H__2C4AB5BC_0742_458D_95EA_E9C77BA5663D__INCLUDED_
-
-
-#if _MSC_VER > 1000
-
-#pragma once
-
-#endif // _MSC_VER > 1000
-
-#include "IFile.h"
-#include "URL.h"
-#include "threads/CriticalSection.h"
-
-#define NT_STATUS_CONNECTION_REFUSED long(0xC0000000 | 0x0236)
-#define NT_STATUS_INVALID_HANDLE long(0xC0000000 | 0x0008)
-#define NT_STATUS_ACCESS_DENIED long(0xC0000000 | 0x0022)
-#define NT_STATUS_OBJECT_NAME_NOT_FOUND long(0xC0000000 | 0x0034)
-#ifdef _LINUX
-#define NT_STATUS_INVALID_COMPUTER_NAME long(0xC0000000 | 0x0122)
-#endif
-
-struct _SMBCCTX;
-typedef _SMBCCTX SMBCCTX;
-
-class CSMB : public CCriticalSection
-{
-public:
-  CSMB();
-  ~CSMB();
-  void Init();
-  void Deinit();
-  void Purge();
-  void PurgeEx(const CURL& url);
-#ifdef _LINUX
-  void CheckIfIdle();
-  void SetActivityTime();
-  void AddActiveConnection();
-  void AddIdleConnection();
-#endif
-  CStdString URLEncode(const CStdString &value);
-  CStdString URLEncode(const CURL &url);
-
-  DWORD ConvertUnixToNT(int error);
-private:
-  SMBCCTX *m_context;
-  CStdString m_strLastHost;
-  CStdString m_strLastShare;
-#ifdef _LINUX
-  int m_OpenConnections;
-  unsigned int m_IdleTimeout;
-#endif
-};
-
-extern CSMB smb;
-
-namespace XFILE
-{
-class CFileSMB : public IFile
-{
-public:
-  CFileSMB();
-  int OpenFile(const CURL &url, CStdString& strAuth);
-  virtual ~CFileSMB();
-  virtual void Close();
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-  virtual int Stat(struct __stat64* buffer);
-  virtual int64_t GetLength();
-  virtual int64_t GetPosition();
-  virtual int Write(const void* lpBuf, int64_t uiBufSize);
-
-  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
-  virtual bool Delete(const CURL& url);
-  virtual bool Rename(const CURL& url, const CURL& urlnew);
-  virtual int  GetChunkSize() {return 1;}
-
-protected:
-  CURL m_url;
-  bool IsValidFile(const CStdString& strFileName);
-  CStdString GetAuthenticatedPath(const CURL &url);
-  int64_t m_fileSize;
-  int m_fd;
-};
-}
-
-#endif // !defined(AFX_FILESMB_H__2C4AB5BC_0742_458D_95EA_E9C77BA5663D__INCLUDED_)
diff --git a/xbmc/filesystem/FileSpecialProtocol.cpp b/xbmc/filesystem/FileSpecialProtocol.cpp
deleted file mode 100644 (file)
index e775689..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "FileSpecialProtocol.h"
-#include "SpecialProtocol.h"
-#include "URL.h"
-
-#include <sys/stat.h>
-
-using namespace XFILE;
-
-CFileSpecialProtocol::CFileSpecialProtocol(void)
-{
-}
-
-CFileSpecialProtocol::~CFileSpecialProtocol(void)
-{
-  Close();
-}
-
-bool CFileSpecialProtocol::Open(const CURL& url)
-{
-  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
-
-  return m_file.Open(strFileName);
-}
-
-bool CFileSpecialProtocol::OpenForWrite(const CURL& url, bool bOverWrite /*=false */)
-{
-  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
-
-  return m_file.OpenForWrite(strFileName,bOverWrite);
-}
-
-bool CFileSpecialProtocol::Delete(const CURL& url)
-{
-  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
-  
-  return m_file.Delete(strFileName);
-}
-
-bool CFileSpecialProtocol::Exists(const CURL& url)
-{
-  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
-
-  return m_file.Exists(strFileName);
-}
-
-int CFileSpecialProtocol::Stat(const CURL& url, struct __stat64* buffer)
-{
-  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
-
-  return m_file.Stat(strFileName, buffer);
-}
-
-bool CFileSpecialProtocol::Rename(const CURL& url, const CURL& urlnew)
-{
-  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
-  CStdString strFileName2=CSpecialProtocol::TranslatePath(urlnew);
-
-  return m_file.Rename(strFileName,strFileName2);
-}
-
-int CFileSpecialProtocol::Stat(struct __stat64* buffer)
-{
-  return m_file.Stat(buffer);
-}
-
-unsigned int CFileSpecialProtocol::Read(void* lpBuf, int64_t uiBufSize)
-{
-  return m_file.Read(lpBuf, uiBufSize);
-}
-  
-int CFileSpecialProtocol::Write(const void* lpBuf, int64_t uiBufSize)
-{
-  return m_file.Write(lpBuf,uiBufSize);
-}
-
-int64_t CFileSpecialProtocol::Seek(int64_t iFilePosition, int iWhence /*=SEEK_SET*/)
-{
-  return m_file.Seek(iFilePosition, iWhence);
-}
-
-void CFileSpecialProtocol::Close()
-{
-  m_file.Close();
-}
-
-int64_t CFileSpecialProtocol::GetPosition()
-{
-  return m_file.GetPosition();
-}
-
-int64_t CFileSpecialProtocol::GetLength()
-{
-  return m_file.GetLength();
-}
-
-
-
diff --git a/xbmc/filesystem/FileSpecialProtocol.h b/xbmc/filesystem/FileSpecialProtocol.h
deleted file mode 100644 (file)
index d9ccc48..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "File.h"
-
-namespace XFILE
-{
-class CFileSpecialProtocol : public IFile
-{
-public:
-  CFileSpecialProtocol(void);
-  virtual ~CFileSpecialProtocol(void);
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-  virtual int Stat(struct __stat64* buffer);
-  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
-  virtual bool Delete(const CURL& url);
-  virtual bool Rename(const CURL& url, const CURL& urlnew);
-
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int Write(const void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-
-protected:
-  CFile m_file;
-};
-}
diff --git a/xbmc/filesystem/FileTuxBox.cpp b/xbmc/filesystem/FileTuxBox.cpp
deleted file mode 100644 (file)
index e6257eb..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "FileTuxBox.h"
-#include <errno.h>
-
-//Reserved for TuxBox Recording!
-
-using namespace XFILE;
-
-CFileTuxBox::CFileTuxBox()
-{}
-
-CFileTuxBox::~CFileTuxBox()
-{
-}
-
-int64_t CFileTuxBox::GetPosition()
-{
-  return 0;
-}
-
-int64_t CFileTuxBox::GetLength()
-{
-  return 0;
-}
-
-bool CFileTuxBox::Open(const CURL& url)
-{
-  return true;
-}
-
-unsigned int CFileTuxBox::Read(void* lpBuf, int64_t uiBufSize)
-{
-  return 0;
-}
-
-int64_t CFileTuxBox::Seek(int64_t iFilePosition, int iWhence)
-{
-  return 0;
-}
-
-void CFileTuxBox::Close()
-{
-}
-
-bool CFileTuxBox::Exists(const CURL& url)
-{
-  return true;
-}
-
-int CFileTuxBox::Stat(const CURL& url, struct __stat64* buffer)
-{
-  errno = ENOENT;
-  return -1;
-}
-
diff --git a/xbmc/filesystem/FileTuxBox.h b/xbmc/filesystem/FileTuxBox.h
deleted file mode 100644 (file)
index be6ff5d..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "IFile.h"
-
-namespace XFILE
-{
-  class CFileTuxBox : public IFile
-  {
-    public:
-      CFileTuxBox();
-      virtual ~CFileTuxBox();
-      virtual int64_t GetPosition();
-      virtual int64_t GetLength();
-      virtual bool Open(const CURL& url);
-      virtual void Close();
-      virtual bool Exists(const CURL& url);
-      virtual int Stat(const CURL& url, struct __stat64* buffer);
-      virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-      virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-    protected:
-  };
-}
-
-
-
diff --git a/xbmc/filesystem/FileUDF.cpp b/xbmc/filesystem/FileUDF.cpp
deleted file mode 100644 (file)
index 112d5ab..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- *      Copyright (C) 2010 Team Boxee
- *      http://www.boxee.tv
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "FileUDF.h"
-#include "URL.h"
-#include "Util.h"
-
-#include <sys/stat.h>
-#include <errno.h>
-
-using namespace std;
-using namespace XFILE;
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-//*********************************************************************************************
-CFileUDF::CFileUDF()
-{
-  m_bOpened = false;
-}
-
-//*********************************************************************************************
-CFileUDF::~CFileUDF()
-{
-  if (m_bOpened)
-  {
-    Close();
-  }
-}
-//*********************************************************************************************
-bool CFileUDF::Open(const CURL& url)
-{
-  CStdString strFName = url.GetHostName();
-
-  CURL::Decode(strFName);
-
-  m_hFile = m_udfIsoReaderLocal.OpenFile((char*)strFName.c_str());
-  if (m_hFile == INVALID_HANDLE_VALUE)
-  {
-    m_bOpened = false;
-    return false;
-  }
-
-  m_bOpened = true;
-  return true;
-}
-
-//*********************************************************************************************
-unsigned int CFileUDF::Read(void *lpBuf, int64_t uiBufSize)
-{
-  if (!m_bOpened) return 0;
-  char *pData = (char *)lpBuf;
-
-  int iResult = m_udfIsoReaderLocal.ReadFile( m_hFile, (unsigned char*)pData, (long)uiBufSize);
-  if (iResult == -1)
-    return 0;
-  return iResult;
-}
-
-//*********************************************************************************************
-void CFileUDF::Close()
-{
-  if (!m_bOpened) return ;
-  m_udfIsoReaderLocal.CloseFile( m_hFile);
-}
-
-//*********************************************************************************************
-int64_t CFileUDF::Seek(int64_t iFilePosition, int iWhence)
-{
-  if (!m_bOpened) return -1;
-  int64_t lNewPos = m_udfIsoReaderLocal.Seek(m_hFile, iFilePosition, iWhence);
-  return lNewPos;
-}
-
-//*********************************************************************************************
-int64_t CFileUDF::GetLength()
-{
-  if (!m_bOpened) return -1;
-  return m_udfIsoReaderLocal.GetFileSize(m_hFile);
-}
-
-//*********************************************************************************************
-int64_t CFileUDF::GetPosition()
-{
-  if (!m_bOpened) return -1;
-  return m_udfIsoReaderLocal.GetFilePosition(m_hFile);
-}
-
-bool CFileUDF::Exists(const CURL& url)
-{
-  string strFName = "\\";
-  strFName += url.GetFileName();
-  for (int i = 0; i < (int)strFName.size(); ++i )
-  {
-    if (strFName[i] == '/') strFName[i] = '\\';
-  }
-  m_hFile = m_udfIsoReaderLocal.OpenFile((char*)strFName.c_str());
-  if (m_hFile == INVALID_HANDLE_VALUE)
-    return false;
-
-  m_udfIsoReaderLocal.CloseFile(m_hFile);
-  return true;
-}
-
-int CFileUDF::Stat(const CURL& url, struct __stat64* buffer)
-{
-  string strFName = "\\";
-  strFName += url.GetFileName();
-  for (int i = 0; i < (int)strFName.size(); ++i )
-  {
-    if (strFName[i] == '/') strFName[i] = '\\';
-  }
-  m_hFile = m_udfIsoReaderLocal.OpenFile((char*)strFName.c_str());
-  if (m_hFile != INVALID_HANDLE_VALUE)
-  {
-    buffer->st_size = m_udfIsoReaderLocal.GetFileSize(m_hFile);
-    buffer->st_mode = _S_IFREG;
-    m_udfIsoReaderLocal.CloseFile(m_hFile);
-    return 0;
-  }
-  errno = ENOENT;
-  return -1;
-}
diff --git a/xbmc/filesystem/FileUDF.h b/xbmc/filesystem/FileUDF.h
deleted file mode 100644 (file)
index fb46b47..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _FILEUDF_H
-#define _FILEUDF_H
-
-/*
- *      Copyright (C) 2010 Team Boxee
- *      http://www.boxee.tv
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "IFile.h"
-#include "udf25.h"
-
-namespace XFILE
-{
-
-class CFileUDF : public IFile
-{
-public:
-  CFileUDF();
-  virtual ~CFileUDF();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-protected:
-  bool m_bOpened;
-  HANDLE m_hFile;
-  udf25 m_udfIsoReaderLocal;
-};
-}
-
-#endif
diff --git a/xbmc/filesystem/FileUPnP.cpp b/xbmc/filesystem/FileUPnP.cpp
deleted file mode 100644 (file)
index 665e096..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *      Copyright (C) 2011 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "FileUPnP.h"
-#include "UPnPDirectory.h"
-#include "FileFactory.h"
-#include "FileItem.h"
-#include "utils/log.h"
-
-using namespace XFILE;
-
-CFileUPnP::CFileUPnP()
-{
-}
-
-CFileUPnP::~CFileUPnP()
-{
-}
-
-bool CFileUPnP::Open(const CURL& url)
-{
-  CFileItem item_new;
-  if (CUPnPDirectory::GetResource(url.Get(), item_new))
-  {
-    //CLog::Log(LOGDEBUG,"FileUPnP - file redirect to %s.", item_new.GetPath().c_str());
-    IFile *pNewImp = CFileFactory::CreateLoader(item_new.GetPath());    
-    CURL *pNewUrl = new CURL(item_new.GetPath());    
-    if (pNewImp)
-    {
-      throw new CRedirectException(pNewImp, pNewUrl);
-    }
-    SAFE_DELETE(pNewUrl);    
-  }
-  return false;
-}
-
-int CFileUPnP::Stat(const CURL& url, struct __stat64* buffer)
-{
-  CFileItem item_new;
-  if (CUPnPDirectory::GetResource(url.Get(), item_new))
-  {
-    //CLog::Log(LOGDEBUG,"FileUPnP - file redirect to %s.", item_new.GetPath().c_str());
-    IFile *pNewImp = CFileFactory::CreateLoader(item_new.GetPath());
-    CURL *pNewUrl = new CURL(item_new.GetPath());
-    if (pNewImp)
-    {
-      throw new CRedirectException(pNewImp, pNewUrl);
-    }
-    SAFE_DELETE(pNewUrl);
-  }
-  return -1;
-}
-
-bool CFileUPnP::Exists(const CURL& url)
-{
-  CFileItem item_new;
-  if (CUPnPDirectory::GetResource(url.Get(), item_new))
-  {
-    //CLog::Log(LOGDEBUG,"FileUPnP - file redirect to %s.", item_new.GetPath().c_str());
-    IFile *pNewImp = CFileFactory::CreateLoader(item_new.GetPath());
-    CURL *pNewUrl = new CURL(item_new.GetPath());
-    if (pNewImp)
-    {
-      throw new CRedirectException(pNewImp, pNewUrl);
-    }
-    SAFE_DELETE(pNewUrl);
-  }
-  return false;
-}
diff --git a/xbmc/filesystem/FileUPnP.h b/xbmc/filesystem/FileUPnP.h
deleted file mode 100644 (file)
index 3d31364..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "IFile.h"
-
-namespace XFILE
-{
-  class CFileUPnP : public IFile
-  {
-    public:
-      CFileUPnP();
-      virtual ~CFileUPnP();
-      virtual bool Open(const CURL& url);      
-      virtual bool Exists(const CURL& url);
-      virtual int Stat(const CURL& url, struct __stat64* buffer);
-      
-      virtual unsigned int Read(void* lpBuf, int64_t uiBufSize) {return -1;}
-      virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET) {return -1;}
-      virtual void Close(){}
-      virtual int64_t GetPosition() {return -1;}
-      virtual int64_t GetLength() {return -1;}
-  };
-}
diff --git a/xbmc/filesystem/FileZip.cpp b/xbmc/filesystem/FileZip.cpp
deleted file mode 100644 (file)
index c59a3b1..0000000
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "FileZip.h"
-#include "URL.h"
-#include "utils/URIUtils.h"
-
-#include <sys/stat.h>
-
-#define ZIP_CACHE_LIMIT 4*1024*1024
-
-using namespace XFILE;
-using namespace std;
-
-CFileZip::CFileZip()
-{
-  m_szStringBuffer = NULL;
-  m_szStartOfStringBuffer = NULL;
-  m_iDataInStringBuffer = 0;
-  m_bCached = false;
-  m_iRead = -1;
-}
-
-CFileZip::~CFileZip()
-{
-  delete[] m_szStringBuffer;
-  Close();
-}
-
-bool CFileZip::Open(const CURL&url)
-{
-  CStdString strOpts = url.GetOptions();
-  CURL url2(url);
-  url2.SetOptions("");
-  CStdString strPath = url2.Get();
-  if (!g_ZipManager.GetZipEntry(strPath,mZipItem))
-    return false;
-
-  if ((mZipItem.flags & 64) == 64)
-  {
-    CLog::Log(LOGERROR,"FileZip: encrypted file, not supported!");
-    return false;
-  }
-
-  if ((mZipItem.method != 8) && (mZipItem.method != 0))
-  {
-    CLog::Log(LOGERROR,"FileZip: unsupported compression method!");
-    return false;
-  }
-
-  if (mZipItem.method != 0 && mZipItem.usize > ZIP_CACHE_LIMIT && strOpts != "?cache=no")
-  {
-    if (!CFile::Exists("special://temp/" + URIUtils::GetFileName(strPath)))
-    {
-      url2.SetOptions("?cache=no");
-      if (!CFile::Cache(url2.Get(), "special://temp/" + URIUtils::GetFileName(strPath)))
-        return false;
-    }
-    m_bCached = true;
-    return mFile.Open("special://temp/" + URIUtils::GetFileName(strPath));
-  }
-
-  if (!mFile.Open(url.GetHostName())) // this is the zip-file, always open binary
-  {
-    CLog::Log(LOGERROR,"FileZip: unable to open zip file %s!",url.GetHostName().c_str());
-    return false;
-  }
-  mFile.Seek(mZipItem.offset,SEEK_SET);
-  return InitDecompress();
-}
-
-bool CFileZip::InitDecompress()
-{
-  m_iRead = 1;
-  m_iFilePos = 0;
-  m_iZipFilePos = 0;
-  m_iAvailBuffer = 0;
-  m_bFlush = false;
-  m_ZStream.zalloc = Z_NULL;
-  m_ZStream.zfree = Z_NULL;
-  m_ZStream.opaque = Z_NULL;
-  if( mZipItem.method != 0 )
-  {
-    if (inflateInit2(&m_ZStream,-MAX_WBITS) != Z_OK)
-    {
-      CLog::Log(LOGERROR,"FileZip: error initializing zlib!");
-      return false;
-    }
-  }
-  m_ZStream.next_in = (Bytef*)m_szBuffer;
-  m_ZStream.avail_in = 0;
-  m_ZStream.total_out = 0;
-
-  return true;
-}
-
-int64_t CFileZip::GetLength()
-{
-  return mZipItem.usize;
-}
-
-int64_t CFileZip::GetPosition()
-{
-  if (m_bCached)
-    return mFile.GetPosition();
-
-  return m_iFilePos;
-}
-
-int64_t CFileZip::Seek(int64_t iFilePosition, int iWhence)
-{
-  if (m_bCached)
-    return mFile.Seek(iFilePosition,iWhence);
-  if (mZipItem.method == 0) // this is easy
-  {
-    int64_t iResult;
-    switch (iWhence)
-    {
-    case SEEK_SET:
-      if (iFilePosition > mZipItem.usize)
-        return -1;
-      m_iFilePos = iFilePosition;
-      m_iZipFilePos = m_iFilePos;
-      iResult = mFile.Seek(iFilePosition+mZipItem.offset,SEEK_SET)-mZipItem.offset;
-      return iResult;
-      break;
-
-    case SEEK_CUR:
-      if (m_iFilePos+iFilePosition > mZipItem.usize)
-        return -1;
-      m_iFilePos += iFilePosition;
-      m_iZipFilePos = m_iFilePos;
-      iResult = mFile.Seek(iFilePosition,SEEK_CUR)-mZipItem.offset;
-      return iResult;
-      break;
-
-    case SEEK_END:
-      if (iFilePosition > mZipItem.usize)
-        return -1;
-      m_iFilePos = mZipItem.usize+iFilePosition;
-      m_iZipFilePos = m_iFilePos;
-      iResult = mFile.Seek(mZipItem.offset+mZipItem.usize+iFilePosition,SEEK_SET)-mZipItem.offset;
-      return iResult;
-      break;
-    default:
-      return -1;
-
-    }
-  }
-  // here goes the stupid part..
-  if (mZipItem.method == 8)
-  {
-    char temp[131072];
-    switch (iWhence)
-    {
-    case SEEK_SET:
-      if (iFilePosition == m_iFilePos)
-        return m_iFilePos; // mp3reader does this lots-of-times
-      if (iFilePosition > mZipItem.usize || iFilePosition < 0)
-        return -1;
-      // read until position in 128k blocks.. only way to do it due to format.
-      // can't start in the middle of data since then we'd have no clue where
-      // we are in uncompressed data..
-      if (iFilePosition < m_iFilePos)
-      {
-        m_iFilePos = 0;
-        m_iZipFilePos = 0;
-        inflateEnd(&m_ZStream);
-        inflateInit2(&m_ZStream,-MAX_WBITS); // simply restart zlib
-        mFile.Seek(mZipItem.offset,SEEK_SET);
-        m_ZStream.next_in = (Bytef*)m_szBuffer;
-        m_ZStream.avail_in = 0;
-        m_ZStream.total_out = 0;
-        while (m_iFilePos < iFilePosition)
-        {
-          unsigned int iToRead = (iFilePosition-m_iFilePos)>131072?131072:(int)(iFilePosition-m_iFilePos);
-          if (Read(temp,iToRead) != iToRead)
-            return -1;
-        }
-        return m_iFilePos;
-      }
-      else // seek forward
-        return Seek(iFilePosition-m_iFilePos,SEEK_CUR);
-      break;
-
-    case SEEK_CUR:
-      if (iFilePosition < 0)
-        return Seek(m_iFilePos+iFilePosition,SEEK_SET); // can't rewind stream
-      // read until requested position, drop data
-      if (m_iFilePos+iFilePosition > mZipItem.usize)
-        return -1;
-      iFilePosition += m_iFilePos;
-      while (m_iFilePos < iFilePosition)
-      {
-        unsigned int iToRead = (iFilePosition-m_iFilePos)>131072?131072:(int)(iFilePosition-m_iFilePos);
-        if (Read(temp,iToRead) != iToRead)
-          return -1;
-      }
-      return m_iFilePos;
-      break;
-
-    case SEEK_END:
-      // now this is a nasty bastard, possibly takes lotsoftime
-      // uncompress, minding m_ZStream.total_out
-
-      while( (int)m_ZStream.total_out < mZipItem.usize+iFilePosition)
-      {
-        unsigned int iToRead = (mZipItem.usize+iFilePosition-m_ZStream.total_out > 131072)?131072:(int)(mZipItem.usize+iFilePosition-m_ZStream.total_out);
-        if (Read(temp,iToRead) != iToRead)
-          return -1;
-      }
-      return m_iFilePos;
-      break;
-    default:
-      return -1;
-    }
-  }
-  return -1;
-}
-
-bool CFileZip::Exists(const CURL& url)
-{
-  SZipEntry item;
-  if (g_ZipManager.GetZipEntry(url.Get(),item))
-    return true;
-  return false;
-}
-
-int CFileZip::Stat(struct __stat64 *buffer)
-{
-  int ret;
-  struct tm tm = {};
-
-  ret = mFile.Stat(buffer);
-  tm.tm_sec = (mZipItem.mod_time & 0x1F) << 1;
-  tm.tm_min = (mZipItem.mod_time & 0x7E0) >> 5;
-  tm.tm_hour = (mZipItem.mod_time & 0xF800) >> 11;
-  tm.tm_mday = (mZipItem.mod_date & 0x1F);
-  tm.tm_mon = (mZipItem.mod_date & 0x1E0) >> 5;
-  tm.tm_year = (mZipItem.mod_date & 0xFE00) >> 9;
-  buffer->st_atime = buffer->st_ctime = buffer->st_mtime = mktime(&tm);
-
-  buffer->st_size = mZipItem.usize;
-  buffer->st_dev = (buffer->st_dev << 16) ^ (buffer->st_ino << 16);
-  buffer->st_ino ^= mZipItem.crc32;
-  return ret;
-}
-
-int CFileZip::Stat(const CURL& url, struct __stat64* buffer)
-{
-  if (!g_ZipManager.GetZipEntry(url.Get(),mZipItem))
-    return -1;
-
-  memset(buffer, 0, sizeof(struct __stat64));
-  buffer->st_gid = 0;
-  buffer->st_atime = buffer->st_ctime = mZipItem.mod_time;
-  buffer->st_size = mZipItem.usize;
-  return 0;
-}
-
-unsigned int CFileZip::Read(void* lpBuf, int64_t uiBufSize)
-{
-  if (m_bCached)
-    return mFile.Read(lpBuf,uiBufSize);
-
-  // flush what might be left in the string buffer
-  if (m_iDataInStringBuffer > 0)
-  {
-    size_t iMax = static_cast<size_t>((uiBufSize>m_iDataInStringBuffer?m_iDataInStringBuffer:uiBufSize));
-    memcpy(lpBuf,m_szStartOfStringBuffer,iMax);
-    uiBufSize -= iMax;
-    m_iDataInStringBuffer -= iMax;
-  }
-  if (mZipItem.method == 8) // deflated
-  {
-    uLong iDecompressed = 0;
-    uLong prevOut = m_ZStream.total_out;
-    while (((int)iDecompressed < uiBufSize) && ((m_iZipFilePos < mZipItem.csize) || (m_bFlush)))
-    {
-      m_ZStream.next_out = (Bytef*)(lpBuf)+iDecompressed;
-      m_ZStream.avail_out = static_cast<uInt>(uiBufSize-iDecompressed);
-      if (m_bFlush) // need to flush buffer !
-      {
-        int iMessage = inflate(&m_ZStream,Z_SYNC_FLUSH);
-        m_bFlush = ((iMessage == Z_OK) && (m_ZStream.avail_out == 0))?true:false;
-        if (!m_ZStream.avail_out) // flush filled buffer, get out of here
-        {
-          iDecompressed = m_ZStream.total_out-prevOut;
-          break;
-        }
-      }
-
-      if (!m_ZStream.avail_in)
-      {
-        if (!FillBuffer()) // eof!
-        {
-          iDecompressed = m_ZStream.total_out-prevOut;
-          break;
-        }
-      }
-
-      int iMessage = inflate(&m_ZStream,Z_SYNC_FLUSH);
-      if (iMessage < 0)
-      {
-        Close();
-        return 0; // READ ERROR
-      }
-
-      m_bFlush = ((iMessage == Z_OK) && (m_ZStream.avail_out == 0))?true:false; // more info in input buffer
-
-      iDecompressed = m_ZStream.total_out-prevOut;
-    }
-    m_iFilePos += iDecompressed;
-    return static_cast<unsigned int>(iDecompressed);
-  }
-  else if (mZipItem.method == 0) // uncompressed. just read from file, but mind our boundaries.
-  {
-    if (uiBufSize+m_iFilePos > mZipItem.csize)
-      uiBufSize = mZipItem.csize-m_iFilePos;
-    if (uiBufSize < 0)
-    {
-      return 0; // we are past eof, this shouldn't happen but test anyway
-    }
-    unsigned int iResult = mFile.Read(lpBuf,uiBufSize);
-    m_iZipFilePos += iResult;
-    m_iFilePos += iResult;
-    return iResult;
-  }
-  else
-    return false; // shouldn't happen. compression method checked in open
-}
-
-void CFileZip::Close()
-{
-  if (mZipItem.method == 8 && !m_bCached && m_iRead != -1)
-    inflateEnd(&m_ZStream);
-
-  mFile.Close();
-}
-/* CHANGED: JM - moved to CFile
-bool CFileZip::ReadString(char* szLine, int iLineLength)
-{
-  if (!m_szStringBuffer)
-  {
-    m_szStringBuffer = new char[1024]; // 1024 byte long strings per read
-    m_szStartOfStringBuffer = m_szStringBuffer;
-    m_iDataInStringBuffer = 0;
-    m_iRead = 0;
-  }
-
-  bool bEof = m_iDataInStringBuffer==0;
-  while ((iLineLength > 1) && (m_iRead > -1))
-  {
-    if (m_iDataInStringBuffer > 0)
-    {
-      bEof = false;
-      m_iRead = 1;
-      int iMax = (iLineLength<m_iDataInStringBuffer?iLineLength-1:m_iDataInStringBuffer-1);
-      for( int i=0;i<iMax;++i )
-      {
-        if (m_szStartOfStringBuffer[i] == '\r') // mac or win32 endings
-        {
-          strncpy(szLine,m_szStartOfStringBuffer,i);
-          szLine[i] = '\0';
-          m_iDataInStringBuffer -= i+1;
-          m_szStartOfStringBuffer += i+1;
-          if( m_szStartOfStringBuffer[0] == '\n') // win32 endings
-          {
-            m_szStartOfStringBuffer++;
-            m_iDataInStringBuffer--;
-          }
-          return true;
-        }
-        else if (m_szStartOfStringBuffer[i] == '\n') // unix or fucked up win32 endings
-        {
-          strncpy(szLine,m_szStartOfStringBuffer,i);
-          szLine[i] = '\0';
-          m_iDataInStringBuffer -= i+1;
-          m_szStartOfStringBuffer += i+1;
-          if (m_szStartOfStringBuffer[0] == '\r')
-          {
-            m_szStartOfStringBuffer++;
-            m_iDataInStringBuffer--;
-          }
-          return true;
-        }
-      }
-      strncpy(szLine,m_szStartOfStringBuffer,iMax);
-      szLine += iMax;
-      iLineLength -= iMax;
-      m_iDataInStringBuffer -= iMax;
-    }
-
-    if (m_iRead == 1 && (m_iDataInStringBuffer == 1))
-    {
-      m_szStringBuffer[0] = m_szStringBuffer[1023]; // need to make sure we don't loose any '\r\n' between buffers
-      m_iDataInStringBuffer = Read(m_szStringBuffer+1,1023);
-    }
-    else
-      m_iDataInStringBuffer = Read(m_szStringBuffer,1024);
-    m_szStartOfStringBuffer = m_szStringBuffer;
-    if (m_iDataInStringBuffer)
-      m_iRead = 1;
-    else
-      m_iRead = -1;
-  }
-  szLine[0] = '\0';
-  return !bEof;
-}*/
-
-bool CFileZip::FillBuffer()
-{
-  unsigned int sToRead = 65535;
-  if (m_iZipFilePos+65535 > mZipItem.csize)
-    sToRead = static_cast<int>(mZipItem.csize-m_iZipFilePos);
-
-  if (sToRead <= 0)
-    return false; // eof!
-
-  if (mFile.Read(m_szBuffer,sToRead) != sToRead)
-    return false;
-  m_ZStream.avail_in = sToRead;
-  m_ZStream.next_in = (Bytef*)m_szBuffer;
-  m_iZipFilePos += sToRead;
-  return true;
-}
-
-void CFileZip::DestroyBuffer(void* lpBuffer, int iBufSize)
-{
-  if (!m_bFlush)
-    return;
-  int iMessage = Z_STREAM_END; // whatever != Z_OK
-  while ((iMessage == Z_OK) && (m_ZStream.avail_out == 0))
-  {
-    m_ZStream.next_out = (Bytef*)lpBuffer;
-    m_ZStream.avail_out = iBufSize;
-    iMessage = inflate(&m_ZStream,Z_SYNC_FLUSH);
-  }
-  m_bFlush = false;
-}
-
-int CFileZip::UnpackFromMemory(string& strDest, const string& strInput, bool isGZ)
-{
-  unsigned int iPos=0;
-  int iResult=0;
-  while( iPos+LHDR_SIZE < strInput.size() || isGZ)
-  {
-    if (!isGZ)
-    {
-      CZipManager::readHeader(strInput.data()+iPos,mZipItem);
-      if( mZipItem.header != ZIP_LOCAL_HEADER )
-        return iResult;
-      if( (mZipItem.flags & 8) == 8 )
-      {
-        CLog::Log(LOGERROR,"FileZip: extended local header, not supported!");
-        return iResult;
-      }
-    }
-    if (!InitDecompress())
-      return iResult;
-    // we have a file - fill the buffer
-    char* temp;
-    int toRead=0;
-    if (isGZ)
-    {
-      m_ZStream.avail_in = strInput.size();
-      m_ZStream.next_in = (Bytef*)strInput.data();
-      temp = new char[8192];
-      toRead = 8191;
-    }
-    else
-    {
-      m_ZStream.avail_in = mZipItem.csize;
-      m_ZStream.next_in = (Bytef*)strInput.data()+iPos+LHDR_SIZE+mZipItem.flength+mZipItem.elength;
-      // init m_zipitem
-      strDest.reserve(mZipItem.usize);
-      temp = new char[mZipItem.usize+1];
-      toRead = mZipItem.usize;
-    }
-    int iCurrResult;
-    while( (iCurrResult=Read(temp,toRead)) > 0)
-    {
-      strDest.append(temp,temp+iCurrResult);
-      iResult += iCurrResult;
-    }
-    Close();
-    delete[] temp;
-    iPos += LHDR_SIZE+mZipItem.flength+mZipItem.elength+mZipItem.csize;
-    if (isGZ)
-      break;
-  }
-
-  return iResult;
-}
-
-
diff --git a/xbmc/filesystem/FileZip.h b/xbmc/filesystem/FileZip.h
deleted file mode 100644 (file)
index 30c4abf..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef FILE_ZIP_H_
-#define FILE_ZIP_H_
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-
-#include "IFile.h"
-#include <zlib.h>
-#include "utils/log.h"
-#include "File.h"
-#include "ZipManager.h"
-
-namespace XFILE
-{
-  class CFileZip : public IFile
-  {
-  public:
-    CFileZip();
-    virtual ~CFileZip();
-
-    virtual int64_t GetPosition();
-    virtual int64_t GetLength();
-    virtual bool Open(const CURL& url);
-    virtual bool Exists(const CURL& url);
-    virtual int Stat(struct __stat64* buffer);
-    virtual int Stat(const CURL& url, struct __stat64* buffer);
-    virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-    //virtual bool ReadString(char *szLine, int iLineLength);
-    virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-    virtual void Close();
-
-    int UnpackFromMemory(std::string& strDest, const std::string& strInput, bool isGZ=false);
-  private:
-    bool InitDecompress();
-    bool FillBuffer();
-    void DestroyBuffer(void* lpBuffer, int iBufSize);
-    CFile mFile;
-    SZipEntry mZipItem;
-    int64_t m_iFilePos; // position in _uncompressed_ data read
-    int64_t m_iZipFilePos; // position in _compressed_ data
-    int m_iAvailBuffer;
-    z_stream m_ZStream;
-    char m_szBuffer[65535];     // 64k buffer for compressed data
-    char* m_szStringBuffer;
-    char* m_szStartOfStringBuffer; // never allocated!
-    int m_iDataInStringBuffer;
-    int m_iRead;
-    bool m_bFlush;
-    bool m_bCached;
-  };
-}
-
-#endif
index 62c8879..66196a6 100644 (file)
@@ -78,9 +78,6 @@ bool CHDDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &items
     // Reset iso reader and remount or
     // we can't access the dvd-rom
     m_isoReader.Reset();
-
-    CIoSupport::Dismount("Cdrom0");
-    CIoSupport::RemapDriveLetter('D', "Cdrom0");
   }
 
 #ifdef _WIN32
diff --git a/xbmc/filesystem/HDFile.cpp b/xbmc/filesystem/HDFile.cpp
new file mode 100644 (file)
index 0000000..e47980a
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * XBMC Media Center
+ * Copyright (c) 2002 Frodo
+ * Portions Copyright (c) by the authors of ffmpeg and xvid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "system.h"
+#include "HDFile.h"
+#include "Util.h"
+#include "URL.h"
+#include "utils/AliasShortcutUtils.h"
+#ifdef _LINUX
+#include "XHandle.h"
+#endif
+
+#include <sys/stat.h>
+#ifdef _LINUX
+#include <sys/ioctl.h>
+#else
+#include <io.h>
+#include "utils/CharsetConverter.h"
+#include "utils/URIUtils.h"
+#endif
+#include "utils/log.h"
+
+
+using namespace XFILE;
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+//*********************************************************************************************
+CHDFile::CHDFile()
+    : m_hFile(INVALID_HANDLE_VALUE)
+{}
+
+//*********************************************************************************************
+CHDFile::~CHDFile()
+{
+  if (m_hFile != INVALID_HANDLE_VALUE) Close();
+}
+//*********************************************************************************************
+CStdString CHDFile::GetLocal(const CURL &url)
+{
+  CStdString path( url.GetFileName() );
+
+  if( url.GetProtocol().Equals("file", false) )
+  {
+    // file://drive[:]/path
+    // file:///drive:/path
+    CStdString host( url.GetHostName() );
+
+    if(host.size() > 0)
+    {
+      if(host.Right(1) == ":")
+        path = host + "/" + path;
+      else
+        path = host + ":/" + path;
+    }
+  }
+
+#ifndef _LINUX
+  path.Replace('/', '\\');
+#endif
+
+  if (IsAliasShortcut(path))
+    TranslateAliasShortcut(path);
+
+  return path;
+}
+
+//*********************************************************************************************
+bool CHDFile::Open(const CURL& url)
+{
+  CStdString strFile = GetLocal(url);
+
+#ifdef _WIN32
+  CStdStringW strWFile;
+  g_charsetConverter.utf8ToW(strFile, strWFile, false);
+  m_hFile.attach(CreateFileW(strWFile.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL));
+#else
+  m_hFile.attach(CreateFile(strFile.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL));
+#endif
+  if (!m_hFile.isValid()) return false;
+
+  m_i64FilePos = 0;
+  m_i64FileLen = 0;
+
+  return true;
+}
+
+bool CHDFile::Exists(const CURL& url)
+{
+  struct __stat64 buffer;
+  CStdString strFile = GetLocal(url);
+
+#ifdef _WIN32
+  CStdStringW strWFile;
+  URIUtils::RemoveSlashAtEnd(strFile);
+  g_charsetConverter.utf8ToW(strFile, strWFile, false);
+  return (_wstat64(strWFile.c_str(), &buffer)==0);
+#else
+  return (_stat64(strFile.c_str(), &buffer)==0);
+#endif
+}
+
+int CHDFile::Stat(struct __stat64* buffer)
+{
+#ifdef _LINUX
+  return _fstat64((*m_hFile).fd, buffer);
+#else
+  // Duplicate the handle, as retrieving and closing a matching crt handle closes the crt handle AND the original Windows handle.
+  HANDLE hFileDup;
+  if (0 == DuplicateHandle(GetCurrentProcess(), (HANDLE)m_hFile, GetCurrentProcess(), &hFileDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
+  {
+    CLog::Log(LOGERROR, __FUNCTION__" - DuplicateHandle()");
+    return -1;
+  }
+
+  int fd;
+  fd = _open_osfhandle((intptr_t)((HANDLE)hFileDup), 0);
+  if (fd == -1)
+  {
+    CLog::Log(LOGERROR, "Stat: fd == -1");
+    return -1;
+  }
+  int result = _fstat64(fd, buffer);
+  _close(fd);
+  return result;
+#endif
+}
+
+int CHDFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  CStdString strFile = GetLocal(url);
+
+#ifdef _WIN32
+  CStdStringW strWFile;
+  // win32 can only stat root drives with a slash at the end
+  if(strFile.length() == 2 && strFile[1] ==':')
+    URIUtils::AddSlashAtEnd(strFile);
+  /* _wstat64 calls FindFirstFileEx. According to MSDN, the path should not end in a trailing backslash.
+    Remove it before calling _wstat64 */
+  if (strFile.length() > 3 && URIUtils::HasSlashAtEnd(strFile))
+    URIUtils::RemoveSlashAtEnd(strFile);
+  g_charsetConverter.utf8ToW(strFile, strWFile, false);
+  return _wstat64(strWFile.c_str(), buffer);
+#else
+  return _stat64(strFile.c_str(), buffer);
+#endif
+}
+
+bool CHDFile::SetHidden(const CURL &url, bool hidden)
+{
+#ifdef _WIN32
+  CStdStringW path;
+  g_charsetConverter.utf8ToW(GetLocal(url), path, false);
+  DWORD attributes = hidden ? FILE_ATTRIBUTE_HIDDEN : FILE_ATTRIBUTE_NORMAL;
+  if (SetFileAttributesW(path.c_str(), attributes))
+    return true;
+#endif
+  return false;
+}
+
+//*********************************************************************************************
+bool CHDFile::OpenForWrite(const CURL& url, bool bOverWrite)
+{
+  // make sure it's a legal FATX filename (we are writing to the harddisk)
+  CStdString strPath = GetLocal(url);
+
+#ifdef _WIN32
+  CStdStringW strWPath;
+  g_charsetConverter.utf8ToW(strPath, strWPath, false);
+  m_hFile.attach(CreateFileW(strWPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
+#else
+  m_hFile.attach(CreateFile(strPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
+#endif
+  if (!m_hFile.isValid())
+    return false;
+
+  m_i64FilePos = 0;
+  Seek(0, SEEK_SET);
+
+  return true;
+}
+
+//*********************************************************************************************
+unsigned int CHDFile::Read(void *lpBuf, int64_t uiBufSize)
+{
+  if (!m_hFile.isValid()) return 0;
+  DWORD nBytesRead;
+  if ( ReadFile((HANDLE)m_hFile, lpBuf, (DWORD)uiBufSize, &nBytesRead, NULL) )
+  {
+    m_i64FilePos += nBytesRead;
+    return nBytesRead;
+  }
+  return 0;
+}
+
+//*********************************************************************************************
+int CHDFile::Write(const void *lpBuf, int64_t uiBufSize)
+{
+  if (!m_hFile.isValid())
+    return 0;
+
+  DWORD nBytesWriten;
+  if ( WriteFile((HANDLE)m_hFile, (void*) lpBuf, (DWORD)uiBufSize, &nBytesWriten, NULL) )
+    return nBytesWriten;
+
+  return 0;
+}
+
+//*********************************************************************************************
+void CHDFile::Close()
+{
+  m_hFile.reset();
+}
+
+//*********************************************************************************************
+int64_t CHDFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  LARGE_INTEGER lPos, lNewPos;
+  lPos.QuadPart = iFilePosition;
+  int bSuccess;
+
+  switch (iWhence)
+  {
+  case SEEK_SET:
+    bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_BEGIN);
+    break;
+
+  case SEEK_CUR:
+    bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_CURRENT);
+    break;
+
+  case SEEK_END:
+    bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_END);
+    break;
+
+  default:
+    return -1;
+  }
+  if (bSuccess)
+  {
+    m_i64FilePos = lNewPos.QuadPart;
+    return m_i64FilePos;
+  }
+  else
+    return -1;
+}
+
+//*********************************************************************************************
+int64_t CHDFile::GetLength()
+{
+  if(m_i64FileLen <= m_i64FilePos || m_i64FileLen == 0)
+  {
+    LARGE_INTEGER i64Size;
+    if(GetFileSizeEx((HANDLE)m_hFile, &i64Size))
+      m_i64FileLen = i64Size.QuadPart;
+    else
+      CLog::Log(LOGERROR, "CHDFile::GetLength - GetFileSizeEx failed with error %d", GetLastError());
+  }
+  return m_i64FileLen;
+}
+
+//*********************************************************************************************
+int64_t CHDFile::GetPosition()
+{
+  return m_i64FilePos;
+}
+
+bool CHDFile::Delete(const CURL& url)
+{
+  CStdString strFile=GetLocal(url);
+
+#ifdef _WIN32
+  CStdStringW strWFile;
+  g_charsetConverter.utf8ToW(strFile, strWFile, false);
+  return ::DeleteFileW(strWFile.c_str()) ? true : false;
+#else
+  return ::DeleteFile(strFile.c_str()) ? true : false;
+#endif
+}
+
+bool CHDFile::Rename(const CURL& url, const CURL& urlnew)
+{
+  CStdString strFile=GetLocal(url);
+  CStdString strNewFile=GetLocal(urlnew);
+
+#ifdef _WIN32
+  CStdStringW strWFile;
+  CStdStringW strWNewFile;
+  g_charsetConverter.utf8ToW(strFile, strWFile, false);
+  g_charsetConverter.utf8ToW(strNewFile, strWNewFile, false);
+  return ::MoveFileW(strWFile.c_str(), strWNewFile.c_str()) ? true : false;
+#else
+  return ::MoveFile(strFile.c_str(), strNewFile.c_str()) ? true : false;
+#endif
+}
+
+void CHDFile::Flush()
+{
+  ::FlushFileBuffers(m_hFile);
+}
+
+int CHDFile::IoControl(EIoControl request, void* param)
+{
+#ifdef _LINUX
+  if(request == IOCTRL_NATIVE && param)
+  {
+    SNativeIoControl* s = (SNativeIoControl*)param;
+    return ioctl((*m_hFile).fd, s->request, s->param);
+  }
+#endif
+  return -1;
+}
diff --git a/xbmc/filesystem/HDFile.h b/xbmc/filesystem/HDFile.h
new file mode 100644 (file)
index 0000000..ababf9e
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * XBMC Media Center
+ * Copyright (c) 2002 Frodo
+ * Portions Copyright (c) by the authors of ffmpeg and xvid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+// FileHD.h: interface for the CHDFile class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_FILEHD_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_)
+#define AFX_FILEHD_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "IFile.h"
+#include "utils/AutoPtrHandle.h"
+
+namespace XFILE
+{
+class CHDFile : public IFile
+{
+public:
+  CHDFile();
+  virtual ~CHDFile();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+  virtual int Stat(struct __stat64* buffer);
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int Write(const void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+  virtual void Flush();
+
+  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
+
+  virtual bool Delete(const CURL& url);
+  virtual bool Rename(const CURL& url, const CURL& urlnew);
+  virtual bool SetHidden(const CURL& url, bool hidden);
+
+  virtual int IoControl(EIoControl request, void* param);
+protected:
+  CStdString GetLocal(const CURL &url); /* crate a properly format path from an url */
+  AUTOPTR::CAutoPtrHandle m_hFile;
+  int64_t m_i64FilePos;
+  int64_t m_i64FileLen;
+};
+
+}
+#endif // !defined(AFX_FILEHD_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_)
diff --git a/xbmc/filesystem/HDHomeRun.cpp b/xbmc/filesystem/HDHomeRun.cpp
deleted file mode 100644 (file)
index ea141d2..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "threads/SystemClock.h"
-#include "system.h"
-#include "URL.h"
-#include "FileItem.h"
-#include "DllHDHomeRun.h"
-#include "HDHomeRun.h"
-#include "utils/TimeUtils.h"
-#include "utils/log.h"
-#include "utils/URIUtils.h"
-#include "Util.h"
-
-using namespace XFILE;
-using namespace std;
-
-class CUrlOptions
-  : public map<CStdString, CStdString>
-{
-public:
-  CUrlOptions(const CStdString& data)
-  {
-    vector<CStdString> options;
-    CUtil::Tokenize(data, options, "&");
-    for(vector<CStdString>::iterator it = options.begin();it != options.end(); it++)
-    {
-      CStdString name, value;
-      unsigned int pos = it->find_first_of('=');
-      if(pos != CStdString::npos)
-      {
-        name = it->substr(0, pos);
-        value = it->substr(pos+1);
-      }
-      else
-      {
-        name = *it;
-        value = "";
-      }
-
-      CURL::Decode(name);
-      CURL::Decode(value);
-      insert(value_type(name, value));
-    }
-  }
-};
-
-
-// -------------------------------------------
-// ---------------- Directory ----------------
-// -------------------------------------------
-
-CDirectoryHomeRun::CDirectoryHomeRun()
-{
-  m_pdll = new DllHdHomeRun;
-  m_pdll->Load();
-}
-
-CDirectoryHomeRun::~CDirectoryHomeRun()
-{
-  m_pdll->Unload();
-  delete m_pdll;
-}
-
-bool CDirectoryHomeRun::GetDirectory(const CStdString& strPath, CFileItemList &items)
-{
-  if(!m_pdll->IsLoaded())
-    return false;
-
-  CURL url(strPath);
-
-  if(url.GetHostName().IsEmpty())
-  {
-    // no hostname, list all available devices
-    int target_ip = 0;
-    struct hdhomerun_discover_device_t result_list[64];
-    int count = m_pdll->discover_find_devices_custom(target_ip, HDHOMERUN_DEVICE_TYPE_TUNER, HDHOMERUN_DEVICE_ID_WILDCARD, result_list, 64);
-    if (count < 0)
-      return false;
-
-    for(int i=0;i<count;i++)
-    {
-      CStdString device, ip;
-      CFileItemPtr item;
-      unsigned int ip_addr = result_list[i].ip_addr;
-
-      device.Format("%x", result_list[i].device_id);
-      ip.Format("%u.%u.%u.%u",
-            (unsigned int)(ip_addr >> 24) & 0xFF, (unsigned int)(ip_addr >> 16) & 0xFF,
-            (unsigned int)(ip_addr >> 8) & 0xFF, (unsigned int)(ip_addr >> 0) & 0xFF);
-
-      item.reset(new CFileItem("hdhomerun://" + device + "/tuner0/", true));
-      item->SetLabel(device + "-0 On " + ip);
-      item->SetLabelPreformated(true);
-      items.Add(item);
-
-      item.reset(new CFileItem("hdhomerun://" + device + "/tuner1/", true));
-      item->SetLabel(device + "-1 On " + ip);
-      item->SetLabelPreformated(true);
-      items.Add(item);
-    }
-    return true;
-  }
-  else
-  {
-    hdhomerun_device_t* device = m_pdll->device_create_from_str(url.GetHostName().c_str(), NULL);
-    if(!device)
-      return false;
-
-    m_pdll->device_set_tuner_from_str(device, url.GetFileName().c_str());
-
-    hdhomerun_tuner_status_t status;
-    if(!m_pdll->device_get_tuner_status(device, NULL, &status))
-    {
-      m_pdll->device_destroy(device);
-      return true;
-    }
-
-    CStdString label;
-    if(status.signal_present)
-      label.Format("Current Stream: N/A");
-    else
-      label.Format("Current Stream: Channel %s, SNR %d", status.channel, status.signal_to_noise_quality);
-
-    CStdString path = "hdhomerun://" + url.GetHostName() + "/" + url.GetFileName();
-    URIUtils::RemoveSlashAtEnd(path);
-    CFileItemPtr item(new CFileItem(path, false));
-    item->SetLabel(label);
-    item->SetLabelPreformated(true);
-    items.Add(item);
-
-    m_pdll->device_destroy(device);
-    return true;
-  }
-
-  return false;
-}
-
-
-// -------------------------------------------
-// ------------------ File -------------------
-// -------------------------------------------
-CFileHomeRun::CFileHomeRun()
-{
-  m_device = NULL;
-  m_pdll = new DllHdHomeRun;
-  m_pdll->Load();
-}
-
-CFileHomeRun::~CFileHomeRun()
-{
-  Close();
-  delete m_pdll;
-}
-
-bool CFileHomeRun::Exists(const CURL& url)
-{
-  CStdString path(url.GetFileName());
-
-  /*
-   * HDHomeRun URLs are of the form hdhomerun://1014F6D1/tuner0?channel=qam:108&program=10
-   * The filename starts with "tuner" and has no extension. This check will cover off requests
-   * for *.tbn, *.jpg, *.jpeg, *.edl etc. that do not exist.
-   */
-  if(path.Left(5) == "tuner"
-  && URIUtils::GetExtension(path).IsEmpty())
-    return true;
-
-  return false;
-}
-
-int64_t CFileHomeRun::Seek(int64_t iFilePosition, int iWhence)
-{
-  return -1;
-}
-
-int CFileHomeRun::Stat(const CURL& url, struct __stat64* buffer)
-{
-  memset(buffer, 0, sizeof(struct __stat64));
-  return 0;
-}
-
-int64_t CFileHomeRun::GetPosition()
-{
-  return 0;
-}
-
-int64_t CFileHomeRun::GetLength()
-{
-  return 0;
-}
-
-bool CFileHomeRun::Open(const CURL &url)
-{
-  if(!m_pdll->IsLoaded())
-    return false;
-
-  m_device = m_pdll->device_create_from_str(url.GetHostName().c_str(), NULL);
-  if(!m_device)
-    return false;
-
-  m_pdll->device_set_tuner_from_str(m_device, url.GetFileName().c_str());
-
-  CUrlOptions options(url.GetOptions().Mid(1));
-  CUrlOptions::iterator it;
-
-  if( (it = options.find("channel")) != options.end() )
-    m_pdll->device_set_tuner_channel(m_device, it->second.c_str());
-
-  if( (it = options.find("program")) != options.end() )
-    m_pdll->device_set_tuner_program(m_device, it->second.c_str());
-
-  // start streaming from selected device and tuner
-  if( m_pdll->device_stream_start(m_device) <= 0 )
-    return false;
-
-  return true;
-}
-
-unsigned int CFileHomeRun::Read(void* lpBuf, int64_t uiBufSize)
-{
-  size_t datasize;
-
-  if(uiBufSize < VIDEO_DATA_PACKET_SIZE)
-    CLog::Log(LOGWARNING, "CFileHomeRun::Read - buffer size too small, will most likely fail");
-
-  // for now, let it it time out after 5 seconds,
-  // neither of the players can be forced to
-  // continue even if read return 0 as can happen
-  // on live streams.
-  XbmcThreads::EndTime timestamp(5000);
-  while(1)
-  {
-    datasize = (size_t) uiBufSize;
-    uint8_t* ptr = m_pdll->device_stream_recv(m_device, datasize, &datasize);
-    if(ptr)
-    {
-      memcpy(lpBuf, ptr, datasize);
-      return (unsigned int)datasize;
-    }
-
-    if(timestamp.IsTimePast())
-      return 0;
-
-    Sleep(64);
-  }
-  return (unsigned int)datasize;
-}
-
-void CFileHomeRun::Close()
-{
-  if(m_device)
-  {
-    m_pdll->device_stream_stop(m_device);
-    m_pdll->device_destroy(m_device);
-    m_device = NULL;
-  }
-}
-
-int CFileHomeRun::GetChunkSize()
-{
-  return VIDEO_DATA_PACKET_SIZE;
-}
diff --git a/xbmc/filesystem/HDHomeRun.h b/xbmc/filesystem/HDHomeRun.h
deleted file mode 100644 (file)
index e3e3a51..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "IDirectory.h"
-#include "IFile.h"
-
-struct hdhomerun_device;
-class DllHdHomeRun;
-
-namespace XFILE
-{
-  class CDirectoryHomeRun : public IDirectory
-  {
-    public:
-      CDirectoryHomeRun(void);
-      virtual ~CDirectoryHomeRun(void);
-      virtual bool IsAllowed(const CStdString &strFile) const { return true; };
-      virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items);
-    private:
-      DllHdHomeRun* m_pdll;
-  };
-}
-
-namespace XFILE
-{
-  class CFileHomeRun : public IFile
-  {
-    public:
-      CFileHomeRun();
-      ~CFileHomeRun();
-
-      virtual bool          Exists(const CURL& url);
-      virtual int64_t       Seek(int64_t iFilePosition, int iWhence);
-      virtual int           Stat(const CURL& url, struct __stat64* buffer);
-      virtual int64_t       GetPosition();
-      virtual int64_t       GetLength();
-
-      virtual bool          Open(const CURL& url);
-      virtual void          Close();
-      virtual unsigned int  Read(void* lpBuf, int64_t uiBufSize);
-      virtual int           GetChunkSize();
-    private:
-      struct hdhomerun_device_t* m_device;
-      DllHdHomeRun* m_pdll;
-  };
-}
diff --git a/xbmc/filesystem/HDHomeRunDirectory.cpp b/xbmc/filesystem/HDHomeRunDirectory.cpp
new file mode 100644 (file)
index 0000000..44719af
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+#include "HDHomeRunDirectory.h"
+#include "URL.h"
+#include "FileItem.h"
+#include "utils/URIUtils.h"
+#include "DllHDHomeRun.h"
+
+using namespace XFILE;
+using namespace std;
+
+// -------------------------------------------
+// ---------------- Directory ----------------
+// -------------------------------------------
+
+CHomeRunDirectory::CHomeRunDirectory()
+{
+  m_pdll = new DllHdHomeRun;
+  m_pdll->Load();
+}
+
+CHomeRunDirectory::~CHomeRunDirectory()
+{
+  m_pdll->Unload();
+  delete m_pdll;
+}
+
+bool CHomeRunDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
+{
+  if(!m_pdll->IsLoaded())
+    return false;
+
+  CURL url(strPath);
+
+  if(url.GetHostName().IsEmpty())
+  {
+    // no hostname, list all available devices
+    int target_ip = 0;
+    struct hdhomerun_discover_device_t result_list[64];
+    int count = m_pdll->discover_find_devices_custom(target_ip, HDHOMERUN_DEVICE_TYPE_TUNER, HDHOMERUN_DEVICE_ID_WILDCARD, result_list, 64);
+    if (count < 0)
+      return false;
+
+    for(int i=0;i<count;i++)
+    {
+      CStdString device, ip;
+      CFileItemPtr item;
+      unsigned int ip_addr = result_list[i].ip_addr;
+
+      device.Format("%x", result_list[i].device_id);
+      ip.Format("%u.%u.%u.%u",
+            (unsigned int)(ip_addr >> 24) & 0xFF, (unsigned int)(ip_addr >> 16) & 0xFF,
+            (unsigned int)(ip_addr >> 8) & 0xFF, (unsigned int)(ip_addr >> 0) & 0xFF);
+
+      item.reset(new CFileItem("hdhomerun://" + device + "/tuner0/", true));
+      item->SetLabel(device + "-0 On " + ip);
+      item->SetLabelPreformated(true);
+      items.Add(item);
+
+      item.reset(new CFileItem("hdhomerun://" + device + "/tuner1/", true));
+      item->SetLabel(device + "-1 On " + ip);
+      item->SetLabelPreformated(true);
+      items.Add(item);
+    }
+    return true;
+  }
+  else
+  {
+    hdhomerun_device_t* device = m_pdll->device_create_from_str(url.GetHostName().c_str(), NULL);
+    if(!device)
+      return false;
+
+    m_pdll->device_set_tuner_from_str(device, url.GetFileName().c_str());
+
+    hdhomerun_tuner_status_t status;
+    if(!m_pdll->device_get_tuner_status(device, NULL, &status))
+    {
+      m_pdll->device_destroy(device);
+      return true;
+    }
+
+    CStdString label;
+    if(status.signal_present)
+      label.Format("Current Stream: N/A");
+    else
+      label.Format("Current Stream: Channel %s, SNR %d", status.channel, status.signal_to_noise_quality);
+
+    CStdString path = "hdhomerun://" + url.GetHostName() + "/" + url.GetFileName();
+    URIUtils::RemoveSlashAtEnd(path);
+    CFileItemPtr item(new CFileItem(path, false));
+    item->SetLabel(label);
+    item->SetLabelPreformated(true);
+    items.Add(item);
+
+    m_pdll->device_destroy(device);
+    return true;
+  }
+
+  return false;
+}
diff --git a/xbmc/filesystem/HDHomeRunDirectory.h b/xbmc/filesystem/HDHomeRunDirectory.h
new file mode 100644 (file)
index 0000000..44ff76b
--- /dev/null
@@ -0,0 +1,39 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+ #include "IDirectory.h"
+
+class DllHdHomeRun;
+namespace XFILE
+{
+  class CHomeRunDirectory : public IDirectory
+  {
+    public:
+      CHomeRunDirectory(void);
+      virtual ~CHomeRunDirectory(void);
+      virtual bool IsAllowed(const CStdString &strFile) const { return true; };
+      virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items);
+    private:
+      DllHdHomeRun* m_pdll;
+  };
+}
diff --git a/xbmc/filesystem/HDHomeRunFile.cpp b/xbmc/filesystem/HDHomeRunFile.cpp
new file mode 100644 (file)
index 0000000..5ab518d
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "threads/SystemClock.h"
+#include "system.h"
+#include "URL.h"
+#include "FileItem.h"
+#include "DllHDHomeRun.h"
+#include "HDHomeRunFile.h"
+#include "utils/TimeUtils.h"
+#include "utils/log.h"
+#include "utils/URIUtils.h"
+#include "Util.h"
+
+using namespace XFILE;
+using namespace std;
+
+class CUrlOptions
+  : public map<CStdString, CStdString>
+{
+public:
+  CUrlOptions(const CStdString& data)
+  {
+    vector<CStdString> options;
+    CUtil::Tokenize(data, options, "&");
+    for(vector<CStdString>::iterator it = options.begin();it != options.end(); it++)
+    {
+      CStdString name, value;
+      unsigned int pos = it->find_first_of('=');
+      if(pos != CStdString::npos)
+      {
+        name = it->substr(0, pos);
+        value = it->substr(pos+1);
+      }
+      else
+      {
+        name = *it;
+        value = "";
+      }
+
+      CURL::Decode(name);
+      CURL::Decode(value);
+      insert(value_type(name, value));
+    }
+  }
+};
+
+// -------------------------------------------
+// ------------------ File -------------------
+// -------------------------------------------
+CHomeRunFile::CHomeRunFile()
+{
+  m_device = NULL;
+  m_pdll = new DllHdHomeRun;
+  m_pdll->Load();
+}
+
+CHomeRunFile::~CHomeRunFile()
+{
+  Close();
+  delete m_pdll;
+}
+
+bool CHomeRunFile::Exists(const CURL& url)
+{
+  CStdString path(url.GetFileName());
+
+  /*
+   * HDHomeRun URLs are of the form hdhomerun://1014F6D1/tuner0?channel=qam:108&program=10
+   * The filename starts with "tuner" and has no extension. This check will cover off requests
+   * for *.tbn, *.jpg, *.jpeg, *.edl etc. that do not exist.
+   */
+  if(path.Left(5) == "tuner"
+  && URIUtils::GetExtension(path).IsEmpty())
+    return true;
+
+  return false;
+}
+
+int64_t CHomeRunFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  return -1;
+}
+
+int CHomeRunFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  memset(buffer, 0, sizeof(struct __stat64));
+  return 0;
+}
+
+int64_t CHomeRunFile::GetPosition()
+{
+  return 0;
+}
+
+int64_t CHomeRunFile::GetLength()
+{
+  return 0;
+}
+
+bool CHomeRunFile::Open(const CURL &url)
+{
+  if(!m_pdll->IsLoaded())
+    return false;
+
+  m_device = m_pdll->device_create_from_str(url.GetHostName().c_str(), NULL);
+  if(!m_device)
+    return false;
+
+  m_pdll->device_set_tuner_from_str(m_device, url.GetFileName().c_str());
+
+  CUrlOptions options(url.GetOptions().Mid(1));
+  CUrlOptions::iterator it;
+
+  if( (it = options.find("channel")) != options.end() )
+    m_pdll->device_set_tuner_channel(m_device, it->second.c_str());
+
+  if( (it = options.find("program")) != options.end() )
+    m_pdll->device_set_tuner_program(m_device, it->second.c_str());
+
+  // start streaming from selected device and tuner
+  if( m_pdll->device_stream_start(m_device) <= 0 )
+    return false;
+
+  return true;
+}
+
+unsigned int CHomeRunFile::Read(void* lpBuf, int64_t uiBufSize)
+{
+  size_t datasize;
+
+  if(uiBufSize < VIDEO_DATA_PACKET_SIZE)
+    CLog::Log(LOGWARNING, "CHomeRunFile::Read - buffer size too small, will most likely fail");
+
+  // for now, let it it time out after 5 seconds,
+  // neither of the players can be forced to
+  // continue even if read return 0 as can happen
+  // on live streams.
+  XbmcThreads::EndTime timestamp(5000);
+  while(1)
+  {
+    datasize = (size_t) uiBufSize;
+    uint8_t* ptr = m_pdll->device_stream_recv(m_device, datasize, &datasize);
+    if(ptr)
+    {
+      memcpy(lpBuf, ptr, datasize);
+      return (unsigned int)datasize;
+    }
+
+    if(timestamp.IsTimePast())
+      return 0;
+
+    Sleep(64);
+  }
+  return (unsigned int)datasize;
+}
+
+void CHomeRunFile::Close()
+{
+  if(m_device)
+  {
+    m_pdll->device_stream_stop(m_device);
+    m_pdll->device_destroy(m_device);
+    m_device = NULL;
+  }
+}
+
+int CHomeRunFile::GetChunkSize()
+{
+  return VIDEO_DATA_PACKET_SIZE;
+}
diff --git a/xbmc/filesystem/HDHomeRunFile.h b/xbmc/filesystem/HDHomeRunFile.h
new file mode 100644 (file)
index 0000000..abb1688
--- /dev/null
@@ -0,0 +1,50 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IFile.h"
+
+struct hdhomerun_device;
+class DllHdHomeRun;
+
+namespace XFILE
+{
+  class CHomeRunFile : public IFile
+  {
+    public:
+      CHomeRunFile();
+      ~CHomeRunFile();
+
+      virtual bool          Exists(const CURL& url);
+      virtual int64_t       Seek(int64_t iFilePosition, int iWhence);
+      virtual int           Stat(const CURL& url, struct __stat64* buffer);
+      virtual int64_t       GetPosition();
+      virtual int64_t       GetLength();
+
+      virtual bool          Open(const CURL& url);
+      virtual void          Close();
+      virtual unsigned int  Read(void* lpBuf, int64_t uiBufSize);
+      virtual int           GetChunkSize();
+    private:
+      struct hdhomerun_device_t* m_device;
+      DllHdHomeRun* m_pdll;
+  };
+}
index 12e4895..da8de46 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "HTTPDirectory.h"
 #include "URL.h"
-#include "FileCurl.h"
+#include "CurlFile.h"
 #include "FileItem.h"
 #include "utils/RegExp.h"
 #include "settings/AdvancedSettings.h"
@@ -39,7 +39,7 @@ CHTTPDirectory::~CHTTPDirectory(void){}
 
 bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
 {
-  CFileCurl http;
+  CCurlFile http;
   CURL url(strPath);
 
   CStdString strName, strLink;
@@ -51,9 +51,21 @@ bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &item
     return false;
   }
 
-  CRegExp reItem;
+  CRegExp reItem(true); // HTML is case-insensitive
   reItem.RegComp("<a href=\"(.*)\">(.*)</a>");
 
+  CRegExp reDateTime(true);
+  reDateTime.RegComp("<td align=\"right\">([0-9]{2})-([A-Z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}) +</td>");
+
+  CRegExp reDateTimeNginx(true);
+  reDateTimeNginx.RegComp("</a> +([0-9]{2})-([A-Z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}) ");
+
+  CRegExp reSize(true);
+  reSize.RegComp(">*([0-9.]+)(B|K|M|G| )</td>");
+
+  CRegExp reSizeNginx;
+  reSizeNginx.RegComp("([0-9]+)$");
+
   /* read response from server into string buffer */
   char buffer[MAX_PATH + 1024];
   while(http.ReadString(buffer, sizeof(buffer)-1))
@@ -75,7 +87,7 @@ bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &item
       URIUtils::RemoveSlashAtEnd(strNameTemp);
       CURL::Decode(strLinkTemp);
 
-      if (strNameTemp == strLinkTemp)
+      if (strNameTemp == strLinkTemp && strLinkTemp != "..")
       {
         CStdStringW wName, wLink, wConverted;
 
@@ -98,18 +110,32 @@ bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &item
         if(URIUtils::HasSlashAtEnd(pItem->GetPath()))
           pItem->m_bIsFolder = true;
 
-        if (!pItem->m_bIsFolder && g_advancedSettings.m_bHTTPDirectoryStatFilesize)
+        CStdString day, month, year, hour, minute;
+
+        if (reDateTime.RegFind(strBuffer.c_str()) >= 0)
+        {
+          day = reDateTime.GetReplaceString("\\1");
+          month = reDateTime.GetReplaceString("\\2");
+          year = reDateTime.GetReplaceString("\\3");
+          hour = reDateTime.GetReplaceString("\\4");
+          minute = reDateTime.GetReplaceString("\\5");
+        }
+        else if (reDateTimeNginx.RegFind(strBuffer.c_str()) >= 0)
+        {
+          day = reDateTimeNginx.GetReplaceString("\\1");
+          month = reDateTimeNginx.GetReplaceString("\\2");
+          year = reDateTimeNginx.GetReplaceString("\\3");
+          hour = reDateTimeNginx.GetReplaceString("\\4");
+          minute = reDateTimeNginx.GetReplaceString("\\5");
+        }
+
+        if (day.length() > 0 && month.length() > 0 && year.length() > 0)
         {
-          CFileCurl file;
-          file.Open(url);
-          pItem->m_dwSize= file.GetLength();
-          file.Close();
+          pItem->m_dateTime = CDateTime(atoi(year.c_str()), CDateTime::MonthStringToMonthNum(month), atoi(day.c_str()), atoi(hour.c_str()), atoi(minute.c_str()), 0);
         }
 
-        if (!pItem->m_bIsFolder && pItem->m_dwSize == 0)
+        if (!pItem->m_bIsFolder)
         {
-          CRegExp reSize;
-          reSize.RegComp(">*([0-9.]+)(B|K|M|G| )</td>");
           if (reSize.RegFind(strBuffer.c_str()) >= 0)
           {
             double Size = atof(reSize.GetReplaceString("\\1"));
@@ -124,8 +150,20 @@ bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &item
 
             pItem->m_dwSize = (int64_t)Size;
           }
+          else if (reSizeNginx.RegFind(strBuffer.c_str()) >= 0)
+          {
+            double Size = atof(reSizeNginx.GetReplaceString("\\1"));
+            pItem->m_dwSize = (int64_t)Size;
+          }
+          else
+          if (g_advancedSettings.m_bHTTPDirectoryStatFilesize) // As a fallback get the size by stat-ing the file (slow)
+          {
+            CCurlFile file;
+            file.Open(url);
+            pItem->m_dwSize=file.GetLength();
+            file.Close();
+          }
         }
-
         items.Add(pItem);
       }
     }
@@ -139,7 +177,7 @@ bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &item
 
 bool CHTTPDirectory::Exists(const char* strPath)
 {
-  CFileCurl http;
+  CCurlFile http;
   CURL url(strPath);
   struct __stat64 buffer;
 
index 01e821b..5729c23 100644 (file)
@@ -38,9 +38,9 @@ namespace XFILE
  \ingroup filesystem
  \brief Interface to the directory on a file system.
 
- This Interface is retrieved from CFactoryDirectory and can be used to
+ This Interface is retrieved from CDirectoryFactory and can be used to
  access the directories on a filesystem.
- \sa CFactoryDirectory
+ \sa CDirectoryFactory
  */
 class IDirectory
 {
@@ -52,21 +52,21 @@ public:
    \param strPath Directory to read.
    \param items Retrieves the directory entries.
    \return Returns \e true, if successfull.
-   \sa CFactoryDirectory
+   \sa CDirectoryFactory
    */
   virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items) = 0;
   /*!
   \brief Create the directory
   \param strPath Directory to create.
   \return Returns \e true, if directory is created or if it already exists
-  \sa CFactoryDirectory
+  \sa CDirectoryFactory
   */
   virtual bool Create(const char* strPath) { return false; }
   /*!
   \brief Check for directory existence
   \param strPath Directory to check.
   \return Returns \e true, if directory exists
-  \sa CFactoryDirectory
+  \sa CDirectoryFactory
   */
   virtual bool Exists(const char* strPath) { return false; }
   /*!
diff --git a/xbmc/filesystem/ISOFile.cpp b/xbmc/filesystem/ISOFile.cpp
new file mode 100644 (file)
index 0000000..9baa95d
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+* XBMC Media Center
+* Copyright (c) 2002 Frodo
+* Portions Copyright (c) by the authors of ffmpeg and xvid
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "ISOFile.h"
+#include "URL.h"
+#include "iso9660.h"
+
+#include <sys/stat.h>
+
+using namespace std;
+using namespace XFILE;
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+//*********************************************************************************************
+CISOFile::CISOFile()
+{
+  m_bOpened = false;
+}
+
+//*********************************************************************************************
+CISOFile::~CISOFile()
+{
+  if (m_bOpened)
+  {
+    Close();
+  }
+}
+//*********************************************************************************************
+bool CISOFile::Open(const CURL& url)
+{
+  string strFName = "\\";
+  strFName += url.GetFileName();
+  for (int i = 0; i < (int)strFName.size(); ++i )
+  {
+    if (strFName[i] == '/') strFName[i] = '\\';
+  }
+  m_hFile = m_isoReader.OpenFile((char*)strFName.c_str());
+  if (m_hFile == INVALID_HANDLE_VALUE)
+  {
+    m_bOpened = false;
+    return false;
+  }
+
+  m_bOpened = true;
+  return true;
+}
+
+//*********************************************************************************************
+unsigned int CISOFile::Read(void *lpBuf, int64_t uiBufSize)
+{
+  if (!m_bOpened) return 0;
+  char *pData = (char *)lpBuf;
+
+  if (m_cache.getSize() > 0)
+  {
+    long lTotalBytesRead = 0;
+    while (uiBufSize > 0)
+    {
+      if (m_cache.getMaxReadSize() )
+      {
+        long lBytes2Read = m_cache.getMaxReadSize();
+        if (lBytes2Read > uiBufSize) lBytes2Read = (long)uiBufSize;
+        m_cache.ReadData(pData, lBytes2Read );
+        uiBufSize -= lBytes2Read ;
+        pData += lBytes2Read;
+        lTotalBytesRead += lBytes2Read ;
+      }
+
+      if (m_cache.getMaxWriteSize() > 5000)
+      {
+        byte buffer[5000];
+        long lBytesRead = m_isoReader.ReadFile( m_hFile, buffer, sizeof(buffer));
+        if (lBytesRead > 0)
+          m_cache.WriteData((char*)buffer, lBytesRead);
+        else
+          return 0;
+      }
+    }
+    return lTotalBytesRead;
+  }
+  int iResult = m_isoReader.ReadFile( m_hFile, (byte*)pData, (long)uiBufSize);
+  if (iResult == -1)
+    return 0;
+  return iResult;
+}
+
+//*********************************************************************************************
+void CISOFile::Close()
+{
+  if (!m_bOpened) return ;
+  m_isoReader.CloseFile( m_hFile);
+}
+
+//*********************************************************************************************
+int64_t CISOFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  if (!m_bOpened) return -1;
+  int64_t lNewPos = m_isoReader.Seek(m_hFile, iFilePosition, iWhence);
+  if(lNewPos >= 0)
+    m_cache.Clear();
+  return lNewPos;
+}
+
+//*********************************************************************************************
+int64_t CISOFile::GetLength()
+{
+  if (!m_bOpened) return -1;
+  return m_isoReader.GetFileSize(m_hFile);
+}
+
+//*********************************************************************************************
+int64_t CISOFile::GetPosition()
+{
+  if (!m_bOpened) return -1;
+  return m_isoReader.GetFilePosition(m_hFile);
+}
+
+bool CISOFile::Exists(const CURL& url)
+{
+  string strFName = "\\";
+  strFName += url.GetFileName();
+  for (int i = 0; i < (int)strFName.size(); ++i )
+  {
+    if (strFName[i] == '/') strFName[i] = '\\';
+  }
+  m_hFile = m_isoReader.OpenFile((char*)strFName.c_str());
+  if (m_hFile == INVALID_HANDLE_VALUE)
+    return false;
+
+  m_isoReader.CloseFile(m_hFile);
+  return true;
+}
+
+int CISOFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  string strFName = "\\";
+  strFName += url.GetFileName();
+  for (int i = 0; i < (int)strFName.size(); ++i )
+  {
+    if (strFName[i] == '/') strFName[i] = '\\';
+  }
+  m_hFile = m_isoReader.OpenFile((char*)strFName.c_str());
+  if (m_hFile != INVALID_HANDLE_VALUE)
+  {
+    memset(buffer, 0, sizeof(struct __stat64));
+    buffer->st_size = m_isoReader.GetFileSize(m_hFile);
+    buffer->st_mode = _S_IFREG;
+    m_isoReader.CloseFile(m_hFile);
+    return 0;
+  }
+  errno = ENOENT;
+  return -1;
+}
diff --git a/xbmc/filesystem/ISOFile.h b/xbmc/filesystem/ISOFile.h
new file mode 100644 (file)
index 0000000..6e87dff
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+* XBMC Media Center
+* Copyright (c) 2002 Frodo
+* Portions Copyright (c) by the authors of ffmpeg and xvid
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+// FileISO.h: interface for the CISOFile class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_FILEISO_H__C2FB9C6D_3319_4182_AB45_65E57EFAC8D1__INCLUDED_)
+#define AFX_FILEISO_H__C2FB9C6D_3319_4182_AB45_65E57EFAC8D1__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "IFile.h"
+#include "utils/RingBuffer.h"
+
+namespace XFILE
+{
+
+class CISOFile : public IFile
+{
+public:
+  CISOFile();
+  virtual ~CISOFile();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+protected:
+  bool m_bOpened;
+  HANDLE m_hFile;
+  CRingBuffer m_cache;
+};
+}
+
+#endif // !defined(AFX_FILEISO_H__C2FB9C6D_3319_4182_AB45_65E57EFAC8D1__INCLUDED_)
index af5621c..2b81346 100644 (file)
@@ -27,7 +27,7 @@
 #include "dialogs/GUIDialogProgress.h"
 #include "settings/GUISettings.h"
 #include "FileItem.h"
-#include "FileCurl.h"
+#include "CurlFile.h"
 #include "utils/StringUtils.h"
 #include "guilib/LocalizeStrings.h"
 #include "utils/log.h"
@@ -627,7 +627,7 @@ DIR_CACHE_TYPE CLastFMDirectory::GetCacheType(const CStdString& strPath) const
 
 void CLastFMDirectory::Run()
 {
-  XFILE::CFileCurl http;
+  XFILE::CCurlFile http;
   if (!http.Download(m_strSource, m_strDestination))
     m_Error=true;
 
index e50178d..ebbcfb6 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 #include "IDirectory.h"
-#include "FileCurl.h"
+#include "CurlFile.h"
 #include "tinyXML/tinyxml.h"
 #include "threads/Thread.h"
 
@@ -62,7 +62,7 @@ protected:
   bool m_Downloaded;
   TiXmlDocument m_xmlDoc;
 
-  XFILE::CFileCurl m_http;
+  XFILE::CCurlFile m_http;
 
   CStdString m_objtype;
   CStdString m_objname;
diff --git a/xbmc/filesystem/LastFMFile.cpp b/xbmc/filesystem/LastFMFile.cpp
new file mode 100644 (file)
index 0000000..1586e26
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "LastFMFile.h"
+
+namespace XFILE
+{
+
+CLastFMFile::CLastFMFile() : CCurlFile()
+{
+  SetUserAgent("");
+  SetBufferSize(8192);
+}
+
+CLastFMFile::~CLastFMFile()
+{
+}
+
+}
+
diff --git a/xbmc/filesystem/LastFMFile.h b/xbmc/filesystem/LastFMFile.h
new file mode 100644 (file)
index 0000000..7746799
--- /dev/null
@@ -0,0 +1,37 @@
+#pragma once
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "CurlFile.h"
+#include "utils/RingBuffer.h"
+
+namespace XFILE
+{
+
+  class CLastFMFile : public CCurlFile
+  {
+  public:
+    CLastFMFile();
+    virtual ~CLastFMFile();
+  protected:
+  };
+
+}
index 467df2b..7a50054 100644 (file)
@@ -4,43 +4,30 @@ CXXFLAGS+=-D__STDC_FORMAT_MACROS \
 
 SRCS=AddonsDirectory.cpp \
      ASAPFileDirectory.cpp \
-     CacheCircular.cpp \
-     CacheMemBuffer.cpp \
      CacheStrategy.cpp \
+     CircularCache.cpp \
      CDDADirectory.cpp \
+     CDDAFile.cpp \
+     CurlFile.cpp \
      DAAPDirectory.cpp \
+     DAAPFile.cpp \
      DAVDirectory.cpp \
-     DirectoryCache.cpp \
      Directory.cpp \
+     DirectoryCache.cpp \
+     DirectoryFactory.cpp \
      DirectoryHistory.cpp \
-     DirectoryTuxBox.cpp \
      DllLibCurl.cpp \
-     FactoryDirectory.cpp \
-     FactoryFileDirectory.cpp \
-     FileCache.cpp \
-     FileCDDA.cpp \
      File.cpp \
-     FileCurl.cpp \
-     FileDAAP.cpp \
+     FileCache.cpp \
+     FileDirectoryFactory.cpp \
      FileFactory.cpp \
-     FileFileReader.cpp \
-     FileHD.cpp \
-     FileISO.cpp \
-     FileLastFM.cpp \
-     FileMusicDatabase.cpp \
-     FilePipe.cpp \
-     FileRTV.cpp \
-     FileShoutcast.cpp \
-     FileSFTP.cpp \
-     FileSpecialProtocol.cpp \
-     FileTuxBox.cpp \
-     FileUDF.cpp \
-     FileUPnP.cpp \
-     FileZip.cpp \
+     FileReaderFile.cpp \
      FTPDirectory.cpp \
      FTPParse.cpp \
      HDDirectory.cpp \
-     HDHomeRun.cpp \
+     HDFile.cpp \
+     HDHomeRunDirectory.cpp \
+     HDHomeRunFile.cpp \
      HTSPDirectory.cpp \
      HTSPSession.cpp \
      HTTPDirectory.cpp \
@@ -48,10 +35,14 @@ SRCS=AddonsDirectory.cpp \
      IFile.cpp \
      iso9660.cpp \
      ISO9660Directory.cpp \
+     ISOFile.cpp \
      LastFMDirectory.cpp \
+     LastFMFile.cpp \
+     MemBufferCache.cpp \
      MultiPathDirectory.cpp \
      MultiPathFile.cpp \
      MusicDatabaseDirectory.cpp \
+     MusicDatabaseFile.cpp \
      MusicFileDirectory.cpp \
      MusicSearchDirectory.cpp \
      MythDirectory.cpp \
@@ -62,23 +53,33 @@ SRCS=AddonsDirectory.cpp \
      OGGFileDirectory.cpp \
      PlaylistDirectory.cpp \
      PlaylistFileDirectory.cpp \
+     PipeFile.cpp \
      PipesManager.cpp \
      PluginDirectory.cpp \
      RSSDirectory.cpp \
      RTVDirectory.cpp \
+     RTVFile.cpp \
      SAPDirectory.cpp \
      SAPFile.cpp \
      SFTPDirectory.cpp \
+     SFTPFile.cpp \
      SIDFileDirectory.cpp \
-     Slingbox.cpp \
+     ShoutcastFile.cpp \
+     SlingboxDirectory.cpp \
+     SlingboxFile.cpp \
      SmartPlaylistDirectory.cpp \
      SourcesDirectory.cpp \
      SpecialProtocol.cpp \
      SpecialProtocolDirectory.cpp \
+     SpecialProtocolFile.cpp \
      StackDirectory.cpp \
+     TuxBoxDirectory.cpp \
+     TuxBoxFile.cpp \
      udf25.cpp \
      UDFDirectory.cpp \
+     UDFFile.cpp \
      UPnPDirectory.cpp \
+     UPnPFile.cpp \
      VideoDatabaseDirectory.cpp \
      VirtualDirectory.cpp \
      VTPDirectory.cpp \
@@ -86,26 +87,27 @@ SRCS=AddonsDirectory.cpp \
      VTPSession.cpp \
      ZeroconfDirectory.cpp \
      ZipDirectory.cpp \
+     ZipFile.cpp \
      ZipManager.cpp
 
 ifeq (@HAVE_XBMC_NONFREE@,1)
-SRCS+=FileRar.cpp
+SRCS+=RarFile.cpp
 SRCS+=RarDirectory.cpp
 SRCS+=RarManager.cpp
 endif
 
 ifeq (@USE_LIBSMBCLIENT@,1)
-SRCS+=FileSmb.cpp
+SRCS+=SmbFile.cpp
 SRCS+=SMBDirectory.cpp
 endif
 
 ifeq (@USE_LIBNFS@,1)
-SRCS+=FileNFS.cpp
+SRCS+=NFSFile.cpp
 SRCS+=NFSDirectory.cpp
 endif
 
 ifeq (@USE_LIBAFPCLIENT@,1)
-SRCS+=FileAFP.cpp
+SRCS+=AFPFile.cpp
 SRCS+=AFPDirectory.cpp
 endif
 
diff --git a/xbmc/filesystem/MemBufferCache.cpp b/xbmc/filesystem/MemBufferCache.cpp
new file mode 100644 (file)
index 0000000..3918673
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifdef _LINUX
+#include "threads/SystemClock.h"
+#include "linux/PlatformDefs.h"
+#endif
+#include "settings/AdvancedSettings.h"
+#include "MemBufferCache.h"
+#include "utils/log.h"
+#include "threads/SingleLock.h"
+#include "utils/TimeUtils.h"
+
+#include <math.h>
+
+using namespace XFILE;
+
+#define SEEK_CHECK_RET(x) if (!(x)) return -1;
+
+MemBufferCache::MemBufferCache()
+ : CCacheStrategy()
+{
+  m_nStartPosition = 0;
+  m_buffer.Create(g_advancedSettings.m_cacheMemBufferSize + 1);
+  m_HistoryBuffer.Create(g_advancedSettings.m_cacheMemBufferSize + 1);
+  m_forwardBuffer.Create(g_advancedSettings.m_cacheMemBufferSize + 1);
+}
+
+
+MemBufferCache::~MemBufferCache()
+{
+  m_buffer.Destroy();
+  m_HistoryBuffer.Destroy();
+  m_forwardBuffer.Destroy();
+}
+
+int MemBufferCache::Open()
+{
+  m_nStartPosition = 0;
+  m_buffer.Clear();
+  m_HistoryBuffer.Clear();
+  m_forwardBuffer.Clear();
+  return CACHE_RC_OK;
+}
+
+void MemBufferCache::Close()
+{
+  m_buffer.Clear();
+  m_HistoryBuffer.Clear();
+  m_forwardBuffer.Clear();
+}
+
+int MemBufferCache::WriteToCache(const char *pBuffer, size_t iSize)
+{
+  CSingleLock lock(m_sync);
+  unsigned int nToWrite = m_buffer.getMaxWriteSize() ;
+
+  // must also check the forward buffer.
+  // if we have leftovers from the previous seek - we need not read anymore until they are utilized
+  if (nToWrite == 0 || m_forwardBuffer.getMaxReadSize() > 0)
+    return 0;
+
+  if (nToWrite > iSize)
+    nToWrite = iSize;
+
+  if (!m_buffer.WriteData((char*)pBuffer, nToWrite))
+  {
+    CLog::Log(LOGWARNING,"%s, failed to write %d bytes to buffer. max buffer size: %d", __FUNCTION__, nToWrite, m_buffer.getMaxWriteSize());
+    nToWrite = 0;
+  }
+
+  m_written.Set();
+
+  return nToWrite;
+}
+
+int MemBufferCache::ReadFromCache(char *pBuffer, size_t iMaxSize)
+{
+  CSingleLock lock(m_sync);
+  if ( m_buffer.getMaxReadSize() == 0 ) {
+    return m_bEndOfInput ? 0 : CACHE_RC_WOULD_BLOCK;
+  }
+
+  int nRead = iMaxSize;
+  if ((size_t) m_buffer.getMaxReadSize() < iMaxSize)
+    nRead = m_buffer.getMaxReadSize();
+
+  if (nRead > 0)
+  {
+    if (!m_buffer.ReadData(pBuffer, nRead))
+    {
+      CLog::Log(LOGWARNING, "%s, failed to read %d bytes from buffer. max read size: %d", __FUNCTION__, nRead, m_buffer.getMaxReadSize());
+      return 0;
+    }
+
+    // copy to history so we can seek back
+    if ((int) m_HistoryBuffer.getMaxWriteSize() < nRead)
+      m_HistoryBuffer.SkipBytes(nRead);
+    m_HistoryBuffer.WriteData(pBuffer, nRead);
+
+    m_nStartPosition += nRead;
+  }
+
+  // check forward buffer and copy it when enough space is available
+  if (m_forwardBuffer.getMaxReadSize() > 0 && m_buffer.getMaxWriteSize() >= m_forwardBuffer.getMaxReadSize())
+  {
+    m_buffer.Append(m_forwardBuffer);
+    m_forwardBuffer.Clear();
+  }
+
+  if (nRead > 0)
+    m_space.Set();
+
+  return nRead;
+}
+
+int64_t MemBufferCache::WaitForData(unsigned int iMinAvail, unsigned int millis)
+{
+  if (millis == 0 || IsEndOfInput())
+    return m_buffer.getMaxReadSize();
+
+  XbmcThreads::EndTime endTime(millis);
+  while (!IsEndOfInput() && (unsigned int) m_buffer.getMaxReadSize() < iMinAvail && !endTime.IsTimePast() )
+    m_written.WaitMSec(50); // may miss the deadline. shouldn't be a problem.
+
+  return m_buffer.getMaxReadSize();
+}
+
+int64_t MemBufferCache::Seek(int64_t iFilePosition)
+{
+  CSingleLock lock(m_sync);
+
+  // if seek is a bit over what we have, try to wait a few seconds for the data to be available.
+  // we try to avoid a (heavy) seek on the source
+  if (iFilePosition > m_nStartPosition + m_buffer.getMaxReadSize() &&
+      iFilePosition < m_nStartPosition + m_buffer.getMaxReadSize() + 100000)
+  {
+    int nRequired = (int)(iFilePosition - (m_nStartPosition + m_buffer.getMaxReadSize()));
+    lock.Leave();
+    WaitForData(nRequired + 1, 5000);
+    lock.Enter();
+  }
+
+  // check if seek is inside the current buffer
+  if (iFilePosition >= m_nStartPosition && iFilePosition < m_nStartPosition + m_buffer.getMaxReadSize())
+  {
+    unsigned int nOffset = (unsigned int)(iFilePosition - m_nStartPosition);
+    // copy to history so we can seek back
+    if (m_HistoryBuffer.getMaxWriteSize() < nOffset)
+      m_HistoryBuffer.SkipBytes(nOffset);
+
+    if (!m_buffer.ReadData(m_HistoryBuffer, nOffset))
+    {
+      CLog::Log(LOGERROR, "%s, failed to copy %d bytes to history", __FUNCTION__, nOffset);
+    }
+
+    m_nStartPosition = iFilePosition;
+    m_space.Set();
+    return m_nStartPosition;
+  }
+
+  int64_t iHistoryStart = m_nStartPosition - m_HistoryBuffer.getMaxReadSize();
+  if (iFilePosition < m_nStartPosition && iFilePosition >= iHistoryStart)
+  {
+    CRingBuffer saveHist, saveUnRead;
+    int64_t nToSkip = iFilePosition - iHistoryStart;
+    SEEK_CHECK_RET(m_HistoryBuffer.ReadData(saveHist, (int)nToSkip));
+
+    SEEK_CHECK_RET(saveUnRead.Copy(m_buffer));
+
+    SEEK_CHECK_RET(m_buffer.Copy(m_HistoryBuffer));
+    int nSpace = m_buffer.getMaxWriteSize();
+    int nToCopy = saveUnRead.getMaxReadSize();
+
+    if (nToCopy < nSpace)
+      nSpace = nToCopy;
+
+    SEEK_CHECK_RET(saveUnRead.ReadData(m_buffer, nSpace));
+    nToCopy -= nSpace;
+    if (nToCopy > 0)
+      m_forwardBuffer.Copy(saveUnRead);
+
+    m_nStartPosition = iFilePosition;
+    m_space.Set();
+    return m_nStartPosition;
+  }
+
+  // seek outside the buffer. return error.
+  return CACHE_RC_ERROR;
+}
+
+void MemBufferCache::Reset(int64_t iSourcePosition)
+{
+  CSingleLock lock(m_sync);
+  m_nStartPosition = iSourcePosition;
+  m_buffer.Clear();
+  m_HistoryBuffer.Clear();
+  m_forwardBuffer.Clear();
+}
+
+
diff --git a/xbmc/filesystem/MemBufferCache.h b/xbmc/filesystem/MemBufferCache.h
new file mode 100644 (file)
index 0000000..1f9a7d3
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifndef MemBufferCache_H
+#define MemBufferCache_H
+
+#include "CacheStrategy.h"
+#include "threads/CriticalSection.h"
+#include "threads/Event.h"
+#include "utils/RingBuffer.h"
+
+/**
+  @author Team XBMC
+*/
+namespace XFILE {
+
+class MemBufferCache : public CCacheStrategy
+{
+public:
+    MemBufferCache();
+    virtual ~MemBufferCache();
+
+    virtual int Open() ;
+    virtual void Close();
+
+    virtual int WriteToCache(const char *pBuffer, size_t iSize) ;
+    virtual int ReadFromCache(char *pBuffer, size_t iMaxSize) ;
+    virtual int64_t WaitForData(unsigned int iMinAvail, unsigned int iMillis) ;
+
+    virtual int64_t Seek(int64_t iFilePosition) ;
+    virtual void Reset(int64_t iSourcePosition) ;
+
+protected:
+    int64_t m_nStartPosition;
+    CRingBuffer m_buffer;
+    CRingBuffer m_HistoryBuffer;
+    CRingBuffer m_forwardBuffer; // for seek cases, to store data already read
+    CCriticalSection m_sync;
+    CEvent m_written;
+};
+
+} // namespace XFILE
+#endif
diff --git a/xbmc/filesystem/MusicDatabaseFile.cpp b/xbmc/filesystem/MusicDatabaseFile.cpp
new file mode 100644 (file)
index 0000000..1711520
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "MusicDatabaseFile.h"
+#include "music/MusicDatabase.h"
+#include "URL.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+
+#include <sys/stat.h>
+
+using namespace XFILE;
+
+CMusicDatabaseFile::CMusicDatabaseFile(void)
+{
+}
+
+CMusicDatabaseFile::~CMusicDatabaseFile(void)
+{
+  Close();
+}
+
+CStdString CMusicDatabaseFile::TranslateUrl(const CURL& url)
+{
+  CMusicDatabase musicDatabase;
+  if (!musicDatabase.Open())
+    return "";
+
+  CStdString strFileName=URIUtils::GetFileName(url.Get());
+  CStdString strExtension;
+  URIUtils::GetExtension(strFileName, strExtension);
+  URIUtils::RemoveExtension(strFileName);
+
+  if (!StringUtils::IsNaturalNumber(strFileName))
+    return "";
+
+  long idSong=atol(strFileName.c_str());
+
+  CSong song;
+  if (!musicDatabase.GetSongById(idSong, song))
+    return "";
+
+  CStdString strExtensionFromDb;
+  URIUtils::GetExtension(song.strFileName, strExtensionFromDb);
+
+  if (!strExtensionFromDb.Equals(strExtension))
+    return "";
+
+  return song.strFileName;
+}
+
+bool CMusicDatabaseFile::Open(const CURL& url)
+{
+  return m_file.Open(TranslateUrl(url));
+}
+
+bool CMusicDatabaseFile::Exists(const CURL& url)
+{
+  return !TranslateUrl(url).IsEmpty();
+}
+
+int CMusicDatabaseFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  return m_file.Stat(TranslateUrl(url), buffer);
+}
+
+unsigned int CMusicDatabaseFile::Read(void* lpBuf, int64_t uiBufSize)
+{
+  return m_file.Read(lpBuf, uiBufSize);
+}
+
+int64_t CMusicDatabaseFile::Seek(int64_t iFilePosition, int iWhence /*=SEEK_SET*/)
+{
+  return m_file.Seek(iFilePosition, iWhence);
+}
+
+void CMusicDatabaseFile::Close()
+{
+  m_file.Close();
+}
+
+int64_t CMusicDatabaseFile::GetPosition()
+{
+  return m_file.GetPosition();
+}
+
+int64_t CMusicDatabaseFile::GetLength()
+{
+  return m_file.GetLength();
+}
+
diff --git a/xbmc/filesystem/MusicDatabaseFile.h b/xbmc/filesystem/MusicDatabaseFile.h
new file mode 100644 (file)
index 0000000..ccc555b
--- /dev/null
@@ -0,0 +1,46 @@
+#pragma once
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "File.h"
+
+namespace XFILE
+{
+class CMusicDatabaseFile : public IFile
+{
+public:
+  CMusicDatabaseFile(void);
+  virtual ~CMusicDatabaseFile(void);
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+
+  static CStdString TranslateUrl(const CURL& url);
+protected:
+  CFile m_file;
+};
+}
index 6337c32..16b21f5 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 #include "IDirectory.h"
-#include "FileNFS.h"
+#include "NFSFile.h"
 
 namespace XFILE
 {
diff --git a/xbmc/filesystem/NFSFile.cpp b/xbmc/filesystem/NFSFile.cpp
new file mode 100644 (file)
index 0000000..b6136d4
--- /dev/null
@@ -0,0 +1,788 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FileNFS.cpp: implementation of the CNFSFile class.
+//
+//////////////////////////////////////////////////////////////////////
+#include "system.h"
+
+#ifdef HAS_FILESYSTEM_NFS
+#include "DllLibNfs.h"
+#include "NFSFile.h"
+#include "threads/SingleLock.h"
+#include "utils/log.h"
+#include "utils/URIUtils.h"
+#include "network/DNSNameCache.h"
+#include "threads/SystemClock.h"
+
+#include <nfsc/libnfs-raw-mount.h>
+
+#ifdef TARGET_WINDOWS
+#include <fcntl.h>
+#include <sys\stat.h>
+#endif
+
+//KEEP_ALIVE_TIMEOUT is decremented every half a second
+//480 * 0.5s == 240s == 4mins
+//so when no read was done for 4mins and files are open
+//do the nfs keep alive for the open files
+#define KEEP_ALIVE_TIMEOUT 480
+
+//4 mins cached context timeout
+#define CONTEXT_TIMEOUT 240000
+
+//return codes for getContextForExport
+#define CONTEXT_INVALID  0    //getcontext failed
+#define CONTEXT_NEW      1    //new context created
+#define CONTEXT_CACHED   2    //context cached and therefore already mounted (no new mount needed)
+
+using namespace XFILE;
+
+CNfsConnection::CNfsConnection()
+: m_pNfsContext(NULL)
+, m_exportPath("")
+, m_hostName("")
+, m_resolvedHostName("")
+, m_readChunkSize(0)
+, m_writeChunkSize(0)
+, m_OpenConnections(0)
+, m_IdleTimeout(0)
+, m_pLibNfs(new DllLibNfs())
+{
+}
+
+CNfsConnection::~CNfsConnection()
+{
+  Deinit();
+  delete m_pLibNfs;
+}
+
+void CNfsConnection::resolveHost(const CURL &url)
+{ 
+  //resolve if hostname has changed
+  CDNSNameCache::Lookup(url.GetHostName(), m_resolvedHostName);
+}
+
+std::list<CStdString> CNfsConnection::GetExportList(const CURL &url)
+{
+    std::list<CStdString> retList;
+
+    if(HandleDyLoad())
+    {
+      struct exportnode *exportlist, *tmp;
+      exportlist = m_pLibNfs->mount_getexports(m_resolvedHostName);
+      tmp = exportlist;
+
+      for(tmp = exportlist; tmp!=NULL; tmp=tmp->ex_next)
+      {
+        retList.push_back(CStdString(tmp->ex_dir));
+      }      
+
+      gNfsConnection.GetImpl()->mount_free_export_list(exportlist);
+    }
+    
+    return retList;
+}
+
+bool CNfsConnection::HandleDyLoad()
+{
+  bool ret = true;
+  
+  if(!m_pLibNfs->IsLoaded())
+  {
+    if(!m_pLibNfs->Load())
+    {
+      CLog::Log(LOGERROR,"NFS: Error loading libnfs (%s).",__FUNCTION__);    
+      ret = false; //fatal
+    }    
+  }
+  return ret;
+}
+
+void CNfsConnection::clearMembers()
+{
+    m_exportPath.clear();
+    m_hostName.clear();
+    m_exportList.clear();
+    m_writeChunkSize = 0;
+    m_readChunkSize = 0;  
+    m_pNfsContext = NULL;
+    m_KeepAliveTimeouts.clear();
+}
+
+void CNfsConnection::destroyOpenContexts()
+{
+  for(tOpenContextMap::iterator it = m_openContextMap.begin();it!=m_openContextMap.end();it++)
+  {
+    m_pLibNfs->nfs_destroy_context(it->second.pContext);
+  }
+  m_openContextMap.clear();
+}
+
+struct nfs_context *CNfsConnection::getContextFromMap(const CStdString &exportname)
+{
+  struct nfs_context *pRet = NULL;
+
+  tOpenContextMap::iterator it = m_openContextMap.find(exportname.c_str());
+  if(it != m_openContextMap.end())
+  {
+    //check if context has timed out already
+    uint64_t now = XbmcThreads::SystemClockMillis();
+    if((now - it->second.lastAccessedTime) < CONTEXT_TIMEOUT)
+    {
+      //its not timedout yet
+      //refresh access time of that
+      //context and return it
+      CLog::Log(LOGDEBUG, "NFS: Refreshing context for %s, old: %"PRId64", new: %"PRId64, exportname.c_str(), it->second.lastAccessedTime, now);
+      it->second.lastAccessedTime = now;
+      pRet = it->second.pContext;
+    }
+    else 
+    {
+      //context is timed out
+      //destroy it and return NULL
+      CLog::Log(LOGDEBUG, "NFS: Old context timed out - destroying it");
+      m_pLibNfs->nfs_destroy_context(it->second.pContext);
+    }
+  }
+  return pRet;
+}
+
+int CNfsConnection::getContextForExport(const CStdString &exportname)
+{
+  int ret = CONTEXT_INVALID; 
+    
+  if(HandleDyLoad())
+  {
+    clearMembers();  
+    
+    m_pNfsContext = getContextFromMap(exportname);
+
+    if(!m_pNfsContext)
+    {
+      CLog::Log(LOGDEBUG,"NFS: Context for %s not open - get a new context.", exportname.c_str());
+      m_pNfsContext = m_pLibNfs->nfs_init_context();
+    
+      if(!m_pNfsContext) 
+      {
+        CLog::Log(LOGERROR,"NFS: Error initcontext in getContextForExport.");
+      }
+      else 
+      {
+        struct contextTimeout tmp;
+        tmp.pContext = m_pNfsContext;
+        tmp.lastAccessedTime = XbmcThreads::SystemClockMillis();
+        m_openContextMap[exportname] = tmp; //add context to list of all contexts      
+        ret = CONTEXT_NEW;
+      }
+    }
+    else
+    {
+      ret = CONTEXT_CACHED;
+      CLog::Log(LOGDEBUG,"NFS: Using cached context.");
+    }
+  }
+  return ret;
+}
+
+bool CNfsConnection::splitUrlIntoExportAndPath(const CURL& url, CStdString &exportPath, CStdString &relativePath)
+{
+    bool ret = false;
+    
+    //refresh exportlist if empty or hostname change
+    if(m_exportList.empty() || !url.GetHostName().Equals(m_hostName,false))
+    {
+      m_exportList = GetExportList(url);
+    }
+
+    if(!m_exportList.empty())
+    {
+      relativePath = "";
+      exportPath = "";
+      
+      CStdString path = url.GetFileName();
+      
+      //GetFileName returns path without leading "/"
+      //but we need it because the export paths start with "/"
+      //and path.Find(*it) wouldn't work else
+      if(!path.empty() && path[0] != '/')
+      {
+        path = "/" + path;
+      }
+      
+      std::list<CStdString>::iterator it;
+      
+      for(it=m_exportList.begin();it!=m_exportList.end();it++)
+      {
+        //if path starts with the current export path
+        if( path.Find(*it) ==  0 )
+        {
+          exportPath = *it;
+          relativePath = "//" + path.Right((path.length()-1) - exportPath.length());
+          ret = true;
+          break;          
+        }
+      }
+    }
+    return ret;
+}
+
+bool CNfsConnection::Connect(const CURL& url, CStdString &relativePath)
+{
+  CSingleLock lock(*this);
+  bool ret = false;
+  int nfsRet = 0;
+  CStdString exportPath = "";
+
+  resolveHost(url);
+  ret = splitUrlIntoExportAndPath(url, exportPath, relativePath);
+  
+  if(ret && (!exportPath.Equals(m_exportPath,true) || !url.GetHostName().Equals(m_hostName,false)) )
+  {
+    int contextRet = getContextForExport(url.GetHostName() + exportPath);
+    
+    if(contextRet == CONTEXT_INVALID)//we need a new context because sharename or hostname has changed
+    {
+      return false;
+    }
+    
+    if(contextRet == CONTEXT_NEW) //new context was created - we need to mount it
+    {
+      //we connect to the directory of the path. This will be the "root" path of this connection then.
+      //So all fileoperations are relative to this mountpoint...
+      nfsRet = m_pLibNfs->nfs_mount(m_pNfsContext, m_resolvedHostName.c_str(), exportPath.c_str());
+
+      if(nfsRet != 0) 
+      {
+        CLog::Log(LOGERROR,"NFS: Failed to mount nfs share: %s (%s)\n", exportPath.c_str(), m_pLibNfs->nfs_get_error(m_pNfsContext));
+        return false;
+      }
+      CLog::Log(LOGDEBUG,"NFS: Connected to server %s and export %s\n", url.GetHostName().c_str(), exportPath.c_str());
+    }
+    m_exportPath = exportPath;
+    m_hostName = url.GetHostName();
+    //read chunksize only works after mount
+    m_readChunkSize = m_pLibNfs->nfs_get_readmax(m_pNfsContext);
+    m_writeChunkSize = m_pLibNfs->nfs_get_writemax(m_pNfsContext);
+
+    if(contextRet == CONTEXT_NEW)
+    {
+      CLog::Log(LOGDEBUG,"NFS: chunks: r/w %i/%i\n", (int)m_readChunkSize,(int)m_writeChunkSize);          
+    }
+  }
+  return ret; 
+}
+
+void CNfsConnection::Deinit()
+{
+  if(m_pNfsContext && m_pLibNfs->IsLoaded())
+  {
+    destroyOpenContexts();
+    m_pNfsContext = NULL;
+    m_pLibNfs->Unload();    
+  }        
+  clearMembers();
+}
+
+/* This is called from CApplication::ProcessSlow() and is used to tell if nfs have been idle for too long */
+void CNfsConnection::CheckIfIdle()
+{
+  /* We check if there are open connections. This is done without a lock to not halt the mainthread. It should be thread safe as
+   worst case scenario is that m_OpenConnections could read 0 and then changed to 1 if this happens it will enter the if wich will lead to another check, wich is locked.  */
+  if (m_OpenConnections == 0 && m_pNfsContext != NULL)
+  { /* I've set the the maxiumum IDLE time to be 1 min and 30 sec. */
+    CSingleLock lock(*this);
+    if (m_OpenConnections == 0 /* check again - when locked */)
+    {
+      if (m_IdleTimeout > 0)
+      {
+        m_IdleTimeout--;
+      }
+      else
+      {
+        CLog::Log(LOGNOTICE, "NFS is idle. Closing the remaining connections.");
+        gNfsConnection.Deinit();
+      }
+    }
+  }
+  
+  if( m_pNfsContext != NULL )
+  {
+    //handle keep alive on opened files
+    for( tFileKeepAliveMap::iterator it = m_KeepAliveTimeouts.begin();it!=m_KeepAliveTimeouts.end();it++)
+    {
+      CSingleLock lock(keepAliveLock);
+      if(it->second > 0)
+      {
+        it->second--;
+      }
+      else
+      {
+        lock.Leave();
+        keepAlive(it->first);
+        //reset timeout
+        resetKeepAlive(it->first);
+      }
+    }
+  }
+}
+
+//remove file handle from keep alive list on file close
+void CNfsConnection::removeFromKeepAliveList(struct nfsfh  *_pFileHandle)
+{
+  CSingleLock lock(keepAliveLock);
+  m_KeepAliveTimeouts.erase(_pFileHandle);
+}
+
+//reset timeouts on read
+void CNfsConnection::resetKeepAlive(struct nfsfh  *_pFileHandle)
+{
+  CSingleLock lock(keepAliveLock);
+  //adds new keys - refreshs existing ones  
+  m_KeepAliveTimeouts[_pFileHandle] = KEEP_ALIVE_TIMEOUT;
+}
+
+//keep alive the filehandles nfs connection
+//by blindly doing a read 32bytes - seek back to where
+//we were before
+void CNfsConnection::keepAlive(struct nfsfh  *_pFileHandle)
+{
+  off64_t offset = 0;
+  char buffer[32];
+  CLog::Log(LOGNOTICE, "NFS: sending keep alive after %i s.",KEEP_ALIVE_TIMEOUT/2);
+  CSingleLock lock(*this);
+  m_pLibNfs->nfs_lseek(m_pNfsContext, _pFileHandle, 0, SEEK_CUR, &offset);
+  m_pLibNfs->nfs_read(m_pNfsContext, _pFileHandle, 32, buffer);
+  m_pLibNfs->nfs_lseek(m_pNfsContext, _pFileHandle, offset, SEEK_SET, &offset);
+}
+
+int CNfsConnection::stat(const CURL &url, struct stat *statbuff)
+{
+  CSingleLock lock(*this);
+  int nfsRet = 0;
+  CStdString exportPath;
+  CStdString relativePath;
+  struct nfs_context *pTmpContext = NULL;
+  
+  if(!HandleDyLoad())
+  {
+    return -1;
+  }
+  
+  resolveHost(url);
+  
+  if(splitUrlIntoExportAndPath(url, exportPath, relativePath))
+  {    
+    pTmpContext = m_pLibNfs->nfs_init_context();
+    
+    if(pTmpContext)
+    {  
+      //we connect to the directory of the path. This will be the "root" path of this connection then.
+      //So all fileoperations are relative to this mountpoint...
+      nfsRet = m_pLibNfs->nfs_mount(pTmpContext, m_resolvedHostName.c_str(), exportPath.c_str());
+      
+      if(nfsRet == 0) 
+      {
+        nfsRet = m_pLibNfs->nfs_stat(pTmpContext, relativePath.c_str(), statbuff);      
+      }
+      else
+      {
+        CLog::Log(LOGERROR,"NFS: Failed to mount nfs share: %s (%s)\n", exportPath.c_str(), m_pLibNfs->nfs_get_error(m_pNfsContext));
+      }
+      
+      m_pLibNfs->nfs_destroy_context(pTmpContext);
+      CLog::Log(LOGDEBUG,"NFS: Connected to server %s and export %s in tmpContext\n", url.GetHostName().c_str(), exportPath.c_str());
+    }
+  }
+  return nfsRet;
+}
+
+/* The following two function is used to keep track on how many Opened files/directories there are.
+needed for unloading the dylib*/
+void CNfsConnection::AddActiveConnection()
+{
+  CSingleLock lock(*this);
+  m_OpenConnections++;
+}
+
+void CNfsConnection::AddIdleConnection()
+{
+  CSingleLock lock(*this);
+  m_OpenConnections--;
+  /* If we close a file we reset the idle timer so that we don't have any wierd behaviours if a user
+   leaves the movie paused for a long while and then press stop */
+  m_IdleTimeout = 180;
+}
+
+CNfsConnection gNfsConnection;
+
+CNFSFile::CNFSFile()
+: m_fileSize(0)
+, m_pFileHandle(NULL)
+, m_pNfsContext(NULL)
+{
+  gNfsConnection.AddActiveConnection();
+}
+
+CNFSFile::~CNFSFile()
+{
+  Close();
+  gNfsConnection.AddIdleConnection();
+}
+
+int64_t CNFSFile::GetPosition()
+{
+  int ret = 0;
+  off64_t offset = 0;
+  CSingleLock lock(gNfsConnection);
+  
+  if (gNfsConnection.GetNfsContext() == NULL || m_pFileHandle == NULL) return 0;
+  
+  ret = (int)gNfsConnection.GetImpl()->nfs_lseek(gNfsConnection.GetNfsContext(), m_pFileHandle, 0, SEEK_CUR, &offset);
+  
+  if (ret < 0) 
+  {
+    CLog::Log(LOGERROR, "NFS: Failed to lseek(%s)",gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
+  }
+  return offset;
+}
+
+int64_t CNFSFile::GetLength()
+{
+  if (m_pFileHandle == NULL) return 0;
+  return m_fileSize;
+}
+
+bool CNFSFile::Open(const CURL& url)
+{
+  int ret = 0;
+  Close();
+  // we can't open files like nfs://file.f or nfs://server/file.f
+  // if a file matches the if below return false, it can't exist on a nfs share.
+  if (!IsValidFile(url.GetFileName()))
+  {
+    CLog::Log(LOGNOTICE,"NFS: Bad URL : '%s'",url.GetFileName().c_str());
+    return false;
+  }
+  
+  CStdString filename = "";
+   
+  CSingleLock lock(gNfsConnection);
+  
+  if(!gNfsConnection.Connect(url, filename))
+    return false;
+  
+  m_pNfsContext = gNfsConnection.GetNfsContext(); 
+  
+  ret = gNfsConnection.GetImpl()->nfs_open(m_pNfsContext, filename.c_str(), O_RDONLY, &m_pFileHandle);
+  
+  if (ret != 0) 
+  {
+    CLog::Log(LOGINFO, "CNFSFile::Open: Unable to open file : '%s'  error : '%s'", url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
+    return false;
+  } 
+  
+  CLog::Log(LOGDEBUG,"CNFSFile::Open - opened %s",url.GetFileName().c_str());
+  m_url=url;
+  
+  struct __stat64 tmpBuffer;
+
+  if( Stat(&tmpBuffer) )
+  {
+    m_url.Reset();
+    Close();
+    return false;
+  }
+  
+  m_fileSize = tmpBuffer.st_size;//cache the size of this file
+  // We've successfully opened the file!
+  return true;
+}
+
+
+bool CNFSFile::Exists(const CURL& url)
+{
+  return Stat(url,NULL) == 0;
+}
+
+int CNFSFile::Stat(struct __stat64* buffer)
+{
+  return Stat(m_url,buffer);
+}
+
+
+int CNFSFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  int ret = 0;
+  CSingleLock lock(gNfsConnection);
+  CStdString filename = "";
+  
+  if(!gNfsConnection.Connect(url,filename))
+    return -1;
+   
+
+  struct stat tmpBuffer = {0};
+
+  ret = gNfsConnection.GetImpl()->nfs_stat(gNfsConnection.GetNfsContext(), filename.c_str(), &tmpBuffer);
+  
+  //if buffer == NULL we where called from Exists - in that case don't spam the log with errors
+  if (ret != 0 && buffer != NULL) 
+  {
+    CLog::Log(LOGERROR, "NFS: Failed to stat(%s) %s\n", url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
+    ret = -1;
+  }
+  else
+  {  
+    if(buffer)
+    {
+      memset(buffer, 0, sizeof(struct __stat64));
+      buffer->st_dev = tmpBuffer.st_dev;
+      buffer->st_ino = tmpBuffer.st_ino;
+      buffer->st_mode = tmpBuffer.st_mode;
+      buffer->st_nlink = tmpBuffer.st_nlink;
+      buffer->st_uid = tmpBuffer.st_uid;
+      buffer->st_gid = tmpBuffer.st_gid;
+      buffer->st_rdev = tmpBuffer.st_rdev;
+      buffer->st_size = tmpBuffer.st_size;
+      buffer->st_atime = tmpBuffer.st_atime;
+      buffer->st_mtime = tmpBuffer.st_mtime;
+      buffer->st_ctime = tmpBuffer.st_ctime;
+    }
+  }
+  return ret;
+}
+
+unsigned int CNFSFile::Read(void *lpBuf, int64_t uiBufSize)
+{
+  int numberOfBytesRead = 0;
+  CSingleLock lock(gNfsConnection);
+  
+  if (m_pFileHandle == NULL || m_pNfsContext == NULL ) return 0;
+
+  numberOfBytesRead = gNfsConnection.GetImpl()->nfs_read(m_pNfsContext, m_pFileHandle, (size_t)uiBufSize, (char *)lpBuf);  
+
+  lock.Leave();//no need to keep the connection lock after that
+  
+  gNfsConnection.resetKeepAlive(m_pFileHandle);//triggers keep alive timer reset for this filehandle
+  
+  //something went wrong ...
+  if (numberOfBytesRead < 0) 
+  {
+    CLog::Log(LOGERROR, "%s - Error( %d, %s )", __FUNCTION__, numberOfBytesRead, gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
+    return 0;
+  }
+  return (unsigned int)numberOfBytesRead;
+}
+
+int64_t CNFSFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  int ret = 0;
+  off64_t offset = 0;
+
+  CSingleLock lock(gNfsConnection);  
+  if (m_pFileHandle == NULL || m_pNfsContext == NULL) return -1;
+  
+  ret = (int)gNfsConnection.GetImpl()->nfs_lseek(m_pNfsContext, m_pFileHandle, iFilePosition, iWhence, &offset);
+  if (ret < 0) 
+  {
+    CLog::Log(LOGERROR, "%s - Error( seekpos: %"PRId64", whence: %i, fsize: %"PRId64", %s)", __FUNCTION__, iFilePosition, iWhence, m_fileSize, gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
+    return -1;
+  }
+  return (int64_t)offset;
+}
+
+void CNFSFile::Close()
+{
+  CSingleLock lock(gNfsConnection);
+  
+  if (m_pFileHandle != NULL && m_pNfsContext != NULL)
+  {
+    int ret = 0;
+    CLog::Log(LOGDEBUG,"CNFSFile::Close closing file %s", m_url.GetFileName().c_str());
+    ret = gNfsConnection.GetImpl()->nfs_close(m_pNfsContext, m_pFileHandle);
+    gNfsConnection.removeFromKeepAliveList(m_pFileHandle);
+        
+         if (ret < 0) 
+    {
+      CLog::Log(LOGERROR, "Failed to close(%s) - %s\n", m_url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));
+    }
+    m_pFileHandle = NULL;
+    m_pNfsContext = NULL;    
+    m_fileSize = 0;
+  }
+}
+
+//this was a bitch!
+//for nfs write to work we have to write chunked
+//otherwise this could crash on big files
+int CNFSFile::Write(const void* lpBuf, int64_t uiBufSize)
+{
+  int numberOfBytesWritten = 0;
+  int writtenBytes = 0;
+  int64_t leftBytes = uiBufSize;
+  //clamp max write chunksize to 32kb - fixme - this might be superfluious with future libnfs versions
+  int64_t chunkSize = gNfsConnection.GetMaxWriteChunkSize() > 32768 ? 32768 : gNfsConnection.GetMaxWriteChunkSize();
+  
+  CSingleLock lock(gNfsConnection);
+  
+  if (m_pFileHandle == NULL || m_pNfsContext == NULL) return -1;
+  
+  //write as long as some bytes are left to be written
+  while( leftBytes )
+  {
+    //the last chunk could be smalle than chunksize
+    if(leftBytes < chunkSize)
+    {
+      chunkSize = leftBytes;//write last chunk with correct size
+    }
+    //write chunk
+    writtenBytes = gNfsConnection.GetImpl()->nfs_write(m_pNfsContext,
+                                  m_pFileHandle, 
+                                  (size_t)chunkSize, 
+                                  (char *)lpBuf + numberOfBytesWritten);
+    //decrease left bytes
+    leftBytes-= writtenBytes;
+    //increase overall written bytes
+    numberOfBytesWritten += writtenBytes;
+        
+    //danger - something went wrong
+    if (writtenBytes < 0) 
+    {
+      CLog::Log(LOGERROR, "Failed to pwrite(%s) %s\n", m_url.GetFileName().c_str(), gNfsConnection.GetImpl()->nfs_get_error(m_pNfsContext));        
+      break;
+    }     
+  }
+  //return total number of written bytes
+  return numberOfBytesWritten;
+}
+
+bool CNFSFile::Delete(const CURL& url)
+{
+  int ret = 0;
+  CSingleLock lock(gNfsConnection);
+  CStdString filename = "";
+  
+  if(!gNfsConnection.Connect(url, filename))
+    return false;
+  
+  
+  ret = gNfsConnection.GetImpl()->nfs_unlink(gNfsConnection.GetNfsContext(), filename.c_str());
+  
+  if(ret != 0)
+  {
+    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
+  }
+  return (ret == 0);
+}
+
+bool CNFSFile::Rename(const CURL& url, const CURL& urlnew)
+{
+  int ret = 0;
+  CSingleLock lock(gNfsConnection);
+  CStdString strFile = "";
+  
+  if(!gNfsConnection.Connect(url,strFile))
+    return false;
+  
+  CStdString strFileNew;
+  CStdString strDummy;
+  gNfsConnection.splitUrlIntoExportAndPath(urlnew, strDummy, strFileNew);
+  
+  ret = gNfsConnection.GetImpl()->nfs_rename(gNfsConnection.GetNfsContext() , strFile.c_str(), strFileNew.c_str());
+  
+  if(ret != 0)
+  {
+    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
+  } 
+  return (ret == 0);
+}
+
+bool CNFSFile::OpenForWrite(const CURL& url, bool bOverWrite)
+{ 
+  int ret = 0;
+  // we can't open files like nfs://file.f or nfs://server/file.f
+  // if a file matches the if below return false, it can't exist on a nfs share.
+  if (!IsValidFile(url.GetFileName())) return false;
+  
+  Close();
+  CSingleLock lock(gNfsConnection);
+  CStdString filename = "";
+  
+  if(!gNfsConnection.Connect(url,filename))
+    return false;
+  
+  m_pNfsContext = gNfsConnection.GetNfsContext();
+  
+  if (bOverWrite)
+  {
+    CLog::Log(LOGWARNING, "FileNFS::OpenForWrite() called with overwriting enabled! - %s", filename.c_str());
+    //create file with proper permissions
+    ret = gNfsConnection.GetImpl()->nfs_creat(m_pNfsContext, filename.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, &m_pFileHandle);    
+    //if file was created the file handle isn't valid ... so close it and open later
+    if(ret == 0)
+    {
+      gNfsConnection.GetImpl()->nfs_close(m_pNfsContext,m_pFileHandle);
+    }
+  }
+
+  ret = gNfsConnection.GetImpl()->nfs_open(m_pNfsContext, filename.c_str(), O_RDWR, &m_pFileHandle);
+  
+  if (ret || m_pFileHandle == NULL)
+  {
+    // write error to logfile
+    CLog::Log(LOGERROR, "CNFSFile::Open: Unable to open file : '%s' error : '%s'", filename.c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext()));
+    return false;
+  }
+  m_url=url;
+  
+  struct __stat64 tmpBuffer = {0};
+
+  //only stat if file was not created
+  if(!bOverWrite) 
+  {
+    if(Stat(&tmpBuffer))
+    {
+      m_url.Reset();
+      Close();
+      return false;
+    }
+    m_fileSize = tmpBuffer.st_size;//cache filesize of this file    
+  }
+  else//file was created - filesize is zero
+  {
+    m_fileSize = 0;    
+  }
+  
+  // We've successfully opened the file!
+  return true;
+}
+
+bool CNFSFile::IsValidFile(const CStdString& strFileName)
+{
+  if (strFileName.Find('/') == -1 || /* doesn't have sharename */
+      strFileName.Right(2) == "/." || /* not current folder */
+      strFileName.Right(3) == "/..")  /* not parent folder */
+    return false;
+  return true;
+}
+#endif//HAS_FILESYSTEM_NFS
+
diff --git a/xbmc/filesystem/NFSFile.h b/xbmc/filesystem/NFSFile.h
new file mode 100644 (file)
index 0000000..67c7e82
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FileNFS.h: interface for the CNFSFile class.
+#ifndef FILENFS_H_
+#define FILENFS_H_
+
+#include "IFile.h"
+#include "URL.h"
+#include "threads/CriticalSection.h"
+#include <list>
+#include "SectionLoader.h"
+#include <map>
+
+#ifdef TARGET_WINDOWS
+#define S_IRGRP 0
+#define S_IROTH 0
+#define S_IWUSR _S_IWRITE
+#define S_IRUSR _S_IREAD
+#define        S_IFLNK 0120000
+
+#define S_ISBLK(m) (0)
+#define S_ISSOCK(m) (0)
+#define S_ISLNK(m) ((m & S_IFLNK) != 0)
+#define S_ISCHR(m) ((m & _S_IFCHR) != 0)
+#define S_ISDIR(m) ((m & _S_IFDIR) != 0)
+#define S_ISFIFO(m) ((m & _S_IFIFO) != 0)
+#define S_ISREG(m) ((m & _S_IFREG) != 0)
+#endif
+
+class DllLibNfs;
+
+class CNfsConnection : public CCriticalSection
+{     
+public:
+  typedef std::map<struct nfsfh  *, unsigned int> tFileKeepAliveMap;  
+
+  struct contextTimeout
+  {
+    struct nfs_context *pContext;
+    uint64_t lastAccessedTime;
+  };
+
+  typedef std::map<std::string, struct contextTimeout> tOpenContextMap;    
+  
+  CNfsConnection();
+  ~CNfsConnection();
+  bool Connect(const CURL &url, CStdString &relativePath);
+  struct nfs_context *GetNfsContext(){return m_pNfsContext;}
+  size_t            GetMaxReadChunkSize(){return m_readChunkSize;}
+  size_t            GetMaxWriteChunkSize(){return m_writeChunkSize;} 
+  DllLibNfs        *GetImpl(){return m_pLibNfs;}
+  std::list<CStdString> GetExportList(const CURL &url);
+  //this functions splits the url into the exportpath (feed to mount) and the rest of the path
+  //relative to the mounted export
+  bool splitUrlIntoExportAndPath(const CURL& url, CStdString &exportPath, CStdString &relativePath);
+  
+  //special stat which uses its own context
+  //needed for getting intervolume symlinks to work
+  int stat(const CURL &url, struct stat *statbuff);
+
+  void AddActiveConnection();
+  void AddIdleConnection();
+  void CheckIfIdle();
+  void Deinit();
+  bool HandleDyLoad();//loads the lib if needed
+  //adds the filehandle to the keep alive list or resets
+  //the timeout for this filehandle if already in list
+  void resetKeepAlive(struct nfsfh  *_pFileHandle);
+  //removes file handle from keep alive list
+  void removeFromKeepAliveList(struct nfsfh  *_pFileHandle);  
+  
+  const CStdString& GetConnectedIp() const {return m_resolvedHostName;}
+  const CStdString& GetConnectedExport() const {return m_exportPath;}
+
+private:
+  struct nfs_context *m_pNfsContext;//current nfs context
+  CStdString m_exportPath;//current connected export path
+  CStdString m_hostName;//current connected host
+  CStdString m_resolvedHostName;//current connected host - as ip
+  size_t m_readChunkSize;//current read chunksize of connected server
+  size_t m_writeChunkSize;//current write chunksize of connected server
+  int m_OpenConnections;//number of open connections
+  unsigned int m_IdleTimeout;//timeout for idle connection close and dyunload
+  tFileKeepAliveMap m_KeepAliveTimeouts;//mapping filehandles to its idle timeout
+  tOpenContextMap m_openContextMap;//unique map for tracking all open contexts
+  DllLibNfs *m_pLibNfs;//the lib
+  std::list<CStdString> m_exportList;//list of exported pathes of current connected servers
+  CCriticalSection keepAliveLock;
+  void clearMembers();
+  struct nfs_context *getContextFromMap(const CStdString &exportname);
+  int  getContextForExport(const CStdString &exportname);//get context for given export and add to open contexts map - sets m_pNfsContext (my return a already mounted cached context)
+  void destroyOpenContexts();
+  void resolveHost(const CURL &url);//resolve hostname by dnslookup
+  void keepAlive(struct nfsfh  *_pFileHandle);
+};
+
+extern CNfsConnection gNfsConnection;
+
+namespace XFILE
+{
+  class CNFSFile : public IFile
+  {
+  public:
+    CNFSFile();
+    virtual ~CNFSFile();
+    virtual void Close();
+    virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+    virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+    virtual bool Open(const CURL& url);
+    virtual bool Exists(const CURL& url);
+    virtual int Stat(const CURL& url, struct __stat64* buffer);
+    virtual int Stat(struct __stat64* buffer);
+    virtual int64_t GetLength();
+    virtual int64_t GetPosition();
+    virtual int Write(const void* lpBuf, int64_t uiBufSize);
+    //implement iocontrol for seek_possible for preventing the stat in File class for
+    //getting this info ...
+    virtual int IoControl(EIoControl request, void* param){ if(request == IOCTRL_SEEK_POSSIBLE) return 1;return -1;};    
+    virtual int  GetChunkSize() {return 1;}
+    
+    virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
+    virtual bool Delete(const CURL& url);
+    virtual bool Rename(const CURL& url, const CURL& urlnew);    
+  protected:
+    CURL m_url;
+    bool IsValidFile(const CStdString& strFileName);
+    int64_t m_fileSize;
+    struct nfsfh  *m_pFileHandle;
+    struct nfs_context *m_pNfsContext;//current nfs context    
+  };
+}
+#endif // FILENFS_H_
+
+
diff --git a/xbmc/filesystem/PipeFile.cpp b/xbmc/filesystem/PipeFile.cpp
new file mode 100644 (file)
index 0000000..7fb39ab
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "PipeFile.h"
+#include "threads/SingleLock.h"
+#include "PipesManager.h"
+#include "utils/StringUtils.h"
+
+using namespace XFILE;
+
+CPipeFile::CPipeFile() : m_pos(0), m_length(-1), m_pipe(NULL)
+{
+}
+
+CPipeFile::~CPipeFile()
+{
+  Close();
+}
+
+int64_t CPipeFile::GetPosition()
+{
+  return m_pos;
+}
+
+int64_t CPipeFile::GetLength()
+{
+  return m_length;
+}
+
+void CPipeFile::SetLength(int64_t len)
+{
+  m_length = len;
+}
+
+bool CPipeFile::Open(const CURL& url)
+{
+  CStdString name = url.Get();
+  m_pipe = PipesManager::GetInstance().OpenPipe(name);
+  if (m_pipe)
+    m_pipe->AddListener(this);
+  return (m_pipe != NULL);
+}
+
+bool CPipeFile::Exists(const CURL& url)
+{
+  CStdString name = url.Get();
+  return PipesManager::GetInstance().Exists(name);
+}
+
+int CPipeFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  return -1;
+}
+
+int CPipeFile::Stat(struct __stat64* buffer)
+{
+  memset(buffer,0,sizeof(struct __stat64));
+  buffer->st_size = m_length;
+  return 0;
+}
+
+unsigned int CPipeFile::Read(void* lpBuf, int64_t uiBufSize)
+{
+  if (!m_pipe)
+    return -1;
+  
+  return m_pipe->Read((char *)lpBuf,(int)uiBufSize,INFINITE);
+}
+
+int CPipeFile::Write(const void* lpBuf, int64_t uiBufSize)
+{
+  if (!m_pipe)
+    return -1;
+  
+  return (int)(m_pipe->Write((const char *)lpBuf,(int)uiBufSize,INFINITE)); // its not the size. its bool. either all was written or not.
+}
+
+void CPipeFile::SetEof()
+{
+  if (!m_pipe)
+    return ;
+  m_pipe->SetEof();
+}
+
+bool CPipeFile::IsEof()
+{
+  if (!m_pipe)
+    return true;
+  return m_pipe->IsEof();
+}
+
+bool CPipeFile::IsEmpty()
+{
+  if (!m_pipe)
+    return true;
+  return m_pipe->IsEmpty();
+}
+
+int64_t CPipeFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  return -1;
+}
+
+void CPipeFile::Close()
+{
+  if (m_pipe)
+  {
+    m_pipe->RemoveListener(this);
+    PipesManager::GetInstance().ClosePipe(m_pipe);    
+  }
+  m_pipe = NULL;
+}
+
+bool CPipeFile::IsClosed()
+{
+  return (m_pipe == NULL);
+}
+
+void CPipeFile::Flush()
+{
+  if (m_pipe)
+    m_pipe->Flush();
+}
+
+bool CPipeFile::OpenForWrite(const CURL& url, bool bOverWrite)
+{
+  CStdString name = url.Get();
+
+  m_pipe = PipesManager::GetInstance().CreatePipe(name);
+  if (m_pipe)
+    m_pipe->AddListener(this);
+  return (m_pipe != NULL);
+}
+
+bool CPipeFile::Delete(const CURL& url)
+{
+  return false;
+}
+
+bool CPipeFile::Rename(const CURL& url, const CURL& urlnew)
+{
+  return false;
+}
+
+int CPipeFile::IoControl(int request, void* param)
+{
+  return -1;
+}
+
+CStdString CPipeFile::GetName() const
+{
+  if (!m_pipe)
+    return StringUtils::EmptyString;
+  return m_pipe->GetName();
+}
+
+void CPipeFile::OnPipeOverFlow()
+{
+  CSingleLock lock(m_lock);
+  for (size_t l=0; l<m_listeners.size(); l++)
+    m_listeners[l]->OnPipeOverFlow();
+}
+
+__int64        CPipeFile::GetAvailableRead()
+{
+  return m_pipe->GetAvailableRead();
+}
+
+void CPipeFile::OnPipeUnderFlow()
+{
+  for (size_t l=0; l<m_listeners.size(); l++)
+    m_listeners[l]->OnPipeUnderFlow();
+}
+
+void CPipeFile::AddListener(IPipeListener *l)
+{
+  CSingleLock lock(m_lock);
+  for (size_t i=0; i<m_listeners.size(); i++)
+  {
+    if (m_listeners[i] == l)
+      return;
+  }
+  m_listeners.push_back(l);
+}
+
+void CPipeFile::RemoveListener(IPipeListener *l)
+{
+  CSingleLock lock(m_lock);
+  std::vector<XFILE::IPipeListener *>::iterator i = m_listeners.begin();
+  while(i != m_listeners.end())
+  {
+    if ( (*i) == l)
+      i = m_listeners.erase(i);
+    else
+      i++;
+  }
+}
+
+void CPipeFile::SetOpenThreashold(int threashold)
+{
+  m_pipe->SetOpenThreashold(threashold);
+}
+
diff --git a/xbmc/filesystem/PipeFile.h b/xbmc/filesystem/PipeFile.h
new file mode 100644 (file)
index 0000000..62ebdc0
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * XBMC Media Center
+ * Copyright (c) 2002 Frodo
+ * Portions Copyright (c) by the authors of ffmpeg and xvid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+// FilePipe.h: interface for the CPipeFile class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_FILEPIPE_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_)
+#define AFX_FILEPIPE_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "IFile.h"
+#include "utils/AutoPtrHandle.h"
+#include "utils/StdString.h"
+#include "threads/Event.h"
+#include "threads/CriticalSection.h"
+#include "utils/RingBuffer.h"
+#include "PipesManager.h"
+
+namespace XFILE
+{
+  
+class CPipeFile : public IFile, public IPipeListener
+{
+public:
+  CPipeFile();
+  virtual ~CPipeFile();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+  virtual void SetLength(int64_t len);
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+  virtual int Stat(struct __stat64* buffer);
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int Write(const void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+  virtual void Flush();
+  virtual __int64      GetAvailableRead();
+
+  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
+
+  virtual bool Delete(const CURL& url);
+  virtual bool Rename(const CURL& url, const CURL& urlnew);
+  virtual int IoControl(int request, void* param);
+  
+  CStdString GetName() const;
+  
+  virtual void OnPipeOverFlow();
+  virtual void OnPipeUnderFlow();
+
+  void AddListener(IPipeListener *l);
+  void RemoveListener(IPipeListener *l);
+
+  void SetEof();
+  bool IsEof();
+  bool IsEmpty();
+  bool IsClosed();
+  
+  void SetOpenThreashold(int threashold);
+
+protected:
+  int64_t m_pos;
+  int64_t m_length;
+  
+  XFILE::Pipe *m_pipe;
+  
+  CCriticalSection m_lock;
+  std::vector<XFILE::IPipeListener *> m_listeners;
+};
+
+}
+#endif // !defined(AFX_FILEPIPE_H__DD2B0A9E_4971_4A29_B525_78CEFCDAF4A1__INCLUDED_)
index 4bbd265..6177a93 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "RSSDirectory.h"
 #include "FileItem.h"
-#include "FileCurl.h"
+#include "CurlFile.h"
 #include "settings/Settings.h"
 #include "utils/URIUtils.h"
 #include "tinyXML/tinyxml.h"
@@ -659,7 +659,7 @@ bool CRSSDirectory::GetDirectory(const CStdString& path, CFileItemList &items)
 
 bool CRSSDirectory::Exists(const char* strPath)
 {
-  CFileCurl rss;
+  CCurlFile rss;
   CURL url(strPath);
   return rss.Exists(url);
 }
index 8e629a5..176dd73 100644 (file)
@@ -122,8 +122,9 @@ bool CRTVDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items
   if (url.HasPort())
   {
     char buffer[10];
+    sprintf(buffer,"%i",url.GetPort());
     strHostAndPort += ':';
-    strHostAndPort += itoa(url.GetPort(), buffer, 10);
+    strHostAndPort += buffer;
   }
 
   // No path given, list shows from ReplayGuide
diff --git a/xbmc/filesystem/RTVFile.cpp b/xbmc/filesystem/RTVFile.cpp
new file mode 100644 (file)
index 0000000..2eee45b
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FileRTV.cpp: implementation of the CRTVFile class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "RTVFile.h"
+#include "SectionLoader.h"
+#include "URL.h"
+#include "utils/log.h"
+#include <errno.h>
+#include <sys/stat.h>
+#ifdef _WIN32
+#include "PlatformDefs.h" //for PRIdS
+#endif
+extern "C"
+{
+#include "lib/libRTV/interface.h"
+}
+
+
+using namespace XFILE;
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CRTVFile::CRTVFile()
+{
+  CSectionLoader::Load("LIBRTV");
+  m_filePos = 0;
+  m_fileSize = 0;
+  m_bOpened = false;
+  m_rtvd = NULL;
+}
+
+CRTVFile::~CRTVFile()
+{
+  Close();
+  CSectionLoader::Unload("LIBRTV");
+}
+
+//*********************************************************************************************
+bool CRTVFile::Open(const char* strHostName, const char* strFileName, int iport)
+{
+  // Close any existing connection
+  if (m_bOpened) Close();
+
+  m_bOpened = false;
+
+  // Set up global variables.  Don't set m_filePos to 0 because we use it to SEEK!
+  m_fileSize = 0;
+  m_rtvd = NULL;
+  strcpy(m_hostName, strHostName);
+  strcpy(m_fileName, strFileName);
+  m_iport = iport;
+
+  // Allow for ReplayTVs on ports other than 80
+  CStdString strHostAndPort;
+  strHostAndPort = strHostName;
+  if (iport)
+  {
+    char buffer[10];
+    sprintf(buffer,"%i",iport);
+    strHostAndPort += ':';
+    strHostAndPort += buffer;
+  }
+
+  // Get the file size of strFileName.  If size is 0 or negative, file doesn't exist so exit.
+  u64 size;
+  size = rtv_get_filesize(strHostAndPort.c_str(), strFileName);
+  if (!size)
+  {
+    CLog::Log(LOGERROR, "%s - Failed to get filesize of %s on %s", __FUNCTION__, strHostName, strFileName);
+    return false;
+  }
+  m_fileSize = size;
+
+  // Open a connection to strFileName stating at position m_filePos
+  // Store the handle to the connection in m_rtvd.  Exit if handle invalid.
+  m_rtvd = rtv_open_file(strHostAndPort.c_str(), strFileName, m_filePos);
+  if (!m_rtvd)
+  {
+    CLog::Log(LOGERROR, "%s - Failed to open %s on %s", __FUNCTION__, strHostName, strFileName);
+    return false;
+  }
+  m_bOpened = true;
+
+  CLog::Log(LOGDEBUG, "%s - Opened %s on %s, Size %"PRIu64", Position %"PRIu64"", __FUNCTION__, strHostName, strFileName, m_fileSize, m_filePos);
+  return true;
+}
+
+bool CRTVFile::Open(const CURL& url)
+{
+  return Open(url.GetHostName(), url.GetFileName(), url.GetPort());
+}
+
+bool CRTVFile::Exists(const CURL& url)
+{
+  return true;
+}
+
+int CRTVFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  errno = ENOENT;
+  return -1;
+}
+
+//*********************************************************************************************
+unsigned int CRTVFile::Read(void *lpBuf, int64_t uiBufSize)
+{
+  size_t lenread;
+
+  // Don't read if no connection is open!
+  if (!m_bOpened) return 0;
+
+  // Read uiBufSize bytes from the m_rtvd connection
+  lenread = rtv_read_file(m_rtvd, (char *) lpBuf, (size_t) uiBufSize);
+
+  CLog::Log(LOGDEBUG, "%s - Requested %"PRIdS", Recieved %"PRIdS"", __FUNCTION__, (size_t)uiBufSize, lenread);
+
+  // Some extra checking so library behaves
+  if(m_filePos + lenread > m_fileSize)
+  {
+    CLog::Log(LOGWARNING, "%s - RTV library read passed filesize, returning last chunk", __FUNCTION__);
+    lenread = (size_t)(m_fileSize - m_filePos);
+    m_filePos = m_fileSize;
+    return lenread;
+  }
+
+  // Increase the file position by the number of bytes we just read
+  m_filePos += lenread;
+
+  // Return the number of bytes we just read
+  return lenread;
+}
+
+//*********************************************************************************************
+void CRTVFile::Close()
+{
+  m_bOpened = false;
+
+  // Only try to close a valid handle!
+  if (m_rtvd)
+  {
+    rtv_close_file(m_rtvd);
+  }
+  m_rtvd = NULL;
+}
+
+//*********************************************************************************************
+int64_t CRTVFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  UINT64 newpos;
+
+  if (!m_bOpened) return 0;
+  switch (iWhence)
+  {
+  case SEEK_SET:
+    // cur = pos
+    newpos = iFilePosition;
+    break;
+  case SEEK_CUR:
+    // cur += pos
+    newpos = m_filePos + iFilePosition;
+    break;
+  case SEEK_END:
+    // end += pos
+    newpos = m_fileSize + iFilePosition;
+    break;
+  default:
+    return -1;
+  }
+  // Return offset from beginning
+  if (newpos > m_fileSize) newpos = m_fileSize;
+
+  // NEW CODE
+  // If the new file position is different from the old, then we must SEEK there!
+  if (m_filePos != newpos)
+  {
+    m_filePos = newpos;
+    Open(m_hostName, m_fileName, m_iport);
+  }
+
+  // OLD CODE
+  // Below is old code that may be useful again.  For some reason I'm not sure of, XBMC
+  // does a few seeks to the beginning and end of the stream before it ever starts playing.
+  // When used instead of the code above, this code seeks only after playing begins.
+  // Theoretically, this saves some time because it prevents needless re-opening of the
+  // connection to the RTV, but in practice it seems to be the same.
+  //m_filePos = newpos;
+
+  //if (m_rtvd->firstReadDone && iWhence == SEEK_SET) {
+  // Open(NULL, NULL, m_hostName, m_fileName, m_iport, true);
+  //}
+
+  // Return the new file position after the seek
+  return m_filePos;
+}
+
+//*********************************************************************************************
+int64_t CRTVFile::GetLength()
+{
+  if (!m_bOpened) return 0;
+  return m_fileSize;
+}
+
+//*********************************************************************************************
+int64_t CRTVFile::GetPosition()
+{
+  if (!m_bOpened) return 0;
+  return m_filePos;
+}
diff --git a/xbmc/filesystem/RTVFile.h b/xbmc/filesystem/RTVFile.h
new file mode 100644 (file)
index 0000000..cadf3d8
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FileRTV.h: interface for the CRTVFile class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_FILERTV_H___INCLUDED_)
+#define AFX_FILERTV_H___INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "IFile.h"
+
+typedef struct rtv_data * RTVD;
+
+namespace XFILE
+{
+
+class CRTVFile : public IFile
+{
+public:
+  CRTVFile();
+  virtual ~CRTVFile();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+  virtual bool Open(const CURL& url);
+  bool Open(const char* strHostName, const char* strFileName, int iport);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+protected:
+  uint64_t m_fileSize;
+  uint64_t m_filePos;
+  char m_hostName[255];
+  char m_fileName[255];
+  int m_iport;
+private:
+  RTVD m_rtvd;
+  bool m_bOpened;
+
+};
+}
+
+#endif // !defined(AFX_FILERTV_H___INCLUDED_)
diff --git a/xbmc/filesystem/RarFile.cpp b/xbmc/filesystem/RarFile.cpp
new file mode 100644 (file)
index 0000000..3fca340
--- /dev/null
@@ -0,0 +1,724 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "system.h"
+#include "RarFile.h"
+#include <sys/stat.h>
+#include "Util.h"
+#include "utils/CharsetConverter.h"
+#include "utils/URIUtils.h"
+#include "URL.h"
+#include "Directory.h"
+#include "RarManager.h"
+#include "settings/AdvancedSettings.h"
+#include "FileItem.h"
+#include "utils/log.h"
+#include "UnrarXLib/rar.hpp"
+
+#ifndef _LINUX
+#include <process.h>
+#endif
+
+using namespace XFILE;
+using namespace std;
+
+#define SEEKTIMOUT 30000
+
+#ifdef HAS_FILESYSTEM_RAR
+CRarFileExtractThread::CRarFileExtractThread() : hRunning(true), hQuit(true)
+{
+  m_pArc = NULL;
+  m_pCmd = NULL;
+  m_pExtract = NULL;
+  StopThread();
+  Create();
+}
+
+CRarFileExtractThread::~CRarFileExtractThread()
+{
+  hQuit.Set();
+  AbortableWait(hRestart);
+  StopThread();
+}
+
+void CRarFileExtractThread::Start(Archive* pArc, CommandData* pCmd, CmdExtract* pExtract, int iSize)
+{
+  m_pArc = pArc;
+  m_pCmd = pCmd;
+  m_pExtract = pExtract;
+  m_iSize = iSize;
+
+  m_pExtract->GetDataIO().hBufferFilled = new CEvent;
+  m_pExtract->GetDataIO().hBufferEmpty = new CEvent;
+  m_pExtract->GetDataIO().hSeek = new CEvent(true);
+  m_pExtract->GetDataIO().hSeekDone = new CEvent;
+  m_pExtract->GetDataIO().hQuit = new CEvent(true);
+
+  hRunning.Set();
+  hRestart.Set();
+}
+
+void CRarFileExtractThread::OnStartup()
+{
+}
+
+void CRarFileExtractThread::OnExit()
+{
+}
+
+void CRarFileExtractThread::Process()
+{
+  while (AbortableWait(hQuit,1) != WAIT_SIGNALED)
+  {
+    if (AbortableWait(hRestart,1) == WAIT_SIGNALED)
+    {
+      bool Repeat = false;
+      try
+      {
+        m_pExtract->ExtractCurrentFile(m_pCmd,*m_pArc,m_iSize,Repeat);
+      }
+      catch (int rarErrCode)
+      {
+        CLog::Log(LOGERROR,"filerar CFileRarExtractThread::Process failed. CmdExtract::ExtractCurrentFile threw a UnrarXLib error code of %d",rarErrCode);
+      }
+      catch (...)
+      {
+        CLog::Log(LOGERROR,"filerar CFileRarExtractThread::Process failed. CmdExtract::ExtractCurrentFile threw an Unknown exception");
+      }
+
+      hRunning.Reset();
+    }
+  }
+  hRestart.Set();
+}
+#endif
+
+CRarFile::CRarFile()
+{
+  m_strCacheDir.Empty();
+  m_strRarPath.Empty();
+  m_strPassword.Empty();
+  m_strPathInRar.Empty();
+  m_bFileOptions = 0;
+#ifdef HAS_FILESYSTEM_RAR
+  m_pArc = NULL;
+  m_pCmd = NULL;
+  m_pExtract = NULL;
+  m_pExtractThread = NULL;
+#endif
+  m_szBuffer = NULL;
+  m_szStartOfBuffer = NULL;
+  m_iDataInBuffer = 0;
+  m_bUseFile = false;
+  m_bOpen = false;
+  m_bSeekable = true;
+}
+
+CRarFile::~CRarFile()
+{
+#ifdef HAS_FILESYSTEM_RAR
+  if (!m_bOpen)
+    return;
+
+  if (m_bUseFile)
+  {
+    m_File.Close();
+    g_RarManager.ClearCachedFile(m_strRarPath,m_strPathInRar);
+  }
+  else
+  {
+    CleanUp();
+    if (m_pExtractThread)
+    {
+      delete m_pExtractThread;
+      m_pExtractThread = NULL;
+    }
+  }
+#endif
+}
+
+bool CRarFile::Open(const CURL& url)
+{
+  InitFromUrl(url);
+  CFileItemList items;
+  g_RarManager.GetFilesInRar(items,m_strRarPath,false);
+  int i;
+  for (i=0;i<items.Size();++i)
+  {
+    if (items[i]->GetLabel() == m_strPathInRar)
+      break;
+  }
+
+  if (i<items.Size())
+  {
+    if (items[i]->m_idepth == 0x30) // stored
+    {
+      if (!OpenInArchive())
+        return false;
+
+      m_iFileSize = items[i]->m_dwSize;
+      m_bOpen = true;
+
+      // perform 'noidx' check
+      CFileInfo* pFile = g_RarManager.GetFileInRar(m_strRarPath,m_strPathInRar);
+      if (pFile)
+      {
+        if (pFile->m_iIsSeekable == -1)
+        {
+          if (Seek(-1,SEEK_END) == -1)
+          {
+            m_bSeekable = false;
+            pFile->m_iIsSeekable = 0;
+          }
+        }
+        else
+          m_bSeekable = (pFile->m_iIsSeekable == 1);
+      }
+      return true;
+    }
+    else
+    {
+      CFileInfo* info = g_RarManager.GetFileInRar(m_strRarPath,m_strPathInRar);
+      if ((!info || !CFile::Exists(info->m_strCachedPath)) && m_bFileOptions & EXFILE_NOCACHE)
+        return false;
+      m_bUseFile = true;
+      CStdString strPathInCache;
+
+      if (!g_RarManager.CacheRarredFile(strPathInCache, m_strRarPath, m_strPathInRar,
+                                        EXFILE_AUTODELETE | m_bFileOptions, m_strCacheDir,
+                                        items[i]->m_dwSize))
+      {
+        CLog::Log(LOGERROR,"filerar::open failed to cache file %s",m_strPathInRar.c_str());
+        return false;
+      }
+
+      if (!m_File.Open( strPathInCache ))
+      {
+        CLog::Log(LOGERROR,"filerar::open failed to open file in cache: %s",strPathInCache.c_str());
+        return false;
+      }
+
+      m_bOpen = true;
+      return true;
+    }
+  }
+  return false;
+}
+
+bool CRarFile::Exists(const CURL& url)
+{
+  InitFromUrl(url);
+  bool bResult;
+
+  if (!g_RarManager.IsFileInRar(bResult, m_strRarPath, m_strPathInRar))
+    return false;
+
+  return bResult;
+}
+
+int CRarFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  memset(buffer, 0, sizeof(struct __stat64));
+  if (Open(url))
+  {
+    buffer->st_size = GetLength();
+    buffer->st_mode = _S_IFREG;
+    Close();
+    errno = 0;
+    return 0;
+  }
+
+  if (CDirectory::Exists(url.Get()))
+  {
+    buffer->st_mode = _S_IFDIR;
+    return 0;
+  }
+
+  errno = ENOENT;
+  return -1;
+}
+
+bool CRarFile::OpenForWrite(const CURL& url)
+{
+  return false;
+}
+
+unsigned int CRarFile::Read(void *lpBuf, int64_t uiBufSize)
+{
+#ifdef HAS_FILESYSTEM_RAR
+  if (!m_bOpen)
+    return 0;
+
+  if (m_bUseFile)
+    return m_File.Read(lpBuf,uiBufSize);
+
+  if (m_iFilePosition >= GetLength()) // we are done
+    return 0;
+
+  if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(5000) )
+  {
+    CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
+    return 0;
+  }
+
+
+  byte* pBuf = (byte*)lpBuf;
+  int64_t uicBufSize = uiBufSize;
+  if (m_iDataInBuffer > 0)
+  {
+    int64_t iCopy = uiBufSize<m_iDataInBuffer?uiBufSize:m_iDataInBuffer;
+    memcpy(lpBuf,m_szStartOfBuffer,size_t(iCopy));
+    m_szStartOfBuffer += iCopy;
+    m_iDataInBuffer -= int(iCopy);
+    pBuf += iCopy;
+    uicBufSize -= iCopy;
+    m_iFilePosition += iCopy;
+  }
+
+  while ((uicBufSize > 0) && m_iFilePosition < GetLength() )
+  {
+    if (m_iDataInBuffer <= 0)
+    {
+      m_pExtract->GetDataIO().SetUnpackToMemory(m_szBuffer,MAXWINMEMSIZE);
+      m_szStartOfBuffer = m_szBuffer;
+      m_iBufferStart = m_iFilePosition;
+    }
+
+    m_pExtract->GetDataIO().hBufferFilled->Set();
+    m_pExtract->GetDataIO().hBufferEmpty->Wait();
+
+    if (m_pExtract->GetDataIO().NextVolumeMissing)
+      break;
+
+    m_iDataInBuffer = MAXWINMEMSIZE-m_pExtract->GetDataIO().UnpackToMemorySize;
+
+    if (m_iDataInBuffer == 0)
+      break;
+
+    if (m_iDataInBuffer > uicBufSize)
+    {
+      memcpy(pBuf,m_szStartOfBuffer,int(uicBufSize));
+      m_szStartOfBuffer += uicBufSize;
+      pBuf += int(uicBufSize);
+      m_iFilePosition += uicBufSize;
+      m_iDataInBuffer -= int(uicBufSize);
+      uicBufSize = 0;
+    }
+    else
+    {
+      memcpy(pBuf,m_szStartOfBuffer,size_t(m_iDataInBuffer));
+      m_iFilePosition += m_iDataInBuffer;
+      m_szStartOfBuffer += m_iDataInBuffer;
+      uicBufSize -= m_iDataInBuffer;
+      pBuf += m_iDataInBuffer;
+      m_iDataInBuffer = 0;
+    }
+  }
+
+  m_pExtract->GetDataIO().hBufferEmpty->Set();
+
+  return static_cast<unsigned int>(uiBufSize-uicBufSize);
+#else
+  return 0;
+#endif
+}
+
+unsigned int CRarFile::Write(void *lpBuf, int64_t uiBufSize)
+{
+  return 0;
+}
+
+void CRarFile::Close()
+{
+#ifdef HAS_FILESYSTEM_RAR
+  if (!m_bOpen)
+    return;
+
+  if (m_bUseFile)
+  {
+    m_File.Close();
+    g_RarManager.ClearCachedFile(m_strRarPath,m_strPathInRar);
+    m_bOpen = false;
+  }
+  else
+  {
+    CleanUp();
+    if (m_pExtractThread)
+    {
+      delete m_pExtractThread;
+      m_pExtractThread = NULL;
+    }
+    m_bOpen = false;
+  }
+#endif
+}
+
+int64_t CRarFile::Seek(int64_t iFilePosition, int iWhence)
+{
+#ifdef HAS_FILESYSTEM_RAR
+  if (!m_bOpen)
+    return -1;
+
+  if (!m_bSeekable)
+    return -1;
+
+  if (m_bUseFile)
+    return m_File.Seek(iFilePosition,iWhence);
+
+  if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(SEEKTIMOUT) )
+  {
+    CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
+    return -1;
+  }
+
+  m_pExtract->GetDataIO().hBufferEmpty->Set();
+
+  switch (iWhence)
+  {
+    case SEEK_CUR:
+      if (iFilePosition == 0)
+        return m_iFilePosition; // happens sometimes
+
+      iFilePosition += m_iFilePosition;
+      break;
+    case SEEK_END:
+      if (iFilePosition == 0) // do not seek to end
+      {
+        m_iFilePosition = this->GetLength();
+        m_iDataInBuffer = 0;
+        m_iBufferStart = this->GetLength();
+
+        return this->GetLength();
+      }
+
+      iFilePosition += GetLength();
+    case SEEK_SET:
+      break;
+    default:
+      return -1;
+  }
+
+  if (iFilePosition > this->GetLength())
+    return -1;
+
+  if (iFilePosition == m_iFilePosition) // happens a lot
+    return m_iFilePosition;
+
+  if ((iFilePosition >= m_iBufferStart) && (iFilePosition < m_iBufferStart+MAXWINMEMSIZE)
+                                        && (m_iDataInBuffer > 0)) // we are within current buffer
+  {
+    m_iDataInBuffer = MAXWINMEMSIZE-(iFilePosition-m_iBufferStart);
+    m_szStartOfBuffer = m_szBuffer+MAXWINMEMSIZE-m_iDataInBuffer;
+    m_iFilePosition = iFilePosition;
+
+    return m_iFilePosition;
+  }
+
+  if (iFilePosition < m_iBufferStart )
+  {
+    CleanUp();
+    if (!OpenInArchive())
+      return -1;
+
+    if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(SEEKTIMOUT) )
+    {
+      CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
+      return -1;
+    }
+    m_pExtract->GetDataIO().hBufferEmpty->Set();
+    m_pExtract->GetDataIO().m_iSeekTo = iFilePosition;
+  }
+  else
+    m_pExtract->GetDataIO().m_iSeekTo = iFilePosition;
+
+  m_pExtract->GetDataIO().SetUnpackToMemory(m_szBuffer,MAXWINMEMSIZE);
+  m_pExtract->GetDataIO().hSeek->Set();
+  m_pExtract->GetDataIO().hBufferFilled->Set();
+  if( !m_pExtract->GetDataIO().hSeekDone->WaitMSec(SEEKTIMOUT))
+  {
+    CLog::Log(LOGERROR, "%s - Timeout waiting for seek to finish", __FUNCTION__);
+    return -1;
+  }
+
+  if (m_pExtract->GetDataIO().NextVolumeMissing)
+  {
+    m_iFilePosition = m_iFileSize;
+    return -1;
+  }
+
+  if( !m_pExtract->GetDataIO().hBufferEmpty->WaitMSec(SEEKTIMOUT) )
+  {
+    CLog::Log(LOGERROR, "%s - Timeout waiting for buffer to empty", __FUNCTION__);
+    return -1;
+  }
+  m_iDataInBuffer = m_pExtract->GetDataIO().m_iSeekTo; // keep data
+  m_iBufferStart = m_pExtract->GetDataIO().m_iStartOfBuffer;
+  m_szStartOfBuffer = m_szBuffer+MAXWINMEMSIZE-m_iDataInBuffer;
+  m_iFilePosition = iFilePosition;
+
+  return m_iFilePosition;
+#else
+  return -1;
+#endif
+}
+
+int64_t CRarFile::GetLength()
+{
+  if (!m_bOpen)
+    return 0;
+
+  if (m_bUseFile)
+    return m_File.GetLength();
+
+  return m_iFileSize;
+}
+
+int64_t CRarFile::GetPosition()
+{
+  if (!m_bOpen)
+    return -1;
+
+  if (m_bUseFile)
+    return m_File.GetPosition();
+
+  return m_iFilePosition;
+}
+
+int CRarFile::Write(const void* lpBuf, int64_t uiBufSize)
+{
+  return -1;
+}
+
+void CRarFile::Flush()
+{
+  if (m_bUseFile)
+    m_File.Flush();
+}
+
+void CRarFile::InitFromUrl(const CURL& url)
+{
+  m_strCacheDir = g_advancedSettings.m_cachePath;//url.GetDomain();
+  URIUtils::AddSlashAtEnd(m_strCacheDir);
+  m_strRarPath = url.GetHostName();
+  m_strPassword = url.GetUserName();
+  m_strPathInRar = url.GetFileName();
+
+  vector<CStdString> options;
+  CUtil::Tokenize(url.GetOptions().Mid(1), options, "&");
+
+  m_bFileOptions = 0;
+
+  for( vector<CStdString>::iterator it = options.begin();it != options.end(); it++)
+  {
+    int iEqual = (*it).Find('=');
+    if( iEqual >= 0 )
+    {
+      CStdString strOption = (*it).Left(iEqual);
+      CStdString strValue = (*it).Mid(iEqual+1);
+
+      if( strOption.Equals("flags") )
+        m_bFileOptions = atoi(strValue.c_str());
+      else if( strOption.Equals("cache") )
+        m_strCacheDir = strValue;
+    }
+  }
+
+}
+
+void CRarFile::CleanUp()
+{
+#ifdef HAS_FILESYSTEM_RAR
+  try
+  {
+    if (m_pExtractThread)
+    {
+      if (m_pExtractThread->hRunning.WaitMSec(1))
+      {
+        m_pExtract->GetDataIO().hQuit->Set();
+        while (m_pExtractThread->hRunning.WaitMSec(1))
+          Sleep(1);
+      }
+      delete m_pExtract->GetDataIO().hBufferFilled;
+      delete m_pExtract->GetDataIO().hBufferEmpty;
+      delete m_pExtract->GetDataIO().hSeek;
+      delete m_pExtract->GetDataIO().hSeekDone;
+      delete m_pExtract->GetDataIO().hQuit;
+    }
+    if (m_pExtract)
+    {
+      delete m_pExtract;
+      m_pExtract = NULL;
+    }
+    if (m_pArc)
+    {
+      delete m_pArc;
+      m_pArc = NULL;
+    }
+    if (m_pCmd)
+    {
+      delete m_pCmd;
+      m_pCmd = NULL;
+    }
+    if (m_szBuffer)
+    {
+      delete[] m_szBuffer;
+      m_szBuffer = NULL;
+      m_szStartOfBuffer = NULL;
+    }
+  }
+  catch (int rarErrCode)
+  {
+    CLog::Log(LOGERROR,"filerar failed in UnrarXLib while deleting CFileRar with an UnrarXLib error code of %d",rarErrCode);
+  }
+  catch (...)
+  {
+    CLog::Log(LOGERROR,"filerar failed in UnrarXLib while deleting CFileRar with an Unknown exception");
+  }
+#endif
+}
+
+bool CRarFile::OpenInArchive()
+{
+#ifdef HAS_FILESYSTEM_RAR
+  try
+  {
+    int iHeaderSize;
+
+    InitCRC();
+
+    m_pCmd = new CommandData;
+    if (!m_pCmd)
+    {
+      CleanUp();
+      return false;
+    }
+
+    // Set the arguments for the extract command
+    strcpy(m_pCmd->Command, "X");
+
+    m_pCmd->AddArcName(const_cast<char*>(m_strRarPath.c_str()),NULL);
+
+    strncpy(m_pCmd->ExtrPath, m_strCacheDir.c_str(), sizeof (m_pCmd->ExtrPath) - 2);
+    m_pCmd->ExtrPath[sizeof (m_pCmd->ExtrPath) - 2] = 0;
+    AddEndSlash(m_pCmd->ExtrPath);
+
+    // Set password for encrypted archives
+    if ((m_strPassword.size() > 0) &&
+        (m_strPassword.size() < sizeof (m_pCmd->Password)))
+    {
+      strcpy(m_pCmd->Password, m_strPassword.c_str());
+    }
+
+    m_pCmd->ParseDone();
+
+    // Open the archive
+    m_pArc = new Archive(m_pCmd);
+    if (!m_pArc)
+    {
+      CleanUp();
+      return false;
+    }
+    if (!m_pArc->WOpen(m_strRarPath.c_str(),NULL))
+    {
+      CleanUp();
+      return false;
+    }
+    if (!(m_pArc->IsOpened() && m_pArc->IsArchive(true)))
+    {
+      CleanUp();
+      return false;
+    }
+
+    m_pExtract = new CmdExtract;
+    if (!m_pExtract)
+    {
+      CleanUp();
+      return false;
+    }
+    m_pExtract->GetDataIO().SetUnpackToMemory(m_szBuffer,0);
+    m_pExtract->GetDataIO().SetCurrentCommand(*(m_pCmd->Command));
+    struct FindData FD;
+    if (FindFile::FastFind(m_strRarPath.c_str(),NULL,&FD))
+      m_pExtract->GetDataIO().TotalArcSize+=FD.Size;
+    m_pExtract->ExtractArchiveInit(m_pCmd,*m_pArc);
+
+    while (true)
+    {
+      if ((iHeaderSize = m_pArc->ReadHeader()) <= 0)
+      {
+        CleanUp();
+        return false;
+      }
+
+      if (m_pArc->GetHeaderType() == FILE_HEAD)
+      {
+        CStdString strFileName;
+
+        if (m_pArc->NewLhd.FileNameW && wcslen(m_pArc->NewLhd.FileNameW) > 0)
+        {
+          g_charsetConverter.wToUTF8(m_pArc->NewLhd.FileNameW, strFileName);
+        }
+        else
+        {
+          g_charsetConverter.unknownToUTF8(m_pArc->NewLhd.FileName, strFileName);
+        }
+
+        /* replace back slashes into forward slashes */
+        /* this could get us into troubles, file could two different files, one with / and one with \ */
+        strFileName.Replace('\\', '/');
+
+        if (strFileName == m_strPathInRar)
+        {
+          break;
+        }
+      }
+
+      m_pArc->SeekToNext();
+    }
+
+    m_szBuffer = new byte[MAXWINMEMSIZE];
+    m_szStartOfBuffer = m_szBuffer;
+    m_pExtract->GetDataIO().SetUnpackToMemory(m_szBuffer,0);
+    m_iDataInBuffer = -1;
+    m_iFilePosition = 0;
+    m_iBufferStart = 0;
+
+    delete m_pExtractThread;
+    m_pExtractThread = new CRarFileExtractThread();
+    m_pExtractThread->Start(m_pArc,m_pCmd,m_pExtract,iHeaderSize);
+
+    return true;
+  }
+  catch (int rarErrCode)
+  {
+    CLog::Log(LOGERROR,"filerar failed in UnrarXLib while CFileRar::OpenInArchive with an UnrarXLib error code of %d",rarErrCode);
+    return false;
+  }
+  catch (...)
+  {
+    CLog::Log(LOGERROR,"filerar failed in UnrarXLib while CFileRar::OpenInArchive with an Unknown exception");
+    return false;
+  }
+#else
+  return false;
+#endif
+}
+
diff --git a/xbmc/filesystem/RarFile.h b/xbmc/filesystem/RarFile.h
new file mode 100644 (file)
index 0000000..30beab4
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FileRar.h: interface for the CRarFile class.
+
+#pragma once
+#ifndef FILERAR_H_
+#define FILERAR_H_
+
+#include "File.h"
+#include "threads/Thread.h"
+#include "threads/Event.h"
+
+class CmdExtract;
+class CommandData;
+class Archive;
+
+namespace XFILE
+{
+#ifdef HAS_FILESYSTEM_RAR
+  class CRarFileExtractThread : public CThread
+  {
+  public:
+    CRarFileExtractThread();
+    ~CRarFileExtractThread();
+
+    void Start(Archive* pArc, CommandData* pCmd, CmdExtract* pExtract, int iSize);
+
+    virtual void OnStartup();
+    virtual void OnExit();
+    virtual void Process();
+
+    CEvent hRunning;
+    CEvent hRestart;
+    CEvent hQuit;
+
+  protected:
+    Archive* m_pArc;
+    CommandData* m_pCmd;
+    CmdExtract* m_pExtract;
+    int m_iSize;
+  };
+#endif
+
+  class CRarFile : public IFile
+  {
+  public:
+    CRarFile();
+    CRarFile(bool bSeekable); // used for caching files
+    virtual ~CRarFile();
+    virtual int64_t       GetPosition();
+    virtual int64_t       GetLength();
+    virtual bool          Open(const CURL& url);
+    virtual bool          Exists(const CURL& url);
+    virtual int           Stat(const CURL& url, struct __stat64* buffer);
+    virtual unsigned int  Read(void* lpBuf, int64_t uiBufSize);
+    virtual int           Write(const void* lpBuf, int64_t uiBufSize);
+    virtual int64_t       Seek(int64_t iFilePosition, int iWhence=SEEK_SET);
+    virtual void          Close();
+    virtual void          Flush();
+
+    virtual bool          OpenForWrite(const CURL& url);
+    unsigned int          Write(void *lpBuf, int64_t uiBufSize);
+
+  protected:
+    CStdString m_strCacheDir;
+    CStdString m_strRarPath;
+    CStdString m_strPassword;
+    CStdString m_strPathInRar;
+    BYTE m_bFileOptions;
+    void Init();
+    void InitFromUrl(const CURL& url);
+    bool OpenInArchive();
+    void CleanUp();
+
+    int64_t m_iFilePosition;
+    int64_t m_iFileSize;
+    // rar stuff
+    bool m_bUseFile;
+    bool m_bOpen;
+    bool m_bSeekable;
+    CFile m_File; // for packed source
+#ifdef HAS_FILESYSTEM_RAR
+    Archive* m_pArc;
+    CommandData* m_pCmd;
+    CmdExtract* m_pExtract;
+    CRarFileExtractThread* m_pExtractThread;
+#endif
+    byte* m_szBuffer;
+    byte* m_szStartOfBuffer;
+    int64_t m_iDataInBuffer;
+    int64_t m_iBufferStart;
+  };
+
+}
+
+#endif  // FILERAR_H_
+
index 3265ab8..2321e0d 100644 (file)
@@ -452,7 +452,7 @@ void CRarManager::ExtractArchive(const CStdString& strArchive, const CStdString&
 int64_t CRarManager::CheckFreeSpace(const CStdString& strDrive)
 {
   ULARGE_INTEGER lTotalFreeBytes;
-  if (GetDiskFreeSpaceEx(_P(strDrive.c_str()), NULL, NULL, &lTotalFreeBytes))
+  if (GetDiskFreeSpaceEx(CSpecialProtocol::TranslatePath(strDrive.c_str()), NULL, NULL, &lTotalFreeBytes))
     return lTotalFreeBytes.QuadPart;
 
   return 0;
index a0eb1a4..8a50ea5 100644 (file)
@@ -23,7 +23,7 @@
 #include "system.h"
 #ifdef HAS_FILESYSTEM_SFTP
 #include "IDirectory.h"
-#include "FileSFTP.h"
+#include "SFTPFile.h"
 
 class CURL;
 class TiXmlElement;
diff --git a/xbmc/filesystem/SFTPFile.cpp b/xbmc/filesystem/SFTPFile.cpp
new file mode 100644 (file)
index 0000000..a948b4f
--- /dev/null
@@ -0,0 +1,615 @@
+/*
+ *      Copyright (C) 2005-2010 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "threads/SystemClock.h"
+#include "SFTPFile.h"
+#ifdef HAS_FILESYSTEM_SFTP
+#include "threads/SingleLock.h"
+#include "utils/log.h"
+#include "utils/TimeUtils.h"
+#include "utils/Variant.h"
+#include "Util.h"
+#include <fcntl.h>
+#include <sstream>
+
+#ifdef _WIN32
+#pragma comment(lib, "ssh.lib")
+#endif
+
+#ifdef _MSC_VER
+#define O_RDONLY _O_RDONLY
+#endif
+
+using namespace XFILE;
+using namespace std;
+
+
+static CStdString CorrectPath(const CStdString path)
+{
+  if(path == "~" || path.Left(2) == "~/")
+    return "./" + path.Mid(2);
+  else
+    return "/" + path;
+}
+
+CSFTPSession::CSFTPSession(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password)
+{
+  CLog::Log(LOGINFO, "SFTPSession: Creating new session on host '%s:%d' with user '%s'", host.c_str(), port, username.c_str());
+  CSingleLock lock(m_critSect);
+  if (!Connect(host, port, username, password))
+    Disconnect();
+
+  m_LastActive = XbmcThreads::SystemClockMillis();
+}
+
+CSFTPSession::~CSFTPSession()
+{
+  CSingleLock lock(m_critSect);
+  Disconnect();
+}
+
+sftp_file CSFTPSession::CreateFileHande(const CStdString &file)
+{
+  if (m_connected)
+  {
+    CSingleLock lock(m_critSect);
+    m_LastActive = XbmcThreads::SystemClockMillis();
+    sftp_file handle = sftp_open(m_sftp_session, CorrectPath(file).c_str(), O_RDONLY, 0);
+    if (handle)
+    {
+      sftp_file_set_blocking(handle);
+      return handle;
+    }
+    else
+      CLog::Log(LOGERROR, "SFTPSession: Was connected but couldn't create filehandle\n");
+  }
+  else
+    CLog::Log(LOGERROR, "SFTPSession: Not connected and can't create file handle");
+
+  return NULL;
+}
+
+void CSFTPSession::CloseFileHandle(sftp_file handle)
+{
+  CSingleLock lock(m_critSect);
+  sftp_close(handle);
+}
+
+bool CSFTPSession::GetDirectory(const CStdString &base, const CStdString &folder, CFileItemList &items)
+{
+  if (m_connected)
+  {
+    sftp_dir dir = NULL;
+
+    {
+      CSingleLock lock(m_critSect);
+      m_LastActive = XbmcThreads::SystemClockMillis();
+      dir = sftp_opendir(m_sftp_session, CorrectPath(folder).c_str());
+    }
+
+    if (dir)
+    {
+      bool read = true;
+      while (read)
+      {
+        sftp_attributes attributes = NULL;
+
+        {
+          CSingleLock lock(m_critSect);
+          read = sftp_dir_eof(dir) == 0;
+          attributes = sftp_readdir(m_sftp_session, dir);
+        }
+
+        if (attributes && (attributes->name == NULL || strcmp(attributes->name, "..") == 0 || strcmp(attributes->name, ".") == 0))
+        {
+          CSingleLock lock(m_critSect);
+          sftp_attributes_free(attributes);
+          continue;
+        }
+        
+        if (attributes)
+        {
+          CStdString itemName = attributes->name;
+          CStdString localPath = folder;
+          localPath.append(itemName);
+
+          if (attributes->type == SSH_FILEXFER_TYPE_SYMLINK)
+          {
+            CSingleLock lock(m_critSect);
+            sftp_attributes_free(attributes);
+            attributes = sftp_stat(m_sftp_session, CorrectPath(localPath).c_str());
+            if (attributes == NULL)
+              continue;
+          }
+
+          CFileItemPtr pItem(new CFileItem);
+          pItem->SetLabel(itemName);
+
+          if (itemName[0] == '.')
+            pItem->SetProperty("file:hidden", true);
+
+          if (attributes->flags & SSH_FILEXFER_ATTR_ACMODTIME)
+            pItem->m_dateTime = attributes->mtime;
+
+          if (attributes->type & SSH_FILEXFER_TYPE_DIRECTORY)
+          {
+            localPath.append("/");
+            pItem->m_bIsFolder = true;
+            pItem->m_dwSize = 0;
+          }
+          else
+          {
+            pItem->m_dwSize = attributes->size;
+          }
+
+          pItem->SetPath(base + localPath);
+          items.Add(pItem);
+
+          {
+            CSingleLock lock(m_critSect);
+            sftp_attributes_free(attributes);
+          }
+        }
+        else
+          read = false;
+      }
+
+      {
+        CSingleLock lock(m_critSect);
+        sftp_closedir(dir);
+      }
+
+      return true;
+    }
+  }
+  else
+    CLog::Log(LOGERROR, "SFTPSession: Not connected, can't list directory");
+
+  return false;
+}
+
+bool CSFTPSession::Exists(const char *path)
+{
+  bool exists = false;
+  CSingleLock lock(m_critSect);
+  if(m_connected)
+  {
+    sftp_attributes attributes = sftp_stat(m_sftp_session, CorrectPath(path).c_str());
+    exists = attributes != NULL;
+
+    if (attributes)
+      sftp_attributes_free(attributes);
+  }
+  return exists;
+}
+
+int CSFTPSession::Stat(const char *path, struct __stat64* buffer)
+{
+  CSingleLock lock(m_critSect);
+  if(m_connected)
+  {
+    m_LastActive = XbmcThreads::SystemClockMillis();
+    sftp_attributes attributes = sftp_stat(m_sftp_session, CorrectPath(path).c_str());
+
+    if (attributes)
+    {
+      memset(buffer, 0, sizeof(struct __stat64));
+      buffer->st_size = attributes->size;
+      buffer->st_mtime = attributes->mtime;
+      buffer->st_atime = attributes->atime;
+
+      sftp_attributes_free(attributes);
+      return 0;
+    }
+    else
+    {
+      CLog::Log(LOGERROR, "SFTPSession: STAT - Failed to get attributes");
+      return -1;
+    }
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "SFTPSession: STAT - Not connected");
+    return -1;
+  }
+}
+
+int CSFTPSession::Seek(sftp_file handle, uint64_t position)
+{
+  CSingleLock lock(m_critSect);
+  m_LastActive = XbmcThreads::SystemClockMillis();
+  return sftp_seek64(handle, position);
+}
+
+int CSFTPSession::Read(sftp_file handle, void *buffer, size_t length)
+{
+  CSingleLock lock(m_critSect);
+  m_LastActive = XbmcThreads::SystemClockMillis();
+  return sftp_read(handle, buffer, length);
+}
+
+int64_t CSFTPSession::GetPosition(sftp_file handle)
+{
+  CSingleLock lock(m_critSect);
+  m_LastActive = XbmcThreads::SystemClockMillis();
+  return sftp_tell64(handle);
+}
+
+bool CSFTPSession::IsIdle()
+{
+  return (XbmcThreads::SystemClockMillis() - m_LastActive) > 90000;
+}
+
+bool CSFTPSession::VerifyKnownHost(ssh_session session)
+{
+  switch (ssh_is_server_known(session))
+  {
+    case SSH_SERVER_KNOWN_OK:
+      return true;
+    case SSH_SERVER_KNOWN_CHANGED:
+      CLog::Log(LOGERROR, "SFTPSession: Server that was known has changed");
+      return false;
+    case SSH_SERVER_FOUND_OTHER:
+      CLog::Log(LOGERROR, "SFTPSession: The host key for this server was not found but an other type of key exists. An attacker might change the default server key to confuse your client into thinking the key does not exist");
+      return false;
+    case SSH_SERVER_FILE_NOT_FOUND:
+      CLog::Log(LOGINFO, "SFTPSession: Server file was not found, creating a new one");
+    case SSH_SERVER_NOT_KNOWN:
+      CLog::Log(LOGINFO, "SFTPSession: Server unkown, we trust it for now");
+      if (ssh_write_knownhost(session) < 0)
+      {
+        CLog::Log(LOGERROR, "CSFTPSession: Failed to save host '%s'", strerror(errno));
+        return false;
+      }
+
+      return true;
+    case SSH_SERVER_ERROR:
+      CLog::Log(LOGERROR, "SFTPSession: Failed to verify host '%s'", ssh_get_error(session));
+      return false;
+  }
+
+  return false;
+}
+
+bool CSFTPSession::Connect(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password)
+{
+  int timeout     = SFTP_TIMEOUT;
+  m_connected     = false;
+  m_session       = NULL;
+  m_sftp_session  = NULL;
+
+  m_session=ssh_new();
+  if (m_session == NULL)
+  {
+    CLog::Log(LOGERROR, "SFTPSession: Failed to initialize session");
+    return false;
+  }
+
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,4,0)
+  if (ssh_options_set(m_session, SSH_OPTIONS_USER, username.c_str()) < 0)
+  {
+    CLog::Log(LOGERROR, "SFTPSession: Failed to set username '%s' for session", username.c_str());
+    return false;
+  }
+
+  if (ssh_options_set(m_session, SSH_OPTIONS_HOST, host.c_str()) < 0)
+  {
+    CLog::Log(LOGERROR, "SFTPSession: Failed to set host '%s' for session", host.c_str());
+    return false;
+  }
+
+  if (ssh_options_set(m_session, SSH_OPTIONS_PORT, &port) < 0)
+  {
+    CLog::Log(LOGERROR, "SFTPSession: Failed to set port '%d' for session", port);
+    return false;
+  }
+
+  ssh_options_set(m_session, SSH_OPTIONS_LOG_VERBOSITY, 0);
+  ssh_options_set(m_session, SSH_OPTIONS_TIMEOUT, &timeout);  
+#else
+  SSH_OPTIONS* options = ssh_options_new();
+
+  if (ssh_options_set_username(options, username.c_str()) < 0)
+  {
+    CLog::Log(LOGERROR, "SFTPSession: Failed to set username '%s' for session", username.c_str());
+    return false;
+  }
+
+  if (ssh_options_set_host(options, host.c_str()) < 0)
+  {
+    CLog::Log(LOGERROR, "SFTPSession: Failed to set host '%s' for session", host.c_str());
+    return false;
+  }
+
+  if (ssh_options_set_port(options, port) < 0)
+  {
+    CLog::Log(LOGERROR, "SFTPSession: Failed to set port '%d' for session", port);
+    return false;
+  }
+  
+  ssh_options_set_timeout(options, timeout, 0);
+
+  ssh_options_set_log_verbosity(options, 0);
+
+  ssh_set_options(m_session, options);
+#endif
+
+  if(ssh_connect(m_session))
+  {
+    CLog::Log(LOGERROR, "SFTPSession: Failed to connect '%s'", ssh_get_error(m_session));
+    return false;
+  }
+
+  if (!VerifyKnownHost(m_session))
+    return false;
+
+
+  int noAuth = SSH_AUTH_DENIED;
+  if ((noAuth = ssh_userauth_none(m_session, NULL)) == SSH_AUTH_ERROR)
+  {
+    CLog::Log(LOGERROR, "SFTPSession: Failed to authenticate via guest '%s'", ssh_get_error(m_session));
+    return false;
+  }
+
+  int method = ssh_auth_list(m_session);
+
+  // Try to authenticate with public key first
+  int publicKeyAuth = SSH_AUTH_DENIED;
+  if (method & SSH_AUTH_METHOD_PUBLICKEY && (publicKeyAuth = ssh_userauth_autopubkey(m_session, NULL)) == SSH_AUTH_ERROR)
+  {
+    CLog::Log(LOGERROR, "SFTPSession: Failed to authenticate via publickey '%s'", ssh_get_error(m_session));
+    return false;
+  }
+
+  // Try to authenticate with password
+  int passwordAuth = SSH_AUTH_DENIED;
+  if (method & SSH_AUTH_METHOD_PASSWORD && publicKeyAuth != SSH_AUTH_SUCCESS && (passwordAuth = ssh_userauth_password(m_session, username.c_str(), password.c_str())) == SSH_AUTH_ERROR)
+  {
+    CLog::Log(LOGERROR, "SFTPSession: Failed to authenticate via password '%s'", ssh_get_error(m_session));
+    return false;
+  }
+
+  if (noAuth == SSH_AUTH_SUCCESS || publicKeyAuth == SSH_AUTH_SUCCESS || passwordAuth == SSH_AUTH_SUCCESS)
+  {
+    m_sftp_session = sftp_new(m_session);
+
+    if (m_sftp_session == NULL)
+    {
+      CLog::Log(LOGERROR, "SFTPSession: Failed to initialize channel '%s'", ssh_get_error(m_session));
+      return false;
+    }
+
+    if (sftp_init(m_sftp_session))
+    {
+      CLog::Log(LOGERROR, "SFTPSession: Failed to initialize sftp '%s'", ssh_get_error(m_session));
+      return false;
+    }
+
+    m_connected = true;
+  }
+
+  return m_connected;
+}
+
+void CSFTPSession::Disconnect()
+{
+  if (m_sftp_session)
+    sftp_free(m_sftp_session);
+
+  if (m_session)
+    ssh_disconnect(m_session);
+
+  m_sftp_session = NULL;
+  m_session = NULL;
+}
+
+CCriticalSection CSFTPSessionManager::m_critSect;
+map<CStdString, CSFTPSessionPtr> CSFTPSessionManager::sessions;
+
+CSFTPSessionPtr CSFTPSessionManager::CreateSession(const CURL &url)
+{
+  string username = url.GetUserName().c_str();
+  string password = url.GetPassWord().c_str();
+  string hostname = url.GetHostName().c_str();
+  unsigned int port = url.HasPort() ? url.GetPort() : 22;
+
+  return CSFTPSessionManager::CreateSession(hostname, port, username, password);
+}
+
+CSFTPSessionPtr CSFTPSessionManager::CreateSession(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password)
+{
+  // Convert port number to string
+  stringstream itoa;
+  itoa << port;
+  CStdString portstr = itoa.str();
+
+  CSingleLock lock(m_critSect);
+  CStdString key = username + ":" + password + "@" + host + ":" + portstr;
+  CSFTPSessionPtr ptr = sessions[key];
+  if (ptr == NULL)
+  {
+    ptr = CSFTPSessionPtr(new CSFTPSession(host, port, username, password));
+    sessions[key] = ptr;
+  }
+
+  return ptr;
+}
+
+void CSFTPSessionManager::ClearOutIdleSessions()
+{
+  CSingleLock lock(m_critSect);
+  for(map<CStdString, CSFTPSessionPtr>::iterator iter = sessions.begin(); iter != sessions.end();)
+  {
+    if (iter->second->IsIdle())
+      sessions.erase(iter++);
+    else
+      iter++;
+  }
+}
+
+void CSFTPSessionManager::DisconnectAllSessions()
+{
+  CSingleLock lock(m_critSect);
+  sessions.clear();
+}
+
+CSFTPFile::CSFTPFile()
+{
+  m_sftp_handle = NULL;
+}
+
+CSFTPFile::~CSFTPFile()
+{
+  Close();
+}
+
+bool CSFTPFile::Open(const CURL& url)
+{
+  m_session = CSFTPSessionManager::CreateSession(url);
+  if (m_session)
+  {
+    m_file = url.GetFileName().c_str();
+    m_sftp_handle = m_session->CreateFileHande(m_file);
+
+    return (m_sftp_handle != NULL);
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "SFTPFile: Failed to allocate session");
+    return false;
+  }
+}
+
+void CSFTPFile::Close()
+{
+  if (m_session && m_sftp_handle)
+  {
+    m_session->CloseFileHandle(m_sftp_handle);
+    m_sftp_handle = NULL;
+    m_session = CSFTPSessionPtr();
+  }
+}
+
+int64_t CSFTPFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  if (m_session && m_sftp_handle)
+  {
+    uint64_t position = 0;
+    if (iWhence == SEEK_SET)
+      position = iFilePosition;
+    else if (iWhence == SEEK_CUR)
+      position = GetPosition() + iFilePosition;
+    else if (iWhence == SEEK_END)
+      position = GetLength() + iFilePosition;
+
+    if (m_session->Seek(m_sftp_handle, position) == 0)
+      return GetPosition();
+    else
+      return -1;
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "SFTPFile: Can't seek without a filehandle");
+    return -1;
+  }
+}
+
+unsigned int CSFTPFile::Read(void* lpBuf, int64_t uiBufSize)
+{
+  if (m_session && m_sftp_handle)
+  {
+    int rc = m_session->Read(m_sftp_handle, lpBuf, (size_t)uiBufSize);
+
+    if (rc >= 0)
+      return rc;
+    else
+      CLog::Log(LOGERROR, "SFTPFile: Failed to read %i", rc);
+  }
+  else
+    CLog::Log(LOGERROR, "SFTPFile: Can't read without a filehandle");
+
+  return 0;
+}
+
+bool CSFTPFile::Exists(const CURL& url)
+{
+  CSFTPSessionPtr session = CSFTPSessionManager::CreateSession(url);
+  if (session)
+    return session->Exists(url.GetFileName().c_str());
+  else
+  {
+    CLog::Log(LOGERROR, "SFTPFile: Failed to create session to check exists");
+    return false;
+  }
+}
+
+int CSFTPFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  CSFTPSessionPtr session = CSFTPSessionManager::CreateSession(url);
+  if (session)
+    return session->Stat(url.GetFileName().c_str(), buffer);
+  else
+  {
+    CLog::Log(LOGERROR, "SFTPFile: Failed to create session to stat");
+    return -1;
+  }
+}
+
+int CSFTPFile::Stat(struct __stat64* buffer)
+{
+  if (m_session)
+    return m_session->Stat(m_file.c_str(), buffer);
+
+  CLog::Log(LOGERROR, "SFTPFile: Can't stat without a session");
+  return -1;
+}
+
+int64_t CSFTPFile::GetLength()
+{
+  struct __stat64 buffer;
+  if (Stat(&buffer) != 0)
+    return 0;
+  else
+  {
+    int64_t length = buffer.st_size;
+    return length;
+  }
+}
+
+int64_t CSFTPFile::GetPosition()
+{
+  if (m_session && m_sftp_handle)
+    return m_session->GetPosition(m_sftp_handle);
+
+  CLog::Log(LOGERROR, "SFTPFile: Can't get position without a filehandle");
+  return 0;
+}
+
+int CSFTPFile::IoControl(EIoControl request, void* param)
+{
+  if(request == IOCTRL_SEEK_POSSIBLE)
+    return 1;
+
+  return -1;
+}
+
+#endif
diff --git a/xbmc/filesystem/SFTPFile.h b/xbmc/filesystem/SFTPFile.h
new file mode 100644 (file)
index 0000000..bf29db6
--- /dev/null
@@ -0,0 +1,117 @@
+#pragma once
+/*
+ *      Copyright (C) 2005-2010 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "system.h"
+#ifdef HAS_FILESYSTEM_SFTP
+#include "IFile.h"
+#include "URL.h"
+#include "FileItem.h"
+#include "threads/CriticalSection.h"
+
+#include <libssh/libssh.h>
+#include <libssh/sftp.h>
+#include <string>
+#include <map>
+#include <boost/shared_ptr.hpp>
+
+#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0,3,2)
+#define ssh_session SSH_SESSION
+#endif
+
+#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0,4,0)
+#define sftp_file SFTP_FILE*
+#define sftp_session SFTP_SESSION*
+#define sftp_attributes SFTP_ATTRIBUTES*
+#define sftp_dir SFTP_DIR*
+#define ssh_session ssh_session*
+#endif
+
+//five secs timeout for SFTP
+#define SFTP_TIMEOUT 5
+
+class CSFTPSession
+{
+public:
+  CSFTPSession(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password);
+  virtual ~CSFTPSession();
+
+  sftp_file CreateFileHande(const CStdString &file);
+  void CloseFileHandle(sftp_file handle);
+  bool GetDirectory(const CStdString &base, const CStdString &folder, CFileItemList &items);
+  bool Exists(const char *path);
+  int Stat(const char *path, struct __stat64* buffer);
+  int Seek(sftp_file handle, uint64_t position);
+  int Read(sftp_file handle, void *buffer, size_t length);
+  int64_t GetPosition(sftp_file handle);
+  bool IsIdle();
+private:
+  bool VerifyKnownHost(ssh_session session);
+  bool Connect(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password);
+  void Disconnect();
+  CCriticalSection m_critSect;
+
+  bool m_connected;
+  ssh_session  m_session;
+  sftp_session m_sftp_session;
+  int m_LastActive;
+};
+
+typedef boost::shared_ptr<CSFTPSession> CSFTPSessionPtr;
+
+class CSFTPSessionManager
+{
+public:
+  static CSFTPSessionPtr CreateSession(const CURL &url);
+  static CSFTPSessionPtr CreateSession(const CStdString &host, unsigned int port, const CStdString &username, const CStdString &password);
+  static void ClearOutIdleSessions();
+  static void DisconnectAllSessions();
+private:
+  static CCriticalSection m_critSect;
+  static std::map<CStdString, CSFTPSessionPtr> sessions;
+};
+
+namespace XFILE
+{
+  class CSFTPFile : public IFile
+  {
+  public:
+    CSFTPFile();
+    virtual ~CSFTPFile();
+    virtual void Close();
+    virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+    virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+    virtual bool Open(const CURL& url);
+    virtual bool Exists(const CURL& url);
+    virtual int Stat(const CURL& url, struct __stat64* buffer);
+    virtual int Stat(struct __stat64* buffer);
+    virtual int64_t GetLength();
+    virtual int64_t GetPosition();
+    virtual int     GetChunkSize() {return 1;};
+    virtual int     IoControl(EIoControl request, void* param);
+  private:
+    CStdString m_file;
+    CSFTPSessionPtr m_session;
+    sftp_file m_sftp_handle;
+  };
+}
+#endif
index 3232f6c..49fa7e5 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 #include "IDirectory.h"
-#include "FileSmb.h"
+#include "SmbFile.h"
 #include "MediaSource.h"
 
 namespace XFILE
diff --git a/xbmc/filesystem/ShoutcastFile.cpp b/xbmc/filesystem/ShoutcastFile.cpp
new file mode 100644 (file)
index 0000000..eeb461f
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+// FileShoutcast.cpp: implementation of the CShoutcastFile class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "threads/SystemClock.h"
+#include "system.h"
+#include "Application.h"
+#include "ShoutcastFile.h"
+#include "settings/GUISettings.h"
+#include "guilib/GUIWindowManager.h"
+#include "URL.h"
+#include "utils/RegExp.h"
+#include "utils/HTMLUtil.h"
+#include "utils/CharsetConverter.h"
+#include "utils/TimeUtils.h"
+#include "GUIInfoManager.h"
+#include "utils/log.h"
+
+using namespace XFILE;
+using namespace MUSIC_INFO;
+
+CShoutcastFile::CShoutcastFile()
+{
+  m_lastTime = XbmcThreads::SystemClockMillis();
+  m_discarded = 0;
+  m_currint = 0;
+  m_buffer = NULL;
+}
+
+CShoutcastFile::~CShoutcastFile()
+{
+  Close();
+}
+
+int64_t CShoutcastFile::GetPosition()
+{
+  return m_file.GetPosition()-m_discarded;
+}
+
+int64_t CShoutcastFile::GetLength()
+{
+  return 0;
+}
+
+bool CShoutcastFile::Open(const CURL& url)
+{
+  CURL url2(url);
+  url2.SetProtocolOptions("noshout=true&Icy-MetaData=1");
+  url2.SetProtocol("http");
+
+  bool result=false;
+  if ((result=m_file.Open(url2.Get())))
+  {
+    m_tag.SetTitle(m_file.GetHttpHeader().GetValue("icy-name"));
+    if (m_tag.GetTitle().IsEmpty())
+      m_tag.SetTitle(m_file.GetHttpHeader().GetValue("ice-name")); // icecast
+    m_tag.SetGenre(m_file.GetHttpHeader().GetValue("icy-genre"));
+    if (m_tag.GetGenre().IsEmpty())
+      m_tag.SetGenre(m_file.GetHttpHeader().GetValue("ice-genre")); // icecast
+    m_tag.SetLoaded(true);
+    g_infoManager.SetCurrentSongTag(m_tag);
+  }
+  m_metaint = atoi(m_file.GetHttpHeader().GetValue("icy-metaint").c_str());
+  if (!m_metaint)
+    m_metaint = -1;
+  m_buffer = new char[16*255];
+
+  return result;
+}
+
+unsigned int CShoutcastFile::Read(void* lpBuf, int64_t uiBufSize)
+{
+  if (m_currint >= m_metaint && m_metaint > 0)
+  {
+    unsigned char header;
+    m_file.Read(&header,1);
+    ReadTruncated(m_buffer, header*16);
+    ExtractTagInfo(m_buffer);
+    m_discarded += header*16+1;
+    m_currint = 0;
+  }
+  if (XbmcThreads::SystemClockMillis() - m_lastTime > 500)
+  {
+    m_lastTime = XbmcThreads::SystemClockMillis();
+    g_infoManager.SetCurrentSongTag(m_tag);
+  }
+
+  unsigned int toRead;
+  if (m_metaint > 0)
+    toRead = std::min((unsigned int)uiBufSize,(unsigned int)m_metaint-m_currint);
+  else
+    toRead = std::min((unsigned int)uiBufSize,(unsigned int)16*255);
+  toRead = m_file.Read(lpBuf,toRead);
+  m_currint += toRead;
+  return toRead;
+}
+
+int64_t CShoutcastFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  return -1;
+}
+
+void CShoutcastFile::Close()
+{
+  delete[] m_buffer;
+  m_file.Close();
+}
+
+void CShoutcastFile::ExtractTagInfo(const char* buf)
+{
+  CStdString strBuffer = buf;
+  g_charsetConverter.unknownToUTF8(strBuffer);
+
+  CStdStringW wBuffer, wConverted;
+  g_charsetConverter.utf8ToW(strBuffer, wBuffer, false);
+  HTML::CHTMLUtil::ConvertHTMLToW(wBuffer, wConverted);
+  g_charsetConverter.wToUTF8(wConverted, strBuffer);
+
+  CRegExp reTitle(true);
+  reTitle.RegComp("StreamTitle=\'(.*?)\';");
+
+  if (reTitle.RegFind(strBuffer.c_str()) != -1)
+    m_tag.SetTitle(reTitle.GetReplaceString("\\1"));
+}
+
+void CShoutcastFile::ReadTruncated(char* buf2, int size)
+{
+  char* buf = buf2;
+  while (size > 0)
+  {
+    int read = m_file.Read(buf,size);
+    size -= read;
+    buf += read;
+  }
+}
+
diff --git a/xbmc/filesystem/ShoutcastFile.h b/xbmc/filesystem/ShoutcastFile.h
new file mode 100644 (file)
index 0000000..5068e57
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FileShoutcast.h: interface for the CShoutcastFile class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include "IFile.h"
+#include "CurlFile.h"
+#include "utils/StdString.h"
+#include "music/tags/MusicInfoTag.h"
+
+namespace XFILE
+{
+class CShoutcastFile : public IFile
+{
+public:
+  CShoutcastFile();
+  virtual ~CShoutcastFile();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url) { return true;};
+  virtual int Stat(const CURL& url, struct __stat64* buffer) { errno = ENOENT; return -1; };
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+protected:
+  void ExtractTagInfo(const char* buf);
+  void ReadTruncated(char* buf2, int size);
+
+  unsigned int m_lastTime;
+  CCurlFile m_file;
+  int m_metaint;
+  int m_discarded; // data used for tags
+  int m_currint;
+  char* m_buffer; // buffer used for tags
+  MUSIC_INFO::CMusicInfoTag m_tag;
+};
+}
+
diff --git a/xbmc/filesystem/Slingbox.cpp b/xbmc/filesystem/Slingbox.cpp
deleted file mode 100644 (file)
index d7e8763..0000000
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- *      Copyright (C) 2011 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "FileItem.h"
-#include "Slingbox.h"
-#include "filesystem/File.h"
-#include "lib/SlingboxLib/SlingboxLib.h"
-#include "settings/Settings.h"
-#include "utils/log.h"
-#include "utils/XMLUtils.h"
-
-using namespace XFILE;
-using namespace std;
-
-CSlingboxDirectory::CSlingboxDirectory()
-{
-}
-
-CSlingboxDirectory::~CSlingboxDirectory()
-{
-}
-
-bool CSlingboxDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
-{
-  // Create generic Watch Slingbox item
-  CFileItemPtr item(new CFileItem(strPath, false));
-  item->SetLabel("Watch Slingbox");
-  item->SetLabelPreformated(true);
-  items.Add(item);
-
-  return true;
-}
-
-CSlingboxFile::CSlingboxFile()
-{
-  // Create the Slingbox object
-  m_pSlingbox = new CSlingbox();
-}
-
-CSlingboxFile::~CSlingboxFile()
-{
-  // Destroy the Slingbox object
-  delete m_pSlingbox;
-}
-
-bool CSlingboxFile::Open(const CURL& url)
-{
-  // Setup the IP/hostname and port (setup default port if none specified)
-  unsigned int uiPort;
-  if (url.HasPort())
-    uiPort = (unsigned int)url.GetPort();
-  else
-    uiPort = 5001;
-  m_pSlingbox->SetAddress(url.GetHostName(), uiPort);
-
-  // Prepare to connect to the Slingbox
-  bool bAdmin;
-  if (url.GetUserName().CompareNoCase("administrator") == 0)
-    bAdmin = true;
-  else if (url.GetUserName().CompareNoCase("viewer") == 0)
-    bAdmin = false;
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Invalid or no username specified for Slingbox: %s",
-      __FUNCTION__, url.GetHostName().c_str());
-    return false;
-  }
-
-  // Connect to the Slingbox
-  if (m_pSlingbox->Connect(bAdmin, url.GetPassWord()))
-  {
-    CLog::Log(LOGDEBUG, "%s - Sucessfully connected to Slingbox: %s",
-      __FUNCTION__, url.GetHostName().c_str());
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Error connecting to Slingbox: %s",
-      __FUNCTION__, url.GetHostName().c_str());
-    return false;
-  }
-
-  // Initialize the stream
-  if (m_pSlingbox->InitializeStream())
-  {
-    CLog::Log(LOGDEBUG, "%s - Successfully initialized stream on Slingbox: %s",
-      __FUNCTION__, url.GetHostName().c_str());
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Error initializing stream on Slingbox: %s",
-      __FUNCTION__, url.GetHostName().c_str());
-    return false;
-  }
-
-  // Set correct input
-  if (url.GetFileNameWithoutPath() != "")
-  {
-    if (m_pSlingbox->SetInput(atoi(url.GetFileNameWithoutPath())))
-      CLog::Log(LOGDEBUG, "%s - Successfully requested change to input %i on Slingbox: %s",
-        __FUNCTION__, atoi(url.GetFileNameWithoutPath()), url.GetHostName().c_str());
-    else
-      CLog::Log(LOGERROR, "%s - Error requesting change to input %i on Slingbox: %s",
-        __FUNCTION__, atoi(url.GetFileNameWithoutPath()), url.GetHostName().c_str());
-  }
-
-  // Load the video settings
-  LoadSettings(url.GetHostName());
-
-  // Setup video options  
-  if (m_pSlingbox->StreamSettings((CSlingbox::Resolution)m_sSlingboxSettings.iVideoResolution,
-    m_sSlingboxSettings.iVideoBitrate, m_sSlingboxSettings.iVideoFramerate,
-    m_sSlingboxSettings.iVideoSmoothing, m_sSlingboxSettings.iAudioBitrate,
-    m_sSlingboxSettings.iIFrameInterval))
-  {
-    CLog::Log(LOGDEBUG, "%s - Successfully set stream options (resolution: %ix%i; "
-      "video bitrate: %i kbit/s; fps: %i; smoothing: %i%%; audio bitrate %i kbit/s; "
-      "I frame interval: %i) on Slingbox: %s", __FUNCTION__,
-      m_sSlingboxSettings.iVideoWidth, m_sSlingboxSettings.iVideoHeight,
-      m_sSlingboxSettings.iVideoBitrate, m_sSlingboxSettings.iVideoFramerate,
-      m_sSlingboxSettings.iVideoSmoothing, m_sSlingboxSettings.iAudioBitrate,
-      m_sSlingboxSettings.iIFrameInterval, url.GetHostName().c_str());
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Error setting stream options on Slingbox: %s",
-      __FUNCTION__, url.GetHostName().c_str());
-  }
-
-  // Start the stream
-  if (m_pSlingbox->StartStream())
-  {
-    CLog::Log(LOGDEBUG, "%s - Successfully started stream on Slingbox: %s",
-      __FUNCTION__, url.GetHostName().c_str());
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Error starting stream on Slingbox: %s",
-      __FUNCTION__, url.GetHostName().c_str());
-    return false;
-  }
-
-  // Check for correct input
-  if (url.GetFileNameWithoutPath() != "")
-  {
-    if (m_pSlingbox->GetInput() == -1)
-      CLog::Log(LOGDEBUG, "%s - Unable to confirm change to input %i on Slingbox: %s",
-        __FUNCTION__, atoi(url.GetFileNameWithoutPath()), url.GetHostName().c_str());
-    else if (m_pSlingbox->GetInput() == atoi(url.GetFileNameWithoutPath()))
-      CLog::Log(LOGDEBUG, "%s - Comfirmed change to input %i on Slingbox: %s",
-        __FUNCTION__, atoi(url.GetFileNameWithoutPath()), url.GetHostName().c_str());
-    else
-      CLog::Log(LOGERROR, "%s - Error changing to input %i on Slingbox: %s",
-        __FUNCTION__, atoi(url.GetFileNameWithoutPath()), url.GetHostName().c_str());
-  }
-
-  return true;
-}
-
-unsigned int CSlingboxFile::Read(void * pBuffer, int64_t iSize)
-{
-  // Read the data and check for any errors
-  int iRead = m_pSlingbox->ReadStream(pBuffer, (unsigned int)iSize);
-  if (iRead < 0)
-  {
-    CLog::Log(LOGERROR, "%s - Error reading stream from Slingbox: %s", __FUNCTION__,
-      m_sSlingboxSettings.strHostname.c_str());
-    return 0;
-  }
-
-  return iRead;
-}
-
-void CSlingboxFile::Close()
-{
-  // Stop the stream
-  if (m_pSlingbox->StopStream())
-    CLog::Log(LOGDEBUG, "%s - Successfully stopped stream on Slingbox: %s", __FUNCTION__,
-    m_sSlingboxSettings.strHostname.c_str());
-  else
-    CLog::Log(LOGERROR, "%s - Error stopping stream on Slingbox: %s", __FUNCTION__,
-    m_sSlingboxSettings.strHostname.c_str());
-
-  // Disconnect from the Slingbox
-  if (m_pSlingbox->Disconnect())
-    CLog::Log(LOGDEBUG, "%s - Successfully disconnected from Slingbox: %s", __FUNCTION__,
-    m_sSlingboxSettings.strHostname.c_str());
-  else
-    CLog::Log(LOGERROR, "%s - Error disconnecting from Slingbox: %s", __FUNCTION__,
-    m_sSlingboxSettings.strHostname.c_str());
-}
-
-bool CSlingboxFile::SkipNext()
-{
-  return m_pSlingbox->IsConnected();
-}
-
-bool CSlingboxFile::NextChannel()
-{
-  // Prepare variables
-  bool bSuccess = true;
-  int iPrevChannel = m_pSlingbox->GetChannel();
-
-  // Stop the stream
-  if (m_pSlingbox->StopStream())
-  {
-    CLog::Log(LOGDEBUG, "%s - Successfully stopped stream before channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Error stopping stream before channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-    bSuccess = false;
-  }
-
-  // Figure out which method to use
-  if (m_sSlingboxSettings.uiCodeChannelUp == 0)
-  {
-    // Change the channel
-    if (m_pSlingbox->ChannelUp())
-    {
-      CLog::Log(LOGDEBUG, "%s - Successfully requested channel change on Slingbox: %s",
-        __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-
-      if (m_pSlingbox->GetChannel() == -1)
-      {
-        CLog::Log(LOGDEBUG, "%s - Unable to confirm channel change on Slingbox: %s",
-          __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-      }
-      else if (m_pSlingbox->GetChannel() != iPrevChannel)
-      {
-        CLog::Log(LOGDEBUG, "%s - Confirmed change to channel %i on Slingbox: %s",
-          __FUNCTION__, m_pSlingbox->GetChannel(), m_sSlingboxSettings.strHostname.c_str());
-      }
-      else
-      {
-        CLog::Log(LOGERROR, "%s - Error changing channel on Slingbox: %s",
-          __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-        bSuccess = false;
-      }
-    }
-    else
-    {
-      CLog::Log(LOGERROR, "%s - Error requesting channel change on Slingbox: %s",
-        __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-      bSuccess = false;
-    }
-  }
-  else
-  {
-    // Change the channel using IR command
-    if (m_pSlingbox->SendIRCommand(m_sSlingboxSettings.uiCodeChannelUp))
-    {
-      CLog::Log(LOGDEBUG, "%s - Successfully sent IR command (code: 0x%.2X) from "
-        "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeChannelUp,
-        m_sSlingboxSettings.strHostname.c_str());
-    }
-    else
-    {
-      CLog::Log(LOGERROR, "%s - Error sending IR command (code: 0x%.2X) from "
-        "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeChannelUp,
-        m_sSlingboxSettings.strHostname.c_str());
-      bSuccess = false;
-    }
-  }
-
-  // Start the stream again
-  if (m_pSlingbox->StartStream())
-  {
-    CLog::Log(LOGDEBUG, "%s - Successfully started stream after channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Error starting stream after channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-    bSuccess = false;
-  }
-
-  return bSuccess;
-}
-
-bool CSlingboxFile::PrevChannel()
-{
-  // Prepare variables
-  bool bSuccess = true;
-  int iPrevChannel = m_pSlingbox->GetChannel();
-
-  // Stop the stream
-  if (m_pSlingbox->StopStream())
-  {
-    CLog::Log(LOGDEBUG, "%s - Successfully stopped stream before channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Error stopping stream before channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-    bSuccess = false;
-  }
-
-  // Figure out which method to use
-  if (m_sSlingboxSettings.uiCodeChannelDown == 0)
-  {
-    // Change the channel
-    if (m_pSlingbox->ChannelDown())
-    {
-      CLog::Log(LOGDEBUG, "%s - Successfully requested channel change on Slingbox: %s",
-        __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-
-      if (m_pSlingbox->GetChannel() == -1)
-      {
-        CLog::Log(LOGDEBUG, "%s - Unable to confirm channel change on Slingbox: %s",
-          __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-      }
-      else if (m_pSlingbox->GetChannel() != iPrevChannel)
-      {
-        CLog::Log(LOGDEBUG, "%s - Confirmed change to channel %i on Slingbox: %s",
-          __FUNCTION__, m_pSlingbox->GetChannel(), m_sSlingboxSettings.strHostname.c_str());
-      }
-      else
-      {
-        CLog::Log(LOGERROR, "%s - Error changing channel on Slingbox: %s",
-          __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-        bSuccess = false;
-      }
-    }
-    else
-    {
-      CLog::Log(LOGERROR, "%s - Error requesting channel change on Slingbox: %s",
-        __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-      bSuccess = false;
-    }
-  }
-  else
-  {
-    // Change the channel using IR command
-    if (m_pSlingbox->SendIRCommand(m_sSlingboxSettings.uiCodeChannelDown))
-    {
-      CLog::Log(LOGDEBUG, "%s - Successfully sent IR command (code: 0x%.2X) from "
-        "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeChannelDown,
-        m_sSlingboxSettings.strHostname.c_str());
-    }
-    else
-    {
-      CLog::Log(LOGERROR, "%s - Error sending IR command (code: 0x%.2X) from "
-        "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeChannelDown,
-        m_sSlingboxSettings.strHostname.c_str());
-      bSuccess = false;
-    }
-  }    
-
-  // Start the stream again
-  if (m_pSlingbox->StartStream())
-  {
-    CLog::Log(LOGDEBUG, "%s - Successfully started stream after channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Error starting Slingbox stream after channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-    bSuccess = false;
-  }
-
-  return bSuccess;
-}
-
-bool CSlingboxFile::SelectChannel(unsigned int uiChannel)
-{
-  // Check if a channel change is required
-  if (m_pSlingbox->GetChannel() == (int)uiChannel)
-    return false;
-
-  // Prepare variables
-  bool bSuccess = true;
-
-  // Stop the stream
-  if (m_pSlingbox->StopStream())
-  {
-    CLog::Log(LOGDEBUG, "%s - Successfully stopped stream before channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Error stopping stream before channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-    bSuccess = false;
-  }
-
-  // Figure out which method to use
-  unsigned int uiButtonsWithCode = 0;
-  for (unsigned int i = 0; i < 10; i++)
-  {
-    if (m_sSlingboxSettings.uiCodeNumber[i] != 0)
-      uiButtonsWithCode++;
-  }
-  if (uiButtonsWithCode == 0)
-  {
-    // Change the channel
-    if (m_pSlingbox->SetChannel(uiChannel))
-    {
-      CLog::Log(LOGDEBUG, "%s - Successfully requested change to channel %i on Slingbox: %s",
-        __FUNCTION__, uiChannel, m_sSlingboxSettings.strHostname.c_str());
-
-      if (m_pSlingbox->GetChannel() == -1)
-      {
-        CLog::Log(LOGDEBUG, "%s - Unable to confirm change to channel %i on Slingbox: %s",
-          __FUNCTION__, uiChannel, m_sSlingboxSettings.strHostname.c_str());
-      }
-      else if (m_pSlingbox->GetChannel() == (int)uiChannel)
-      {
-        CLog::Log(LOGDEBUG, "%s - Confirmed change to channel %i on Slingbox: %s",
-          __FUNCTION__, uiChannel, m_sSlingboxSettings.strHostname.c_str());
-      }
-      else
-      {
-        CLog::Log(LOGERROR, "%s - Error changing to channel %i on Slingbox: %s",
-          __FUNCTION__, uiChannel, m_sSlingboxSettings.strHostname.c_str());
-        bSuccess = false;
-      }
-    }
-    else
-    {
-      CLog::Log(LOGERROR, "%s - Error requesting change to channel %i on Slingbox: %s",
-        __FUNCTION__, uiChannel, m_sSlingboxSettings.strHostname.c_str());
-      bSuccess = false;
-    }
-  }
-  else if (uiButtonsWithCode == 10)
-  {
-    // Prepare variables
-    CStdString strDigits;
-    strDigits.Format("%u", uiChannel);
-    unsigned int uiNumberOfDigits = strDigits.GetLength();
-
-    // Change the channel using IR commands
-    for (unsigned int i = 0; i < uiNumberOfDigits; i++)
-    {
-      if (m_pSlingbox->SendIRCommand(m_sSlingboxSettings.uiCodeNumber[strDigits[i] - '0']))
-      {
-        CLog::Log(LOGDEBUG, "%s - Successfully sent IR command (code: 0x%.2X) from "
-          "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeNumber[strDigits[i] - '0'],
-          m_sSlingboxSettings.strHostname.c_str());
-      }
-      else
-      {
-        CLog::Log(LOGDEBUG, "%s - Error sending IR command (code: 0x%.2X) from "
-          "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeNumber[strDigits[i] - '0'],
-          m_sSlingboxSettings.strHostname.c_str());
-        bSuccess = false;
-      }
-    }
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Error requesting change to channel %i on Slingbox due to one or more "
-      "missing button codes from advancedsettings.xml for Slingbox: %s", __FUNCTION__, uiChannel,
-      m_sSlingboxSettings.strHostname.c_str());
-    bSuccess = false;
-  }
-
-  // Start the stream again
-  if (m_pSlingbox->StartStream())
-  {
-    CLog::Log(LOGDEBUG, "%s - Successfully started stream after channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-  }
-  else
-  {
-    CLog::Log(LOGERROR, "%s - Error starting stream after channel change request on "
-      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-    bSuccess = false;
-  }
-
-  return bSuccess;
-}
-
-void CSlingboxFile::LoadSettings(const CStdString& strHostname)
-{
-  // Load default settings
-  m_sSlingboxSettings.strHostname = strHostname;
-  m_sSlingboxSettings.iVideoWidth = 320;
-  m_sSlingboxSettings.iVideoHeight = 240;
-  m_sSlingboxSettings.iVideoResolution = (int)CSlingbox::RESOLUTION320X240;
-  m_sSlingboxSettings.iVideoBitrate = 704;
-  m_sSlingboxSettings.iVideoFramerate = 30;
-  m_sSlingboxSettings.iVideoSmoothing = 50;
-  m_sSlingboxSettings.iAudioBitrate = 64;
-  m_sSlingboxSettings.iIFrameInterval = 10;
-  m_sSlingboxSettings.uiCodeChannelUp = 0;
-  m_sSlingboxSettings.uiCodeChannelDown = 0;
-  for (unsigned int i = 0; i < 10; i++)
-    m_sSlingboxSettings.uiCodeNumber[i] = 0;
-
-  // Check if a SlingboxSettings.xml file exists
-  CStdString slingboxXMLFile = g_settings.GetUserDataItem("SlingboxSettings.xml");
-  if (!CFile::Exists(slingboxXMLFile))
-  {
-    CLog::Log(LOGNOTICE, "No SlingboxSettings.xml file (%s) found - using default settings",
-      slingboxXMLFile.c_str());
-    return;
-  }
-
-  // Load the XML file
-  TiXmlDocument slingboxXML;
-  if (!slingboxXML.LoadFile(slingboxXMLFile))
-  {
-    CLog::Log(LOGERROR, "%s - Error loading %s - line %d\n%s", __FUNCTION__, 
-      slingboxXMLFile.c_str(), slingboxXML.ErrorRow(), slingboxXML.ErrorDesc());
-    return;
-  }
-
-  // Check to make sure layout is correct
-  TiXmlElement * pRootElement = slingboxXML.RootElement();
-  if (!pRootElement || strcmpi(pRootElement->Value(), "slingboxsettings") != 0)
-  {
-    CLog::Log(LOGERROR, "%s - Error loading %s - no <slingboxsettings> node found",
-      __FUNCTION__, slingboxXMLFile.c_str());
-    return;
-  }
-
-  // Success so far
-  CLog::Log(LOGNOTICE, "Loaded SlingboxSettings.xml from %s", slingboxXMLFile.c_str());
-
-  // Search for the first settings that specify no hostname or match our hostname
-  TiXmlElement *pElement;
-  for (pElement = pRootElement->FirstChildElement("slingbox"); pElement;
-    pElement = pElement->NextSiblingElement("slingbox"))
-  {
-    if (pElement->Attribute("hostname") == NULL ||      
-      !m_sSlingboxSettings.strHostname.CompareNoCase(pElement->Attribute("hostname")))
-    {
-      // Load setting values
-      XMLUtils::GetInt(pElement, "width", m_sSlingboxSettings.iVideoWidth, 0, 640);
-      XMLUtils::GetInt(pElement, "height", m_sSlingboxSettings.iVideoHeight, 0, 480);
-      XMLUtils::GetInt(pElement, "videobitrate", m_sSlingboxSettings.iVideoBitrate, 50, 8000);
-      XMLUtils::GetInt(pElement, "framerate", m_sSlingboxSettings.iVideoFramerate, 1, 30);
-      XMLUtils::GetInt(pElement, "smoothing", m_sSlingboxSettings.iVideoSmoothing, 0, 100);
-      XMLUtils::GetInt(pElement, "audiobitrate", m_sSlingboxSettings.iAudioBitrate, 16, 96);
-      XMLUtils::GetInt(pElement, "iframeinterval", m_sSlingboxSettings.iIFrameInterval, 1, 30);
-
-      // Load any button code values
-      TiXmlElement * pCodes = pElement->FirstChildElement("buttons");
-      if (pCodes)
-      {
-        XMLUtils::GetHex(pCodes, "channelup", m_sSlingboxSettings.uiCodeChannelUp);
-        XMLUtils::GetHex(pCodes, "channeldown", m_sSlingboxSettings.uiCodeChannelDown);
-        XMLUtils::GetHex(pCodes, "zero", m_sSlingboxSettings.uiCodeNumber[0]);
-        XMLUtils::GetHex(pCodes, "one", m_sSlingboxSettings.uiCodeNumber[1]);
-        XMLUtils::GetHex(pCodes, "two", m_sSlingboxSettings.uiCodeNumber[2]);
-        XMLUtils::GetHex(pCodes, "three", m_sSlingboxSettings.uiCodeNumber[3]);
-        XMLUtils::GetHex(pCodes, "four", m_sSlingboxSettings.uiCodeNumber[4]);
-        XMLUtils::GetHex(pCodes, "five", m_sSlingboxSettings.uiCodeNumber[5]);
-        XMLUtils::GetHex(pCodes, "six", m_sSlingboxSettings.uiCodeNumber[6]);
-        XMLUtils::GetHex(pCodes, "seven", m_sSlingboxSettings.uiCodeNumber[7]);
-        XMLUtils::GetHex(pCodes, "eight", m_sSlingboxSettings.uiCodeNumber[8]);
-        XMLUtils::GetHex(pCodes, "nine", m_sSlingboxSettings.uiCodeNumber[9]);
-      }
-
-      break;
-    }
-  }
-
-  // Prepare our resolution enum mapping array
-  const struct
-  {
-    unsigned int uiWidth;
-    unsigned int uiHeight;
-    CSlingbox::Resolution eEnum;
-  } m_resolutionMap[11] = {
-    {0, 0, CSlingbox::NOVIDEO},
-    {128, 96, CSlingbox::RESOLUTION128X96},
-    {160, 120, CSlingbox::RESOLUTION160X120},
-    {176, 120, CSlingbox::RESOLUTION176X120},
-    {224, 176, CSlingbox::RESOLUTION224X176},
-    {256, 192, CSlingbox::RESOLUTION256X192},
-    {320, 240, CSlingbox::RESOLUTION320X240},
-    {352, 240, CSlingbox::RESOLUTION352X240},
-    {320, 480, CSlingbox::RESOLUTION320X480},
-    {640, 240, CSlingbox::RESOLUTION640X240},
-    {640, 480, CSlingbox::RESOLUTION640X480}
-  };
-
-  // See if the specified resolution matches something in our mapping array and
-  // setup things accordingly
-  for (unsigned int i = 0; i < 11; i++)
-  {
-    if (m_sSlingboxSettings.iVideoWidth == (int)m_resolutionMap[i].uiWidth &&
-      m_sSlingboxSettings.iVideoHeight == (int)m_resolutionMap[i].uiHeight)
-    {
-      m_sSlingboxSettings.iVideoResolution = (int)m_resolutionMap[i].eEnum;
-      return;
-    }
-  }
-
-  // If it didn't match anything setup safe defaults
-  CLog::Log(LOGERROR, "%s - Defaulting to 320x240 resolution due to invalid "
-    "resolution specified in SlingboxSettings.xml for Slingbox: %s",
-    __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
-  m_sSlingboxSettings.iVideoWidth = 320;
-  m_sSlingboxSettings.iVideoHeight = 240;
-  m_sSlingboxSettings.iVideoResolution = (int)CSlingbox::RESOLUTION320X240;
-}
diff --git a/xbmc/filesystem/Slingbox.h b/xbmc/filesystem/Slingbox.h
deleted file mode 100644 (file)
index 22ad11f..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2011 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "IDirectory.h"
-#include "IFile.h"
-#include "ILiveTV.h"
-
-class CSlingbox;
-
-namespace XFILE
-{
-
-class CSlingboxDirectory
-  : public IDirectory
-{
-public:
-  CSlingboxDirectory();
-  virtual ~CSlingboxDirectory();
-
-  virtual bool IsAllowed(const CStdString &strFile) const    { return true; }
-  virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items);
-};
-
-class CSlingboxFile
-  : public IFile, ILiveTVInterface
-{
-public:
-  CSlingboxFile();
-  virtual ~CSlingboxFile();
-  virtual bool Open(const CURL& url);
-  virtual unsigned int Read(void * buffer, int64_t size);
-  virtual void Close();
-  virtual bool SkipNext();
-
-  virtual int GetStartTime()                                 { return 0; }
-  virtual int GetTotalTime()                                 { return 0; }
-  virtual int64_t GetLength()                                { return -1; }
-  virtual int64_t GetPosition()                              { return -1; }
-  virtual int64_t Seek(int64_t pos, int whence)              { return -1; }
-  virtual bool UpdateItem(CFileItem& item)                   { return false; }
-    
-  virtual bool Exists(const CURL& url)                       { return false; }
-  virtual int Stat(const CURL& url, struct __stat64* buffer) { return -1; }
-
-  virtual ILiveTVInterface * GetLiveTV()                     { return (ILiveTVInterface *)this; }
-
-  virtual bool NextChannel();
-  virtual bool PrevChannel();
-  virtual bool SelectChannel(unsigned int uiChannel);
-
-protected:
-  struct
-  {
-    CStdString strHostname;
-    int iVideoWidth;
-    int iVideoHeight;
-    int iVideoResolution;
-    int iVideoBitrate;
-    int iVideoFramerate;
-    int iVideoSmoothing;
-    int iAudioBitrate;
-    int iIFrameInterval;
-    unsigned int uiCodeChannelUp;
-    unsigned int uiCodeChannelDown;
-    unsigned int uiCodeNumber[10];
-  } m_sSlingboxSettings;
-
-  void LoadSettings(const CStdString& strSlingbox);
-  CSlingbox * m_pSlingbox;
-};
-
-}
diff --git a/xbmc/filesystem/SlingboxDirectory.cpp b/xbmc/filesystem/SlingboxDirectory.cpp
new file mode 100644 (file)
index 0000000..7085a2e
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "SlingboxDirectory.h"
+#include "FileItem.h"
+
+using namespace XFILE;
+using namespace std;
+
+CSlingboxDirectory::CSlingboxDirectory()
+{
+}
+
+CSlingboxDirectory::~CSlingboxDirectory()
+{
+}
+
+bool CSlingboxDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
+{
+  // Create generic Watch Slingbox item
+  CFileItemPtr item(new CFileItem(strPath, false));
+  item->SetLabel("Watch Slingbox");
+  item->SetLabelPreformated(true);
+  items.Add(item);
+
+  return true;
+}
\ No newline at end of file
diff --git a/xbmc/filesystem/SlingboxDirectory.h b/xbmc/filesystem/SlingboxDirectory.h
new file mode 100644 (file)
index 0000000..22bfd23
--- /dev/null
@@ -0,0 +1,38 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+ #include "IDirectory.h"
+namespace XFILE
+{
+  
+  class CSlingboxDirectory
+  : public IDirectory
+  {
+  public:
+    CSlingboxDirectory();
+    virtual ~CSlingboxDirectory();
+    
+    virtual bool IsAllowed(const CStdString &strFile) const    { return true; }
+    virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items);
+  };
+}
\ No newline at end of file
diff --git a/xbmc/filesystem/SlingboxFile.cpp b/xbmc/filesystem/SlingboxFile.cpp
new file mode 100644 (file)
index 0000000..d392b29
--- /dev/null
@@ -0,0 +1,603 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "FileItem.h"
+#include "SlingboxFile.h"
+#include "filesystem/File.h"
+#include "lib/SlingboxLib/SlingboxLib.h"
+#include "settings/Settings.h"
+#include "utils/log.h"
+#include "utils/XMLUtils.h"
+
+using namespace XFILE;
+using namespace std;
+
+CSlingboxFile::CSlingboxFile()
+{
+  // Create the Slingbox object
+  m_pSlingbox = new CSlingbox();
+}
+
+CSlingboxFile::~CSlingboxFile()
+{
+  // Destroy the Slingbox object
+  delete m_pSlingbox;
+}
+
+bool CSlingboxFile::Open(const CURL& url)
+{
+  // Setup the IP/hostname and port (setup default port if none specified)
+  unsigned int uiPort;
+  if (url.HasPort())
+    uiPort = (unsigned int)url.GetPort();
+  else
+    uiPort = 5001;
+  m_pSlingbox->SetAddress(url.GetHostName(), uiPort);
+
+  // Prepare to connect to the Slingbox
+  bool bAdmin;
+  if (url.GetUserName().CompareNoCase("administrator") == 0)
+    bAdmin = true;
+  else if (url.GetUserName().CompareNoCase("viewer") == 0)
+    bAdmin = false;
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Invalid or no username specified for Slingbox: %s",
+      __FUNCTION__, url.GetHostName().c_str());
+    return false;
+  }
+
+  // Connect to the Slingbox
+  if (m_pSlingbox->Connect(bAdmin, url.GetPassWord()))
+  {
+    CLog::Log(LOGDEBUG, "%s - Sucessfully connected to Slingbox: %s",
+      __FUNCTION__, url.GetHostName().c_str());
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Error connecting to Slingbox: %s",
+      __FUNCTION__, url.GetHostName().c_str());
+    return false;
+  }
+
+  // Initialize the stream
+  if (m_pSlingbox->InitializeStream())
+  {
+    CLog::Log(LOGDEBUG, "%s - Successfully initialized stream on Slingbox: %s",
+      __FUNCTION__, url.GetHostName().c_str());
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Error initializing stream on Slingbox: %s",
+      __FUNCTION__, url.GetHostName().c_str());
+    return false;
+  }
+
+  // Set correct input
+  if (url.GetFileNameWithoutPath() != "")
+  {
+    if (m_pSlingbox->SetInput(atoi(url.GetFileNameWithoutPath())))
+      CLog::Log(LOGDEBUG, "%s - Successfully requested change to input %i on Slingbox: %s",
+        __FUNCTION__, atoi(url.GetFileNameWithoutPath()), url.GetHostName().c_str());
+    else
+      CLog::Log(LOGERROR, "%s - Error requesting change to input %i on Slingbox: %s",
+        __FUNCTION__, atoi(url.GetFileNameWithoutPath()), url.GetHostName().c_str());
+  }
+
+  // Load the video settings
+  LoadSettings(url.GetHostName());
+
+  // Setup video options  
+  if (m_pSlingbox->StreamSettings((CSlingbox::Resolution)m_sSlingboxSettings.iVideoResolution,
+    m_sSlingboxSettings.iVideoBitrate, m_sSlingboxSettings.iVideoFramerate,
+    m_sSlingboxSettings.iVideoSmoothing, m_sSlingboxSettings.iAudioBitrate,
+    m_sSlingboxSettings.iIFrameInterval))
+  {
+    CLog::Log(LOGDEBUG, "%s - Successfully set stream options (resolution: %ix%i; "
+      "video bitrate: %i kbit/s; fps: %i; smoothing: %i%%; audio bitrate %i kbit/s; "
+      "I frame interval: %i) on Slingbox: %s", __FUNCTION__,
+      m_sSlingboxSettings.iVideoWidth, m_sSlingboxSettings.iVideoHeight,
+      m_sSlingboxSettings.iVideoBitrate, m_sSlingboxSettings.iVideoFramerate,
+      m_sSlingboxSettings.iVideoSmoothing, m_sSlingboxSettings.iAudioBitrate,
+      m_sSlingboxSettings.iIFrameInterval, url.GetHostName().c_str());
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Error setting stream options on Slingbox: %s",
+      __FUNCTION__, url.GetHostName().c_str());
+  }
+
+  // Start the stream
+  if (m_pSlingbox->StartStream())
+  {
+    CLog::Log(LOGDEBUG, "%s - Successfully started stream on Slingbox: %s",
+      __FUNCTION__, url.GetHostName().c_str());
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Error starting stream on Slingbox: %s",
+      __FUNCTION__, url.GetHostName().c_str());
+    return false;
+  }
+
+  // Check for correct input
+  if (url.GetFileNameWithoutPath() != "")
+  {
+    if (m_pSlingbox->GetInput() == -1)
+      CLog::Log(LOGDEBUG, "%s - Unable to confirm change to input %i on Slingbox: %s",
+        __FUNCTION__, atoi(url.GetFileNameWithoutPath()), url.GetHostName().c_str());
+    else if (m_pSlingbox->GetInput() == atoi(url.GetFileNameWithoutPath()))
+      CLog::Log(LOGDEBUG, "%s - Comfirmed change to input %i on Slingbox: %s",
+        __FUNCTION__, atoi(url.GetFileNameWithoutPath()), url.GetHostName().c_str());
+    else
+      CLog::Log(LOGERROR, "%s - Error changing to input %i on Slingbox: %s",
+        __FUNCTION__, atoi(url.GetFileNameWithoutPath()), url.GetHostName().c_str());
+  }
+
+  return true;
+}
+
+unsigned int CSlingboxFile::Read(void * pBuffer, int64_t iSize)
+{
+  // Read the data and check for any errors
+  int iRead = m_pSlingbox->ReadStream(pBuffer, (unsigned int)iSize);
+  if (iRead < 0)
+  {
+    CLog::Log(LOGERROR, "%s - Error reading stream from Slingbox: %s", __FUNCTION__,
+      m_sSlingboxSettings.strHostname.c_str());
+    return 0;
+  }
+
+  return iRead;
+}
+
+void CSlingboxFile::Close()
+{
+  // Stop the stream
+  if (m_pSlingbox->StopStream())
+    CLog::Log(LOGDEBUG, "%s - Successfully stopped stream on Slingbox: %s", __FUNCTION__,
+    m_sSlingboxSettings.strHostname.c_str());
+  else
+    CLog::Log(LOGERROR, "%s - Error stopping stream on Slingbox: %s", __FUNCTION__,
+    m_sSlingboxSettings.strHostname.c_str());
+
+  // Disconnect from the Slingbox
+  if (m_pSlingbox->Disconnect())
+    CLog::Log(LOGDEBUG, "%s - Successfully disconnected from Slingbox: %s", __FUNCTION__,
+    m_sSlingboxSettings.strHostname.c_str());
+  else
+    CLog::Log(LOGERROR, "%s - Error disconnecting from Slingbox: %s", __FUNCTION__,
+    m_sSlingboxSettings.strHostname.c_str());
+}
+
+bool CSlingboxFile::SkipNext()
+{
+  return m_pSlingbox->IsConnected();
+}
+
+bool CSlingboxFile::NextChannel()
+{
+  // Prepare variables
+  bool bSuccess = true;
+  int iPrevChannel = m_pSlingbox->GetChannel();
+
+  // Stop the stream
+  if (m_pSlingbox->StopStream())
+  {
+    CLog::Log(LOGDEBUG, "%s - Successfully stopped stream before channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Error stopping stream before channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+    bSuccess = false;
+  }
+
+  // Figure out which method to use
+  if (m_sSlingboxSettings.uiCodeChannelUp == 0)
+  {
+    // Change the channel
+    if (m_pSlingbox->ChannelUp())
+    {
+      CLog::Log(LOGDEBUG, "%s - Successfully requested channel change on Slingbox: %s",
+        __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+
+      if (m_pSlingbox->GetChannel() == -1)
+      {
+        CLog::Log(LOGDEBUG, "%s - Unable to confirm channel change on Slingbox: %s",
+          __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+      }
+      else if (m_pSlingbox->GetChannel() != iPrevChannel)
+      {
+        CLog::Log(LOGDEBUG, "%s - Confirmed change to channel %i on Slingbox: %s",
+          __FUNCTION__, m_pSlingbox->GetChannel(), m_sSlingboxSettings.strHostname.c_str());
+      }
+      else
+      {
+        CLog::Log(LOGERROR, "%s - Error changing channel on Slingbox: %s",
+          __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+        bSuccess = false;
+      }
+    }
+    else
+    {
+      CLog::Log(LOGERROR, "%s - Error requesting channel change on Slingbox: %s",
+        __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+      bSuccess = false;
+    }
+  }
+  else
+  {
+    // Change the channel using IR command
+    if (m_pSlingbox->SendIRCommand(m_sSlingboxSettings.uiCodeChannelUp))
+    {
+      CLog::Log(LOGDEBUG, "%s - Successfully sent IR command (code: 0x%.2X) from "
+        "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeChannelUp,
+        m_sSlingboxSettings.strHostname.c_str());
+    }
+    else
+    {
+      CLog::Log(LOGERROR, "%s - Error sending IR command (code: 0x%.2X) from "
+        "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeChannelUp,
+        m_sSlingboxSettings.strHostname.c_str());
+      bSuccess = false;
+    }
+  }
+
+  // Start the stream again
+  if (m_pSlingbox->StartStream())
+  {
+    CLog::Log(LOGDEBUG, "%s - Successfully started stream after channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Error starting stream after channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+    bSuccess = false;
+  }
+
+  return bSuccess;
+}
+
+bool CSlingboxFile::PrevChannel()
+{
+  // Prepare variables
+  bool bSuccess = true;
+  int iPrevChannel = m_pSlingbox->GetChannel();
+
+  // Stop the stream
+  if (m_pSlingbox->StopStream())
+  {
+    CLog::Log(LOGDEBUG, "%s - Successfully stopped stream before channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Error stopping stream before channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+    bSuccess = false;
+  }
+
+  // Figure out which method to use
+  if (m_sSlingboxSettings.uiCodeChannelDown == 0)
+  {
+    // Change the channel
+    if (m_pSlingbox->ChannelDown())
+    {
+      CLog::Log(LOGDEBUG, "%s - Successfully requested channel change on Slingbox: %s",
+        __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+
+      if (m_pSlingbox->GetChannel() == -1)
+      {
+        CLog::Log(LOGDEBUG, "%s - Unable to confirm channel change on Slingbox: %s",
+          __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+      }
+      else if (m_pSlingbox->GetChannel() != iPrevChannel)
+      {
+        CLog::Log(LOGDEBUG, "%s - Confirmed change to channel %i on Slingbox: %s",
+          __FUNCTION__, m_pSlingbox->GetChannel(), m_sSlingboxSettings.strHostname.c_str());
+      }
+      else
+      {
+        CLog::Log(LOGERROR, "%s - Error changing channel on Slingbox: %s",
+          __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+        bSuccess = false;
+      }
+    }
+    else
+    {
+      CLog::Log(LOGERROR, "%s - Error requesting channel change on Slingbox: %s",
+        __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+      bSuccess = false;
+    }
+  }
+  else
+  {
+    // Change the channel using IR command
+    if (m_pSlingbox->SendIRCommand(m_sSlingboxSettings.uiCodeChannelDown))
+    {
+      CLog::Log(LOGDEBUG, "%s - Successfully sent IR command (code: 0x%.2X) from "
+        "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeChannelDown,
+        m_sSlingboxSettings.strHostname.c_str());
+    }
+    else
+    {
+      CLog::Log(LOGERROR, "%s - Error sending IR command (code: 0x%.2X) from "
+        "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeChannelDown,
+        m_sSlingboxSettings.strHostname.c_str());
+      bSuccess = false;
+    }
+  }    
+
+  // Start the stream again
+  if (m_pSlingbox->StartStream())
+  {
+    CLog::Log(LOGDEBUG, "%s - Successfully started stream after channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Error starting Slingbox stream after channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+    bSuccess = false;
+  }
+
+  return bSuccess;
+}
+
+bool CSlingboxFile::SelectChannel(unsigned int uiChannel)
+{
+  // Check if a channel change is required
+  if (m_pSlingbox->GetChannel() == (int)uiChannel)
+    return false;
+
+  // Prepare variables
+  bool bSuccess = true;
+
+  // Stop the stream
+  if (m_pSlingbox->StopStream())
+  {
+    CLog::Log(LOGDEBUG, "%s - Successfully stopped stream before channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Error stopping stream before channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+    bSuccess = false;
+  }
+
+  // Figure out which method to use
+  unsigned int uiButtonsWithCode = 0;
+  for (unsigned int i = 0; i < 10; i++)
+  {
+    if (m_sSlingboxSettings.uiCodeNumber[i] != 0)
+      uiButtonsWithCode++;
+  }
+  if (uiButtonsWithCode == 0)
+  {
+    // Change the channel
+    if (m_pSlingbox->SetChannel(uiChannel))
+    {
+      CLog::Log(LOGDEBUG, "%s - Successfully requested change to channel %i on Slingbox: %s",
+        __FUNCTION__, uiChannel, m_sSlingboxSettings.strHostname.c_str());
+
+      if (m_pSlingbox->GetChannel() == -1)
+      {
+        CLog::Log(LOGDEBUG, "%s - Unable to confirm change to channel %i on Slingbox: %s",
+          __FUNCTION__, uiChannel, m_sSlingboxSettings.strHostname.c_str());
+      }
+      else if (m_pSlingbox->GetChannel() == (int)uiChannel)
+      {
+        CLog::Log(LOGDEBUG, "%s - Confirmed change to channel %i on Slingbox: %s",
+          __FUNCTION__, uiChannel, m_sSlingboxSettings.strHostname.c_str());
+      }
+      else
+      {
+        CLog::Log(LOGERROR, "%s - Error changing to channel %i on Slingbox: %s",
+          __FUNCTION__, uiChannel, m_sSlingboxSettings.strHostname.c_str());
+        bSuccess = false;
+      }
+    }
+    else
+    {
+      CLog::Log(LOGERROR, "%s - Error requesting change to channel %i on Slingbox: %s",
+        __FUNCTION__, uiChannel, m_sSlingboxSettings.strHostname.c_str());
+      bSuccess = false;
+    }
+  }
+  else if (uiButtonsWithCode == 10)
+  {
+    // Prepare variables
+    CStdString strDigits;
+    strDigits.Format("%u", uiChannel);
+    unsigned int uiNumberOfDigits = strDigits.GetLength();
+
+    // Change the channel using IR commands
+    for (unsigned int i = 0; i < uiNumberOfDigits; i++)
+    {
+      if (m_pSlingbox->SendIRCommand(m_sSlingboxSettings.uiCodeNumber[strDigits[i] - '0']))
+      {
+        CLog::Log(LOGDEBUG, "%s - Successfully sent IR command (code: 0x%.2X) from "
+          "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeNumber[strDigits[i] - '0'],
+          m_sSlingboxSettings.strHostname.c_str());
+      }
+      else
+      {
+        CLog::Log(LOGDEBUG, "%s - Error sending IR command (code: 0x%.2X) from "
+          "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.uiCodeNumber[strDigits[i] - '0'],
+          m_sSlingboxSettings.strHostname.c_str());
+        bSuccess = false;
+      }
+    }
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Error requesting change to channel %i on Slingbox due to one or more "
+      "missing button codes from advancedsettings.xml for Slingbox: %s", __FUNCTION__, uiChannel,
+      m_sSlingboxSettings.strHostname.c_str());
+    bSuccess = false;
+  }
+
+  // Start the stream again
+  if (m_pSlingbox->StartStream())
+  {
+    CLog::Log(LOGDEBUG, "%s - Successfully started stream after channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+  }
+  else
+  {
+    CLog::Log(LOGERROR, "%s - Error starting stream after channel change request on "
+      "Slingbox: %s", __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+    bSuccess = false;
+  }
+
+  return bSuccess;
+}
+
+void CSlingboxFile::LoadSettings(const CStdString& strHostname)
+{
+  // Load default settings
+  m_sSlingboxSettings.strHostname = strHostname;
+  m_sSlingboxSettings.iVideoWidth = 320;
+  m_sSlingboxSettings.iVideoHeight = 240;
+  m_sSlingboxSettings.iVideoResolution = (int)CSlingbox::RESOLUTION320X240;
+  m_sSlingboxSettings.iVideoBitrate = 704;
+  m_sSlingboxSettings.iVideoFramerate = 30;
+  m_sSlingboxSettings.iVideoSmoothing = 50;
+  m_sSlingboxSettings.iAudioBitrate = 64;
+  m_sSlingboxSettings.iIFrameInterval = 10;
+  m_sSlingboxSettings.uiCodeChannelUp = 0;
+  m_sSlingboxSettings.uiCodeChannelDown = 0;
+  for (unsigned int i = 0; i < 10; i++)
+    m_sSlingboxSettings.uiCodeNumber[i] = 0;
+
+  // Check if a SlingboxSettings.xml file exists
+  CStdString slingboxXMLFile = g_settings.GetUserDataItem("SlingboxSettings.xml");
+  if (!CFile::Exists(slingboxXMLFile))
+  {
+    CLog::Log(LOGNOTICE, "No SlingboxSettings.xml file (%s) found - using default settings",
+      slingboxXMLFile.c_str());
+    return;
+  }
+
+  // Load the XML file
+  TiXmlDocument slingboxXML;
+  if (!slingboxXML.LoadFile(slingboxXMLFile))
+  {
+    CLog::Log(LOGERROR, "%s - Error loading %s - line %d\n%s", __FUNCTION__, 
+      slingboxXMLFile.c_str(), slingboxXML.ErrorRow(), slingboxXML.ErrorDesc());
+    return;
+  }
+
+  // Check to make sure layout is correct
+  TiXmlElement * pRootElement = slingboxXML.RootElement();
+  if (!pRootElement || strcmpi(pRootElement->Value(), "slingboxsettings") != 0)
+  {
+    CLog::Log(LOGERROR, "%s - Error loading %s - no <slingboxsettings> node found",
+      __FUNCTION__, slingboxXMLFile.c_str());
+    return;
+  }
+
+  // Success so far
+  CLog::Log(LOGNOTICE, "Loaded SlingboxSettings.xml from %s", slingboxXMLFile.c_str());
+
+  // Search for the first settings that specify no hostname or match our hostname
+  TiXmlElement *pElement;
+  for (pElement = pRootElement->FirstChildElement("slingbox"); pElement;
+    pElement = pElement->NextSiblingElement("slingbox"))
+  {
+    if (pElement->Attribute("hostname") == NULL ||      
+      !m_sSlingboxSettings.strHostname.CompareNoCase(pElement->Attribute("hostname")))
+    {
+      // Load setting values
+      XMLUtils::GetInt(pElement, "width", m_sSlingboxSettings.iVideoWidth, 0, 640);
+      XMLUtils::GetInt(pElement, "height", m_sSlingboxSettings.iVideoHeight, 0, 480);
+      XMLUtils::GetInt(pElement, "videobitrate", m_sSlingboxSettings.iVideoBitrate, 50, 8000);
+      XMLUtils::GetInt(pElement, "framerate", m_sSlingboxSettings.iVideoFramerate, 1, 30);
+      XMLUtils::GetInt(pElement, "smoothing", m_sSlingboxSettings.iVideoSmoothing, 0, 100);
+      XMLUtils::GetInt(pElement, "audiobitrate", m_sSlingboxSettings.iAudioBitrate, 16, 96);
+      XMLUtils::GetInt(pElement, "iframeinterval", m_sSlingboxSettings.iIFrameInterval, 1, 30);
+
+      // Load any button code values
+      TiXmlElement * pCodes = pElement->FirstChildElement("buttons");
+      if (pCodes)
+      {
+        XMLUtils::GetHex(pCodes, "channelup", m_sSlingboxSettings.uiCodeChannelUp);
+        XMLUtils::GetHex(pCodes, "channeldown", m_sSlingboxSettings.uiCodeChannelDown);
+        XMLUtils::GetHex(pCodes, "zero", m_sSlingboxSettings.uiCodeNumber[0]);
+        XMLUtils::GetHex(pCodes, "one", m_sSlingboxSettings.uiCodeNumber[1]);
+        XMLUtils::GetHex(pCodes, "two", m_sSlingboxSettings.uiCodeNumber[2]);
+        XMLUtils::GetHex(pCodes, "three", m_sSlingboxSettings.uiCodeNumber[3]);
+        XMLUtils::GetHex(pCodes, "four", m_sSlingboxSettings.uiCodeNumber[4]);
+        XMLUtils::GetHex(pCodes, "five", m_sSlingboxSettings.uiCodeNumber[5]);
+        XMLUtils::GetHex(pCodes, "six", m_sSlingboxSettings.uiCodeNumber[6]);
+        XMLUtils::GetHex(pCodes, "seven", m_sSlingboxSettings.uiCodeNumber[7]);
+        XMLUtils::GetHex(pCodes, "eight", m_sSlingboxSettings.uiCodeNumber[8]);
+        XMLUtils::GetHex(pCodes, "nine", m_sSlingboxSettings.uiCodeNumber[9]);
+      }
+
+      break;
+    }
+  }
+
+  // Prepare our resolution enum mapping array
+  const struct
+  {
+    unsigned int uiWidth;
+    unsigned int uiHeight;
+    CSlingbox::Resolution eEnum;
+  } m_resolutionMap[11] = {
+    {0, 0, CSlingbox::NOVIDEO},
+    {128, 96, CSlingbox::RESOLUTION128X96},
+    {160, 120, CSlingbox::RESOLUTION160X120},
+    {176, 120, CSlingbox::RESOLUTION176X120},
+    {224, 176, CSlingbox::RESOLUTION224X176},
+    {256, 192, CSlingbox::RESOLUTION256X192},
+    {320, 240, CSlingbox::RESOLUTION320X240},
+    {352, 240, CSlingbox::RESOLUTION352X240},
+    {320, 480, CSlingbox::RESOLUTION320X480},
+    {640, 240, CSlingbox::RESOLUTION640X240},
+    {640, 480, CSlingbox::RESOLUTION640X480}
+  };
+
+  // See if the specified resolution matches something in our mapping array and
+  // setup things accordingly
+  for (unsigned int i = 0; i < 11; i++)
+  {
+    if (m_sSlingboxSettings.iVideoWidth == (int)m_resolutionMap[i].uiWidth &&
+      m_sSlingboxSettings.iVideoHeight == (int)m_resolutionMap[i].uiHeight)
+    {
+      m_sSlingboxSettings.iVideoResolution = (int)m_resolutionMap[i].eEnum;
+      return;
+    }
+  }
+
+  // If it didn't match anything setup safe defaults
+  CLog::Log(LOGERROR, "%s - Defaulting to 320x240 resolution due to invalid "
+    "resolution specified in SlingboxSettings.xml for Slingbox: %s",
+    __FUNCTION__, m_sSlingboxSettings.strHostname.c_str());
+  m_sSlingboxSettings.iVideoWidth = 320;
+  m_sSlingboxSettings.iVideoHeight = 240;
+  m_sSlingboxSettings.iVideoResolution = (int)CSlingbox::RESOLUTION320X240;
+}
diff --git a/xbmc/filesystem/SlingboxFile.h b/xbmc/filesystem/SlingboxFile.h
new file mode 100644 (file)
index 0000000..45082c9
--- /dev/null
@@ -0,0 +1,78 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IFile.h"
+#include "ILiveTV.h"
+
+class CSlingbox;
+
+namespace XFILE
+{
+  class CSlingboxFile
+  : public IFile, ILiveTVInterface
+  {
+  public:
+    CSlingboxFile();
+    virtual ~CSlingboxFile();
+    virtual bool Open(const CURL& url);
+    virtual unsigned int Read(void * buffer, int64_t size);
+    virtual void Close();
+    virtual bool SkipNext();
+    
+    virtual int GetStartTime()                                 { return 0; }
+    virtual int GetTotalTime()                                 { return 0; }
+    virtual int64_t GetLength()                                { return -1; }
+    virtual int64_t GetPosition()                              { return -1; }
+    virtual int64_t Seek(int64_t pos, int whence)              { return -1; }
+    virtual bool UpdateItem(CFileItem& item)                   { return false; }
+    
+    virtual bool Exists(const CURL& url)                       { return false; }
+    virtual int Stat(const CURL& url, struct __stat64* buffer) { return -1; }
+    
+    virtual ILiveTVInterface * GetLiveTV()                     { return (ILiveTVInterface *)this; }
+    
+    virtual bool NextChannel();
+    virtual bool PrevChannel();
+    virtual bool SelectChannel(unsigned int uiChannel);
+    
+  protected:
+    struct
+    {
+      CStdString strHostname;
+      int iVideoWidth;
+      int iVideoHeight;
+      int iVideoResolution;
+      int iVideoBitrate;
+      int iVideoFramerate;
+      int iVideoSmoothing;
+      int iAudioBitrate;
+      int iIFrameInterval;
+      unsigned int uiCodeChannelUp;
+      unsigned int uiCodeChannelDown;
+      unsigned int uiCodeNumber[10];
+    } m_sSlingboxSettings;
+    
+    void LoadSettings(const CStdString& strSlingbox);
+    CSlingbox * m_pSlingbox;
+  };
+  
+}
index 449e26b..45cf607 100644 (file)
@@ -27,6 +27,7 @@
 #include "Directory.h"
 #include "File.h"
 #include "FileItem.h"
+#include "utils/URIUtils.h"
 
 namespace XFILE
 {
@@ -45,11 +46,12 @@ namespace XFILE
     if (!playlist.Load(strPath))
       return false;
     bool success = false, success2 = false;
+    std::set<CStdString> playlists;
     if (playlist.GetType().Equals("tvshows"))
     {
       CVideoDatabase db;
       db.Open();
-      CStdString whereOrder = playlist.GetWhereClause(db) + " " + playlist.GetOrderClause(db);
+      CStdString whereOrder = playlist.GetWhereClause(db, playlists) + " " + playlist.GetOrderClause(db);
       success = db.GetTvShowsByWhere("videodb://2/2/", whereOrder, items);
       items.SetContent("tvshows");
       db.Close();
@@ -58,7 +60,7 @@ namespace XFILE
     {
       CVideoDatabase db;
       db.Open();
-      CStdString whereOrder = playlist.GetWhereClause(db) + " " + playlist.GetOrderClause(db);
+      CStdString whereOrder = playlist.GetWhereClause(db, playlists) + " " + playlist.GetOrderClause(db);
       success = db.GetEpisodesByWhere("videodb://2/2/", whereOrder, items);
       items.SetContent("episodes");
       db.Close();
@@ -67,7 +69,7 @@ namespace XFILE
     {
       CVideoDatabase db;
       db.Open();
-      success = db.GetMoviesByWhere("videodb://1/2/", playlist.GetWhereClause(db), playlist.GetOrderClause(db), items, true);
+      success = db.GetMoviesByWhere("videodb://1/2/", playlist.GetWhereClause(db, playlists), playlist.GetOrderClause(db), items, true);
       items.SetContent("movies");
       db.Close();
     }
@@ -75,7 +77,7 @@ namespace XFILE
     {
       CMusicDatabase db;
       db.Open();
-      success = db.GetAlbumsByWhere("musicdb://3/", playlist.GetWhereClause(db), playlist.GetOrderClause(db), items);
+      success = db.GetAlbumsByWhere("musicdb://3/", playlist.GetWhereClause(db, playlists), playlist.GetOrderClause(db), items);
       items.SetContent("albums");
       db.Close();
     }
@@ -89,7 +91,7 @@ namespace XFILE
       if (playlist.GetType().Equals("mixed"))
         playlist.SetType("songs");
 
-      CStdString whereOrder = playlist.GetWhereClause(db) + " " + playlist.GetOrderClause(db);
+      CStdString whereOrder = playlist.GetWhereClause(db, playlists) + " " + playlist.GetOrderClause(db);
       success = db.GetSongsByWhere("", whereOrder, items);
       items.SetContent("songs");
       db.Close();
@@ -102,7 +104,7 @@ namespace XFILE
       CStdString type=playlist.GetType();
       if (playlist.GetType().Equals("mixed"))
         playlist.SetType("musicvideos");
-      CStdString whereOrder = playlist.GetWhereClause(db) + " " + playlist.GetOrderClause(db);
+      CStdString whereOrder = playlist.GetWhereClause(db, playlists) + " " + playlist.GetOrderClause(db);
       CFileItemList items2;
       success2 = db.GetMusicVideosByWhere("videodb://3/2/", whereOrder, items2, false); // TODO: SMARTPLAYLISTS Don't check locks???
       db.Close();
@@ -137,15 +139,25 @@ namespace XFILE
     CFileItemList list;
     bool filesExist = false;
     if (playlistType == "songs" || playlistType == "albums")
-      filesExist = CDirectory::GetDirectory("special://musicplaylists/", list, "*.xsp");
+      filesExist = CDirectory::GetDirectory("special://musicplaylists/", list, ".xsp", false);
     else // all others are video
-      filesExist = CDirectory::GetDirectory("special://videoplaylists/", list, "*.xsp");
+      filesExist = CDirectory::GetDirectory("special://videoplaylists/", list, ".xsp", false);
     if (filesExist)
     {
       for (int i = 0; i < list.Size(); i++)
       {
         CFileItemPtr item = list[i];
-        if (item->GetLabel().CompareNoCase(name) == 0)
+        CSmartPlaylist playlist;
+        if (playlist.OpenAndReadName(item->GetPath()))
+        {
+          if (playlist.GetName().CompareNoCase(name) == 0)
+            return item->GetPath();
+        }
+      }
+      for (int i = 0; i < list.Size(); i++)
+      { // check based on filename
+        CFileItemPtr item = list[i];
+        if (URIUtils::GetFileName(item->GetPath()) == name)
         { // found :)
           return item->GetPath();
         }
diff --git a/xbmc/filesystem/SmbFile.cpp b/xbmc/filesystem/SmbFile.cpp
new file mode 100644 (file)
index 0000000..4ab5f76
--- /dev/null
@@ -0,0 +1,777 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FileSmb.cpp: implementation of the CSmbFile class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "system.h"
+#include "SmbFile.h"
+#include "PasswordManager.h"
+#include "SMBDirectory.h"
+#include "Util.h"
+#include <libsmbclient.h>
+#include "settings/AdvancedSettings.h"
+#include "settings/GUISettings.h"
+#include "threads/SingleLock.h"
+#include "utils/log.h"
+#include "utils/TimeUtils.h"
+
+using namespace XFILE;
+
+void xb_smbc_log(const char* msg)
+{
+  CLog::Log(LOGINFO, "%s%s", "smb: ", msg);
+}
+
+void xb_smbc_auth(const char *srv, const char *shr, char *wg, int wglen,
+                  char *un, int unlen, char *pw, int pwlen)
+{
+  return ;
+}
+
+smbc_get_cached_srv_fn orig_cache;
+
+SMBCSRV* xb_smbc_cache(SMBCCTX* c, const char* server, const char* share, const char* workgroup, const char* username)
+{
+  return orig_cache(c, server, share, workgroup, username);
+}
+
+CSMB::CSMB()
+{
+#ifdef TARGET_POSIX
+  m_IdleTimeout = 0;
+#endif
+  m_context = NULL;
+  smbc_init(xb_smbc_auth, 0);
+}
+
+CSMB::~CSMB()
+{
+  Deinit();
+}
+
+void CSMB::Deinit()
+{
+  CSingleLock lock(*this);
+
+  /* samba goes loco if deinited while it has some files opened */
+  if (m_context)
+  {
+    try
+    {
+      smbc_set_context(NULL);
+      smbc_free_context(m_context, 1);
+    }
+#ifdef TARGET_WINDOWS
+    catch(win32_exception e)
+    {
+      e.writelog(__FUNCTION__);
+    }
+    m_IdleTimeout = 180;
+#else
+    catch(...)
+    {
+      CLog::Log(LOGERROR,"exception on CSMB::Deinit. errno: %d", errno);
+    }
+#endif
+    m_context = NULL;
+  }
+}
+
+void CSMB::Init()
+{
+  CSingleLock lock(*this);
+  if (!m_context)
+  {
+#ifdef TARGET_POSIX
+    // Create ~/.smb/smb.conf. This file is used by libsmbclient.
+    // http://us1.samba.org/samba/docs/man/manpages-3/libsmbclient.7.html
+    // http://us1.samba.org/samba/docs/man/manpages-3/smb.conf.5.html
+    char smb_conf[MAX_PATH];
+    sprintf(smb_conf, "%s/.smb", getenv("HOME"));
+    mkdir(smb_conf, 0755);
+    sprintf(smb_conf, "%s/.smb/smb.conf", getenv("HOME"));
+    FILE* f = fopen(smb_conf, "w");
+    if (f != NULL)
+    {
+      fprintf(f, "[global]\n");
+
+      // make sure we're not acting like a server
+      fprintf(f, "\tpreferred master = no\n");
+      fprintf(f, "\tlocal master = no\n");
+      fprintf(f, "\tdomain master = no\n");
+
+      // use the weaker LANMAN password hash in order to be compatible with older servers
+      fprintf(f, "\tclient lanman auth = yes\n");
+      fprintf(f, "\tlanman auth = yes\n");
+
+      fprintf(f, "\tsocket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536\n");      
+      fprintf(f, "\tlock directory = %s/.smb/\n", getenv("HOME"));
+
+      // set wins server if there's one. name resolve order defaults to 'lmhosts host wins bcast'.
+      // if no WINS server has been specified the wins method will be ignored.
+      if ( g_guiSettings.GetString("smb.winsserver").length() > 0 && !g_guiSettings.GetString("smb.winsserver").Equals("0.0.0.0") )
+      {
+        fprintf(f, "\twins server = %s\n", g_guiSettings.GetString("smb.winsserver").c_str());
+        fprintf(f, "\tname resolve order = bcast wins host\n");
+      }
+      else
+        fprintf(f, "\tname resolve order = bcast host\n");
+
+      // use user-configured charset. if no charset is specified,
+      // samba tries to use charset 850 but falls back to ASCII in case it is not available
+      if (g_advancedSettings.m_sambadoscodepage.length() > 0)
+        fprintf(f, "\tdos charset = %s\n", g_advancedSettings.m_sambadoscodepage.c_str());
+
+      // if no workgroup string is specified, samba will use the default value 'WORKGROUP'
+      if ( g_guiSettings.GetString("smb.workgroup").length() > 0 )
+        fprintf(f, "\tworkgroup = %s\n", g_guiSettings.GetString("smb.workgroup").c_str());
+      fclose(f);
+    }
+#endif
+
+#ifdef TARGET_WINDOWS
+    // set the log function
+    set_log_callback(xb_smbc_log);
+#endif
+
+    // setup our context
+    m_context = smbc_new_context();
+#ifdef DEPRECATED_SMBC_INTERFACE
+    smbc_setDebug(m_context, g_advancedSettings.m_logLevel == LOG_LEVEL_DEBUG_SAMBA ? 10 : 0);
+    smbc_setFunctionAuthData(m_context, xb_smbc_auth);
+    orig_cache = smbc_getFunctionGetCachedServer(m_context);
+    smbc_setFunctionGetCachedServer(m_context, xb_smbc_cache);
+    smbc_setOptionOneSharePerServer(m_context, false);
+    smbc_setOptionBrowseMaxLmbCount(m_context, 0);
+    smbc_setTimeout(m_context, g_advancedSettings.m_sambaclienttimeout * 1000);
+#else
+    m_context->debug = g_advancedSettings.m_logLevel == LOG_LEVEL_DEBUG_SAMBA ? 10 : 0;
+    m_context->callbacks.auth_fn = xb_smbc_auth;
+    orig_cache = m_context->callbacks.get_cached_srv_fn;
+    m_context->callbacks.get_cached_srv_fn = xb_smbc_cache;
+    m_context->options.one_share_per_server = false;
+    m_context->options.browse_max_lmb_count = 0;
+    m_context->timeout = g_advancedSettings.m_sambaclienttimeout * 1000;
+#endif
+
+    // initialize samba and do some hacking into the settings
+    if (smbc_init_context(m_context))
+    {
+      /* setup old interface to use this context */
+      smbc_set_context(m_context);
+
+#ifdef TARGET_WINDOWS
+      // if a wins-server is set, we have to change name resolve order to
+      if ( g_guiSettings.GetString("smb.winsserver").length() > 0 && !g_guiSettings.GetString("smb.winsserver").Equals("0.0.0.0") )
+      {
+        lp_do_parameter( -1, "wins server", g_guiSettings.GetString("smb.winsserver").c_str());
+        lp_do_parameter( -1, "name resolve order", "bcast wins host");
+      }
+      else
+        lp_do_parameter( -1, "name resolve order", "bcast host");
+
+      if (g_advancedSettings.m_sambadoscodepage.length() > 0)
+        lp_do_parameter( -1, "dos charset", g_advancedSettings.m_sambadoscodepage.c_str());
+      else
+        lp_do_parameter( -1, "dos charset", "CP850");
+#endif
+    }
+    else
+    {
+      smbc_free_context(m_context, 1);
+      m_context = NULL;
+    }
+  }
+#ifdef TARGET_POSIX
+  m_IdleTimeout = 180;
+#endif
+}
+
+void CSMB::Purge()
+{
+#ifdef TARGET_WINDOWS
+  CSingleLock lock(*this);
+  smbc_purge();
+#endif
+}
+
+/*
+ * For each new connection samba creates a new session
+ * But this is not what we want, we just want to have one session at the time
+ * This means that we have to call smbc_purge() if samba created a new session
+ * Samba will create a new session when:
+ * - connecting to another server
+ * - connecting to another share on the same server (share, not a different folder!)
+ *
+ * We try to avoid lot's of purge commands because it slow samba down.
+ */
+void CSMB::PurgeEx(const CURL& url)
+{
+  CSingleLock lock(*this);
+  CStdString strShare = url.GetFileName().substr(0, url.GetFileName().Find('/'));
+
+#ifdef TARGET_WINDOWS
+  if (m_strLastShare.length() > 0 && (m_strLastShare != strShare || m_strLastHost != url.GetHostName()))
+    smbc_purge();
+#endif
+
+  m_strLastShare = strShare;
+  m_strLastHost = url.GetHostName();
+}
+
+CStdString CSMB::URLEncode(const CURL &url)
+{
+  /* due to smb wanting encoded urls we have to build it manually */
+
+  CStdString flat = "smb://";
+
+  if(url.GetDomain().length() > 0)
+  {
+    flat += URLEncode(url.GetDomain());
+    flat += ";";
+  }
+
+  /* samba messes up of password is set but no username is set. don't know why yet */
+  /* probably the url parser that goes crazy */
+  if(url.GetUserName().length() > 0 /* || url.GetPassWord().length() > 0 */)
+  {
+    flat += URLEncode(url.GetUserName());
+    flat += ":";
+    flat += URLEncode(url.GetPassWord());
+    flat += "@";
+  }
+  flat += URLEncode(url.GetHostName());
+
+  /* okey sadly since a slash is an invalid name we have to tokenize */
+  std::vector<CStdString> parts;
+  std::vector<CStdString>::iterator it;
+  CUtil::Tokenize(url.GetFileName(), parts, "/");
+  for( it = parts.begin(); it != parts.end(); it++ )
+  {
+    flat += "/";
+    flat += URLEncode((*it));
+  }
+
+  /* okey options should go here, thou current samba doesn't support any */
+
+  return flat;
+}
+
+CStdString CSMB::URLEncode(const CStdString &value)
+{
+  CStdString encoded(value);
+  CURL::Encode(encoded);
+  return encoded;
+}
+
+#ifdef TARGET_WINDOWS
+DWORD CSMB::ConvertUnixToNT(int error)
+{
+  DWORD nt_error;
+  if (error == ENODEV || error == ENETUNREACH || error == WSAETIMEDOUT) nt_error = NT_STATUS_INVALID_COMPUTER_NAME;
+  else if(error == WSAECONNREFUSED || error == WSAECONNABORTED) nt_error = NT_STATUS_CONNECTION_REFUSED;
+  else nt_error = map_nt_error_from_unix(error);
+
+  return nt_error;
+}
+#endif
+
+#ifdef TARGET_POSIX
+/* This is called from CApplication::ProcessSlow() and is used to tell if smbclient have been idle for too long */
+void CSMB::CheckIfIdle()
+{
+/* We check if there are open connections. This is done without a lock to not halt the mainthread. It should be thread safe as
+   worst case scenario is that m_OpenConnections could read 0 and then changed to 1 if this happens it will enter the if wich will lead to another check, wich is locked.  */
+  if (m_OpenConnections == 0)
+  { /* I've set the the maxiumum IDLE time to be 1 min and 30 sec. */
+    CSingleLock lock(*this);
+    if (m_OpenConnections == 0 /* check again - when locked */ && m_context != NULL)
+    {
+      if (m_IdleTimeout > 0)
+         {
+        m_IdleTimeout--;
+      }
+         else
+         {
+        CLog::Log(LOGNOTICE, "Samba is idle. Closing the remaining connections");
+        smb.Deinit();
+      }
+    }
+  }
+}
+
+void CSMB::SetActivityTime()
+{
+  /* Since we get called every 500ms from ProcessSlow we limit the tick count to 180 */
+  /* That means we have 2 ticks per second which equals 180/2 == 90 seconds */
+  m_IdleTimeout = 180;
+}
+
+/* The following two function is used to keep track on how many Opened files/directories there are.
+   This makes the idle timer not count if a movie is paused for example */
+void CSMB::AddActiveConnection()
+{
+  CSingleLock lock(*this);
+  m_OpenConnections++;
+}
+void CSMB::AddIdleConnection()
+{
+  CSingleLock lock(*this);
+  m_OpenConnections--;
+  /* If we close a file we reset the idle timer so that we don't have any wierd behaviours if a user
+     leaves the movie paused for a long while and then press stop */
+  m_IdleTimeout = 180;
+}
+#endif
+
+CSMB smb;
+
+CSmbFile::CSmbFile()
+{
+  smb.Init();
+  m_fd = -1;
+#ifdef TARGET_POSIX
+  smb.AddActiveConnection();
+#endif
+}
+
+CSmbFile::~CSmbFile()
+{
+  Close();
+#ifdef TARGET_POSIX
+  smb.AddIdleConnection();
+#endif
+}
+
+int64_t CSmbFile::GetPosition()
+{
+  if (m_fd == -1) return 0;
+  smb.Init();
+  CSingleLock lock(smb);
+  int64_t pos = smbc_lseek(m_fd, 0, SEEK_CUR);
+  if ( pos < 0 )
+    return 0;
+  return pos;
+}
+
+int64_t CSmbFile::GetLength()
+{
+  if (m_fd == -1) return 0;
+  return m_fileSize;
+}
+
+bool CSmbFile::Open(const CURL& url)
+{
+  Close();
+
+  // we can't open files like smb://file.f or smb://server/file.f
+  // if a file matches the if below return false, it can't exist on a samba share.
+  if (!IsValidFile(url.GetFileName()))
+  {
+      CLog::Log(LOGNOTICE,"FileSmb->Open: Bad URL : '%s'",url.GetFileName().c_str());
+      return false;
+  }
+  m_url = url;
+
+  // opening a file to another computer share will create a new session
+  // when opening smb://server xbms will try to find folder.jpg in all shares
+  // listed, which will create lot's of open sessions.
+
+  CStdString strFileName;
+  m_fd = OpenFile(url, strFileName);
+
+  CLog::Log(LOGDEBUG,"CSmbFile::Open - opened %s, fd=%d",url.GetFileName().c_str(), m_fd);
+  if (m_fd == -1)
+  {
+    // write error to logfile
+#ifdef TARGET_WINDOWS
+    int nt_error = smb.ConvertUnixToNT(errno);
+    CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' nt_err : '%x' error : '%s'", strFileName.c_str(), errno, nt_error, get_friendly_nt_error_msg(nt_error));
+#else
+    CLog::Log(LOGINFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strFileName.c_str(), errno, strerror(errno));
+#endif
+    return false;
+  }
+
+  CSingleLock lock(smb);
+#ifdef TARGET_WINDOWS
+  struct __stat64 tmpBuffer = {0};
+#else
+  struct stat tmpBuffer;
+#endif
+  if (smbc_stat(strFileName, &tmpBuffer) < 0)
+  {
+    smbc_close(m_fd);
+    m_fd = -1;
+    return false;
+  }
+
+  m_fileSize = tmpBuffer.st_size;
+
+  int64_t ret = smbc_lseek(m_fd, 0, SEEK_SET);
+  if ( ret < 0 )
+  {
+    smbc_close(m_fd);
+    m_fd = -1;
+    return false;
+  }
+  // We've successfully opened the file!
+  return true;
+}
+
+
+/// \brief Checks authentication against SAMBA share. Reads password cache created in CSMBDirectory::OpenDir().
+/// \param strAuth The SMB style path
+/// \return SMB file descriptor
+/*
+int CSmbFile::OpenFile(CStdString& strAuth)
+{
+  int fd = -1;
+
+  CStdString strPath = g_passwordManager.GetSMBAuthFilename(strAuth);
+
+  fd = smbc_open(strPath.c_str(), O_RDONLY, 0);
+  // TODO: Run a loop here that prompts for our username/password as appropriate?
+  // We have the ability to run a file (eg from a button action) without browsing to
+  // the directory first.  In the case of a password protected share that we do
+  // not have the authentication information for, the above smbc_open() will have
+  // returned negative, and the file will not be opened.  While this is not a particular
+  // likely scenario, we might want to implement prompting for the password in this case.
+  // The code from SMBDirectory can be used for this.
+  if(fd >= 0)
+    strAuth = strPath;
+
+  return fd;
+}
+*/
+
+int CSmbFile::OpenFile(const CURL &url, CStdString& strAuth)
+{
+  int fd = -1;
+  smb.Init();
+
+  strAuth = GetAuthenticatedPath(url);
+  CStdString strPath = strAuth;
+
+  {
+    CSingleLock lock(smb);
+    fd = smbc_open(strPath.c_str(), O_RDONLY, 0);
+  }
+
+  // file open failed, try to open the directory to force authentication
+#ifdef TARGET_WINDOWS
+  if (fd < 0 && smb.ConvertUnixToNT(errno) == NT_STATUS_ACCESS_DENIED)
+#else
+  if (fd < 0 && errno == EACCES)
+#endif
+  {
+    CURL urlshare(url);
+
+    /* just replace the filename with the sharename */
+    urlshare.SetFileName(url.GetShareName());
+
+    CSMBDirectory smbDir;
+    // TODO: Currently we always allow prompting on files.  This may need to
+    // change in the future as background scanners are more prolific.
+    smbDir.SetAllowPrompting(true);
+    fd = smbDir.Open(urlshare);
+
+    // directory open worked, try opening the file again
+    if (fd >= 0)
+    {
+      CSingleLock lock(smb);
+      // close current directory filehandle
+      // dont need to purge since its the same server and share
+      smbc_closedir(fd);
+
+      // set up new filehandle (as CSmbFile::Open does)
+      strPath = GetAuthenticatedPath(url);
+
+      fd = smbc_open(strPath.c_str(), O_RDONLY, 0);
+    }
+  }
+
+  if (fd >= 0)
+    strAuth = strPath;
+
+  return fd;
+}
+
+bool CSmbFile::Exists(const CURL& url)
+{
+  // we can't open files like smb://file.f or smb://server/file.f
+  // if a file matches the if below return false, it can't exist on a samba share.
+  if (!IsValidFile(url.GetFileName())) return false;
+
+  smb.Init();
+  CStdString strFileName = GetAuthenticatedPath(url);
+
+#ifdef TARGET_WINDOWS
+  struct __stat64 info;
+#else
+  struct stat info;
+#endif
+
+  CSingleLock lock(smb);
+  int iResult = smbc_stat(strFileName, &info);
+
+  if (iResult < 0) return false;
+  return true;
+}
+
+int CSmbFile::Stat(struct __stat64* buffer)
+{
+  if (m_fd == -1)
+    return -1;
+
+#ifdef TARGET_WINDOWS
+  struct __stat64 tmpBuffer = {0};
+#else
+  struct stat tmpBuffer = {0};
+#endif
+
+  CSingleLock lock(smb);
+  int iResult = smbc_fstat(m_fd, &tmpBuffer);
+
+  memset(buffer, 0, sizeof(struct __stat64));
+  buffer->st_dev = tmpBuffer.st_dev;
+  buffer->st_ino = tmpBuffer.st_ino;
+  buffer->st_mode = tmpBuffer.st_mode;
+  buffer->st_nlink = tmpBuffer.st_nlink;
+  buffer->st_uid = tmpBuffer.st_uid;
+  buffer->st_gid = tmpBuffer.st_gid;
+  buffer->st_rdev = tmpBuffer.st_rdev;
+  buffer->st_size = tmpBuffer.st_size;
+  buffer->st_atime = tmpBuffer.st_atime;
+  buffer->st_mtime = tmpBuffer.st_mtime;
+  buffer->st_ctime = tmpBuffer.st_ctime;
+
+  return iResult;
+}
+
+int CSmbFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  smb.Init();
+  CStdString strFileName = GetAuthenticatedPath(url);
+  CSingleLock lock(smb);
+
+#ifdef TARGET_WINDOWS
+  struct __stat64 tmpBuffer = {0};
+#else
+  struct stat tmpBuffer = {0};
+#endif
+  int iResult = smbc_stat(strFileName, &tmpBuffer);
+
+  memset(buffer, 0, sizeof(struct __stat64));
+  buffer->st_dev = tmpBuffer.st_dev;
+  buffer->st_ino = tmpBuffer.st_ino;
+  buffer->st_mode = tmpBuffer.st_mode;
+  buffer->st_nlink = tmpBuffer.st_nlink;
+  buffer->st_uid = tmpBuffer.st_uid;
+  buffer->st_gid = tmpBuffer.st_gid;
+  buffer->st_rdev = tmpBuffer.st_rdev;
+  buffer->st_size = tmpBuffer.st_size;
+  buffer->st_atime = tmpBuffer.st_atime;
+  buffer->st_mtime = tmpBuffer.st_mtime;
+  buffer->st_ctime = tmpBuffer.st_ctime;
+
+  return iResult;
+}
+
+unsigned int CSmbFile::Read(void *lpBuf, int64_t uiBufSize)
+{
+  if (m_fd == -1) return 0;
+  CSingleLock lock(smb); // Init not called since it has to be "inited" by now
+#ifdef TARGET_POSIX
+  smb.SetActivityTime();
+#endif
+  /* work around stupid bug in samba */
+  /* some samba servers has a bug in it where the */
+  /* 17th bit will be ignored in a request of data */
+  /* this can lead to a very small return of data */
+  /* also worse, a request of exactly 64k will return */
+  /* as if eof, client has a workaround for windows */
+  /* thou it seems other servers are affected too */
+  if( uiBufSize >= 64*1024-2 )
+    uiBufSize = 64*1024-2;
+
+  int bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize);
+
+  if ( bytesRead < 0 && errno == EINVAL )
+  {
+    CLog::Log(LOGERROR, "%s - Error( %d, %d, %s ) - Retrying", __FUNCTION__, bytesRead, errno, strerror(errno));
+    bytesRead = smbc_read(m_fd, lpBuf, (int)uiBufSize);
+  }
+
+  if ( bytesRead < 0 )
+  {
+#ifdef TARGET_WINDOWS
+    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
+#else
+    CLog::Log(LOGERROR, "%s - Error( %d, %d, %s )", __FUNCTION__, bytesRead, errno, strerror(errno));
+#endif
+    return 0;
+  }
+
+  return (unsigned int)bytesRead;
+}
+
+int64_t CSmbFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  if (m_fd == -1) return -1;
+
+  CSingleLock lock(smb); // Init not called since it has to be "inited" by now
+#ifdef TARGET_POSIX
+  smb.SetActivityTime();
+#endif
+  int64_t pos = smbc_lseek(m_fd, iFilePosition, iWhence);
+
+  if ( pos < 0 )
+  {
+#ifdef TARGET_WINDOWS
+    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
+#else
+    CLog::Log(LOGERROR, "%s - Error( %"PRId64", %d, %s )", __FUNCTION__, pos, errno, strerror(errno));
+#endif
+    return -1;
+  }
+
+  return (int64_t)pos;
+}
+
+void CSmbFile::Close()
+{
+  if (m_fd != -1)
+  {
+    CLog::Log(LOGDEBUG,"CSmbFile::Close closing fd %d", m_fd);
+    CSingleLock lock(smb);
+    smbc_close(m_fd);
+  }
+  m_fd = -1;
+}
+
+int CSmbFile::Write(const void* lpBuf, int64_t uiBufSize)
+{
+  if (m_fd == -1) return -1;
+  DWORD dwNumberOfBytesWritten = 0;
+
+  // lpBuf can be safely casted to void* since xmbc_write will only read from it.
+  smb.Init();
+  CSingleLock lock(smb);
+  dwNumberOfBytesWritten = smbc_write(m_fd, (void*)lpBuf, (DWORD)uiBufSize);
+
+  return (int)dwNumberOfBytesWritten;
+}
+
+bool CSmbFile::Delete(const CURL& url)
+{
+  smb.Init();
+  CStdString strFile = GetAuthenticatedPath(url);
+
+  CSingleLock lock(smb);
+
+  int result = smbc_unlink(strFile.c_str());
+
+  if(result != 0)
+#ifdef TARGET_WINDOWS
+    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
+#else
+    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno));
+#endif
+
+  return (result == 0);
+}
+
+bool CSmbFile::Rename(const CURL& url, const CURL& urlnew)
+{
+  smb.Init();
+  CStdString strFile = GetAuthenticatedPath(url);
+  CStdString strFileNew = GetAuthenticatedPath(urlnew);
+  CSingleLock lock(smb);
+
+  int result = smbc_rename(strFile.c_str(), strFileNew.c_str());
+
+  if(result != 0)
+#ifdef TARGET_WINDOWS
+    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, get_friendly_nt_error_msg(smb.ConvertUnixToNT(errno)));
+#else
+    CLog::Log(LOGERROR, "%s - Error( %s )", __FUNCTION__, strerror(errno));
+#endif
+
+  return (result == 0);
+}
+
+bool CSmbFile::OpenForWrite(const CURL& url, bool bOverWrite)
+{
+  m_fileSize = 0;
+
+  Close();
+  smb.Init();
+  // we can't open files like smb://file.f or smb://server/file.f
+  // if a file matches the if below return false, it can't exist on a samba share.
+  if (!IsValidFile(url.GetFileName())) return false;
+
+  CStdString strFileName = GetAuthenticatedPath(url);
+  CSingleLock lock(smb);
+
+  if (bOverWrite)
+  {
+    CLog::Log(LOGWARNING, "FileSmb::OpenForWrite() called with overwriting enabled! - %s", strFileName.c_str());
+    m_fd = smbc_creat(strFileName.c_str(), 0);
+  }
+  else
+  {
+    m_fd = smbc_open(strFileName.c_str(), O_RDWR, 0);
+  }
+
+  if (m_fd == -1)
+  {
+    // write error to logfile
+#ifdef TARGET_WINDOWS
+    int nt_error = map_nt_error_from_unix(errno);
+    CLog::Log(LOGERROR, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' nt_err : '%x' error : '%s'", strFileName.c_str(), errno, nt_error, get_friendly_nt_error_msg(nt_error));
+#else
+    CLog::Log(LOGERROR, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strFileName.c_str(), errno, strerror(errno));
+#endif
+    return false;
+  }
+
+  // We've successfully opened the file!
+  return true;
+}
+
+bool CSmbFile::IsValidFile(const CStdString& strFileName)
+{
+  if (strFileName.Find('/') == -1 || /* doesn't have sharename */
+      strFileName.Right(2) == "/." || /* not current folder */
+      strFileName.Right(3) == "/..")  /* not parent folder */
+      return false;
+  return true;
+}
+
+CStdString CSmbFile::GetAuthenticatedPath(const CURL &url)
+{
+  CURL authURL(url);
+  CPasswordManager::GetInstance().AuthenticateURL(authURL);
+  return smb.URLEncode(authURL);
+}
diff --git a/xbmc/filesystem/SmbFile.h b/xbmc/filesystem/SmbFile.h
new file mode 100644 (file)
index 0000000..8cfbc78
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+// FileSmb.h: interface for the CSmbFile class.
+
+//
+
+//////////////////////////////////////////////////////////////////////
+
+
+
+#if !defined(AFX_FILESMB_H__2C4AB5BC_0742_458D_95EA_E9C77BA5663D__INCLUDED_)
+
+#define AFX_FILESMB_H__2C4AB5BC_0742_458D_95EA_E9C77BA5663D__INCLUDED_
+
+
+#if _MSC_VER > 1000
+
+#pragma once
+
+#endif // _MSC_VER > 1000
+
+#include "IFile.h"
+#include "URL.h"
+#include "threads/CriticalSection.h"
+
+#define NT_STATUS_CONNECTION_REFUSED long(0xC0000000 | 0x0236)
+#define NT_STATUS_INVALID_HANDLE long(0xC0000000 | 0x0008)
+#define NT_STATUS_ACCESS_DENIED long(0xC0000000 | 0x0022)
+#define NT_STATUS_OBJECT_NAME_NOT_FOUND long(0xC0000000 | 0x0034)
+#ifdef _LINUX
+#define NT_STATUS_INVALID_COMPUTER_NAME long(0xC0000000 | 0x0122)
+#endif
+
+struct _SMBCCTX;
+typedef _SMBCCTX SMBCCTX;
+
+class CSMB : public CCriticalSection
+{
+public:
+  CSMB();
+  ~CSMB();
+  void Init();
+  void Deinit();
+  void Purge();
+  void PurgeEx(const CURL& url);
+#ifdef _LINUX
+  void CheckIfIdle();
+  void SetActivityTime();
+  void AddActiveConnection();
+  void AddIdleConnection();
+#endif
+  CStdString URLEncode(const CStdString &value);
+  CStdString URLEncode(const CURL &url);
+
+  DWORD ConvertUnixToNT(int error);
+private:
+  SMBCCTX *m_context;
+  CStdString m_strLastHost;
+  CStdString m_strLastShare;
+#ifdef _LINUX
+  int m_OpenConnections;
+  unsigned int m_IdleTimeout;
+#endif
+};
+
+extern CSMB smb;
+
+namespace XFILE
+{
+class CSmbFile : public IFile
+{
+public:
+  CSmbFile();
+  int OpenFile(const CURL &url, CStdString& strAuth);
+  virtual ~CSmbFile();
+  virtual void Close();
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+  virtual int Stat(struct __stat64* buffer);
+  virtual int64_t GetLength();
+  virtual int64_t GetPosition();
+  virtual int Write(const void* lpBuf, int64_t uiBufSize);
+
+  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
+  virtual bool Delete(const CURL& url);
+  virtual bool Rename(const CURL& url, const CURL& urlnew);
+  virtual int  GetChunkSize() {return 1;}
+
+protected:
+  CURL m_url;
+  bool IsValidFile(const CStdString& strFileName);
+  CStdString GetAuthenticatedPath(const CURL &url);
+  int64_t m_fileSize;
+  int m_fd;
+};
+}
+
+#endif // !defined(AFX_FILESMB_H__2C4AB5BC_0742_458D_95EA_E9C77BA5663D__INCLUDED_)
index 15ce760..c351bab 100644 (file)
@@ -236,24 +236,6 @@ CStdString CSpecialProtocol::TranslatePathConvertCase(const CStdString& path)
 #endif
 }
 
-CStdString CSpecialProtocol::ReplaceOldPath(const CStdString &oldPath, int pathVersion)
-{
-  if (pathVersion < 1)
-  {
-    if (oldPath.Left(2).CompareNoCase("P:") == 0)
-      return URIUtils::AddFileToFolder("special://profile/", oldPath.Mid(2));
-    else if (oldPath.Left(2).CompareNoCase("Q:") == 0)
-      return URIUtils::AddFileToFolder("special://xbmc/", oldPath.Mid(2));
-    else if (oldPath.Left(2).CompareNoCase("T:") == 0)
-      return URIUtils::AddFileToFolder("special://masterprofile/", oldPath.Mid(2));
-    else if (oldPath.Left(2).CompareNoCase("U:") == 0)
-      return URIUtils::AddFileToFolder("special://home/", oldPath.Mid(2));
-    else if (oldPath.Left(2).CompareNoCase("Z:") == 0)
-      return URIUtils::AddFileToFolder("special://temp/", oldPath.Mid(2));
-  }
-  return oldPath;
-}
-
 void CSpecialProtocol::LogPaths()
 {
   CLog::Log(LOGNOTICE, "special://xbmc/ is mapped to: %s", GetPath("xbmc").c_str());
index dcb3b9a..86ac838 100644 (file)
@@ -68,8 +68,6 @@ public:
   static CStdString TranslatePath(const CStdString &path);
   static CStdString TranslatePath(const CURL &url);
   static CStdString TranslatePathConvertCase(const CStdString& path);
-  static CStdString ReplaceOldPath(const CStdString &oldPath, int pathVersion);
-  static const int path_version = 1;
 
 private:
   static void SetPath(const CStdString &key, const CStdString &path);
@@ -78,9 +76,6 @@ private:
   static std::map<CStdString, CStdString> m_pathMap;
 };
 
-#define _P(x)     CSpecialProtocol::TranslatePath(x)
-#define PTH_IC(x) CSpecialProtocol::TranslatePathConvertCase(x)
-
 #ifdef _WIN32
 #define PATH_SEPARATOR_CHAR '\\'
 #define PATH_SEPARATOR_STRING "\\"
diff --git a/xbmc/filesystem/SpecialProtocolFile.cpp b/xbmc/filesystem/SpecialProtocolFile.cpp
new file mode 100644 (file)
index 0000000..ebcb941
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "SpecialProtocolFile.h"
+#include "SpecialProtocol.h"
+#include "URL.h"
+
+#include <sys/stat.h>
+
+using namespace XFILE;
+
+CSpecialProtocolFile::CSpecialProtocolFile(void)
+{
+}
+
+CSpecialProtocolFile::~CSpecialProtocolFile(void)
+{
+  Close();
+}
+
+bool CSpecialProtocolFile::Open(const CURL& url)
+{
+  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
+
+  return m_file.Open(strFileName);
+}
+
+bool CSpecialProtocolFile::OpenForWrite(const CURL& url, bool bOverWrite /*=false */)
+{
+  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
+
+  return m_file.OpenForWrite(strFileName,bOverWrite);
+}
+
+bool CSpecialProtocolFile::Delete(const CURL& url)
+{
+  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
+  
+  return m_file.Delete(strFileName);
+}
+
+bool CSpecialProtocolFile::Exists(const CURL& url)
+{
+  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
+
+  return m_file.Exists(strFileName);
+}
+
+int CSpecialProtocolFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
+
+  return m_file.Stat(strFileName, buffer);
+}
+
+bool CSpecialProtocolFile::Rename(const CURL& url, const CURL& urlnew)
+{
+  CStdString strFileName=CSpecialProtocol::TranslatePath(url);
+  CStdString strFileName2=CSpecialProtocol::TranslatePath(urlnew);
+
+  return m_file.Rename(strFileName,strFileName2);
+}
+
+int CSpecialProtocolFile::Stat(struct __stat64* buffer)
+{
+  return m_file.Stat(buffer);
+}
+
+unsigned int CSpecialProtocolFile::Read(void* lpBuf, int64_t uiBufSize)
+{
+  return m_file.Read(lpBuf, uiBufSize);
+}
+  
+int CSpecialProtocolFile::Write(const void* lpBuf, int64_t uiBufSize)
+{
+  return m_file.Write(lpBuf,uiBufSize);
+}
+
+int64_t CSpecialProtocolFile::Seek(int64_t iFilePosition, int iWhence /*=SEEK_SET*/)
+{
+  return m_file.Seek(iFilePosition, iWhence);
+}
+
+void CSpecialProtocolFile::Close()
+{
+  m_file.Close();
+}
+
+int64_t CSpecialProtocolFile::GetPosition()
+{
+  return m_file.GetPosition();
+}
+
+int64_t CSpecialProtocolFile::GetLength()
+{
+  return m_file.GetLength();
+}
+
+
+
diff --git a/xbmc/filesystem/SpecialProtocolFile.h b/xbmc/filesystem/SpecialProtocolFile.h
new file mode 100644 (file)
index 0000000..d9e05de
--- /dev/null
@@ -0,0 +1,50 @@
+#pragma once
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "File.h"
+
+namespace XFILE
+{
+class CSpecialProtocolFile : public IFile
+{
+public:
+  CSpecialProtocolFile(void);
+  virtual ~CSpecialProtocolFile(void);
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+  virtual int Stat(struct __stat64* buffer);
+  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
+  virtual bool Delete(const CURL& url);
+  virtual bool Rename(const CURL& url, const CURL& urlnew);
+
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int Write(const void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+
+protected:
+  CFile m_file;
+};
+}
diff --git a/xbmc/filesystem/TuxBoxDirectory.cpp b/xbmc/filesystem/TuxBoxDirectory.cpp
new file mode 100644 (file)
index 0000000..cdc2deb
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "TuxBoxDirectory.h"
+#include "DirectoryCache.h"
+#include "CurlFile.h"
+#include "utils/HttpHeader.h"
+#include "utils/TuxBoxUtil.h"
+#include "URL.h"
+#include "tinyXML/tinyxml.h"
+#include "settings/AdvancedSettings.h"
+#include "FileItem.h"
+#include "utils/log.h"
+#include "utils/URIUtils.h"
+
+using namespace XFILE;
+
+CTuxBoxDirectory::CTuxBoxDirectory(void)
+{
+}
+
+CTuxBoxDirectory::~CTuxBoxDirectory(void)
+{
+}
+
+bool CTuxBoxDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
+{
+  // so we know that we have enigma2
+  static bool enigma2 = false;
+  // Detect and delete slash at end
+  CStdString strRoot = strPath;
+  URIUtils::RemoveSlashAtEnd(strRoot);
+
+  //Get the request strings
+  CStdString strBQRequest;
+  CStdString strXMLRootString;
+  CStdString strXMLChildString;
+  if(!GetRootAndChildString(strRoot, strBQRequest, strXMLRootString, strXMLChildString))
+    return false;
+
+  //Set url Protocol
+  CURL url(strRoot);
+  CStdString strFilter;
+  CStdString protocol = url.GetProtocol();
+  CStdString strOptions = url.GetOptions();
+  url.SetProtocol("http");
+  bool bIsBouquet=false;
+
+  int ipoint = strOptions.Find("?path=");
+  if (ipoint >=0)
+  {
+    // send Zap!
+    return g_tuxbox.ZapToUrl(url, strOptions, ipoint);
+  }
+  else
+  {
+    ipoint = strOptions.Find("&reference=");
+    if (ipoint >=0 || enigma2)
+    {
+      //List reference
+      strFilter = strOptions.Right((strOptions.size()-(ipoint+11)));
+      bIsBouquet = false; //On Empty is Bouquet
+      if (enigma2)
+      {
+        CStdString strPort;
+        strPort.Format(":%i",url.GetPort());
+        if (strRoot.Right(strPort.GetLength()) != strPort) // If not root dir, enable Channels
+          strFilter = "e2"; // Disable Bouquets for Enigma2
+
+        GetRootAndChildStringEnigma2(strBQRequest, strXMLRootString, strXMLChildString);
+        url.SetOptions("");
+        url.SetFileName(strBQRequest);
+      }
+    }
+  }
+  if(strFilter.IsEmpty())
+  {
+    url.SetOptions(strBQRequest);
+    bIsBouquet = true;
+  }
+  //Open
+  CCurlFile http;
+  int iTryConnect = 0;
+  int iWaitTimer = 20;
+  bool result = false;
+
+  while (iTryConnect < 4)
+  {
+    http.SetTimeout(iWaitTimer);
+    if(http.Open(url))
+    {
+      //We are connected!
+      iTryConnect = 4;
+
+      // restore protocol
+      url.SetProtocol(protocol);
+
+      int size_read = 0;
+      int size_total = (int)http.GetLength();
+      int data_size = 0;
+      CStdString data;
+      data.reserve(size_total);
+
+      // read response from server into string buffer
+      char buffer[16384];
+      while ((size_read = http.Read(buffer, sizeof(buffer)-1)) > 0)
+      {
+        buffer[size_read] = 0;
+        data += buffer;
+        data_size += size_read;
+      }
+      http.Close();
+
+      // parse returned xml
+      TiXmlDocument doc;
+      data.Replace("></",">-</"); //FILL EMPTY ELEMENTS WITH "-"!
+      doc.Parse(data.c_str());
+      TiXmlElement *root = doc.RootElement();
+      if(root == NULL)
+      {
+        CLog::Log(LOGERROR, "%s - Unable to parse xml", __FUNCTION__);
+        CLog::Log(LOGERROR, "%s - Sample follows...\n%s", __FUNCTION__, data.c_str());
+        return false;
+      }
+      if( strXMLRootString.Equals(root->Value()) && bIsBouquet)
+      {
+        data.Empty();
+        if (enigma2)
+          result = g_tuxbox.ParseBouquetsEnigma2(root, items, url, strFilter, strXMLChildString);
+        else
+          result = g_tuxbox.ParseBouquets(root, items, url, strFilter, strXMLChildString);
+      }
+      else if( strXMLRootString.Equals(root->Value()) && !strFilter.IsEmpty() )
+      {
+        data.Empty();
+        if (enigma2)
+          result = g_tuxbox.ParseChannelsEnigma2(root, items, url, strFilter, strXMLChildString);
+        else
+          result = g_tuxbox.ParseChannels(root, items, url, strFilter, strXMLChildString);
+      }
+      else
+      {
+        CLog::Log(LOGERROR, "%s - Invalid root xml element for TuxBox", __FUNCTION__);
+        CLog::Log(LOGERROR, "%s - Sample follows...\n%s", __FUNCTION__, data.c_str());
+        data.Empty();
+        result = false;
+      }
+    }
+    else
+    {
+      CLog::Log(LOGERROR, "%s - Unable to get XML structure! Try count:%i, Wait Timer:%is",__FUNCTION__, iTryConnect, iWaitTimer);
+      iTryConnect++;
+      if (iTryConnect == 2) //try enigma2 instead of enigma1, best entrypoint here i thought
+      {        
+        enigma2 = true;
+        GetRootAndChildStringEnigma2(strBQRequest, strXMLRootString, strXMLChildString);
+        url.SetOptions("");
+        url.SetFileName(strBQRequest);
+//        iTryConnect = 0;
+        iWaitTimer = 20;
+      }
+      else
+        iWaitTimer = iWaitTimer+10;
+
+      result = false;
+      http.Close(); // Close old connections
+    }
+  }
+  items.SetContent("movies");
+  return result;
+}
+
+void CTuxBoxDirectory::GetRootAndChildStringEnigma2(CStdString& strBQRequest, CStdString& strXMLRootString, CStdString& strXMLChildString )
+{
+  // Allways take getallservices for Enigma2
+  strBQRequest = "web/getallservices"; //Bouquets and Channels
+  strXMLRootString.Format("e2servicelistrecursive");
+  strXMLChildString.Format("e2bouquet");
+}
+
+bool CTuxBoxDirectory::GetRootAndChildString(const CStdString strPath, CStdString& strBQRequest, CStdString& strXMLRootString, CStdString& strXMLChildString )
+{
+  //Advanced Settings: RootMode! Movies:
+  if(g_advancedSettings.m_iTuxBoxDefaultRootMenu == 3) //Movies! Fixed-> mode=3&submode=4
+  {
+    CLog::Log(LOGDEBUG, "%s - Default defined RootMenu : (3) Movies", __FUNCTION__);
+    strBQRequest = "xml/services?mode=3&submode=4";
+    strXMLRootString.Format("movies");
+    strXMLChildString.Format("service");
+  }
+  else if(g_advancedSettings.m_iTuxBoxDefaultRootMenu <= 0 || g_advancedSettings.m_iTuxBoxDefaultRootMenu == 1 ||
+    g_advancedSettings.m_iTuxBoxDefaultRootMenu > 4 )
+  {
+    //Falling Back to the Default RootMenu => 0 Bouquets
+    if(g_advancedSettings.m_iTuxBoxDefaultRootMenu < 0 || g_advancedSettings.m_iTuxBoxDefaultRootMenu > 4)
+    {
+      g_advancedSettings.m_iTuxBoxDefaultRootMenu = 0;
+    }
+
+    //Advanced Settings: SubMenu!
+    if(g_advancedSettings.m_bTuxBoxSubMenuSelection)
+    {
+      CLog::Log(LOGDEBUG, "%s SubMenu Channel Selection is Enabled! Requesting Submenu!", __FUNCTION__);
+      // DeActivated: Timing Problems, bug in TuxBox.. etc.!
+      bool bReqMoRe = true;
+      // Detect the RootMode !
+      if (strPath.Find("?mode=")>=0)
+      {
+        CStdString strMode;
+        bReqMoRe=false;
+        strMode = g_tuxbox.DetectSubMode(strPath, strXMLRootString, strXMLChildString);
+      }
+      if(bReqMoRe)
+      {
+        //PopUp Context and Request SubMode with root and child string
+        strBQRequest = g_tuxbox.GetSubMode(g_advancedSettings.m_iTuxBoxDefaultRootMenu, strXMLRootString, strXMLChildString);
+        if(strBQRequest.IsEmpty())
+        {
+          strBQRequest = "xml/services?mode=0&submode=4"; //Bouquets
+          strXMLRootString.Format("bouquets");
+          strXMLChildString.Format("bouquet");
+        }
+      }
+    }
+    else
+    {
+      //Advanced Settings: Set Default Subemnu
+      if(g_advancedSettings.m_iTuxBoxDefaultSubMenu == 1)
+      {
+        CLog::Log(LOGDEBUG, "%s - Default defined SubMenu : (1) Services", __FUNCTION__);
+        strBQRequest = "xml/services?mode=0&submode=1"; //Services
+        strXMLRootString.Format("services");
+        strXMLChildString.Format("service");
+      }
+      else if(g_advancedSettings.m_iTuxBoxDefaultSubMenu == 2)
+      {
+        CLog::Log(LOGDEBUG, "%s - Default defined SubMenu : (2) Satellites", __FUNCTION__);
+        strBQRequest = "xml/services?mode=0&submode=2"; //Satellites
+        strXMLRootString.Format("satellites");
+        strXMLChildString.Format("satellite");
+      }
+      else if(g_advancedSettings.m_iTuxBoxDefaultSubMenu == 3)
+      {
+        CLog::Log(LOGDEBUG, "%s - Default defined SubMenu : (3) Providers", __FUNCTION__);
+        strBQRequest = "xml/services?mode=0&submode=3"; //Providers
+        strXMLRootString.Format("providers");
+        strXMLChildString.Format("provider");
+      }
+      else
+      {
+        CLog::Log(LOGDEBUG, "%s - Default defined SubMenu : (4) Bouquets", __FUNCTION__);
+        strBQRequest = "xml/services?mode=0&submode=4"; //Bouquets
+        strXMLRootString.Format("bouquets");
+        strXMLChildString.Format("bouquet");
+      }
+    }
+  }
+  if(strBQRequest.IsEmpty() || strXMLRootString.IsEmpty() || strXMLChildString.IsEmpty())
+    return false;
+  else
+    return true;
+}
diff --git a/xbmc/filesystem/TuxBoxDirectory.h b/xbmc/filesystem/TuxBoxDirectory.h
new file mode 100644 (file)
index 0000000..eebb8c9
--- /dev/null
@@ -0,0 +1,43 @@
+#pragma once
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IDirectory.h"
+
+class CURL;
+class TiXmlElement;
+
+namespace XFILE
+{
+  class CTuxBoxDirectory : public IDirectory
+  {
+    public:
+      CTuxBoxDirectory(void);
+      virtual ~CTuxBoxDirectory(void);
+      virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items);
+      virtual bool IsAllowed(const CStdString &strFile) const { return true; };
+      virtual DIR_CACHE_TYPE GetCacheType(const CStdString& strPath) const { return DIR_CACHE_ALWAYS; };
+    private:
+      bool GetRootAndChildString(const CStdString strPath, CStdString& strBQRequest, CStdString& strXMLRootString, CStdString& strXMLChildString );
+      void GetRootAndChildStringEnigma2(CStdString& strBQRequest, CStdString& strXMLRootString, CStdString& strXMLChildString );
+  };
+}
+
diff --git a/xbmc/filesystem/TuxBoxFile.cpp b/xbmc/filesystem/TuxBoxFile.cpp
new file mode 100644 (file)
index 0000000..877df91
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "TuxBoxFile.h"
+#include <errno.h>
+
+//Reserved for TuxBox Recording!
+
+using namespace XFILE;
+
+CTuxBoxFile::CTuxBoxFile()
+{}
+
+CTuxBoxFile::~CTuxBoxFile()
+{
+}
+
+int64_t CTuxBoxFile::GetPosition()
+{
+  return 0;
+}
+
+int64_t CTuxBoxFile::GetLength()
+{
+  return 0;
+}
+
+bool CTuxBoxFile::Open(const CURL& url)
+{
+  return true;
+}
+
+unsigned int CTuxBoxFile::Read(void* lpBuf, int64_t uiBufSize)
+{
+  return 0;
+}
+
+int64_t CTuxBoxFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  return 0;
+}
+
+void CTuxBoxFile::Close()
+{
+}
+
+bool CTuxBoxFile::Exists(const CURL& url)
+{
+  return true;
+}
+
+int CTuxBoxFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  errno = ENOENT;
+  return -1;
+}
+
diff --git a/xbmc/filesystem/TuxBoxFile.h b/xbmc/filesystem/TuxBoxFile.h
new file mode 100644 (file)
index 0000000..9e0aa3a
--- /dev/null
@@ -0,0 +1,45 @@
+#pragma once
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IFile.h"
+
+namespace XFILE
+{
+  class CTuxBoxFile : public IFile
+  {
+    public:
+      CTuxBoxFile();
+      virtual ~CTuxBoxFile();
+      virtual int64_t GetPosition();
+      virtual int64_t GetLength();
+      virtual bool Open(const CURL& url);
+      virtual void Close();
+      virtual bool Exists(const CURL& url);
+      virtual int Stat(const CURL& url, struct __stat64* buffer);
+      virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+      virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+    protected:
+  };
+}
+
+
+
diff --git a/xbmc/filesystem/UDFFile.cpp b/xbmc/filesystem/UDFFile.cpp
new file mode 100644 (file)
index 0000000..863ac37
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ *      Copyright (C) 2010 Team Boxee
+ *      http://www.boxee.tv
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "UDFFile.h"
+#include "URL.h"
+#include "Util.h"
+
+#include <sys/stat.h>
+#include <errno.h>
+
+using namespace std;
+using namespace XFILE;
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+//*********************************************************************************************
+CUDFFile::CUDFFile()
+{
+  m_bOpened = false;
+}
+
+//*********************************************************************************************
+CUDFFile::~CUDFFile()
+{
+  if (m_bOpened)
+  {
+    Close();
+  }
+}
+//*********************************************************************************************
+bool CUDFFile::Open(const CURL& url)
+{
+  CStdString strFName = url.GetHostName();
+
+  CURL::Decode(strFName);
+
+  m_hFile = m_udfIsoReaderLocal.OpenFile((char*)strFName.c_str());
+  if (m_hFile == INVALID_HANDLE_VALUE)
+  {
+    m_bOpened = false;
+    return false;
+  }
+
+  m_bOpened = true;
+  return true;
+}
+
+//*********************************************************************************************
+unsigned int CUDFFile::Read(void *lpBuf, int64_t uiBufSize)
+{
+  if (!m_bOpened) return 0;
+  char *pData = (char *)lpBuf;
+
+  int iResult = m_udfIsoReaderLocal.ReadFile( m_hFile, (unsigned char*)pData, (long)uiBufSize);
+  if (iResult == -1)
+    return 0;
+  return iResult;
+}
+
+//*********************************************************************************************
+void CUDFFile::Close()
+{
+  if (!m_bOpened) return ;
+  m_udfIsoReaderLocal.CloseFile( m_hFile);
+}
+
+//*********************************************************************************************
+int64_t CUDFFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  if (!m_bOpened) return -1;
+  int64_t lNewPos = m_udfIsoReaderLocal.Seek(m_hFile, iFilePosition, iWhence);
+  return lNewPos;
+}
+
+//*********************************************************************************************
+int64_t CUDFFile::GetLength()
+{
+  if (!m_bOpened) return -1;
+  return m_udfIsoReaderLocal.GetFileSize(m_hFile);
+}
+
+//*********************************************************************************************
+int64_t CUDFFile::GetPosition()
+{
+  if (!m_bOpened) return -1;
+  return m_udfIsoReaderLocal.GetFilePosition(m_hFile);
+}
+
+bool CUDFFile::Exists(const CURL& url)
+{
+  string strFName = "\\";
+  strFName += url.GetFileName();
+  for (int i = 0; i < (int)strFName.size(); ++i )
+  {
+    if (strFName[i] == '/') strFName[i] = '\\';
+  }
+  m_hFile = m_udfIsoReaderLocal.OpenFile((char*)strFName.c_str());
+  if (m_hFile == INVALID_HANDLE_VALUE)
+    return false;
+
+  m_udfIsoReaderLocal.CloseFile(m_hFile);
+  return true;
+}
+
+int CUDFFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  string strFName = "\\";
+  strFName += url.GetFileName();
+  for (int i = 0; i < (int)strFName.size(); ++i )
+  {
+    if (strFName[i] == '/') strFName[i] = '\\';
+  }
+  m_hFile = m_udfIsoReaderLocal.OpenFile((char*)strFName.c_str());
+  if (m_hFile != INVALID_HANDLE_VALUE)
+  {
+    buffer->st_size = m_udfIsoReaderLocal.GetFileSize(m_hFile);
+    buffer->st_mode = _S_IFREG;
+    m_udfIsoReaderLocal.CloseFile(m_hFile);
+    return 0;
+  }
+  errno = ENOENT;
+  return -1;
+}
diff --git a/xbmc/filesystem/UDFFile.h b/xbmc/filesystem/UDFFile.h
new file mode 100644 (file)
index 0000000..a8deba1
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _FILEUDF_H
+#define _FILEUDF_H
+
+/*
+ *      Copyright (C) 2010 Team Boxee
+ *      http://www.boxee.tv
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IFile.h"
+#include "udf25.h"
+
+namespace XFILE
+{
+
+class CUDFFile : public IFile
+{
+public:
+  CUDFFile();
+  virtual ~CUDFFile();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+protected:
+  bool m_bOpened;
+  HANDLE m_hFile;
+  udf25 m_udfIsoReaderLocal;
+};
+}
+
+#endif
diff --git a/xbmc/filesystem/UPnPFile.cpp b/xbmc/filesystem/UPnPFile.cpp
new file mode 100644 (file)
index 0000000..3d7db4b
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "UPnPFile.h"
+#include "UPnPDirectory.h"
+#include "FileFactory.h"
+#include "FileItem.h"
+#include "utils/log.h"
+
+using namespace XFILE;
+
+CUPnPFile::CUPnPFile()
+{
+}
+
+CUPnPFile::~CUPnPFile()
+{
+}
+
+bool CUPnPFile::Open(const CURL& url)
+{
+  CFileItem item_new;
+  if (CUPnPDirectory::GetResource(url.Get(), item_new))
+  {
+    //CLog::Log(LOGDEBUG,"FileUPnP - file redirect to %s.", item_new.GetPath().c_str());
+    IFile *pNewImp = CFileFactory::CreateLoader(item_new.GetPath());    
+    CURL *pNewUrl = new CURL(item_new.GetPath());    
+    if (pNewImp)
+    {
+      throw new CRedirectException(pNewImp, pNewUrl);
+    }
+    SAFE_DELETE(pNewUrl);    
+  }
+  return false;
+}
+
+int CUPnPFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  CFileItem item_new;
+  if (CUPnPDirectory::GetResource(url.Get(), item_new))
+  {
+    //CLog::Log(LOGDEBUG,"FileUPnP - file redirect to %s.", item_new.GetPath().c_str());
+    IFile *pNewImp = CFileFactory::CreateLoader(item_new.GetPath());
+    CURL *pNewUrl = new CURL(item_new.GetPath());
+    if (pNewImp)
+    {
+      throw new CRedirectException(pNewImp, pNewUrl);
+    }
+    SAFE_DELETE(pNewUrl);
+  }
+  return -1;
+}
+
+bool CUPnPFile::Exists(const CURL& url)
+{
+  CFileItem item_new;
+  if (CUPnPDirectory::GetResource(url.Get(), item_new))
+  {
+    //CLog::Log(LOGDEBUG,"FileUPnP - file redirect to %s.", item_new.GetPath().c_str());
+    IFile *pNewImp = CFileFactory::CreateLoader(item_new.GetPath());
+    CURL *pNewUrl = new CURL(item_new.GetPath());
+    if (pNewImp)
+    {
+      throw new CRedirectException(pNewImp, pNewUrl);
+    }
+    SAFE_DELETE(pNewUrl);
+  }
+  return false;
+}
diff --git a/xbmc/filesystem/UPnPFile.h b/xbmc/filesystem/UPnPFile.h
new file mode 100644 (file)
index 0000000..e98e091
--- /dev/null
@@ -0,0 +1,42 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IFile.h"
+
+namespace XFILE
+{
+  class CUPnPFile : public IFile
+  {
+    public:
+      CUPnPFile();
+      virtual ~CUPnPFile();
+      virtual bool Open(const CURL& url);      
+      virtual bool Exists(const CURL& url);
+      virtual int Stat(const CURL& url, struct __stat64* buffer);
+      
+      virtual unsigned int Read(void* lpBuf, int64_t uiBufSize) {return -1;}
+      virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET) {return -1;}
+      virtual void Close(){}
+      virtual int64_t GetPosition() {return -1;}
+      virtual int64_t GetLength() {return -1;}
+  };
+}
index 3e3a49c..064639f 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "system.h"
 #include "VirtualDirectory.h"
-#include "FactoryDirectory.h"
+#include "DirectoryFactory.h"
 #include "Util.h"
 #include "utils/URIUtils.h"
 #include "Directory.h"
diff --git a/xbmc/filesystem/ZipFile.cpp b/xbmc/filesystem/ZipFile.cpp
new file mode 100644 (file)
index 0000000..25ef89d
--- /dev/null
@@ -0,0 +1,514 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "ZipFile.h"
+#include "URL.h"
+#include "utils/URIUtils.h"
+
+#include <sys/stat.h>
+
+#define ZIP_CACHE_LIMIT 4*1024*1024
+
+using namespace XFILE;
+using namespace std;
+
+CZipFile::CZipFile()
+{
+  m_szStringBuffer = NULL;
+  m_szStartOfStringBuffer = NULL;
+  m_iDataInStringBuffer = 0;
+  m_bCached = false;
+  m_iRead = -1;
+}
+
+CZipFile::~CZipFile()
+{
+  delete[] m_szStringBuffer;
+  Close();
+}
+
+bool CZipFile::Open(const CURL&url)
+{
+  CStdString strOpts = url.GetOptions();
+  CURL url2(url);
+  url2.SetOptions("");
+  CStdString strPath = url2.Get();
+  if (!g_ZipManager.GetZipEntry(strPath,mZipItem))
+    return false;
+
+  if ((mZipItem.flags & 64) == 64)
+  {
+    CLog::Log(LOGERROR,"FileZip: encrypted file, not supported!");
+    return false;
+  }
+
+  if ((mZipItem.method != 8) && (mZipItem.method != 0))
+  {
+    CLog::Log(LOGERROR,"FileZip: unsupported compression method!");
+    return false;
+  }
+
+  if (mZipItem.method != 0 && mZipItem.usize > ZIP_CACHE_LIMIT && strOpts != "?cache=no")
+  {
+    if (!CFile::Exists("special://temp/" + URIUtils::GetFileName(strPath)))
+    {
+      url2.SetOptions("?cache=no");
+      if (!CFile::Cache(url2.Get(), "special://temp/" + URIUtils::GetFileName(strPath)))
+        return false;
+    }
+    m_bCached = true;
+    return mFile.Open("special://temp/" + URIUtils::GetFileName(strPath));
+  }
+
+  if (!mFile.Open(url.GetHostName())) // this is the zip-file, always open binary
+  {
+    CLog::Log(LOGERROR,"FileZip: unable to open zip file %s!",url.GetHostName().c_str());
+    return false;
+  }
+  mFile.Seek(mZipItem.offset,SEEK_SET);
+  return InitDecompress();
+}
+
+bool CZipFile::InitDecompress()
+{
+  m_iRead = 1;
+  m_iFilePos = 0;
+  m_iZipFilePos = 0;
+  m_iAvailBuffer = 0;
+  m_bFlush = false;
+  m_ZStream.zalloc = Z_NULL;
+  m_ZStream.zfree = Z_NULL;
+  m_ZStream.opaque = Z_NULL;
+  if( mZipItem.method != 0 )
+  {
+    if (inflateInit2(&m_ZStream,-MAX_WBITS) != Z_OK)
+    {
+      CLog::Log(LOGERROR,"FileZip: error initializing zlib!");
+      return false;
+    }
+  }
+  m_ZStream.next_in = (Bytef*)m_szBuffer;
+  m_ZStream.avail_in = 0;
+  m_ZStream.total_out = 0;
+
+  return true;
+}
+
+int64_t CZipFile::GetLength()
+{
+  return mZipItem.usize;
+}
+
+int64_t CZipFile::GetPosition()
+{
+  if (m_bCached)
+    return mFile.GetPosition();
+
+  return m_iFilePos;
+}
+
+int64_t CZipFile::Seek(int64_t iFilePosition, int iWhence)
+{
+  if (m_bCached)
+    return mFile.Seek(iFilePosition,iWhence);
+  if (mZipItem.method == 0) // this is easy
+  {
+    int64_t iResult;
+    switch (iWhence)
+    {
+    case SEEK_SET:
+      if (iFilePosition > mZipItem.usize)
+        return -1;
+      m_iFilePos = iFilePosition;
+      m_iZipFilePos = m_iFilePos;
+      iResult = mFile.Seek(iFilePosition+mZipItem.offset,SEEK_SET)-mZipItem.offset;
+      return iResult;
+      break;
+
+    case SEEK_CUR:
+      if (m_iFilePos+iFilePosition > mZipItem.usize)
+        return -1;
+      m_iFilePos += iFilePosition;
+      m_iZipFilePos = m_iFilePos;
+      iResult = mFile.Seek(iFilePosition,SEEK_CUR)-mZipItem.offset;
+      return iResult;
+      break;
+
+    case SEEK_END:
+      if (iFilePosition > mZipItem.usize)
+        return -1;
+      m_iFilePos = mZipItem.usize+iFilePosition;
+      m_iZipFilePos = m_iFilePos;
+      iResult = mFile.Seek(mZipItem.offset+mZipItem.usize+iFilePosition,SEEK_SET)-mZipItem.offset;
+      return iResult;
+      break;
+    default:
+      return -1;
+
+    }
+  }
+  // here goes the stupid part..
+  if (mZipItem.method == 8)
+  {
+    char temp[131072];
+    switch (iWhence)
+    {
+    case SEEK_SET:
+      if (iFilePosition == m_iFilePos)
+        return m_iFilePos; // mp3reader does this lots-of-times
+      if (iFilePosition > mZipItem.usize || iFilePosition < 0)
+        return -1;
+      // read until position in 128k blocks.. only way to do it due to format.
+      // can't start in the middle of data since then we'd have no clue where
+      // we are in uncompressed data..
+      if (iFilePosition < m_iFilePos)
+      {
+        m_iFilePos = 0;
+        m_iZipFilePos = 0;
+        inflateEnd(&m_ZStream);
+        inflateInit2(&m_ZStream,-MAX_WBITS); // simply restart zlib
+        mFile.Seek(mZipItem.offset,SEEK_SET);
+        m_ZStream.next_in = (Bytef*)m_szBuffer;
+        m_ZStream.avail_in = 0;
+        m_ZStream.total_out = 0;
+        while (m_iFilePos < iFilePosition)
+        {
+          unsigned int iToRead = (iFilePosition-m_iFilePos)>131072?131072:(int)(iFilePosition-m_iFilePos);
+          if (Read(temp,iToRead) != iToRead)
+            return -1;
+        }
+        return m_iFilePos;
+      }
+      else // seek forward
+        return Seek(iFilePosition-m_iFilePos,SEEK_CUR);
+      break;
+
+    case SEEK_CUR:
+      if (iFilePosition < 0)
+        return Seek(m_iFilePos+iFilePosition,SEEK_SET); // can't rewind stream
+      // read until requested position, drop data
+      if (m_iFilePos+iFilePosition > mZipItem.usize)
+        return -1;
+      iFilePosition += m_iFilePos;
+      while (m_iFilePos < iFilePosition)
+      {
+        unsigned int iToRead = (iFilePosition-m_iFilePos)>131072?131072:(int)(iFilePosition-m_iFilePos);
+        if (Read(temp,iToRead) != iToRead)
+          return -1;
+      }
+      return m_iFilePos;
+      break;
+
+    case SEEK_END:
+      // now this is a nasty bastard, possibly takes lotsoftime
+      // uncompress, minding m_ZStream.total_out
+
+      while( (int)m_ZStream.total_out < mZipItem.usize+iFilePosition)
+      {
+        unsigned int iToRead = (mZipItem.usize+iFilePosition-m_ZStream.total_out > 131072)?131072:(int)(mZipItem.usize+iFilePosition-m_ZStream.total_out);
+        if (Read(temp,iToRead) != iToRead)
+          return -1;
+      }
+      return m_iFilePos;
+      break;
+    default:
+      return -1;
+    }
+  }
+  return -1;
+}
+
+bool CZipFile::Exists(const CURL& url)
+{
+  SZipEntry item;
+  if (g_ZipManager.GetZipEntry(url.Get(),item))
+    return true;
+  return false;
+}
+
+int CZipFile::Stat(struct __stat64 *buffer)
+{
+  int ret;
+  struct tm tm = {};
+
+  ret = mFile.Stat(buffer);
+  tm.tm_sec = (mZipItem.mod_time & 0x1F) << 1;
+  tm.tm_min = (mZipItem.mod_time & 0x7E0) >> 5;
+  tm.tm_hour = (mZipItem.mod_time & 0xF800) >> 11;
+  tm.tm_mday = (mZipItem.mod_date & 0x1F);
+  tm.tm_mon = (mZipItem.mod_date & 0x1E0) >> 5;
+  tm.tm_year = (mZipItem.mod_date & 0xFE00) >> 9;
+  buffer->st_atime = buffer->st_ctime = buffer->st_mtime = mktime(&tm);
+
+  buffer->st_size = mZipItem.usize;
+  buffer->st_dev = (buffer->st_dev << 16) ^ (buffer->st_ino << 16);
+  buffer->st_ino ^= mZipItem.crc32;
+  return ret;
+}
+
+int CZipFile::Stat(const CURL& url, struct __stat64* buffer)
+{
+  if (!g_ZipManager.GetZipEntry(url.Get(),mZipItem))
+    return -1;
+
+  memset(buffer, 0, sizeof(struct __stat64));
+  buffer->st_gid = 0;
+  buffer->st_atime = buffer->st_ctime = mZipItem.mod_time;
+  buffer->st_size = mZipItem.usize;
+  return 0;
+}
+
+unsigned int CZipFile::Read(void* lpBuf, int64_t uiBufSize)
+{
+  if (m_bCached)
+    return mFile.Read(lpBuf,uiBufSize);
+
+  // flush what might be left in the string buffer
+  if (m_iDataInStringBuffer > 0)
+  {
+    size_t iMax = static_cast<size_t>((uiBufSize>m_iDataInStringBuffer?m_iDataInStringBuffer:uiBufSize));
+    memcpy(lpBuf,m_szStartOfStringBuffer,iMax);
+    uiBufSize -= iMax;
+    m_iDataInStringBuffer -= iMax;
+  }
+  if (mZipItem.method == 8) // deflated
+  {
+    uLong iDecompressed = 0;
+    uLong prevOut = m_ZStream.total_out;
+    while (((int)iDecompressed < uiBufSize) && ((m_iZipFilePos < mZipItem.csize) || (m_bFlush)))
+    {
+      m_ZStream.next_out = (Bytef*)(lpBuf)+iDecompressed;
+      m_ZStream.avail_out = static_cast<uInt>(uiBufSize-iDecompressed);
+      if (m_bFlush) // need to flush buffer !
+      {
+        int iMessage = inflate(&m_ZStream,Z_SYNC_FLUSH);
+        m_bFlush = ((iMessage == Z_OK) && (m_ZStream.avail_out == 0))?true:false;
+        if (!m_ZStream.avail_out) // flush filled buffer, get out of here
+        {
+          iDecompressed = m_ZStream.total_out-prevOut;
+          break;
+        }
+      }
+
+      if (!m_ZStream.avail_in)
+      {
+        if (!FillBuffer()) // eof!
+        {
+          iDecompressed = m_ZStream.total_out-prevOut;
+          break;
+        }
+      }
+
+      int iMessage = inflate(&m_ZStream,Z_SYNC_FLUSH);
+      if (iMessage < 0)
+      {
+        Close();
+        return 0; // READ ERROR
+      }
+
+      m_bFlush = ((iMessage == Z_OK) && (m_ZStream.avail_out == 0))?true:false; // more info in input buffer
+
+      iDecompressed = m_ZStream.total_out-prevOut;
+    }
+    m_iFilePos += iDecompressed;
+    return static_cast<unsigned int>(iDecompressed);
+  }
+  else if (mZipItem.method == 0) // uncompressed. just read from file, but mind our boundaries.
+  {
+    if (uiBufSize+m_iFilePos > mZipItem.csize)
+      uiBufSize = mZipItem.csize-m_iFilePos;
+    if (uiBufSize < 0)
+    {
+      return 0; // we are past eof, this shouldn't happen but test anyway
+    }
+    unsigned int iResult = mFile.Read(lpBuf,uiBufSize);
+    m_iZipFilePos += iResult;
+    m_iFilePos += iResult;
+    return iResult;
+  }
+  else
+    return false; // shouldn't happen. compression method checked in open
+}
+
+void CZipFile::Close()
+{
+  if (mZipItem.method == 8 && !m_bCached && m_iRead != -1)
+    inflateEnd(&m_ZStream);
+
+  mFile.Close();
+}
+/* CHANGED: JM - moved to CFile
+bool CZipFile::ReadString(char* szLine, int iLineLength)
+{
+  if (!m_szStringBuffer)
+  {
+    m_szStringBuffer = new char[1024]; // 1024 byte long strings per read
+    m_szStartOfStringBuffer = m_szStringBuffer;
+    m_iDataInStringBuffer = 0;
+    m_iRead = 0;
+  }
+
+  bool bEof = m_iDataInStringBuffer==0;
+  while ((iLineLength > 1) && (m_iRead > -1))
+  {
+    if (m_iDataInStringBuffer > 0)
+    {
+      bEof = false;
+      m_iRead = 1;
+      int iMax = (iLineLength<m_iDataInStringBuffer?iLineLength-1:m_iDataInStringBuffer-1);
+      for( int i=0;i<iMax;++i )
+      {
+        if (m_szStartOfStringBuffer[i] == '\r') // mac or win32 endings
+        {
+          strncpy(szLine,m_szStartOfStringBuffer,i);
+          szLine[i] = '\0';
+          m_iDataInStringBuffer -= i+1;
+          m_szStartOfStringBuffer += i+1;
+          if( m_szStartOfStringBuffer[0] == '\n') // win32 endings
+          {
+            m_szStartOfStringBuffer++;
+            m_iDataInStringBuffer--;
+          }
+          return true;
+        }
+        else if (m_szStartOfStringBuffer[i] == '\n') // unix or fucked up win32 endings
+        {
+          strncpy(szLine,m_szStartOfStringBuffer,i);
+          szLine[i] = '\0';
+          m_iDataInStringBuffer -= i+1;
+          m_szStartOfStringBuffer += i+1;
+          if (m_szStartOfStringBuffer[0] == '\r')
+          {
+            m_szStartOfStringBuffer++;
+            m_iDataInStringBuffer--;
+          }
+          return true;
+        }
+      }
+      strncpy(szLine,m_szStartOfStringBuffer,iMax);
+      szLine += iMax;
+      iLineLength -= iMax;
+      m_iDataInStringBuffer -= iMax;
+    }
+
+    if (m_iRead == 1 && (m_iDataInStringBuffer == 1))
+    {
+      m_szStringBuffer[0] = m_szStringBuffer[1023]; // need to make sure we don't loose any '\r\n' between buffers
+      m_iDataInStringBuffer = Read(m_szStringBuffer+1,1023);
+    }
+    else
+      m_iDataInStringBuffer = Read(m_szStringBuffer,1024);
+    m_szStartOfStringBuffer = m_szStringBuffer;
+    if (m_iDataInStringBuffer)
+      m_iRead = 1;
+    else
+      m_iRead = -1;
+  }
+  szLine[0] = '\0';
+  return !bEof;
+}*/
+
+bool CZipFile::FillBuffer()
+{
+  unsigned int sToRead = 65535;
+  if (m_iZipFilePos+65535 > mZipItem.csize)
+    sToRead = static_cast<int>(mZipItem.csize-m_iZipFilePos);
+
+  if (sToRead <= 0)
+    return false; // eof!
+
+  if (mFile.Read(m_szBuffer,sToRead) != sToRead)
+    return false;
+  m_ZStream.avail_in = sToRead;
+  m_ZStream.next_in = (Bytef*)m_szBuffer;
+  m_iZipFilePos += sToRead;
+  return true;
+}
+
+void CZipFile::DestroyBuffer(void* lpBuffer, int iBufSize)
+{
+  if (!m_bFlush)
+    return;
+  int iMessage = Z_STREAM_END; // whatever != Z_OK
+  while ((iMessage == Z_OK) && (m_ZStream.avail_out == 0))
+  {
+    m_ZStream.next_out = (Bytef*)lpBuffer;
+    m_ZStream.avail_out = iBufSize;
+    iMessage = inflate(&m_ZStream,Z_SYNC_FLUSH);
+  }
+  m_bFlush = false;
+}
+
+int CZipFile::UnpackFromMemory(string& strDest, const string& strInput, bool isGZ)
+{
+  unsigned int iPos=0;
+  int iResult=0;
+  while( iPos+LHDR_SIZE < strInput.size() || isGZ)
+  {
+    if (!isGZ)
+    {
+      CZipManager::readHeader(strInput.data()+iPos,mZipItem);
+      if( mZipItem.header != ZIP_LOCAL_HEADER )
+        return iResult;
+      if( (mZipItem.flags & 8) == 8 )
+      {
+        CLog::Log(LOGERROR,"FileZip: extended local header, not supported!");
+        return iResult;
+      }
+    }
+    if (!InitDecompress())
+      return iResult;
+    // we have a file - fill the buffer
+    char* temp;
+    int toRead=0;
+    if (isGZ)
+    {
+      m_ZStream.avail_in = strInput.size();
+      m_ZStream.next_in = (Bytef*)strInput.data();
+      temp = new char[8192];
+      toRead = 8191;
+    }
+    else
+    {
+      m_ZStream.avail_in = mZipItem.csize;
+      m_ZStream.next_in = (Bytef*)strInput.data()+iPos+LHDR_SIZE+mZipItem.flength+mZipItem.elength;
+      // init m_zipitem
+      strDest.reserve(mZipItem.usize);
+      temp = new char[mZipItem.usize+1];
+      toRead = mZipItem.usize;
+    }
+    int iCurrResult;
+    while( (iCurrResult=Read(temp,toRead)) > 0)
+    {
+      strDest.append(temp,temp+iCurrResult);
+      iResult += iCurrResult;
+    }
+    Close();
+    delete[] temp;
+    iPos += LHDR_SIZE+mZipItem.flength+mZipItem.elength+mZipItem.csize;
+    if (isGZ)
+      break;
+  }
+
+  return iResult;
+}
+
+
diff --git a/xbmc/filesystem/ZipFile.h b/xbmc/filesystem/ZipFile.h
new file mode 100644 (file)
index 0000000..f4fb1ee
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef FILE_ZIP_H_
+#define FILE_ZIP_H_
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "IFile.h"
+#include <zlib.h>
+#include "utils/log.h"
+#include "File.h"
+#include "ZipManager.h"
+
+namespace XFILE
+{
+  class CZipFile : public IFile
+  {
+  public:
+    CZipFile();
+    virtual ~CZipFile();
+
+    virtual int64_t GetPosition();
+    virtual int64_t GetLength();
+    virtual bool Open(const CURL& url);
+    virtual bool Exists(const CURL& url);
+    virtual int Stat(struct __stat64* buffer);
+    virtual int Stat(const CURL& url, struct __stat64* buffer);
+    virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+    //virtual bool ReadString(char *szLine, int iLineLength);
+    virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+    virtual void Close();
+
+    int UnpackFromMemory(std::string& strDest, const std::string& strInput, bool isGZ=false);
+  private:
+    bool InitDecompress();
+    bool FillBuffer();
+    void DestroyBuffer(void* lpBuffer, int iBufSize);
+    CFile mFile;
+    SZipEntry mZipItem;
+    int64_t m_iFilePos; // position in _uncompressed_ data read
+    int64_t m_iZipFilePos; // position in _compressed_ data
+    int m_iAvailBuffer;
+    z_stream m_ZStream;
+    char m_szBuffer[65535];     // 64k buffer for compressed data
+    char* m_szStringBuffer;
+    char* m_szStartOfStringBuffer; // never allocated!
+    int m_iDataInStringBuffer;
+    int m_iRead;
+    bool m_bFlush;
+    bool m_bCached;
+  };
+}
+
+#endif
index 2110ddb..e011f3d 100644 (file)
@@ -573,7 +573,7 @@ void iso9660::Reset()
   }
   m_vecDirsAndFiles.erase(m_vecDirsAndFiles.begin(), m_vecDirsAndFiles.end());
 
-  for (int i = 0; i < MAX_ISO_FILES;++i)
+  for (intptr_t i = 0; i < MAX_ISO_FILES;++i)
   {
     FreeFileContext( (HANDLE)i);
   }
@@ -1007,7 +1007,7 @@ void iso9660::FreeFileContext(HANDLE hFile)
 //************************************************************************************
 HANDLE iso9660::AllocFileContext()
 {
-  for (int i = 1; i < MAX_ISO_FILES; ++i)
+  for (intptr_t i = 1; i < MAX_ISO_FILES; ++i)
   {
     if (m_isoFiles[i] == NULL)
     {
diff --git a/xbmc/filesystem/windows/WINFileSMB.cpp b/xbmc/filesystem/windows/WINFileSMB.cpp
new file mode 100644 (file)
index 0000000..9c59c5d
--- /dev/null
@@ -0,0 +1,321 @@
+
+/*
+ * XBMC Media Center
+ * Copyright (c) 2002 Frodo
+ * Portions Copyright (c) by the authors of ffmpeg and xvid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#include "WINFileSMB.h"
+#include "URL.h"
+#include "settings/GUISettings.h"
+
+#include <sys/stat.h>
+#include <io.h>
+#include "utils/log.h"
+#include "utils/CharsetConverter.h"
+#include "utils/URIUtils.h"
+#include "WINSMBDirectory.h"
+
+using namespace XFILE;
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+//*********************************************************************************************
+CWINFileSMB::CWINFileSMB()
+    : m_hFile(INVALID_HANDLE_VALUE)
+{}
+
+//*********************************************************************************************
+CWINFileSMB::~CWINFileSMB()
+{
+  if (m_hFile != INVALID_HANDLE_VALUE) Close();
+}
+//*********************************************************************************************
+CStdString CWINFileSMB::GetLocal(const CURL &url)
+{
+  CStdString path( url.GetFileName() );
+
+  if( url.GetProtocol().Equals("smb", false) )
+  {
+    CStdString host( url.GetHostName() );
+
+    if(host.size() > 0)
+    {
+      path = "//" + host + "/" + path;
+    }
+  }
+
+  path.Replace('/', '\\');
+
+  return path;
+}
+
+//*********************************************************************************************
+bool CWINFileSMB::Open(const CURL& url)
+{
+  CStdString strFile = GetLocal(url);
+
+  CStdStringW strWFile;
+  g_charsetConverter.utf8ToW(strFile, strWFile, false);
+  m_hFile.attach(CreateFileW(strWFile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL));
+
+  if (!m_hFile.isValid())
+  {
+    if(GetLastError() == ERROR_FILE_NOT_FOUND)
+      return false;
+
+    XFILE::CWINSMBDirectory smb;
+    smb.ConnectToShare(url);
+    m_hFile.attach(CreateFileW(strWFile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL));
+    if (!m_hFile.isValid())
+    {
+      CLog::Log(LOGERROR,"CWINFileSMB: Unable to open file '%s' Error '%d%",strWFile.c_str(), GetLastError());
+      return false;
+    }
+  }
+
+  m_i64FilePos = 0;
+  Seek(0, SEEK_SET);
+
+  return true;
+}
+
+bool CWINFileSMB::Exists(const CURL& url)
+{
+  struct __stat64 buffer;
+  if(url.GetFileName() == url.GetShareName())
+    return false;
+  CStdString strFile = GetLocal(url);
+  URIUtils::RemoveSlashAtEnd(strFile);
+  CStdStringW strWFile;
+  g_charsetConverter.utf8ToW(strFile, strWFile, false);
+  if(_wstat64(strWFile.c_str(), &buffer) == 0)
+    return true;
+
+  if(errno == ENOENT)
+    return false;
+
+  XFILE::CWINSMBDirectory smb;
+  if(smb.ConnectToShare(url) == false)
+    return false;
+
+  return (_wstat64(strWFile.c_str(), &buffer) == 0);
+}
+
+int CWINFileSMB::Stat(struct __stat64* buffer)
+{
+  int fd;
+  HANDLE hFileDup;
+  if (0 == DuplicateHandle(GetCurrentProcess(), (HANDLE)m_hFile, GetCurrentProcess(), &hFileDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
+  {
+    CLog::Log(LOGERROR, __FUNCTION__" - DuplicateHandle()");
+    return -1;
+  }
+
+  fd = _open_osfhandle((intptr_t)((HANDLE)hFileDup), 0);
+  if (fd == -1)
+  {
+    CLog::Log(LOGERROR, "CWINFileSMB Stat: fd == -1");
+    return -1;
+  }
+
+  int result = _fstat64(fd, buffer);
+  _close(fd);
+  return result;
+}
+
+int CWINFileSMB::Stat(const CURL& url, struct __stat64* buffer)
+{
+  CStdString strFile = GetLocal(url);
+  /* _wstat64 calls FindFirstFileEx. According to MSDN, the path should not end in a trailing backslash.
+    Remove it before calling _wstat64 */
+  if (strFile.length() > 3 && URIUtils::HasSlashAtEnd(strFile))
+    URIUtils::RemoveSlashAtEnd(strFile);
+  CStdStringW strWFile;
+  g_charsetConverter.utf8ToW(strFile, strWFile, false);
+  if(_wstat64(strWFile.c_str(), buffer) == 0)
+    return 0;
+
+  if(errno == ENOENT)
+    return -1;
+
+  XFILE::CWINSMBDirectory smb;
+  if(smb.ConnectToShare(url) == false)
+    return -1;
+
+  return _wstat64(strWFile.c_str(), buffer);
+}
+
+
+//*********************************************************************************************
+bool CWINFileSMB::OpenForWrite(const CURL& url, bool bOverWrite)
+{
+  CStdString strPath = GetLocal(url);
+
+  CStdStringW strWPath;
+  g_charsetConverter.utf8ToW(strPath, strWPath, false);
+  m_hFile.attach(CreateFileW(strWPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
+
+  if (!m_hFile.isValid())
+  {
+    if(GetLastError() == ERROR_FILE_NOT_FOUND)
+      return false;
+
+    XFILE::CWINSMBDirectory smb;
+    smb.ConnectToShare(url);
+    m_hFile.attach(CreateFileW(strWPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
+    if (!m_hFile.isValid())
+    {
+      CLog::Log(LOGERROR,"CWINFileSMB: Unable to open file for writing '%s' Error '%d%",strWPath.c_str(), GetLastError());
+      return false;
+    }
+  }
+
+  m_i64FilePos = 0;
+  Seek(0, SEEK_SET);
+
+  return true;
+}
+
+//*********************************************************************************************
+unsigned int CWINFileSMB::Read(void *lpBuf, int64_t uiBufSize)
+{
+  if (!m_hFile.isValid()) return 0;
+  DWORD nBytesRead;
+  if ( ReadFile((HANDLE)m_hFile, lpBuf, (DWORD)uiBufSize, &nBytesRead, NULL) )
+  {
+    m_i64FilePos += nBytesRead;
+    return nBytesRead;
+  }
+  return 0;
+}
+
+//*********************************************************************************************
+int CWINFileSMB::Write(const void *lpBuf, int64_t uiBufSize)
+{
+  if (!m_hFile.isValid())
+    return 0;
+  
+  DWORD nBytesWriten;
+  if ( WriteFile((HANDLE)m_hFile, (void*) lpBuf, (DWORD)uiBufSize, &nBytesWriten, NULL) )
+    return nBytesWriten;
+  
+  return 0;
+}
+
+//*********************************************************************************************
+void CWINFileSMB::Close()
+{
+  m_hFile.reset();
+}
+
+//*********************************************************************************************
+int64_t CWINFileSMB::Seek(int64_t iFilePosition, int iWhence)
+{
+  LARGE_INTEGER lPos, lNewPos;
+  lPos.QuadPart = iFilePosition;
+  int bSuccess;
+
+  int64_t length = GetLength();
+
+  switch (iWhence)
+  {
+  case SEEK_SET:
+    if (iFilePosition <= length || length == 0)
+      bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_BEGIN);
+    else
+      bSuccess = false;
+    break;
+
+  case SEEK_CUR:
+    if ((GetPosition()+iFilePosition) <= length || length == 0)
+      bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_CURRENT);
+    else
+      bSuccess = false;
+    break;
+
+  case SEEK_END:
+    bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_END);
+    break;
+
+  default:
+    return -1;
+  }
+  if (bSuccess)
+  {
+    m_i64FilePos = lNewPos.QuadPart;
+    return m_i64FilePos;
+  }
+  else
+    return -1;
+}
+
+//*********************************************************************************************
+int64_t CWINFileSMB::GetLength()
+{
+  LARGE_INTEGER i64Size;
+  GetFileSizeEx((HANDLE)m_hFile, &i64Size);
+  return i64Size.QuadPart;
+}
+
+//*********************************************************************************************
+int64_t CWINFileSMB::GetPosition()
+{
+  return m_i64FilePos;
+}
+
+bool CWINFileSMB::Delete(const CURL& url)
+{
+  CStdString strFile=GetLocal(url);
+
+  CStdStringW strWFile;
+  g_charsetConverter.utf8ToW(strFile, strWFile, false);
+  return ::DeleteFileW(strWFile.c_str()) ? true : false;
+}
+
+bool CWINFileSMB::Rename(const CURL& url, const CURL& urlnew)
+{
+  CStdString strFile=GetLocal(url);
+  CStdString strNewFile=GetLocal(urlnew);
+
+  CStdStringW strWFile;
+  CStdStringW strWNewFile;
+  g_charsetConverter.utf8ToW(strFile, strWFile, false);
+  g_charsetConverter.utf8ToW(strNewFile, strWNewFile, false);
+  return ::MoveFileW(strWFile.c_str(), strWNewFile.c_str()) ? true : false;
+}
+
+bool CWINFileSMB::SetHidden(const CURL &url, bool hidden)
+{
+  CStdStringW path;
+  g_charsetConverter.utf8ToW(GetLocal(url), path, false);
+  DWORD attributes = hidden ? FILE_ATTRIBUTE_HIDDEN : FILE_ATTRIBUTE_NORMAL;
+  if (SetFileAttributesW(path.c_str(), attributes))
+    return true;
+  return false;
+}
+
+void CWINFileSMB::Flush()
+{
+  ::FlushFileBuffers(m_hFile);
+}
+
+int CWINFileSMB::IoControl(EIoControl request, void* param)
+{ 
+  return -1;
+}
diff --git a/xbmc/filesystem/windows/WINFileSMB.h b/xbmc/filesystem/windows/WINFileSMB.h
new file mode 100644 (file)
index 0000000..3f89fb3
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * XBMC Media Center
+ * Copyright (c) 2002 Frodo
+ * Portions Copyright (c) by the authors of ffmpeg and xvid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+// WINFileSMB.h: interface for the CWINFileSMB class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "filesystem/IFile.h"
+#include "utils/AutoPtrHandle.h"
+
+namespace XFILE
+{
+class CWINFileSMB : public IFile
+{
+public:
+  CWINFileSMB();
+  virtual ~CWINFileSMB();
+  virtual int64_t GetPosition();
+  virtual int64_t GetLength();
+  virtual bool Open(const CURL& url);
+  virtual bool Exists(const CURL& url);
+  virtual int Stat(const CURL& url, struct __stat64* buffer);
+  virtual int Stat(struct __stat64* buffer);
+  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
+  virtual int Write(const void* lpBuf, int64_t uiBufSize);
+  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
+  virtual void Close();
+  virtual void Flush();
+
+  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
+
+  virtual bool Delete(const CURL& url);
+  virtual bool Rename(const CURL& url, const CURL& urlnew);
+  virtual bool SetHidden(const CURL& url, bool hidden);
+
+  virtual int IoControl(EIoControl request, void* param);
+protected:
+  CStdString GetLocal(const CURL &url); /* crate a properly format path from an url */
+  AUTOPTR::CAutoPtrHandle m_hFile;
+  int64_t m_i64FilePos;
+};
+
+}
diff --git a/xbmc/filesystem/windows/WINSMBDirectory.cpp b/xbmc/filesystem/windows/WINSMBDirectory.cpp
new file mode 100644 (file)
index 0000000..5e2c2de
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "WINSMBDirectory.h"
+#include "URL.h"
+#include "utils/URIUtils.h"
+#include "settings/GUISettings.h"
+#include "FileItem.h"
+#include "WIN32Util.h"
+#include "utils/AutoPtrHandle.h"
+#include "utils/log.h"
+#include "utils/CharsetConverter.h"
+#include "PasswordManager.h"
+#include "Util.h"
+
+#ifndef INVALID_FILE_ATTRIBUTES
+#define INVALID_FILE_ATTRIBUTES ((DWORD) -1)
+#endif
+
+
+using namespace AUTOPTR;
+using namespace XFILE;
+
+CWINSMBDirectory::CWINSMBDirectory(void)
+{
+  m_bHost=false;
+}
+
+CWINSMBDirectory::~CWINSMBDirectory(void)
+{
+}
+
+CStdString CWINSMBDirectory::GetLocal(const CStdString& strPath)
+{
+  CURL url(strPath);
+  CStdString path( url.GetFileName() );
+  if( url.GetProtocol().Equals("smb", false) )
+  {
+    CStdString host( url.GetHostName() );
+
+    if(host.size() > 0)
+    {
+      path = "//" + host + "/" + path;
+    }
+  }
+  path.Replace('/', '\\');
+  return path;
+}
+
+bool CWINSMBDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &items)
+{
+  WIN32_FIND_DATAW wfd;
+
+  CStdString strPath=strPath1;
+
+  CURL url(strPath);
+
+  if(url.GetShareName().empty())
+  {
+    LPNETRESOURCEW lpnr = NULL;
+    bool ret;
+    if(!url.GetHostName().empty())
+    {
+      lpnr = (LPNETRESOURCEW) GlobalAlloc(GPTR, 16384);
+      if(lpnr == NULL)
+        return false;
+
+      ConnectToShare(url);
+      CStdString strHost = "\\\\" + url.GetHostName();
+      CStdStringW strHostW;
+      g_charsetConverter.utf8ToW(strHost,strHostW);
+      lpnr->lpRemoteName = (LPWSTR)strHostW.c_str();
+      m_bHost = true;
+      ret = EnumerateFunc(lpnr, items);
+      GlobalFree((HGLOBAL) lpnr);
+      m_bHost = false;
+    }
+    else
+      ret = EnumerateFunc(lpnr, items);  
+    return ret; 
+  }
+
+  memset(&wfd, 0, sizeof(wfd));
+  //rebuild the URL
+  CStdString strUNCShare = "\\\\" + url.GetHostName() + "\\" + url.GetFileName();
+  strUNCShare.Replace("/", "\\");
+  if(!URIUtils::HasSlashAtEnd(strUNCShare))
+    strUNCShare.append("\\");
+
+  CStdStringW strSearchMask;
+  g_charsetConverter.utf8ToW(strUNCShare, strSearchMask, false); 
+  strSearchMask += "*";
+
+  FILETIME localTime;
+  CAutoPtrFind hFind ( FindFirstFileW(strSearchMask.c_str(), &wfd));
+  
+  // on error, check if path exists at all, this will return true if empty folder
+  if (!hFind.isValid()) 
+  {
+    DWORD ret = GetLastError();
+    if(ret == ERROR_INVALID_PASSWORD || ret == ERROR_LOGON_FAILURE || ret == ERROR_ACCESS_DENIED || ret == ERROR_INVALID_HANDLE)
+    {
+      if(ConnectToShare(url) == false)
+        return false;
+      hFind.attach(FindFirstFileW(strSearchMask.c_str(), &wfd));
+    }
+    else
+      return Exists(strPath1);
+  }
+
+  if (hFind.isValid())
+  {
+    do
+    {
+      if (wfd.cFileName[0] != 0)
+      {
+        CStdString strLabel;
+        g_charsetConverter.wToUTF8(wfd.cFileName,strLabel);
+        if ( (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
+        {
+          if (strLabel != "." && strLabel != "..")
+          {
+            CFileItemPtr pItem(new CFileItem(strLabel));
+            CStdString path = URIUtils::AddFileToFolder(strPath, strLabel);
+            URIUtils::AddSlashAtEnd(path);
+            pItem->SetPath(path);
+            pItem->m_bIsFolder = true;
+            FileTimeToLocalFileTime(&wfd.ftLastWriteTime, &localTime);
+            pItem->m_dateTime=localTime;
+
+            if (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+              pItem->SetProperty("file:hidden", true);
+
+            items.Add(pItem);
+          }
+        }
+        else
+        {
+          CFileItemPtr pItem(new CFileItem(strLabel));
+          pItem->SetPath(URIUtils::AddFileToFolder(strPath, strLabel));
+          pItem->m_bIsFolder = false;
+          pItem->m_dwSize = CUtil::ToInt64(wfd.nFileSizeHigh, wfd.nFileSizeLow);
+          FileTimeToLocalFileTime(&wfd.ftLastWriteTime, &localTime);
+          pItem->m_dateTime=localTime;
+
+          if (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+            pItem->SetProperty("file:hidden", true);
+          items.Add(pItem);
+        }
+      }
+    }
+    while (FindNextFileW((HANDLE)hFind, &wfd));
+  }
+  return true;
+}
+
+bool CWINSMBDirectory::Create(const char* strPath)
+{
+  CStdString strPath1 = GetLocal(strPath);
+  CStdStringW strWPath1;
+  g_charsetConverter.utf8ToW(strPath1, strWPath1, false);
+  if(::CreateDirectoryW(strWPath1, NULL))
+    return true;
+  else if(GetLastError() == ERROR_ALREADY_EXISTS)
+    return true;
+
+  return false;
+}
+
+bool CWINSMBDirectory::Remove(const char* strPath)
+{
+  CStdStringW strWPath;
+  CStdString strPath1 = GetLocal(strPath);
+  g_charsetConverter.utf8ToW(strPath1, strWPath, false);
+  return ::RemoveDirectoryW(strWPath) ? true : false;
+}
+
+bool CWINSMBDirectory::Exists(const char* strPath)
+{
+  CStdString strReplaced=GetLocal(strPath);
+  CStdStringW strWReplaced;
+  g_charsetConverter.utf8ToW(strReplaced, strWReplaced, false);
+  // this will fail on shares, needs a subdirectory inside a share
+  DWORD attributes = GetFileAttributesW(strWReplaced);
+  if(attributes == INVALID_FILE_ATTRIBUTES)
+    return false;
+  if (FILE_ATTRIBUTE_DIRECTORY & attributes) 
+    return true;
+  return false;
+}
+
+bool CWINSMBDirectory::EnumerateFunc(LPNETRESOURCEW lpnr, CFileItemList &items)
+{
+  DWORD dwResult, dwResultEnum;
+  HANDLE hEnum;
+  DWORD cbBuffer = 16384;     // 16K is a good size
+  LPNETRESOURCEW lpnrLocal;   // pointer to enumerated structures
+  DWORD cEntries = -1;        // enumerate all possible entries
+  //
+  // Call the WNetOpenEnum function to begin the enumeration.
+  //
+  dwResult = WNetOpenEnumW( RESOURCE_GLOBALNET,  // all network resources
+                            RESOURCETYPE_DISK,   // all disk resources
+                            0,                   // enumerate all resources
+                            lpnr,                // NULL first time the function is called
+                            &hEnum);             // handle to the resource
+
+  if (dwResult != NO_ERROR) 
+  {
+    CLog::Log(LOGERROR,"WnetOpenEnum failed with error %d", dwResult);
+    if(dwResult == ERROR_EXTENDED_ERROR)
+    {
+      DWORD dwWNetResult, dwLastError;   
+      CHAR szDescription[256]; 
+      CHAR szProvider[256]; 
+      dwWNetResult = WNetGetLastError(&dwLastError, // error code
+                            (LPSTR) szDescription,  // buffer for error description 
+                            sizeof(szDescription),  // size of error buffer
+                            (LPSTR) szProvider,     // buffer for provider name 
+                            sizeof(szProvider));    // size of name buffer
+      if(dwWNetResult == NO_ERROR) 
+        CLog::Log(LOGERROR,"%s failed with code %ld; %s", szProvider, dwLastError, szDescription);
+    }
+    return false;
+  }
+  //
+  // Call the GlobalAlloc function to allocate resources.
+  //
+  lpnrLocal = (LPNETRESOURCEW) GlobalAlloc(GPTR, cbBuffer);
+  if (lpnrLocal == NULL) 
+  {
+    CLog::Log(LOGERROR,"Can't allocate buffer %d", cbBuffer);
+    return false;
+  }
+
+  do 
+  {
+    //
+    // Initialize the buffer.
+    //
+    ZeroMemory(lpnrLocal, cbBuffer);
+    //
+    // Call the WNetEnumResource function to continue
+    //  the enumeration.
+    //
+    dwResultEnum = WNetEnumResourceW( hEnum,          // resource handle
+                                      &cEntries,      // defined locally as -1
+                                      lpnrLocal,      // LPNETRESOURCE
+                                      &cbBuffer);     // buffer size
+    //
+    // If the call succeeds, loop through the structures.
+    //
+    if (dwResultEnum == NO_ERROR) 
+    {
+      for (DWORD i = 0; i < cEntries; i++) 
+      {
+        DWORD dwDisplayType = lpnrLocal[i].dwDisplayType;
+        DWORD dwType = lpnrLocal[i].dwType;
+
+        if((((dwDisplayType == RESOURCEDISPLAYTYPE_SERVER) && (m_bHost == false)) || 
+           ((dwDisplayType == RESOURCEDISPLAYTYPE_SHARE) && m_bHost)) &&
+           (dwType != RESOURCETYPE_PRINT))
+        {
+          CStdString strurl = "smb:";
+          CStdStringW strRemoteNameW = lpnrLocal[i].lpRemoteName;
+          CStdString  strName,strRemoteName;
+
+          g_charsetConverter.wToUTF8(strRemoteNameW,strRemoteName);
+          CLog::Log(LOGDEBUG,"Found Server/Share: %s", strRemoteName.c_str());
+
+          strurl.append(strRemoteName);
+          strurl.Replace("\\","/");
+          CURL rooturl(strurl);
+          rooturl.SetFileName("");
+
+          if(!rooturl.GetShareName().empty())
+            strName = rooturl.GetShareName();
+          else
+            strName = rooturl.GetHostName();
+
+          strName.Replace("\\","");
+
+          URIUtils::AddSlashAtEnd(strurl);
+          CFileItemPtr pItem(new CFileItem(strName));
+          pItem->SetPath(strurl);
+          pItem->m_bIsFolder = true;
+          items.Add(pItem);
+        }
+
+        // If the NETRESOURCE structure represents a container resource, 
+        //  call the EnumerateFunc function recursively.
+        if (RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage & RESOURCEUSAGE_CONTAINER))
+          EnumerateFunc(&lpnrLocal[i], items);
+      }
+    }
+    // Process errors.
+    //
+    else if (dwResultEnum != ERROR_NO_MORE_ITEMS) 
+    {
+      CLog::Log(LOGERROR,"WNetEnumResource failed with error %d", dwResultEnum);
+      break;
+    }
+  }
+  //
+  // End do.
+  //
+  while (dwResultEnum != ERROR_NO_MORE_ITEMS);
+  //
+  // Call the GlobalFree function to free the memory.
+  //
+  GlobalFree((HGLOBAL) lpnrLocal);
+  //
+  // Call WNetCloseEnum to end the enumeration.
+  //
+  dwResult = WNetCloseEnum(hEnum);
+
+  if (dwResult != NO_ERROR) 
+  {
+      //
+      // Process errors.
+      //
+      CLog::Log(LOGERROR,"WNetCloseEnum failed with error %d", dwResult);
+      return false;
+  }
+
+  return true;
+}
+
+bool CWINSMBDirectory::ConnectToShare(const CURL& url)
+{
+  NETRESOURCE nr;
+  CURL urlIn(url);
+  DWORD dwRet=-1;
+  CStdString strUNC("\\\\"+url.GetHostName());
+  if(!url.GetShareName().empty())
+    strUNC.append("\\"+url.GetShareName());
+
+  CStdString strPath;
+  memset(&nr,0,sizeof(nr));
+  nr.dwType = RESOURCETYPE_ANY;
+  nr.lpRemoteName = (char*)strUNC.c_str();
+
+  // in general we shouldn't need the password manager as we won't disconnect from shares yet
+  CPasswordManager::GetInstance().AuthenticateURL(urlIn);
+
+  CStdString strAuth = URLEncode(urlIn);
+
+  while(dwRet != NO_ERROR)
+  {
+    strPath = URLEncode(urlIn);
+    LPCTSTR pUser = urlIn.GetUserNameA().empty() ? NULL : (LPCTSTR)urlIn.GetUserNameA().c_str();
+    LPCTSTR pPass = urlIn.GetPassWord().empty() ? NULL : (LPCTSTR)urlIn.GetPassWord().c_str();
+    dwRet = WNetAddConnection2(&nr, pPass, pUser, CONNECT_TEMPORARY);
+#ifdef _DEBUG
+    CLog::Log(LOGDEBUG,"Trying to connect to %s with username(%s) and password(%s)", strUNC.c_str(), urlIn.GetUserNameA().c_str(), urlIn.GetPassWord().c_str());
+#else
+    CLog::Log(LOGDEBUG,"Trying to connect to %s with username(%s) and password(%s)", strUNC.c_str(), urlIn.GetUserNameA().c_str(), "XXXX");
+#endif
+    if(dwRet == ERROR_ACCESS_DENIED || dwRet == ERROR_INVALID_PASSWORD || dwRet == ERROR_LOGON_FAILURE)
+    {
+      CLog::Log(LOGERROR,"Couldn't connect to %s, access denied", strUNC.c_str());
+      if (m_allowPrompting)
+        RequireAuthentication(urlIn.Get());
+      break;
+    }
+    else if(dwRet == ERROR_SESSION_CREDENTIAL_CONFLICT)
+    {
+      DWORD dwRet2=-1;
+      CStdString strRN = nr.lpRemoteName;
+      do
+      {
+        dwRet2 = WNetCancelConnection2((LPCSTR)strRN.c_str(), 0, false);
+        strRN.erase(strRN.find_last_of("\\"),CStdString::npos);
+      } 
+      while(dwRet2 == ERROR_NOT_CONNECTED && !strRN.Equals("\\\\"));
+    }
+    else if(dwRet != NO_ERROR)
+    {
+      break;
+    }
+  }
+
+  if(dwRet != NO_ERROR)
+  {
+    CLog::Log(LOGERROR,"Couldn't connect to %s, error code %d", strUNC.c_str(), dwRet);
+    return false;
+  }
+  return true;
+}
+
+CStdString CWINSMBDirectory::URLEncode(const CURL &url)
+{
+  /* due to smb wanting encoded urls we have to build it manually */
+
+  CStdString flat = "smb://";
+
+  /* samba messes up of password is set but no username is set. don't know why yet */
+  /* probably the url parser that goes crazy */
+  if(url.GetUserName().length() > 0 /* || url.GetPassWord().length() > 0 */)
+  {
+    flat += url.GetUserName();
+    flat += ":";
+    flat += url.GetPassWord();
+    flat += "@";
+  }
+  flat += url.GetHostName();
+
+  /* okey sadly since a slash is an invalid name we have to tokenize */
+  std::vector<CStdString> parts;
+  std::vector<CStdString>::iterator it;
+  CUtil::Tokenize(url.GetFileName(), parts, "/");
+  for( it = parts.begin(); it != parts.end(); it++ )
+  {
+    flat += "/";
+    flat += (*it);
+  }
+
+  /* okey options should go here, thou current samba doesn't support any */
+
+  return flat;
+}
diff --git a/xbmc/filesystem/windows/WINSMBDirectory.h b/xbmc/filesystem/windows/WINSMBDirectory.h
new file mode 100644 (file)
index 0000000..f7811be
--- /dev/null
@@ -0,0 +1,48 @@
+#pragma once
+/*
+ *      Copyright (C) 2005-2008 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "filesystem/IDirectory.h"
+#include "URL.h"
+
+namespace XFILE
+{
+
+class CWINSMBDirectory : public IDirectory
+{
+public:
+  CWINSMBDirectory(void);
+  virtual ~CWINSMBDirectory(void);
+  virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items);
+  virtual DIR_CACHE_TYPE GetCacheType(const CStdString &strPath) const { return DIR_CACHE_ONCE; };
+  virtual bool Create(const char* strPath);
+  virtual bool Exists(const char* strPath);
+  virtual bool Remove(const char* strPath);
+
+  bool ConnectToShare(const CURL& url);
+private:
+  bool m_bHost;
+  bool EnumerateFunc(LPNETRESOURCEW lpnr, CFileItemList &items);
+  CStdString GetLocal(const CStdString& strPath);
+  CStdString URLEncode(const CURL &url);
+};
+}
index f96d977..1b904ad 100644 (file)
@@ -224,7 +224,7 @@ int CAnimatedGifSet::LoadGIF (const char * szFileName)
   int GraphicExtensionFound = 0;
 
   // OPEN FILE
-  FILE *fd = fopen_utf8(_P(szFileName), "rb");
+  FILE *fd = fopen_utf8(CSpecialProtocol::TranslatePath(szFileName), "rb");
   if (!fd)
   {
     return 0;
index 3543f01..23beb9f 100644 (file)
@@ -32,6 +32,12 @@ CGUIAction::CGUIAction()
   m_sendThreadMessages = false;
 }
 
+CGUIAction::CGUIAction(int controlID)
+{
+  m_sendThreadMessages = false;
+  SetNavigation(controlID);
+}
+
 bool CGUIAction::Execute(int controlID, int parentID, int direction /*= 0*/) const
 {
   if (m_actions.size() == 0) return false;
index 19c5f32..0a7a6d7 100644 (file)
@@ -32,6 +32,7 @@ class CGUIAction
 {
 public:
   CGUIAction();
+  CGUIAction(int controlID);
 
   /**
    * Execute actions, if action is paired with condition - evaluate condition first
index 5a5030c..6df37fc 100644 (file)
@@ -821,9 +821,9 @@ void CGUIBaseContainer::UpdateVisibility(const CGUIListItem *item)
       (m_focusedLayout && !m_focusedLayout->CheckCondition()))
   {
     // and do it
-    int item = GetSelectedItem();
+    int itemIndex = GetSelectedItem();
     UpdateLayout(true); // true to refresh all items
-    SelectItem(item);
+    SelectItem(itemIndex);
   }
 
   if (m_staticContent)
@@ -843,21 +843,21 @@ void CGUIBaseContainer::UpdateVisibility(const CGUIListItem *item)
     }
     for (unsigned int i = 0; i < m_staticItems.size(); ++i)
     {
-      CGUIStaticItemPtr item = boost::static_pointer_cast<CGUIStaticItem>(m_staticItems[i]);
-      if (item->UpdateVisibility(GetParentID()))
+      CGUIStaticItemPtr staticItem = boost::static_pointer_cast<CGUIStaticItem>(m_staticItems[i]);
+      if (staticItem->UpdateVisibility(GetParentID()))
         MarkDirtyRegion();
-      if (item->IsVisible())
+      if (staticItem->IsVisible())
       {
-        m_items.push_back(item);
-        if (item.get() == lastItem)
+        m_items.push_back(staticItem);
+        if (staticItem.get() == lastItem)
           m_lastItem = lastItem;
         // if item is selected and it changed position, re-select it
-        if (item.get() == selectedItem && selected != (int)m_items.size() - 1)
+        if (staticItem.get() == selectedItem && selected != (int)m_items.size() - 1)
           SelectItem(m_items.size() - 1);
       }
       // update any properties
       if (updateItems)
-        item->UpdateProperties(GetParentID());
+        staticItem->UpdateProperties(GetParentID());
     }
     UpdateScrollByLetter();
   }
@@ -876,7 +876,7 @@ void CGUIBaseContainer::CalculateLayout()
   if (oldLayout == m_layout && oldFocusedLayout == m_focusedLayout)
     return; // nothing has changed, so don't update stuff
 
-  m_itemsPerPage = (int)((Size() - m_focusedLayout->Size(m_orientation)) / m_layout->Size(m_orientation)) + 1;
+  m_itemsPerPage = std::max((int)((Size() - m_focusedLayout->Size(m_orientation)) / m_layout->Size(m_orientation)) + 1, 1);
 
   // ensure that the scroll offset is a multiple of our size
   m_scroller.SetValue(GetOffset() * m_layout->Size(m_orientation));
index 996c2c1..6e69c86 100644 (file)
@@ -49,7 +49,7 @@ void CGUIColorManager::Load(const CStdString &colorFile)
 
   // load the global color map if it exists
   TiXmlDocument xmlDoc;
-  if (xmlDoc.LoadFile(PTH_IC("special://xbmc/system/colors.xml")))
+  if (xmlDoc.LoadFile(CSpecialProtocol::TranslatePathConvertCase("special://xbmc/system/colors.xml")))
     LoadXML(xmlDoc);
 
   // first load the default color map if it exists
@@ -57,7 +57,7 @@ void CGUIColorManager::Load(const CStdString &colorFile)
   URIUtils::AddFileToFolder(g_SkinInfo->Path(), "colors", basePath);
   URIUtils::AddFileToFolder(basePath, "defaults.xml", path);
 
-  if (xmlDoc.LoadFile(PTH_IC(path)))
+  if (xmlDoc.LoadFile(CSpecialProtocol::TranslatePathConvertCase(path)))
     LoadXML(xmlDoc);
 
   // now the color map requested
index 981e891..7eed981 100644 (file)
@@ -138,7 +138,10 @@ void CGUIControl::DoProcess(unsigned int currentTime, CDirtyRegionList &dirtyreg
     g_graphicsContext.SetCameraPosition(m_camera);
 
   if (IsVisible())
+  {
     Process(currentTime, dirtyregions);
+    m_bInvalidated = false;
+  }
 
   changed |=  m_controlIsDirty;
 
@@ -152,7 +155,6 @@ void CGUIControl::DoProcess(unsigned int currentTime, CDirtyRegionList &dirtyreg
     g_graphicsContext.RestoreCameraPosition();
   g_graphicsContext.RemoveTransform();
 
-  m_bInvalidated = false;
   m_controlIsDirty = false;
 }
 
@@ -478,6 +480,33 @@ void CGUIControl::SetNavigationActions(const CGUIAction &up, const CGUIAction &d
   if (!m_actionBack.HasAnyActions()  || replace) m_actionBack  = back;
 }
 
+void CGUIControl::SetNavigationAction(int direction, const CGUIAction &action, bool replace /*= true*/)
+{
+  switch (direction)
+  {
+  case ACTION_MOVE_UP:
+    if (!m_actionUp.HasAnyActions() || replace)
+      m_actionUp = action;
+    break;
+  case ACTION_MOVE_DOWN:
+    if (!m_actionDown.HasAnyActions() || replace)
+      m_actionDown = action;
+    break;
+  case ACTION_MOVE_LEFT:
+    if (!m_actionLeft.HasAnyActions() || replace)
+      m_actionLeft = action;
+    break;
+  case ACTION_MOVE_RIGHT:
+    if (!m_actionRight.HasAnyActions() || replace)
+      m_actionRight = action;
+    break;
+  case ACTION_NAV_BACK:
+    if (!m_actionBack.HasAnyActions() || replace)
+      m_actionBack = action;
+    break;
+  }
+}
+
 void CGUIControl::SetWidth(float width)
 {
   if (m_width != width)
index e18a04e..72f4189 100644 (file)
@@ -193,6 +193,7 @@ public:
   virtual void SetNavigationActions(const CGUIAction &up, const CGUIAction &down,
                                     const CGUIAction &left, const CGUIAction &right,
                                     const CGUIAction &back, bool replace = true);
+  void SetNavigationAction(int direction, const CGUIAction &action, bool replace = true);
   int GetControlIdUp() const { return m_actionUp.GetNavigation(); };
   int GetControlIdDown() const { return  m_actionDown.GetNavigation(); };
   int GetControlIdLeft() const { return m_actionLeft.GetNavigation(); };
index 7637211..5f00ad2 100644 (file)
@@ -721,12 +721,12 @@ CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlEl
   hitRect.SetRect(posX, posY, posX + width, posY + height);
   GetHitRect(pControlNode, hitRect);
 
-  if (!GetActions(pControlNode, "onup",    upActions))    upActions.SetNavigation(id);
-  if (!GetActions(pControlNode, "ondown",  downActions))  downActions.SetNavigation(id);
-  if (!GetActions(pControlNode, "onleft",  leftActions))  leftActions.SetNavigation(id);
-  if (!GetActions(pControlNode, "onright", rightActions)) rightActions.SetNavigation(id);
-  if (!GetActions(pControlNode, "onnext",  nextActions))  nextActions.SetNavigation(id);
-  if (!GetActions(pControlNode, "onprev",  prevActions))  prevActions.SetNavigation(id);
+  GetActions(pControlNode, "onup",    upActions);
+  GetActions(pControlNode, "ondown",  downActions);
+  GetActions(pControlNode, "onleft",  leftActions);
+  GetActions(pControlNode, "onright", rightActions);
+  GetActions(pControlNode, "onnext",  nextActions);
+  GetActions(pControlNode, "onprev",  prevActions);
   GetActions(pControlNode, "onback",  backActions);
 
   if (XMLUtils::GetInt(pControlNode, "defaultcontrol", defaultControl))
index 8c03e18..c57c15d 100644 (file)
@@ -226,8 +226,8 @@ void CGUIControlGroupList::AddControl(CGUIControl *control, int position /*= -1*
 
   if (control)
   { // set the navigation of items so that they form a list
-    int beforeID = (m_orientation == VERTICAL) ? GetControlIdUp() : GetControlIdLeft();
-    int afterID = (m_orientation == VERTICAL) ? GetControlIdDown() : GetControlIdRight();
+    CGUIAction beforeAction = (m_orientation == VERTICAL) ? m_actionUp : m_actionLeft;
+    CGUIAction afterAction = (m_orientation == VERTICAL) ? m_actionDown : m_actionRight;
     if (m_children.size())
     {
       // we're inserting at the given position, so grab the items above and below and alter
@@ -237,55 +237,62 @@ void CGUIControlGroupList::AddControl(CGUIControl *control, int position /*= -1*
       if (position == 0)
       { // inserting at the beginning
         after = m_children[0];
-        if (afterID == GetID()) // we're wrapping around bottom->top, so we have to update the last item
+        if (!afterAction.HasActionsMeetingCondition() || afterAction.GetNavigation() == GetID()) // we're wrapping around bottom->top, so we have to update the last item
           before = m_children[m_children.size() - 1];
-        if (beforeID == GetID())   // we're wrapping around top->bottom
-          beforeID = m_children[m_children.size() - 1]->GetID();
-        afterID = after->GetID();
+        if (!beforeAction.HasActionsMeetingCondition() || beforeAction.GetNavigation() == GetID())   // we're wrapping around top->bottom
+          beforeAction = CGUIAction(m_children[m_children.size() - 1]->GetID());
+        afterAction = CGUIAction(after->GetID());
       }
       else if (position == (int)m_children.size())
       { // inserting at the end
         before = m_children[m_children.size() - 1];
-        if (beforeID == GetID())   // we're wrapping around top->bottom, so we have to update the first item
+        if (!beforeAction.HasActionsMeetingCondition() || beforeAction.GetNavigation() == GetID())   // we're wrapping around top->bottom, so we have to update the first item
           after = m_children[0];
-        if (afterID == GetID()) // we're wrapping around bottom->top
-          afterID = m_children[0]->GetID();
-        beforeID = before->GetID();
+        if (!afterAction.HasActionsMeetingCondition() || afterAction.GetNavigation() == GetID()) // we're wrapping around bottom->top
+          afterAction = CGUIAction(m_children[0]->GetID());
+        beforeAction = CGUIAction(before->GetID());
       }
       else
       { // inserting somewhere in the middle
         before = m_children[position - 1];
         after = m_children[position];
-        beforeID = before->GetID();
-        afterID = after->GetID();
+        beforeAction = CGUIAction(before->GetID());
+        afterAction = CGUIAction(after->GetID());
       }
       if (m_orientation == VERTICAL)
       {
         if (before) // update the DOWN action to point to us
-          before->SetNavigation(before->GetControlIdUp(), control->GetID(), GetControlIdLeft(), GetControlIdRight(), GetControlIdBack());
+          before->SetNavigationAction(ACTION_MOVE_DOWN, CGUIAction(control->GetID()));
         if (after) // update the UP action to point to us
-          after->SetNavigation(control->GetID(), after->GetControlIdDown(), GetControlIdLeft(), GetControlIdRight(), GetControlIdBack());
+          after->SetNavigationAction(ACTION_MOVE_UP, CGUIAction(control->GetID()));
       }
       else
       {
         if (before) // update the RIGHT action to point to us
-          before->SetNavigation(GetControlIdUp(), GetControlIdDown(), before->GetControlIdLeft(), control->GetID(), GetControlIdBack());
+          before->SetNavigationAction(ACTION_MOVE_RIGHT, CGUIAction(control->GetID()));
         if (after) // update the LEFT action to point to us
-          after->SetNavigation(GetControlIdUp(), GetControlIdDown(), control->GetID(), after->GetControlIdRight(), GetControlIdBack());
+          after->SetNavigationAction(ACTION_MOVE_LEFT, CGUIAction(control->GetID()));
       }
     }
     // now the control's nav
-    CGUIAction empty;
+    // set navigation path on orientation axis
+    // and try to apply other nav actions from grouplist
+    // don't override them if child have already defined actions
     if (m_orientation == VERTICAL)
     {
-      control->SetNavigation(beforeID, afterID, GetControlIdLeft(), GetControlIdRight(), GetControlIdBack());
-      control->SetNavigationActions(empty, empty, m_actionLeft, m_actionRight, empty, false);
+      control->SetNavigationAction(ACTION_MOVE_UP, beforeAction);
+      control->SetNavigationAction(ACTION_MOVE_DOWN, afterAction);
+      control->SetNavigationAction(ACTION_MOVE_LEFT, m_actionLeft, false);
+      control->SetNavigationAction(ACTION_MOVE_RIGHT, m_actionRight, false);
     }
     else
     {
-      control->SetNavigation(GetControlIdUp(), GetControlIdDown(), beforeID, afterID, GetControlIdBack());
-      control->SetNavigationActions(m_actionUp, m_actionDown, empty, empty, empty, false);
+      control->SetNavigationAction(ACTION_MOVE_LEFT, beforeAction);
+      control->SetNavigationAction(ACTION_MOVE_RIGHT, afterAction);
+      control->SetNavigationAction(ACTION_MOVE_UP, m_actionUp, false);
+      control->SetNavigationAction(ACTION_MOVE_DOWN, m_actionDown, false);
     }
+    control->SetNavigationAction(ACTION_NAV_BACK, m_actionBack, false);
 
     if (!m_useControlPositions)
       control->SetPosition(0,0);
index ae6a610..bde4e8e 100644 (file)
@@ -80,7 +80,7 @@ static bool CheckFont(CStdString& strPath, const CStdString& newPath,
   {
     strPath = URIUtils::AddFileToFolder(newPath,filename);
 #ifdef _LINUX
-    strPath = PTH_IC(strPath);
+    strPath = CSpecialProtocol::TranslatePathConvertCase(strPath);
 #endif
     return false;
   }
@@ -114,7 +114,7 @@ CGUIFont* GUIFontManager::LoadTTF(const CStdString& strFontName, const CStdStrin
     strPath = strFilename;
 
 #ifdef _LINUX
-  strPath = PTH_IC(strPath);
+  strPath = CSpecialProtocol::TranslatePathConvertCase(strPath);
 #endif
 
   // Check if the file exists, otherwise try loading it from the global media dir
index 35c36ed..58f7f48 100644 (file)
@@ -82,7 +82,7 @@ public:
     FT_Face face;
 
     // ok, now load the font face
-    if (FT_New_Face( m_library, _P(filename).c_str(), 0, &face ))
+    if (FT_New_Face( m_library, CSpecialProtocol::TranslatePath(filename).c_str(), 0, &face ))
       return NULL;
 
     unsigned int ydpi = GetDPI();
index a3ef506..9018f12 100644 (file)
  */
 #define GUI_MSG_GESTURE_NOTIFY  38
 
+/*!
+ \brief A request to add a control
+ */
+#define GUI_MSG_ADD_CONTROL     39
+
+/*!
+ \brief A request to remove a control
+ */
+#define GUI_MSG_REMOVE_CONTROL  40
+
 #define GUI_MSG_USER         1000
 
 /*!
index c169611..a384480 100644 (file)
@@ -23,7 +23,6 @@
 #include "GUIUserMessages.h"
 #include "addons/Visualisation.h"
 #include "threads/SingleLock.h"
-#include "utils/GLUtils.h"
 
 using namespace std;
 using namespace ADDON;
@@ -67,7 +66,6 @@ void CGUIRenderingControl::LoadAddon(const AddonPtr &addon)
   }
 
   g_graphicsContext.ApplyStateBlock();
-  VerifyGLState();
 }
 
 void CGUIRenderingControl::UpdateVisibility(const CGUIListItem *item)
index 7e954bf..316792b 100644 (file)
@@ -80,7 +80,7 @@ bool CGUISound::Load(const CStdString& strFile)
 
   return bReady;
 #elif defined(HAS_SDL_AUDIO)
-  m_soundBuffer = Mix_LoadWAV(_P(strFile));
+  m_soundBuffer = Mix_LoadWAV(CSpecialProtocol::TranslatePath(strFile));
   if (!m_soundBuffer)
     return false;
 
index 66fc49c..37a9216 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include "GUIInfoTypes.h"
-#include "../xbmc/FileItem.h"
+#include "xbmc/FileItem.h"
 #include "GUIAction.h"
 
 class TiXmlElement;
index 686f191..85789f3 100644 (file)
@@ -91,7 +91,7 @@ bool CGUIVisualisationControl::OnAction(const CAction &action)
   }
 }
 
-void CGUIVisualisationControl::Render()
+void CGUIVisualisationControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
 {
   if (g_application.IsPlayingAudio())
   {
@@ -107,7 +107,7 @@ void CGUIVisualisationControl::Render()
       m_bAttemptedLoad = true;
     }
   }
-  CGUIRenderingControl::Render();
+  CGUIRenderingControl::Process(currentTime, dirtyregions);
 }
 
 void CGUIVisualisationControl::FreeResources(bool immediately)
index 3d355a1..cb6fdae 100644 (file)
@@ -29,7 +29,7 @@ public:
   CGUIVisualisationControl(const CGUIVisualisationControl &from);
   virtual CGUIVisualisationControl *Clone() const { return new CGUIVisualisationControl(*this); }; //TODO check for naughties
   virtual void FreeResources(bool immediately = false);
-  virtual void Render();
+  virtual void Process(unsigned int currentTime, CDirtyRegionList &dirtyregions);
   virtual bool OnAction(const CAction &action);
   virtual bool OnMessage(CGUIMessage &message);
 private:
index c287ba6..c3dad9a 100644 (file)
@@ -602,6 +602,27 @@ bool CGUIWindow::OnMessage(CGUIMessage& message)
       message.SetParam1(result);
       return result != EVENT_RESULT_UNHANDLED;
     }
+  case GUI_MSG_ADD_CONTROL:
+    {
+      if (message.GetPointer())
+      {
+        CGUIControl *control = (CGUIControl *)message.GetPointer();
+        control->AllocResources();
+        AddControl(control);
+      }
+      return true;
+    }
+  case GUI_MSG_REMOVE_CONTROL:
+    {
+      if (message.GetPointer())
+      {
+        CGUIControl *control = (CGUIControl *)message.GetPointer();
+        RemoveControl(control);
+        control->FreeResources(true);
+        delete control;
+      }
+      return true;
+    }
   case GUI_MSG_NOTIFY_ALL:
     {
       // only process those notifications that come from this window, or those intended for every window
index a20eb37..d46a3e2 100644 (file)
@@ -79,7 +79,7 @@ void CKey::Reset()
   m_rightThumbX = 0.0f;
   m_rightThumbY = 0.0f;
   m_repeat = 0.0f;
-  m_fromHttpApi = false;
+  m_fromService = false;
   m_buttonCode = KEY_INVALID;
   m_vkey = 0;
   m_unicode = 0;
@@ -98,7 +98,7 @@ const CKey& CKey::operator=(const CKey& key)
   m_rightThumbX  = key.m_rightThumbX;
   m_rightThumbY  = key.m_rightThumbY;
   m_repeat       = key.m_repeat;
-  m_fromHttpApi  = key.m_fromHttpApi;
+  m_fromService  = key.m_fromService;
   m_buttonCode   = key.m_buttonCode;
   m_vkey         = key.m_vkey;
   m_unicode     = key.m_unicode;
@@ -164,22 +164,15 @@ float CKey::GetRepeat() const
   return m_repeat;
 }
 
-bool CKey::GetFromHttpApi() const
+void CKey::SetFromService(bool fromService)
 {
-  return m_fromHttpApi;
-}
-
-void CKey::SetFromHttpApi(bool bFromHttpApi)
-{
-  if(bFromHttpApi && (m_buttonCode & KEY_ASCII) )
-  {
-      m_unicode = m_buttonCode - KEY_ASCII;      
-  }
+  if (fromService && (m_buttonCode & KEY_ASCII))
+    m_unicode = m_buttonCode - KEY_ASCII;
     
-  m_fromHttpApi = bFromHttpApi;
+  m_fromService = fromService;
 }
 
-CAction::CAction(int actionID, float amount1 /* = 1.0f */, float amount2 /* = 0.0f */, const CStdString &name /* = "" */)
+CAction::CAction(int actionID, float amount1 /* = 1.0f */, float amount2 /* = 0.0f */, const CStdString &name /* = "" */, unsigned int holdTime /*= 0*/)
 {
   m_id = actionID;
   m_amount[0] = amount1;
@@ -190,7 +183,7 @@ CAction::CAction(int actionID, float amount1 /* = 1.0f */, float amount2 /* = 0.
   m_repeat = 0;
   m_buttonCode = 0;
   m_unicode = 0;
-  m_holdTime = 0;
+  m_holdTime = holdTime;
 }
 
 CAction::CAction(int actionID, unsigned int state, float posX, float posY, float offsetX, float offsetY, const CStdString &name)
index aa0e7ae..30f462b 100644 (file)
 #define ACTION_VOLUME_DOWN          89
 #define ACTION_MUTE                 91
 #define ACTION_NAV_BACK             92
+#define ACTION_VOLAMP_UP            93
+#define ACTION_VOLAMP_DOWN          94
 
 #define ACTION_MOUSE_START            100
 #define ACTION_MOUSE_LEFT_CLICK       100
 #define WINDOW_SETTINGS_MYMUSIC           10015
 #define WINDOW_SETTINGS_SYSTEM            10016
 #define WINDOW_SETTINGS_MYVIDEOS          10017
-#define WINDOW_SETTINGS_NETWORK           10018
+#define WINDOW_SETTINGS_SERVICE           10018 // former (Eden) WINDOW_SETTINGS_NETWORK
 #define WINDOW_SETTINGS_APPEARANCE        10019
 
 #define WINDOW_SCRIPTS                    10020 // virtual window for backward compatibility
@@ -436,7 +438,7 @@ class CKey;
 class CAction
 {
 public:
-  CAction(int actionID, float amount1 = 1.0f, float amount2 = 0.0f, const CStdString &name = "");
+  CAction(int actionID, float amount1 = 1.0f, float amount2 = 0.0f, const CStdString &name = "", unsigned int holdTime = 0);
   CAction(int actionID, wchar_t unicode);
   CAction(int actionID, unsigned int state, float posX, float posY, float offsetX, float offsetY, const CStdString &name = "");
   CAction(int actionID, const CStdString &name, const CKey &key);
@@ -543,8 +545,8 @@ public:
   bool FromKeyboard() const;
   bool IsAnalogButton() const;
   bool IsIRRemote() const;
-  void SetFromHttpApi(bool);
-  bool GetFromHttpApi() const;
+  void SetFromService(bool fromService);
+  bool GetFromService() const { return m_fromService; }
 
   inline uint32_t GetButtonCode() const { return m_buttonCode; }
   inline uint8_t  GetVKey() const       { return m_vkey; }
@@ -578,7 +580,7 @@ private:
   float m_rightThumbX;
   float m_rightThumbY;
   float m_repeat; // time since last keypress
-  bool m_fromHttpApi;
+  bool m_fromService;
 };
 #endif
 
index 13eab06..fd94350 100644 (file)
@@ -73,7 +73,7 @@ bool CLocalizeStrings::LoadSkinStrings(const CStdString& path, const CStdString&
 bool CLocalizeStrings::LoadXML(const CStdString &filename, CStdString &encoding, uint32_t offset /* = 0 */)
 {
   TiXmlDocument xmlDoc;
-  if (!xmlDoc.LoadFile(PTH_IC(filename)))
+  if (!xmlDoc.LoadFile(CSpecialProtocol::TranslatePathConvertCase(filename)))
   {
     CLog::Log(LOGDEBUG, "unable to load %s: %s at line %d", filename.c_str(), xmlDoc.ErrorDesc(), xmlDoc.ErrorRow());
     return false;
index 1c0245b..c8c64aa 100644 (file)
@@ -34,9 +34,9 @@ CMatrixGLES g_matrices;
 
 CMatrixGLES::CMatrixGLES()
 {
-  for (int i=0; i<(int)MM_MATRIXSIZE; i++)
+  for (unsigned int i=0; i < MM_MATRIXSIZE; i++)
   {
-    m_matrices[i].push_back(new GLfloat[16]);
+    m_matrices[i].push_back(MatrixWrapper());
     MatrixMode((EMATRIXMODE)i);
     LoadIdentity();
   }
@@ -46,17 +46,6 @@ CMatrixGLES::CMatrixGLES()
 
 CMatrixGLES::~CMatrixGLES()
 {
-  for (int i=0; i<(int)MM_MATRIXSIZE; i++)
-  {
-    while (!m_matrices[i].empty())
-    {
-      GLfloat *matrix = m_matrices[i].back();
-      delete [] matrix;
-      m_matrices[i].pop_back();
-    }
-  }
-  m_matrixMode = (EMATRIXMODE)-1;
-  m_pMatrix    = NULL;
 }
 
 GLfloat* CMatrixGLES::GetMatrix(EMATRIXMODE mode)
@@ -89,10 +78,8 @@ void CMatrixGLES::PushMatrix()
 {
   if (m_pMatrix && MODE_WITHIN_RANGE(m_matrixMode))
   {
-    GLfloat *matrix = new GLfloat[16];
-    memcpy(matrix, m_pMatrix, sizeof(GLfloat)*16);
-    m_matrices[m_matrixMode].push_back(matrix);
-    m_pMatrix = matrix;
+    m_matrices[m_matrixMode].push_back(MatrixWrapper(m_pMatrix));
+    m_pMatrix =  m_matrices[m_matrixMode].back();
   }
 }
 
@@ -102,8 +89,6 @@ void CMatrixGLES::PopMatrix()
   {
     if (m_matrices[m_matrixMode].size() > 1)
     { 
-      GLfloat *matrix = m_matrices[m_matrixMode].back();
-      delete [] matrix;
       m_matrices[m_matrixMode].pop_back();
     }
     m_pMatrix = m_matrices[m_matrixMode].back();
@@ -394,7 +379,7 @@ bool CMatrixGLES::Project(GLfloat objx, GLfloat objy, GLfloat objz, const GLfloa
 
 void CMatrixGLES::PrintMatrix(void)
 {
-  for (int i=0; i<(int)MM_MATRIXSIZE; i++)
+  for (unsigned int i=0; i < MM_MATRIXSIZE; i++)
   {
     GLfloat *m = GetMatrix((EMATRIXMODE)i);
     CLog::Log(LOGDEBUG, "MatrixGLES - Matrix:%d", i);
index 6bbdff9..365445f 100644 (file)
@@ -1,3 +1,4 @@
+#pragma once
 /*
 *      Copyright (C) 2005-2008 Team XBMC
 *      http://www.xbmc.org
 *
 */
 
-#ifndef MATRIX_GLES_H
-#define MATRIX_GLES_H
-
-#pragma once
-
 #include <vector>
-
-using namespace std;
+#include <string.h>
 
 enum EMATRIXMODE
 {
@@ -60,11 +55,22 @@ public:
   bool Project(GLfloat objx, GLfloat objy, GLfloat objz, const GLfloat modelMatrix[16], const GLfloat projMatrix[16], const GLint viewport[4], GLfloat* winx, GLfloat* winy, GLfloat* winz);
 
 protected:
-  vector<GLfloat*> m_matrices[(int)MM_MATRIXSIZE];
+
+  struct MatrixWrapper 
+  {
+    MatrixWrapper(){};
+    MatrixWrapper( const float values[16]) { memcpy(m_values,values,sizeof(m_values)); }
+    MatrixWrapper( const MatrixWrapper &rhs ) { memcpy(m_values, rhs.m_values, sizeof(m_values)); }
+    MatrixWrapper &operator=( const MatrixWrapper &rhs ) { memcpy(m_values, rhs.m_values, sizeof(m_values)); return *this;}
+    operator float*() { return m_values; }
+    operator const float*() const { return m_values; }
+
+    float m_values[16];
+  };
+
+  std::vector<struct MatrixWrapper> m_matrices[(int)MM_MATRIXSIZE];
   GLfloat *m_pMatrix;
   EMATRIXMODE m_matrixMode;
 };
 
 extern CMatrixGLES g_matrices;
-
-#endif // MATRIX_GLES_H
index 692d299..a9676f3 100644 (file)
@@ -49,12 +49,7 @@ bool CShader::LoadSource(const string& filename, const string& prefix)
     CLog::Log(LOGERROR, "CYUVShaderGLSL::CYUVShaderGLSL - failed to open file %s", filename.c_str());
     return false;
   }
-#ifdef _ARMEL
-  CLog::Log(LOGDEBUG, "Shader - Loading shader file %s", filename.c_str());
-  m_source.assign(file.ReadFile());
-#else
   getline(file, m_source, '\0');
-#endif
   m_source.insert(0, prefix);
   return true;
 }
index ff94284..09bc869 100644 (file)
@@ -75,7 +75,7 @@ bool CTextureBundleXBT::OpenBundle()
     strPath = URIUtils::AddFileToFolder(g_graphicsContext.GetMediaDir(), "media/Textures.xbt");
   }
 
-  strPath = PTH_IC(strPath);
+  strPath = CSpecialProtocol::TranslatePathConvertCase(strPath);
 
   // Load the texture file
   if (!m_XBTFReader.Open(strPath))
index 037b4c6..c7e68bb 100644 (file)
@@ -138,11 +138,11 @@ bool CTextureBundleXPR::OpenBundle()
   else
     strPath = URIUtils::AddFileToFolder(g_graphicsContext.GetMediaDir(), "media/Textures.xpr");
 
-  strPath = PTH_IC(strPath);
+  strPath = CSpecialProtocol::TranslatePathConvertCase(strPath);
 
 #ifndef _LINUX
   CStdStringW strPathW;
-  g_charsetConverter.utf8ToW(_P(strPath), strPathW, false);
+  g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(strPath), strPathW, false);
   m_hFile = _wfopen(strPathW.c_str(), L"rb");
 #else
   m_hFile = fopen(strPath.c_str(), "rb");
index b32dce7..f084476 100644 (file)
@@ -525,18 +525,21 @@ unsigned int CGUITextureManager::GetMemoryUsage() const
 
 void CGUITextureManager::SetTexturePath(const CStdString &texturePath)
 {
+  CSingleLock lock(m_section);
   m_texturePaths.clear();
   AddTexturePath(texturePath);
 }
 
 void CGUITextureManager::AddTexturePath(const CStdString &texturePath)
 {
+  CSingleLock lock(m_section);
   if (!texturePath.IsEmpty())
     m_texturePaths.push_back(texturePath);
 }
 
 void CGUITextureManager::RemoveTexturePath(const CStdString &texturePath)
 {
+  CSingleLock lock(m_section);
   for (vector<CStdString>::iterator it = m_texturePaths.begin(); it != m_texturePaths.end(); ++it)
   {
     if (*it == texturePath)
@@ -553,6 +556,7 @@ CStdString CGUITextureManager::GetTexturePath(const CStdString &textureName, boo
     return textureName;
   else
   { // texture doesn't include the full path, so check all fallbacks
+    CSingleLock lock(m_section);
     for (vector<CStdString>::iterator it = m_texturePaths.begin(); it != m_texturePaths.end(); ++it)
     {
       CStdString path = URIUtils::AddFileToFolder(it->c_str(), "media");
index c9dac5d..dd47f48 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <vector>
 #include "TextureBundle.h"
+#include "threads/CriticalSection.h"
 
 #pragma once
 
@@ -131,6 +132,7 @@ protected:
   CTextureBundle m_TexBundle[2];
 
   std::vector<CStdString> m_texturePaths;
+  CCriticalSection m_section;
 };
 
 /*!
index db96fd1..8394c03 100644 (file)
@@ -60,7 +60,7 @@ bool CXBTFReader::Open(const CStdString& fileName)
 
 #ifdef _WIN32
   CStdStringW strPathW;
-  g_charsetConverter.utf8ToW(_P(m_fileName), strPathW, false);
+  g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(m_fileName), strPathW, false);
   m_file = _wfopen(strPathW.c_str(), L"rb");
 #else
   m_file = fopen(m_fileName.c_str(), "rb");
index 7c640db..632c7db 100644 (file)
@@ -201,6 +201,8 @@ static const ActionMapping actions[] =
         {"blue"              , ACTION_TELETEXT_BLUE},
         {"increasepar"       , ACTION_INCREASE_PAR},
         {"decreasepar"       , ACTION_DECREASE_PAR},
+        {"volampup"          , ACTION_VOLAMP_UP},
+        {"volampdown"        , ACTION_VOLAMP_DOWN},
 
         // Mouse actions
         {"leftclick"         , ACTION_MOUSE_LEFT_CLICK},
@@ -236,7 +238,8 @@ static const ActionMapping windows[] =
         {"musicsettings"            , WINDOW_SETTINGS_MYMUSIC},
         {"systemsettings"           , WINDOW_SETTINGS_SYSTEM},
         {"videossettings"           , WINDOW_SETTINGS_MYVIDEOS},
-        {"networksettings"          , WINDOW_SETTINGS_NETWORK},
+        {"networksettings"          , WINDOW_SETTINGS_SERVICE}, // backward compat
+        {"servicesettings"          , WINDOW_SETTINGS_SERVICE},
         {"appearancesettings"       , WINDOW_SETTINGS_APPEARANCE},
         {"scripts"                  , WINDOW_PROGRAMS}, // backward compat
         {"videofiles"               , WINDOW_VIDEO_FILES},
@@ -363,7 +366,6 @@ CButtonTranslator& CButtonTranslator::GetInstance()
 
 CButtonTranslator::CButtonTranslator()
 {
-  m_baseMap.clear();
   m_deviceList.clear();
   m_Loaded = false;
 }
@@ -429,37 +431,48 @@ bool CButtonTranslator::Load(bool AlwaysLoad)
   };
   bool success = false;
 
-  // If we've already loaded the m_baseMap we don't need to load it
-  // again - this speeds up reloads caused by plugging and unplugging
-  // HID devices. However if AlwaysLoad is true always load the keymaps
-  // from scratch.
-  if (m_Loaded && !AlwaysLoad)
+  for (unsigned int dirIndex = 0; dirIndex < sizeof(DIRS_TO_CHECK)/sizeof(DIRS_TO_CHECK[0]); ++dirIndex)
   {
-    m_translatorMap = m_baseMap;
-  }
+    if (XFILE::CDirectory::Exists(DIRS_TO_CHECK[dirIndex]))
+    {
+      CFileItemList files;
+      XFILE::CDirectory::GetDirectory(DIRS_TO_CHECK[dirIndex], files, ".xml");
+      // Sort the list for filesystem based priorities, e.g. 01-keymap.xml, 02-keymap-overrides.xml
+      files.Sort(SORT_METHOD_FILE, SORT_ORDER_ASC);
+      for(int fileIndex = 0; fileIndex<files.Size(); ++fileIndex)
+      {
+        if (!files[fileIndex]->m_bIsFolder)
+          success |= LoadKeymap(files[fileIndex]->GetPath());
+      }
 
-  // Else load the standard mappings
-  else
-  {
-    for(unsigned int dirIndex = 0; dirIndex < sizeof(DIRS_TO_CHECK)/sizeof(DIRS_TO_CHECK[0]); ++dirIndex) {
-      if( XFILE::CDirectory::Exists(DIRS_TO_CHECK[dirIndex]) )
+      // Load mappings for any HID devices we have connected
+      std::list<CStdString>::iterator it;
+      for (it = m_deviceList.begin(); it != m_deviceList.end(); it++)
       {
-        CFileItemList files;
-        XFILE::CDirectory::GetDirectory(DIRS_TO_CHECK[dirIndex], files, "*.xml");
-        // Sort the list for filesystem based priorities, e.g. 01-keymap.xml, 02-keymap-overrides.xml
-        files.Sort(SORT_METHOD_FILE, SORT_ORDER_ASC);
-        // In (at least) Windows the GetDirectory returns all files not just *.xml files
-        for(int fileIndex = 0; fileIndex<files.Size(); ++fileIndex)
-          if (files[fileIndex]->GetPath().Right(4) == ".xml")
-            success |= LoadKeymap(files[fileIndex]->GetPath());
+        CStdString devicedir = DIRS_TO_CHECK[dirIndex];
+        devicedir.append(*it);
+        devicedir.append("/");
+        if( XFILE::CDirectory::Exists(devicedir) )
+        {
+          CFileItemList files;
+          XFILE::CDirectory::GetDirectory(devicedir, files, ".xml");
+          // Sort the list for filesystem based priorities, e.g. 01-keymap.xml, 02-keymap-overrides.xml
+          files.Sort(SORT_METHOD_FILE, SORT_ORDER_ASC);
+          for(int fileIndex = 0; fileIndex<files.Size(); ++fileIndex)
+          {
+            if (!files[fileIndex]->m_bIsFolder)
+              success |= LoadKeymap(files[fileIndex]->GetPath());
+          }
+        }
       }
     }
+  }
 
-    if (!success)
-    {
-      CLog::Log(LOGERROR, "Error loading keymaps from: %s or %s or %s", DIRS_TO_CHECK[0], DIRS_TO_CHECK[1], DIRS_TO_CHECK[2]);
-      return false;
-    }
+  if (!success)
+  {
+    CLog::Log(LOGERROR, "Error loading keymaps from: %s or %s or %s", DIRS_TO_CHECK[0], DIRS_TO_CHECK[1], DIRS_TO_CHECK[2]);
+    return false;
+  }
 
 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
 #ifdef _LINUX
@@ -467,53 +480,25 @@ bool CButtonTranslator::Load(bool AlwaysLoad)
 #else
 #define REMOTEMAP "IRSSmap.xml"
 #endif
-    CStdString lircmapPath;
-    URIUtils::AddFileToFolder("special://xbmc/system/", REMOTEMAP, lircmapPath);
-    lircRemotesMap.clear();
-    if(CFile::Exists(lircmapPath))
-      success |= LoadLircMap(lircmapPath);
-    else
-      CLog::Log(LOGDEBUG, "CButtonTranslator::Load - no system %s found, skipping", REMOTEMAP);
+  CStdString lircmapPath;
+  URIUtils::AddFileToFolder("special://xbmc/system/", REMOTEMAP, lircmapPath);
+  lircRemotesMap.clear();
+  if(CFile::Exists(lircmapPath))
+    success |= LoadLircMap(lircmapPath);
+  else
+    CLog::Log(LOGDEBUG, "CButtonTranslator::Load - no system %s found, skipping", REMOTEMAP);
 
-    lircmapPath = g_settings.GetUserDataItem(REMOTEMAP);
-    if(CFile::Exists(lircmapPath))
-      success |= LoadLircMap(lircmapPath);
-    else
-      CLog::Log(LOGDEBUG, "CButtonTranslator::Load - no userdata %s found, skipping", REMOTEMAP);
+  lircmapPath = g_settings.GetUserDataItem(REMOTEMAP);
+  if(CFile::Exists(lircmapPath))
+    success |= LoadLircMap(lircmapPath);
+  else
+    CLog::Log(LOGDEBUG, "CButtonTranslator::Load - no userdata %s found, skipping", REMOTEMAP);
 
-    if (!success)
-      CLog::Log(LOGERROR, "CButtonTranslator::Load - unable to load remote map %s", REMOTEMAP);
-    // don't return false - it is to only indicate a fatal error (which this is not)
+  if (!success)
+    CLog::Log(LOGERROR, "CButtonTranslator::Load - unable to load remote map %s", REMOTEMAP);
+  // don't return false - it is to only indicate a fatal error (which this is not)
 #endif
 
-    // Standard mappings have been loaded into m_translatorMap, copy them to
-    // m_baseMap for future reuse.
-    m_baseMap = m_translatorMap;
-  }
-
-  // Load mappings for any HID devices we have connected
-  std::list<CStdString>::iterator it;
-  for (it = m_deviceList.begin(); it != m_deviceList.end(); it++)
-  {
-    for(unsigned int dirIndex = 0; dirIndex < sizeof(DIRS_TO_CHECK)/sizeof(DIRS_TO_CHECK[0]); ++dirIndex)
-    {
-      CStdString devicedir = DIRS_TO_CHECK[dirIndex];
-      devicedir.append(*it);
-      devicedir.append("/");
-      if( XFILE::CDirectory::Exists(devicedir) )
-      {
-        CFileItemList files;
-        XFILE::CDirectory::GetDirectory(devicedir, files, "*.xml");
-        // Sort the list for filesystem based priorities, e.g. 01-keymap.xml, 02-keymap-overrides.xml
-        files.Sort(SORT_METHOD_FILE, SORT_ORDER_ASC);
-        // In (at least) Windows the GetDirectory returns all files not just *.xml files
-        for(int fileIndex = 0; fileIndex<files.Size(); ++fileIndex)
-          if (files[fileIndex]->GetPath().Right(4) == ".xml")
-            success |= LoadKeymap(files[fileIndex]->GetPath());
-      }
-    }
-  }
-
   // Done!
   m_Loaded = true;
   return true;
index 802f16b..0a8cec7 100644 (file)
@@ -101,8 +101,6 @@ public:
 private:
   typedef std::multimap<uint32_t, CButtonAction> buttonMap; // our button map to fill in
 
-  // m_baseMap contains all the standard mappings
-  std::map<int, buttonMap> m_baseMap;
   // m_translatorMap contains all mappings i.e. m_BaseMap + HID device mappings
   std::map<int, buttonMap> m_translatorMap;
   // m_deviceList contains the list of connected HID devices
index 458ad59..1dfe459 100644 (file)
@@ -75,6 +75,11 @@ bool CInertialScrollingHandler::CheckForInertialScrolling(const CAction* action)
   //on begin/tap stop all inertial scrolling
   if ( action->GetID() == ACTION_GESTURE_BEGIN )
   {
+    //release any former exclusive mouse mode
+    //for making switching between multiple lists
+    //possible
+    CGUIMessage message(GUI_MSG_EXCLUSIVE_MOUSE, 0, 0);
+    g_windowManager.SendMessage(message);     
     m_bScrolling = false;
     //wakeup screensaver on pan begin
     g_application.ResetScreenSaver();    
index 4caad37..ee4b589 100644 (file)
@@ -408,4 +408,24 @@ float CJoystick::SetDeadzone(float val)
   return val;
 }
 
+bool CJoystick::Reinitialize()
+{
+  // Restart SDL joystick subsystem
+  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+  if (SDL_WasInit(SDL_INIT_JOYSTICK) !=  0)
+  {
+    CLog::Log(LOGERROR, "Stop joystick subsystem failed");
+    return false;
+  }
+  if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0)
+  {
+    CLog::Log(LOGERROR, "Restart joystick subsystem failed : %s",SDL_GetError());
+    return false;
+  }
+
+  Initialize();
+
+  return true;
+}
+
 #endif
index a08364f..e7803d1 100644 (file)
@@ -64,6 +64,7 @@ public:
   float GetAmount(int axis);
   float GetAmount() { return GetAmount(m_AxisId); }
   float SetDeadzone(float val);
+  bool Reinitialize();
 
 private:
   void SetAxisActive(bool active=true) { m_ActiveFlags = active?(m_ActiveFlags|JACTIVE_AXIS):(m_ActiveFlags&(~JACTIVE_AXIS)); }
index 6463112..59e0413 100644 (file)
@@ -62,13 +62,13 @@ void CAnnouncementManager::RemoveAnnouncer(IAnnouncer *listener)
   }
 }
 
-void CAnnouncementManager::Announce(EAnnouncementFlag flag, const char *sender, const char *message)
+void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message)
 {
   CVariant data;
   Announce(flag, sender, message, data);
 }
 
-void CAnnouncementManager::Announce(EAnnouncementFlag flag, const char *sender, const char *message, CVariant &data)
+void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CVariant &data)
 {
   CLog::Log(LOGDEBUG, "CAnnouncementManager - Announcement: %s from %s", message, sender);
   CSingleLock lock (m_critSection);
@@ -76,13 +76,13 @@ void CAnnouncementManager::Announce(EAnnouncementFlag flag, const char *sender,
     m_announcers[i]->Announce(flag, sender, message, data);
 }
 
-void CAnnouncementManager::Announce(EAnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item)
+void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item)
 {
   CVariant data;
   Announce(flag, sender, message, item, data);
 }
 
-void CAnnouncementManager::Announce(EAnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data)
+void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data)
 {
   if (!item.get())
   {
index c05fd28..1890ed9 100644 (file)
@@ -32,10 +32,10 @@ namespace ANNOUNCEMENT
   public:
     static void AddAnnouncer(IAnnouncer *listener);
     static void RemoveAnnouncer(IAnnouncer *listener);
-    static void Announce(EAnnouncementFlag flag, const char *sender, const char *message);
-    static void Announce(EAnnouncementFlag flag, const char *sender, const char *message, CVariant &data);
-    static void Announce(EAnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item);
-    static void Announce(EAnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data);
+    static void Announce(AnnouncementFlag flag, const char *sender, const char *message);
+    static void Announce(AnnouncementFlag flag, const char *sender, const char *message, CVariant &data);
+    static void Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item);
+    static void Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data);
   private:
     static std::vector<IAnnouncer *> m_announcers;
     static CCriticalSection m_critSection;
diff --git a/xbmc/interfaces/AnnouncementUtils.h b/xbmc/interfaces/AnnouncementUtils.h
deleted file mode 100644 (file)
index 2baa5e6..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2011 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include "IAnnouncer.h"
-
-namespace ANNOUNCEMENT
-{
-  class CAnnouncementUtils
-  {
-  public:
-    /*!
-     \brief Returns a string representation for the 
-     given EAnnouncementFlag
-     \param notification Specific EAnnouncementFlag
-     \return String representation of the given EAnnouncementFlag
-     */
-    static inline const char *AnnouncementFlagToString(const EAnnouncementFlag &notification)
-    {
-      switch (notification)
-      {
-      case Player:
-        return "Player";
-      case GUI:
-        return "GUI";
-      case System:
-        return "System";
-      case VideoLibrary:
-        return "VideoLibrary";
-      case AudioLibrary:
-        return "AudioLibrary";
-      case Other:
-        return "Other";
-      default:
-        return "Unknown";
-      }
-    }
-  };
-}
index 958692c..588be8d 100644 (file)
@@ -826,9 +826,12 @@ int CBuiltins::Execute(const CStdString& execString)
   {
     int oldVolume = g_application.GetVolume();
     int volume = atoi(parameter.c_str());
-  
-    g_application.SetVolume(volume);
-    g_application.getApplicationMessenger().ShowVolumeBar(oldVolume < volume);  
+
+    g_application.SetVolume(volume);   
+    if(oldVolume != volume)
+    {
+      g_application.getApplicationMessenger().ShowVolumeBar(oldVolume < volume);  
+    }
   }
   else if (execute.Equals("playlist.playoffset"))
   {
index aab575f..35360a6 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 /*
- *      Copyright (C) 2005-2010 Team XBMC
+ *      Copyright (C) 2005-2012 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
 class CVariant;
 namespace ANNOUNCEMENT
 {
-  enum EAnnouncementFlag
+  enum AnnouncementFlag
   {
     Player = 0x1,
     GUI = 0x2,
     System = 0x4,
     VideoLibrary = 0x8,
     AudioLibrary = 0x10,
-    Other = 0x20
+    Application = 0x20,
+    Other = 0x40
   };
 
-  #define ANNOUNCE_ALL (Player | GUI | System | VideoLibrary | AudioLibrary | Other)
+  #define ANNOUNCE_ALL (Player | GUI | System | VideoLibrary | AudioLibrary | Application | Other)
+
+  /*!
+    \brief Returns a string representation for the 
+    given AnnouncementFlag
+    \param notification Specific AnnouncementFlag
+    \return String representation of the given AnnouncementFlag
+    */
+  inline const char *AnnouncementFlagToString(const AnnouncementFlag &notification)
+  {
+    switch (notification)
+    {
+    case Player:
+      return "Player";
+    case GUI:
+      return "GUI";
+    case System:
+      return "System";
+    case VideoLibrary:
+      return "VideoLibrary";
+    case AudioLibrary:
+      return "AudioLibrary";
+    case Application:
+      return "Application";
+    case Other:
+      return "Other";
+    default:
+      return "Unknown";
+    }
+  }
 
   class IAnnouncer
   {
   public:
     IAnnouncer() { };
     virtual ~IAnnouncer() { };
-    virtual void Announce(EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) = 0;
+    virtual void Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data) = 0;
   };
 }
index a2bc84b..4a7a5c6 100644 (file)
@@ -67,13 +67,14 @@ int CXbmcConfiguration::BookmarkSize( int eid, webs_t wp, CStdString& response,
   if (pShares)
   {
     char buffer[10];
+    sprintf(buffer,"%i",pShares->size());
 
-    if (eid!=-1) 
-      ejSetResult( eid, itoa(pShares->size(), buffer, 10));
+    if (eid!=-1)
+      ejSetResult( eid, buffer);
     else
     {
       CStdString tmp;
-      tmp.Format("%s", itoa(pShares->size(), buffer, 10));
+      tmp.Format("%i", pShares->size());
       response="" + tmp;
     }
 
index 49b214a..20fff7e 100644 (file)
@@ -44,7 +44,7 @@
 #include "settings/Settings.h"
 #include "settings/AdvancedSettings.h"
 #include "settings/GUISettings.h"
-#include "filesystem/FactoryDirectory.h"
+#include "filesystem/DirectoryFactory.h"
 #include "guilib/LocalizeStrings.h"
 #include "utils/StringUtils.h"
 #include "utils/TimeUtils.h"
@@ -187,9 +187,9 @@ bool CXbmcHttp::decodeBase64ToFile( const CStdString &inString, const CStdString
   try
   {
     if (append)
-      outfile = fopen_utf8(_P(outfilename).c_str(), "ab" );
+      outfile = fopen_utf8(CSpecialProtocol::TranslatePath(outfilename).c_str(), "ab" );
     else
-      outfile = fopen_utf8(_P(outfilename).c_str(), "wb" );
+      outfile = fopen_utf8(CSpecialProtocol::TranslatePath(outfilename).c_str(), "wb" );
     while( ptr < inString.length() )
     {
       for( len = 0, i = 0; i < 4 && ptr < inString.length(); i++ ) 
@@ -1671,7 +1671,7 @@ int CXbmcHttp::xbmcAddToSlideshow(int numParas, CStdString paras[])
   // if its not a picture type, test to see if its a folder
   if (!pItem->IsPicture())
   {
-    IDirectory *pDirectory = CFactoryDirectory::Create(pItem->GetPath());
+    IDirectory *pDirectory = CDirectoryFactory::Create(pItem->GetPath());
     if (!pDirectory)
       return SetResponse(openTag+"Error");  
     bool bResult=pDirectory->Exists(pItem->GetPath());
@@ -2085,7 +2085,7 @@ int CXbmcHttp::xbmcSetKey(int numParas, CStdString paras[])
       }
     }
     CKey tempKey(buttonCode, leftTrigger, rightTrigger, fLeftThumbX, fLeftThumbY, fRightThumbX, fRightThumbY) ;
-    tempKey.SetFromHttpApi(true);
+    tempKey.SetFromService(true);
     key = tempKey;
     lastKey = key;
     return SetResponse(openTag+"OK");
@@ -2303,7 +2303,7 @@ int CXbmcHttp::xbmcChooseAlbum(int numParas, CStdString paras[])
     try
     {
       CMusicAlbumInfo musicInfo;//("", "") ;
-      XFILE::CFileCurl http;
+      XFILE::CCurlFile http;
       ScraperPtr info; // TODO - WTF is this code supposed to do?
       if (musicInfo.Load(http,info))
       {
@@ -2345,7 +2345,7 @@ int CXbmcHttp::xbmcDownloadInternetFile(int numParas, CStdString paras[])
           tempSkipWebFooterHeader=paras[1].ToLower() == "bare";
         if (numParas>2)
           tempSkipWebFooterHeader=paras[2].ToLower() == "bare";
-        XFILE::CFileCurl http;
+        XFILE::CCurlFile http;
         http.Download(src, dest);
         CStdString encoded="";
         encoded=encodeFileToBase64(dest, 80);
index 796708a..8b17ef8 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include "ApplicationOperations.h"
+#include "InputOperations.h"
 #include "Application.h"
 #include "ApplicationMessenger.h"
 #include "FileItem.h"
 
 using namespace JSONRPC;
 
-JSON_STATUS CApplicationOperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CApplicationOperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CVariant properties = CVariant(CVariant::VariantTypeObject);
   for (unsigned int index = 0; index < parameterObject["properties"].size(); index++)
   {
     CStdString propertyName = parameterObject["properties"][index].asString();
     CVariant property;
-    JSON_STATUS ret;
+    JSONRPC_STATUS ret;
     if ((ret = GetPropertyValue(propertyName, property)) != OK)
       return ret;
 
@@ -49,19 +50,47 @@ JSON_STATUS CApplicationOperations::GetProperties(const CStdString &method, ITra
   return OK;
 }
 
-JSON_STATUS CApplicationOperations::SetVolume(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CApplicationOperations::SetVolume(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  int oldVolume = g_application.GetVolume();
-  int volume = (int)parameterObject["volume"].asInteger();
+  bool up = false;
+  if (parameterObject["volume"].isInteger())
+  {
+    int oldVolume = g_application.GetVolume();
+    int volume = (int)parameterObject["volume"].asInteger();
   
-  g_application.SetVolume(volume);
+    g_application.SetVolume(volume);
+
+    up = oldVolume < volume;
+  }
+  else if (parameterObject["volume"].isString())
+  {
+    JSONRPC_STATUS ret;
+    std::string direction = parameterObject["volume"].asString();
+    if (direction.compare("increment") == 0)
+    {
+      ret = CInputOperations::SendAction(ACTION_VOLUME_UP, false, true);
+      up = true;
+    }
+    else if (direction.compare("decrement") == 0)
+    {
+      ret = CInputOperations::SendAction(ACTION_VOLUME_DOWN, false, true);
+      up = false;
+    }
+    else
+      return InvalidParams;
+
+    if (ret != ACK && ret != OK)
+      return ret;
+  }
+  else
+    return InvalidParams;
 
-  g_application.getApplicationMessenger().ShowVolumeBar(oldVolume < volume);
+  g_application.getApplicationMessenger().ShowVolumeBar(up);
 
   return GetPropertyValue("volume", result);
 }
 
-JSON_STATUS CApplicationOperations::SetMute(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CApplicationOperations::SetMute(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   if ((parameterObject["mute"].isString() && parameterObject["mute"].asString().compare("toggle") == 0) ||
       (parameterObject["mute"].isBoolean() && parameterObject["mute"].asBoolean() != g_application.IsMuted()))
@@ -72,13 +101,13 @@ JSON_STATUS CApplicationOperations::SetMute(const CStdString &method, ITransport
   return GetPropertyValue("muted", result);
 }
 
-JSON_STATUS CApplicationOperations::Quit(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CApplicationOperations::Quit(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   g_application.getApplicationMessenger().Quit();
   return ACK;
 }
 
-JSON_STATUS CApplicationOperations::GetPropertyValue(const CStdString &property, CVariant &result)
+JSONRPC_STATUS CApplicationOperations::GetPropertyValue(const CStdString &property, CVariant &result)
 {
   if (property.Equals("volume"))
     result = g_application.GetVolume();
index 139a29a..906e20b 100644 (file)
@@ -29,13 +29,13 @@ namespace JSONRPC
   class CApplicationOperations : CFileItemHandler
   {
   public:
-    static JSON_STATUS GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS SetVolume(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS SetMute(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS SetVolume(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS SetMute(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS Quit(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Quit(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
   private:
-    static JSON_STATUS GetPropertyValue(const CStdString &property, CVariant &result);
+    static JSONRPC_STATUS GetPropertyValue(const CStdString &property, CVariant &result);
   };
 }
index ca7f7b5..284b80d 100644 (file)
@@ -36,7 +36,7 @@ using namespace MUSIC_INFO;
 using namespace JSONRPC;
 using namespace XFILE;
 
-JSON_STATUS CAudioLibrary::GetArtists(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::GetArtists(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CMusicDatabase musicdatabase;
   if (!musicdatabase.Open())
@@ -62,7 +62,7 @@ JSON_STATUS CAudioLibrary::GetArtists(const CStdString &method, ITransportLayer
   return OK;
 }
 
-JSON_STATUS CAudioLibrary::GetArtistDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::GetArtistDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int artistID = (int)parameterObject["artistid"].asInteger();
 
@@ -88,7 +88,7 @@ JSON_STATUS CAudioLibrary::GetArtistDetails(const CStdString &method, ITransport
   return OK;
 }
 
-JSON_STATUS CAudioLibrary::GetAlbums(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::GetAlbums(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CMusicDatabase musicdatabase;
   if (!musicdatabase.Open())
@@ -105,7 +105,7 @@ JSON_STATUS CAudioLibrary::GetAlbums(const CStdString &method, ITransportLayer *
   return OK;
 }
 
-JSON_STATUS CAudioLibrary::GetAlbumDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::GetAlbumDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int albumID = (int)parameterObject["albumid"].asInteger();
 
@@ -131,7 +131,7 @@ JSON_STATUS CAudioLibrary::GetAlbumDetails(const CStdString &method, ITransportL
   return OK;
 }
 
-JSON_STATUS CAudioLibrary::GetSongs(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::GetSongs(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CMusicDatabase musicdatabase;
   if (!musicdatabase.Open())
@@ -149,7 +149,7 @@ JSON_STATUS CAudioLibrary::GetSongs(const CStdString &method, ITransportLayer *t
   return OK;
 }
 
-JSON_STATUS CAudioLibrary::GetSongDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::GetSongDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int idSong = (int)parameterObject["songid"].asInteger();
 
@@ -170,7 +170,7 @@ JSON_STATUS CAudioLibrary::GetSongDetails(const CStdString &method, ITransportLa
   return OK;
 }
 
-JSON_STATUS CAudioLibrary::GetRecentlyAddedAlbums(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::GetRecentlyAddedAlbums(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CMusicDatabase musicdatabase;
   if (!musicdatabase.Open())
@@ -198,7 +198,7 @@ JSON_STATUS CAudioLibrary::GetRecentlyAddedAlbums(const CStdString &method, ITra
   return OK;
 }
 
-JSON_STATUS CAudioLibrary::GetRecentlyAddedSongs(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::GetRecentlyAddedSongs(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CMusicDatabase musicdatabase;
   if (!musicdatabase.Open())
@@ -216,7 +216,7 @@ JSON_STATUS CAudioLibrary::GetRecentlyAddedSongs(const CStdString &method, ITran
   return OK;
 }
 
-JSON_STATUS CAudioLibrary::GetGenres(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::GetGenres(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CMusicDatabase musicdatabase;
   if (!musicdatabase.Open())
@@ -236,13 +236,62 @@ JSON_STATUS CAudioLibrary::GetGenres(const CStdString &method, ITransportLayer *
   return OK;
 }
 
-JSON_STATUS CAudioLibrary::Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::GetRecentlyPlayedAlbums(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  g_application.getApplicationMessenger().ExecBuiltIn("updatelibrary(music)");
+  CMusicDatabase musicdatabase;
+  if (!musicdatabase.Open())
+    return InternalError;
+
+  VECALBUMS albums;
+  if (musicdatabase.GetRecentlyPlayedAlbums(albums))
+  {
+    CFileItemList items;
+
+    for (unsigned int index = 0; index < albums.size(); index++)
+    {
+      CStdString path;
+      path.Format("musicdb://8/%i/", albums[index].idAlbum);
+
+      CFileItemPtr item;
+      FillAlbumItem(albums[index], path, item);
+      items.Add(item);
+    }
+
+    HandleFileItemList("albumid", false, "albums", items, parameterObject, result);
+  }
+
+  musicdatabase.Close();
+  return OK;
+}
+
+JSONRPC_STATUS CAudioLibrary::GetRecentlyPlayedSongs(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+{
+  CMusicDatabase musicdatabase;
+  if (!musicdatabase.Open())
+    return InternalError;
+
+  CFileItemList items;
+  if (musicdatabase.GetRecentlyPlayedAlbumSongs("musicdb://", items))
+    HandleFileItemList("songid", true, "songs", items, parameterObject, result);
+
+  musicdatabase.Close();
+  return OK;
+}
+
+JSONRPC_STATUS CAudioLibrary::Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+{
+  std::string directory = parameterObject["directory"].asString();
+  CStdString cmd;
+  if (directory.empty())
+    cmd = "updatelibrary(music)";
+  else
+    cmd.Format("updatelibrary(music, %s)", directory.c_str());
+
+  g_application.getApplicationMessenger().ExecBuiltIn(cmd);
   return ACK;
 }
 
-JSON_STATUS CAudioLibrary::Export(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::Export(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CStdString cmd;
   if (parameterObject["options"].isMember("path"))
@@ -256,7 +305,7 @@ JSON_STATUS CAudioLibrary::Export(const CStdString &method, ITransportLayer *tra
   return ACK;
 }
 
-JSON_STATUS CAudioLibrary::Clean(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CAudioLibrary::Clean(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   g_application.getApplicationMessenger().ExecBuiltIn("cleanlibrary(music)");
   return ACK;
index 17066b0..6d58918 100644 (file)
@@ -29,19 +29,22 @@ namespace JSONRPC
   class CAudioLibrary : public CFileItemHandler
   {
   public:
-    static JSON_STATUS GetArtists(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetArtistDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetAlbums(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetAlbumDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetSongs(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetSongDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetRecentlyAddedAlbums(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetRecentlyAddedSongs(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetGenres(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetArtists(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetArtistDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetAlbums(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetAlbumDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetSongs(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetSongDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetGenres(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Export(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Clean(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetRecentlyAddedAlbums(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetRecentlyAddedSongs(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetRecentlyPlayedAlbums(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetRecentlyPlayedSongs(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+
+    static JSONRPC_STATUS Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Export(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Clean(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
     static bool FillFileItem(const CStdString &strFilename, CFileItem &item);
     static bool FillFileItemList(const CVariant &parameterObject, CFileItemList &list);
index 097ea31..256111d 100644 (file)
@@ -84,9 +84,29 @@ void CFileItemHandler::FillDetails(ISerializable* info, CFileItemPtr item, const
 
         continue;
       }
+
+      if (item->HasVideoInfoTag() && item->GetVideoContentType() == VIDEODB_CONTENT_TVSHOWS)
+      {
+        if (item->GetVideoInfoTag()->m_iSeason < 0 && field == "season")
+        {
+          result[field] = (int)item->GetProperty("totalseasons").asInteger();
+          continue;
+        }
+        if (field == "watchedepisodes")
+        {
+          result[field] = (int)item->GetProperty("watchedepisodes").asInteger();
+          continue;
+        }
+      }
+
+      if (field == "lastmodified" && item->m_dateTime.IsValid())
+      {
+        result[field] = item->m_dateTime.GetAsLocalizedDateTime();
+        continue;
+      }
     }
 
-    if (serialization.isMember(field) && !result.isMember(field))
+    if (serialization.isMember(field) && (!result.isMember(field) || result[field].empty()))
       result[field] = serialization[field];
   }
 }
@@ -214,6 +234,8 @@ void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char
         object["thumbnail"] = "";
     }
 
+    FillDetails(item.get(), item, validFields, object);
+
     if (item->HasVideoInfoTag())
       FillDetails(item->GetVideoInfoTag(), item, validFields, object);
     if (item->HasMusicInfoTag())
@@ -260,8 +282,8 @@ bool CFileItemHandler::FillFileItemList(const CVariant &parameterObject, CFileIt
       if (item->IsPicture())
       {
         CPictureInfoTag picture;
-        if (picture.Load(item->GetPath()))
-          *item->GetPictureInfoTag() = picture;
+        picture.Load(item->GetPath());
+        *item->GetPictureInfoTag() = picture;
       }
       if (item->GetLabel().IsEmpty())
         item->SetLabel(CUtil::GetTitleFromPath(file, false));
@@ -305,10 +327,14 @@ bool CFileItemHandler::ParseSortMethods(const CStdString &method, const bool &ig
     sortmethod = ignorethe ? SORT_METHOD_ALBUM_IGNORE_THE : SORT_METHOD_ALBUM;
   else if (method.Equals("genre"))
     sortmethod = SORT_METHOD_GENRE;
+  else if (method.Equals("country"))
+    sortmethod = SORT_METHOD_COUNTRY;
   else if (method.Equals("year"))
     sortmethod = SORT_METHOD_YEAR;
   else if (method.Equals("videorating"))
     sortmethod = SORT_METHOD_VIDEO_RATING;
+  else if (method.Equals("dateadded"))
+    sortmethod = SORT_METHOD_DATEADDED;
   else if (method.Equals("programcount"))
     sortmethod = SORT_METHOD_PROGRAM_COUNT;
   else if (method.Equals("playlist"))
@@ -335,8 +361,12 @@ bool CFileItemHandler::ParseSortMethods(const CStdString &method, const bool &ig
     sortmethod = SORT_METHOD_LASTPLAYED;
   else if (method.Equals("playcount"))
     sortmethod = SORT_METHOD_PLAYCOUNT;
+  else if (method.Equals("listeners"))
+    sortmethod = SORT_METHOD_LISTENERS;
   else if (method.Equals("unsorted"))
     sortmethod = SORT_METHOD_UNSORTED;
+  else if (method.Equals("bitrate"))
+    sortmethod = SORT_METHOD_BITRATE;
   else
     return false;
 
index 2f0eb9e..53b2ab9 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 /*
- *      Copyright (C) 2005-2010 Team XBMC
+ *      Copyright (C) 2005-2012 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
  *
  */
 
-#include "utils/StdString.h"
 #include "JSONRPC.h"
 #include "JSONUtils.h"
 #include "FileItem.h"
+#include "utils/StdString.h"
 
 namespace JSONRPC
 {
index 7902a0f..cf0945d 100644 (file)
@@ -37,7 +37,7 @@ using namespace JSONRPC;
 static const unsigned int SourcesSize = 5;
 static CStdString SourceNames[] = { "programs", "files", "video", "music", "pictures" };
 
-JSON_STATUS CFileOperations::GetRootDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CFileOperations::GetRootDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CStdString media = parameterObject["media"].asString();
   media = media.ToLower();
@@ -74,12 +74,11 @@ JSON_STATUS CFileOperations::GetRootDirectory(const CStdString &method, ITranspo
   return OK;
 }
 
-JSON_STATUS CFileOperations::GetDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CFileOperations::GetDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CStdString media = parameterObject["media"].asString();
   media = media.ToLower();
 
-  CDirectory directory;
   CFileItemList items;
   CStdString strPath = parameterObject["directory"].asString();
 
@@ -112,7 +111,7 @@ JSON_STATUS CFileOperations::GetDirectory(const CStdString &method, ITransportLa
     extensions = g_settings.m_pictureExtensions;
   }
 
-  if (directory.GetDirectory(strPath, items, extensions))
+  if (CDirectory::GetDirectory(strPath, items, extensions))
   {
     CFileItemList filteredDirectories, filteredFiles;
     for (unsigned int i = 0; i < (unsigned int)items.Size(); i++)
@@ -127,7 +126,9 @@ JSON_STATUS CFileOperations::GetDirectory(const CStdString &method, ITransportLa
       }
 
       if ((media == "video" && items[i]->HasVideoInfoTag()) ||
-          (media == "music" && items[i]->HasMusicInfoTag()))
+          (media == "music" && items[i]->HasMusicInfoTag()) ||
+          (media == "picture" && items[i]->HasPictureInfoTag()) ||
+           media == "files")
       {
         if (items[i]->m_bIsFolder)
           filteredDirectories.Add(items[i]);
@@ -139,6 +140,11 @@ JSON_STATUS CFileOperations::GetDirectory(const CStdString &method, ITransportLa
         CFileItem fileItem;
         if (FillFileItem(items[i], fileItem, media))
         {
+          fileItem.m_bIsFolder = items[i]->m_bIsFolder;
+          fileItem.m_dateTime = items[i]->m_dateTime;
+          fileItem.m_dwSize = items[i]->m_dwSize;
+          fileItem.SetMimeType(items[i]->GetMimeType());
+
           if (items[i]->m_bIsFolder)
             filteredDirectories.Add(CFileItemPtr(new CFileItem(fileItem)));
           else
@@ -197,7 +203,7 @@ JSON_STATUS CFileOperations::GetDirectory(const CStdString &method, ITransportLa
   return InvalidParams;
 }
 
-JSON_STATUS CFileOperations::PrepareDownload(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CFileOperations::PrepareDownload(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   std::string protocol;
   if (transport->PrepareDownload(parameterObject["path"].asString().c_str(), result["details"], protocol))
@@ -215,7 +221,7 @@ JSON_STATUS CFileOperations::PrepareDownload(const CStdString &method, ITranspor
   return InvalidParams;
 }
 
-JSON_STATUS CFileOperations::Download(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CFileOperations::Download(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   return transport->Download(parameterObject["path"].asString().c_str(), result) ? OK : InvalidParams;
 }
index 31d3bae..d7077c1 100644 (file)
@@ -29,11 +29,11 @@ namespace JSONRPC
   class CFileOperations : public CFileItemHandler
   {
   public:
-    static JSON_STATUS GetRootDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetRootDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetDirectory(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
     
-    static JSON_STATUS PrepareDownload(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Download(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS PrepareDownload(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Download(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
     static bool FillFileItem(const CFileItemPtr &originalItem, CFileItem &item, CStdString media = "");
     static bool FillFileItemList(const CVariant &parameterObject, CFileItemList &list);
diff --git a/xbmc/interfaces/json-rpc/GUIOperations.cpp b/xbmc/interfaces/json-rpc/GUIOperations.cpp
new file mode 100644 (file)
index 0000000..0bf77b2
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "GUIOperations.h"
+#include "Application.h"
+#include "GUIInfoManager.h"
+#include "guilib/GUIWindowManager.h"
+#include "dialogs/GUIDialogKaiToast.h"
+#include "addons/AddonManager.h"
+#include "settings/GUISettings.h"
+#include "utils/Variant.h"
+
+using namespace std;
+using namespace JSONRPC;
+using namespace ADDON;
+
+JSONRPC_STATUS CGUIOperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+{
+  CVariant properties = CVariant(CVariant::VariantTypeObject);
+  for (unsigned int index = 0; index < parameterObject["properties"].size(); index++)
+  {
+    CStdString propertyName = parameterObject["properties"][index].asString();
+    CVariant property;
+    JSONRPC_STATUS ret;
+    if ((ret = GetPropertyValue(propertyName, property)) != OK)
+      return ret;
+
+    properties[propertyName] = property;
+  }
+
+  result = properties;
+
+  return OK;
+}
+
+JSONRPC_STATUS CGUIOperations::ShowNotification(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+{
+  string image = parameterObject["image"].asString();
+  string title = parameterObject["title"].asString();
+  string message = parameterObject["message"].asString();
+  unsigned int displaytime = (unsigned int)parameterObject["displaytime"].asUnsignedInteger();
+
+  if (image.compare("info") == 0)
+    CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, title, message, displaytime);
+  else if (image.compare("warning") == 0)
+    CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, title, message, displaytime);
+  else if (image.compare("error") == 0)
+    CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, title, message, displaytime);
+  else
+    CGUIDialogKaiToast::QueueNotification(image, title, message, displaytime);
+
+  return ACK;
+}
+
+JSONRPC_STATUS CGUIOperations::SetFullscreen(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+{
+  if ((parameterObject["fullscreen"].isString() &&
+       parameterObject["fullscreen"].asString().compare("toggle") == 0) ||
+      (parameterObject["fullscreen"].isBoolean() &&
+       parameterObject["fullscreen"].asBoolean() != g_application.IsFullScreen()))
+    g_application.getApplicationMessenger().SendAction(CAction(ACTION_SHOW_GUI));
+  else if (!parameterObject["fullscreen"].isBoolean() && !parameterObject["fullscreen"].isString())
+    return InvalidParams;
+
+  return GetPropertyValue("fullscreen", result);
+}
+
+JSONRPC_STATUS CGUIOperations::GetPropertyValue(const CStdString &property, CVariant &result)
+{
+  if (property.Equals("currentwindow"))
+  {
+    result["label"] = g_infoManager.GetLabel(g_infoManager.TranslateString("System.CurrentWindow"));
+    result["id"] = g_windowManager.GetFocusedWindow();
+  }
+  else if (property.Equals("currentcontrol"))
+    result["label"] = g_infoManager.GetLabel(g_infoManager.TranslateString("System.CurrentControl"));
+  else if (property.Equals("skin"))
+  {
+    CStdString skinId = g_guiSettings.GetString("lookandfeel.skin");
+    AddonPtr addon;
+    CAddonMgr::Get().GetAddon(skinId, addon, ADDON_SKIN);
+
+    result["id"] = skinId;
+    if (addon.get())
+      result["name"] = addon->Name();
+  }
+  else if (property.Equals("fullscreen"))
+    result = g_application.IsFullScreen();
+  else
+    return InvalidParams;
+
+  return OK;
+}
diff --git a/xbmc/interfaces/json-rpc/GUIOperations.h b/xbmc/interfaces/json-rpc/GUIOperations.h
new file mode 100644 (file)
index 0000000..7b4c060
--- /dev/null
@@ -0,0 +1,38 @@
+#pragma once
+/*
+ *      Copyright (C) 2012 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "JSONRPC.h"
+#include "utils/StdString.h"
+
+namespace JSONRPC
+{
+  class CGUIOperations
+  {
+  public:
+    static JSONRPC_STATUS GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+
+    static JSONRPC_STATUS ShowNotification(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS SetFullscreen(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+  private:
+    static JSONRPC_STATUS GetPropertyValue(const CStdString &property, CVariant &result);
+  };
+}
diff --git a/xbmc/interfaces/json-rpc/IJSONRPCAnnouncer.h b/xbmc/interfaces/json-rpc/IJSONRPCAnnouncer.h
new file mode 100644 (file)
index 0000000..cbf875c
--- /dev/null
@@ -0,0 +1,50 @@
+#pragma once
+/*
+ *      Copyright (C) 2012 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "interfaces/IAnnouncer.h"
+#include "utils/JSONVariantWriter.h"
+
+namespace JSONRPC
+{
+  class IJSONRPCAnnouncer : public ANNOUNCEMENT::IAnnouncer
+  {
+  public:
+    virtual ~IJSONRPCAnnouncer() { }
+
+  protected:
+    static std::string AnnouncementToJSONRPC(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *method, const CVariant &data, bool compactOutput)
+    {
+      CVariant root;
+      root["jsonrpc"] = "2.0";
+
+      std::string namespaceMethod = ANNOUNCEMENT::AnnouncementFlagToString(flag);
+      namespaceMethod += ".";
+      namespaceMethod += method;
+      root["method"] = namespaceMethod;
+
+      root["params"]["data"] = data;
+      root["params"]["sender"] = sender;
+
+      return CJSONVariantWriter::Write(root, compactOutput);
+    }
+  };
+}
index a0b6316..6970056 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 /*
- *      Copyright (C) 2005-2010 Team XBMC
+ *      Copyright (C) 2005-2012 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
@@ -21,7 +21,6 @@
  */
 
 #include <string>
-#include "IClient.h"
 
 class CVariant;
 
index 4ad75ce..541c679 100644 (file)
@@ -55,7 +55,7 @@ bool CInputOperations::handleScreenSaver()
   return screenSaverBroken;
 }
 
-JSON_STATUS CInputOperations::sendKey(uint32_t keyCode)
+JSONRPC_STATUS CInputOperations::SendKey(uint32_t keyCode)
 {
   if (keyCode == KEY_INVALID)
     return InternalError;
@@ -65,18 +65,18 @@ JSON_STATUS CInputOperations::sendKey(uint32_t keyCode)
   return ACK;
 }
 
-JSON_STATUS CInputOperations::sendAction(int actionID)
+JSONRPC_STATUS CInputOperations::SendAction(int actionID, bool wakeScreensaver /* = true */, bool waitResult /* = false */)
 {
-  if(!handleScreenSaver())
+  if(!wakeScreensaver || !handleScreenSaver())
   {
     g_application.ResetSystemIdleTimer();
     g_audioManager.PlayActionSound(actionID);
-    g_application.getApplicationMessenger().SendAction(CAction(actionID), WINDOW_INVALID, false);
+    g_application.getApplicationMessenger().SendAction(CAction(actionID), WINDOW_INVALID, waitResult);
   }
   return ACK;
 }
 
-JSON_STATUS CInputOperations::activateWindow(int windowID)
+JSONRPC_STATUS CInputOperations::activateWindow(int windowID)
 {
   if(!handleScreenSaver())
     g_application.getApplicationMessenger().ActivateWindow(windowID, std::vector<CStdString>(), false);
@@ -84,37 +84,47 @@ JSON_STATUS CInputOperations::activateWindow(int windowID)
   return ACK;
 }
 
-JSON_STATUS CInputOperations::Left(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CInputOperations::Left(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+{
+  return SendKey(XBMCVK_LEFT);
+}
+
+JSONRPC_STATUS CInputOperations::Right(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+{
+  return SendKey(XBMCVK_RIGHT);
+}
+
+JSONRPC_STATUS CInputOperations::Down(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  return sendKey(XBMCVK_LEFT);
+  return SendKey(XBMCVK_DOWN);
 }
 
-JSON_STATUS CInputOperations::Right(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CInputOperations::Up(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  return sendKey(XBMCVK_RIGHT);
+  return SendKey(XBMCVK_UP);
 }
 
-JSON_STATUS CInputOperations::Down(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CInputOperations::Select(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  return sendKey(XBMCVK_DOWN);
+  return SendKey(XBMCVK_RETURN);
 }
 
-JSON_STATUS CInputOperations::Up(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CInputOperations::Back(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  return sendKey(XBMCVK_UP);
+  return SendKey(XBMCVK_BACK);
 }
 
-JSON_STATUS CInputOperations::Select(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CInputOperations::ContextMenu(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  return sendKey(XBMCVK_RETURN);
+  return SendAction(ACTION_CONTEXT_MENU);
 }
 
-JSON_STATUS CInputOperations::Back(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CInputOperations::Info(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  return sendKey(XBMCVK_BACK);
+  return SendAction(ACTION_SHOW_INFO);
 }
 
-JSON_STATUS CInputOperations::Home(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CInputOperations::Home(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   return activateWindow(WINDOW_HOME);
 }
index 507f739..2d82ed4 100644 (file)
@@ -31,21 +31,22 @@ namespace JSONRPC
   public:
     static uint32_t GetKey();
 
-    static JSON_STATUS Left(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Right(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Down(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Up(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Left(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Right(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Down(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Up(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS Select(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Select(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Back(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS ContextMenu(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Info(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Home(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS Back(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-
-    static JSON_STATUS Home(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS SendKey(uint32_t keyCode);
+    static JSONRPC_STATUS SendAction(int actionID, bool wakeScreensaver = true, bool waitResult = false);
 
   private:
-    static JSON_STATUS sendKey(uint32_t keyCode);
-    static JSON_STATUS sendAction(int actionID);
-    static JSON_STATUS activateWindow(int windowID);
+    static JSONRPC_STATUS activateWindow(int windowID);
     static bool        handleScreenSaver();
 
     static CCriticalSection m_critSection;
index 8edb053..f437952 100644 (file)
  *
  */
 
+#include <string.h>
+
 #include "JSONRPC.h"
-#include "settings/AdvancedSettings.h"
+#include "ServiceDescription.h"
 #include "interfaces/AnnouncementManager.h"
-#include "interfaces/AnnouncementUtils.h"
+#include "settings/AdvancedSettings.h"
 #include "utils/log.h"
 #include "utils/Variant.h"
-#include <string.h>
-#include "ServiceDescription.h"
 
 using namespace ANNOUNCEMENT;
 using namespace JSONRPC;
@@ -58,48 +58,48 @@ void CJSONRPC::Initialize()
   CLog::Log(LOGINFO, "JSONRPC: Sucessfully initialized");
 }
 
-JSON_STATUS CJSONRPC::Introspect(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
+JSONRPC_STATUS CJSONRPC::Introspect(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
 {
   return CJSONServiceDescription::Print(result, transport, client,
     parameterObject["getdescriptions"].asBoolean(), parameterObject["getmetadata"].asBoolean(), parameterObject["filterbytransport"].asBoolean(),
     parameterObject["filter"]["id"].asString(), parameterObject["filter"]["type"].asString(), parameterObject["filter"]["getreferences"].asBoolean());
 }
 
-JSON_STATUS CJSONRPC::Version(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
+JSONRPC_STATUS CJSONRPC::Version(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
 {
   result["version"] = CJSONServiceDescription::GetVersion();
 
   return OK;
 }
 
-JSON_STATUS CJSONRPC::Permission(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
+JSONRPC_STATUS CJSONRPC::Permission(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
 {
   int flags = client->GetPermissionFlags();
 
   for (int i = 1; i <= OPERATION_PERMISSION_ALL; i *= 2)
-    result[PermissionToString((OperationPermission)i)] = (flags & i) > 0;
+    result[PermissionToString((OperationPermission)i)] = (flags & i) == i;
 
   return OK;
 }
 
-JSON_STATUS CJSONRPC::Ping(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
+JSONRPC_STATUS CJSONRPC::Ping(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
 {
   CVariant temp = "pong";
   result.swap(temp);
   return OK;
 }
 
-JSON_STATUS CJSONRPC::GetConfiguration(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
+JSONRPC_STATUS CJSONRPC::GetConfiguration(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
 {
   int flags = client->GetAnnouncementFlags();
 
   for (int i = 1; i <= ANNOUNCE_ALL; i *= 2)
-    result["notifications"][CAnnouncementUtils::AnnouncementFlagToString((EAnnouncementFlag)i)] = (flags & i) > 0;
+    result["notifications"][AnnouncementFlagToString((AnnouncementFlag)i)] = (flags & i) == i;
 
   return OK;
 }
 
-JSON_STATUS CJSONRPC::SetConfiguration(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
+JSONRPC_STATUS CJSONRPC::SetConfiguration(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
 {
   int flags = 0;
   int oldFlags = client->GetAnnouncementFlags();
@@ -122,6 +122,9 @@ JSON_STATUS CJSONRPC::SetConfiguration(const CStdString &method, ITransportLayer
     if ((notifications["AudioLibrary"].isNull() && (oldFlags & AudioLibrary)) ||
         (notifications["AudioLibrary"].isBoolean() && notifications["AudioLibrary"].asBoolean()))
       flags |= AudioLibrary;
+    if ((notifications["Application"].isNull() && (oldFlags & Other)) ||
+        (notifications["Application"].isBoolean() && notifications["Application"].asBoolean()))
+      flags |= Application;
     if ((notifications["Other"].isNull() && (oldFlags & Other)) ||
         (notifications["Other"].isBoolean() && notifications["Other"].asBoolean()))
       flags |= Other;
@@ -133,7 +136,7 @@ JSON_STATUS CJSONRPC::SetConfiguration(const CStdString &method, ITransportLayer
   return GetConfiguration(method, transport, client, parameterObject, result);
 }
 
-JSON_STATUS CJSONRPC::NotifyAll(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
+JSONRPC_STATUS CJSONRPC::NotifyAll(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
 {
   if (parameterObject["data"].isNull())
     CAnnouncementManager::Announce(Other, parameterObject["sender"].asString().c_str(),  
@@ -194,7 +197,7 @@ CStdString CJSONRPC::MethodCall(const CStdString &inputString, ITransportLayer *
 
 bool CJSONRPC::HandleMethodCall(const CVariant& request, CVariant& response, ITransportLayer *transport, IClient *client)
 {
-  JSON_STATUS errorCode = OK;
+  JSONRPC_STATUS errorCode = OK;
   CVariant result;
   bool isNotification = false;
 
@@ -230,7 +233,7 @@ inline bool CJSONRPC::IsProperJSONRPC(const CVariant& inputroot)
   return inputroot.isObject() && inputroot.isMember("jsonrpc") && inputroot["jsonrpc"].isString() && inputroot["jsonrpc"] == CVariant("2.0") && inputroot.isMember("method") && inputroot["method"].isString() && (!inputroot.isMember("params") || inputroot["params"].isArray() || inputroot["params"].isObject());
 }
 
-inline void CJSONRPC::BuildResponse(const CVariant& request, JSON_STATUS code, const CVariant& result, CVariant& response)
+inline void CJSONRPC::BuildResponse(const CVariant& request, JSONRPC_STATUS code, const CVariant& result, CVariant& response)
 {
   response["jsonrpc"] = "2.0";
   response["id"] = request.isObject() && request.isMember("id") ? request["id"] : CVariant();
index 847567f..bd8ef8f 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 /*
- *      Copyright (C) 2005-2010 Team XBMC
+ *      Copyright (C) 2005-2012 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
  *
  */
 
-#include "utils/StdString.h"
+#include <iostream>
 #include <map>
 #include <stdio.h>
 #include <string>
-#include <iostream>
-#include "ITransportLayer.h"
-#include "interfaces/IAnnouncer.h"
-#include "JSONUtils.h"
+
+#include "JSONRPCUtils.h"
 #include "JSONServiceDescription.h"
+#include "interfaces/IAnnouncer.h"
+#include "utils/StdString.h"
 
 namespace JSONRPC
 {
@@ -37,46 +37,46 @@ namespace JSONRPC
    \brief JSON RPC handler
 
    Sets up and manages all needed information to process
-   JSON RPC requests and answering with the appropriate
-   JSON RPC response (actual response or error message).
+   JSON-RPC requests and answering with the appropriate
+   JSON-RPC response (actual response or error message).
    */
-  class CJSONRPC : public CJSONUtils
+  class CJSONRPC
   {
   public:
     /*!
-     \brief Initializes the JSON RPC handler
+     \brief Initializes the JSON-RPC handler
      */
     static void Initialize();
 
     /*
-     \brief Handles an incoming JSON RPC request
-     \param inputString received JSON RPC request
+     \brief Handles an incoming JSON-RPC request
+     \param inputString received JSON-RPC request
      \param transport Transport protocol on which the request arrived
      \param client Client which sent the request
-     \return JSON RPC response to be sent back to the client
+     \return JSON-RPC response to be sent back to the client
 
      Parses the received input string for the called method and provided
-     parameters. If the request does not conform to the JSON RPC 2.0
+     parameters. If the request does not conform to the JSON-RPC 2.0
      specification an error is returned. Otherwise the parameters provided
      in the request are checked for validity and completeness. If the request
      is valid and the requested method exists it is called and executed.
      */
     static CStdString MethodCall(const CStdString &inputString, ITransportLayer *transport, IClient *client);
 
-    static JSON_STATUS Introspect(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
-    static JSON_STATUS Version(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
-    static JSON_STATUS Permission(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
-    static JSON_STATUS Ping(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
-    static JSON_STATUS GetConfiguration(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
-    static JSON_STATUS SetConfiguration(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
-    static JSON_STATUS NotifyAll(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
+    static JSONRPC_STATUS Introspect(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
+    static JSONRPC_STATUS Version(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
+    static JSONRPC_STATUS Permission(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
+    static JSONRPC_STATUS Ping(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetConfiguration(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
+    static JSONRPC_STATUS SetConfiguration(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
+    static JSONRPC_STATUS NotifyAll(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
   
   private:
     static void setup();
     static bool HandleMethodCall(const CVariant& request, CVariant& response, ITransportLayer *transport, IClient *client);
     static inline bool IsProperJSONRPC(const CVariant& inputroot);
 
-    inline static void BuildResponse(const CVariant& request, JSON_STATUS code, const CVariant& result, CVariant& response);
+    inline static void BuildResponse(const CVariant& request, JSONRPC_STATUS code, const CVariant& result, CVariant& response);
 
     static bool m_initialized;
   };
diff --git a/xbmc/interfaces/json-rpc/JSONRPCUtils.h b/xbmc/interfaces/json-rpc/JSONRPCUtils.h
new file mode 100644 (file)
index 0000000..97350b9
--- /dev/null
@@ -0,0 +1,149 @@
+#pragma once
+/*
+ *      Copyright (C) 2012 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IClient.h"
+#include "ITransportLayer.h"
+#include "interfaces/IAnnouncer.h"
+#include "utils/StdString.h"
+#include "utils/Variant.h"
+
+namespace JSONRPC
+{
+  /*!
+   \ingroup jsonrpc
+   \brief Possible statuc codes of a response
+   to a JSON-RPC request
+   */
+  enum JSONRPC_STATUS
+  {
+    OK = 0,
+    ACK = -1,
+    InvalidRequest = -32600,
+    MethodNotFound = -32601,
+    InvalidParams = -32602,
+    InternalError = -32603,
+    ParseError = -32700,
+    //-32099..-32000 Reserved for implementation-defined server-errors.
+    BadPermission = -32099,
+    FailedToExecute = -32100
+  };
+
+  /*!
+   \brief Function pointer for JSON-RPC methods
+   */
+  typedef JSONRPC_STATUS (*MethodCall) (const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
+
+  /*!
+   \ingroup jsonrpc
+   \brief Permission categories for json rpc methods
+   
+   A JSON-RPC method will only be called if the caller 
+   has the correct permissions to exectue the method.
+   The method call needs to be perfectly threadsafe.
+  */
+  enum OperationPermission
+  {
+    ReadData        =   0x1,
+    ControlPlayback =   0x2,
+    ControlNotify   =   0x4,
+    ControlPower    =   0x8,
+    UpdateData      =  0x10,
+    RemoveData      =  0x20,
+    Navigate        =  0x40,
+    WriteFile       =  0x80,
+    ControlSystem   = 0x100,
+    ControlGUI      = 0x200
+  };
+
+  const int OPERATION_PERMISSION_ALL = (ReadData | ControlPlayback | ControlNotify | ControlPower |
+                                        UpdateData | RemoveData | Navigate | WriteFile |
+                                        ControlSystem | ControlGUI);
+
+  const int OPERATION_PERMISSION_NOTIFICATION = (ControlPlayback | ControlNotify | ControlPower | UpdateData |
+                                                 RemoveData | Navigate | WriteFile | ControlSystem |
+                                                 ControlGUI);
+
+  /*!
+    \brief Returns a string representation for the 
+    given OperationPermission
+    \param permission Specific OperationPermission
+    \return String representation of the given OperationPermission
+    */
+  inline const char *PermissionToString(const OperationPermission &permission)
+  {
+    switch (permission)
+    {
+    case ReadData:
+      return "ReadData";
+    case ControlPlayback:
+      return "ControlPlayback";
+    case ControlNotify:
+      return "ControlNotify";
+    case ControlPower:
+      return "ControlPower";
+    case UpdateData:
+      return "UpdateData";
+    case RemoveData:
+      return "RemoveData";
+    case Navigate:
+      return "Navigate";
+    case WriteFile:
+      return "WriteFile";
+    case ControlSystem:
+      return "ControlSystem";
+    case ControlGUI:
+      return "ControlGUI";
+    default:
+      return "Unknown";
+    }
+  }
+
+  /*!
+    \brief Returns a OperationPermission value for the given
+    string representation
+    \param permission String representation of the OperationPermission
+    \return OperationPermission value of the given string representation
+    */
+  inline OperationPermission StringToPermission(std::string permission)
+  {
+    if (permission.compare("ControlPlayback") == 0)
+      return ControlPlayback;
+    if (permission.compare("ControlNotify") == 0)
+      return ControlNotify;
+    if (permission.compare("ControlPower") == 0)
+      return ControlPower;
+    if (permission.compare("UpdateData") == 0)
+      return UpdateData;
+    if (permission.compare("RemoveData") == 0)
+      return RemoveData;
+    if (permission.compare("Navigate") == 0)
+      return Navigate;
+    if (permission.compare("WriteFile") == 0)
+      return WriteFile;
+    if (permission.compare("ControlSystem") == 0)
+      return ControlSystem;
+    if (permission.compare("ControlGUI") == 0)
+      return ControlGUI;
+
+    return ReadData;
+  }
+}
index b38806f..be82704 100644 (file)
@@ -30,6 +30,7 @@
 #include "FileOperations.h"
 #include "AudioLibrary.h"
 #include "VideoLibrary.h"
+#include "GUIOperations.h"
 #include "SystemOperations.h"
 #include "InputOperations.h"
 #include "XBMCOperations.h"
@@ -140,6 +141,8 @@ JsonRpcMethodMap CJSONServiceDescription::m_methodMaps[] = {
   { "AudioLibrary.GetSongDetails",                  CAudioLibrary::GetSongDetails },
   { "AudioLibrary.GetRecentlyAddedAlbums",          CAudioLibrary::GetRecentlyAddedAlbums },
   { "AudioLibrary.GetRecentlyAddedSongs",           CAudioLibrary::GetRecentlyAddedSongs },
+  { "AudioLibrary.GetRecentlyPlayedAlbums",         CAudioLibrary::GetRecentlyPlayedAlbums },
+  { "AudioLibrary.GetRecentlyPlayedSongs",          CAudioLibrary::GetRecentlyPlayedSongs },
   { "AudioLibrary.GetGenres",                       CAudioLibrary::GetGenres },
   { "AudioLibrary.Scan",                            CAudioLibrary::Scan },
   { "AudioLibrary.Export",                          CAudioLibrary::Export },
@@ -165,8 +168,14 @@ JsonRpcMethodMap CJSONServiceDescription::m_methodMaps[] = {
   { "VideoLibrary.Export",                          CVideoLibrary::Export },
   { "VideoLibrary.Clean",                           CVideoLibrary::Clean },
 
+// GUI operations
+  { "GUI.GetProperties",                            CGUIOperations::GetProperties },
+  { "GUI.ShowNotification",                         CGUIOperations::ShowNotification },
+  { "GUI.SetFullscreen",                            CGUIOperations::SetFullscreen },
+
 // System operations
   { "System.GetProperties",                         CSystemOperations::GetProperties },
+  { "System.EjectOpticalDrive",                     CSystemOperations::EjectOpticalDrive },
   { "System.Shutdown",                              CSystemOperations::Shutdown },
   { "System.Suspend",                               CSystemOperations::Suspend },
   { "System.Hibernate",                             CSystemOperations::Hibernate },
@@ -179,6 +188,8 @@ JsonRpcMethodMap CJSONServiceDescription::m_methodMaps[] = {
   { "Input.Up",                                     CInputOperations::Up },
   { "Input.Select",                                 CInputOperations::Select },
   { "Input.Back",                                   CInputOperations::Back },
+  { "Input.ContextMenu",                            CInputOperations::ContextMenu },
+  { "Input.Info",                                   CInputOperations::Info },
   { "Input.Home",                                   CInputOperations::Home },
 
 // Application operations
@@ -372,7 +383,7 @@ int CJSONServiceDescription::GetVersion()
   return JSONRPC_SERVICE_VERSION;
 }
 
-JSON_STATUS CJSONServiceDescription::Print(CVariant &result, ITransportLayer *transport, IClient *client,
+JSONRPC_STATUS CJSONServiceDescription::Print(CVariant &result, ITransportLayer *transport, IClient *client,
   bool printDescriptions /* = true */, bool printMetadata /* = false */, bool filterByTransport /* = true */,
   std::string filterByName /* = "" */, std::string filterByType /* = "" */, bool printReferences /* = true */)
 {
@@ -537,7 +548,7 @@ JSON_STATUS CJSONServiceDescription::Print(CVariant &result, ITransportLayer *tr
   return OK;
 }
 
-JSON_STATUS CJSONServiceDescription::CheckCall(const char* const method, const CVariant &requestParameters, ITransportLayer *transport, IClient *client, bool notification, MethodCall &methodCall, CVariant &outputParameters)
+JSONRPC_STATUS CJSONServiceDescription::CheckCall(const char* const method, const CVariant &requestParameters, ITransportLayer *transport, IClient *client, bool notification, MethodCall &methodCall, CVariant &outputParameters)
 {
   CJsonRpcMethodMap::JsonRpcMethodIterator iter = m_actionMap.find(method);
   if (iter != m_actionMap.end())
@@ -558,7 +569,7 @@ JSON_STATUS CJSONServiceDescription::CheckCall(const char* const method, const C
         for (unsigned int i = 0; i < iter->second.parameters.size(); i++)
         {
           // Evaluate the current parameter
-          JSON_STATUS status = checkParameter(requestParameters, iter->second.parameters.at(i), i, outputParameters, handled, errorData);
+          JSONRPC_STATUS status = checkParameter(requestParameters, iter->second.parameters.at(i), i, outputParameters, handled, errorData);
           if (status != OK)
           {
             // Return the error data object in the outputParameters reference
@@ -740,7 +751,7 @@ void CJSONServiceDescription::printType(const JSONSchemaTypeDefinition &type, bo
   }
 }
 
-JSON_STATUS CJSONServiceDescription::checkParameter(const CVariant &requestParameters, const JSONSchemaTypeDefinition &type, unsigned int position, CVariant &outputParameters, unsigned int &handled, CVariant &errorData)
+JSONRPC_STATUS CJSONServiceDescription::checkParameter(const CVariant &requestParameters, const JSONSchemaTypeDefinition &type, unsigned int position, CVariant &outputParameters, unsigned int &handled, CVariant &errorData)
 {
   // Let's check if the parameter has been provided
   if (ParameterExists(requestParameters, type.name, position))
@@ -749,7 +760,7 @@ JSON_STATUS CJSONServiceDescription::checkParameter(const CVariant &requestParam
     CVariant parameterValue = GetParameter(requestParameters, type.name, position);
 
     // Evaluate the type of the parameter
-    JSON_STATUS status = checkType(parameterValue, type, outputParameters[type.name], errorData["stack"]);
+    JSONRPC_STATUS status = checkType(parameterValue, type, outputParameters[type.name], errorData["stack"]);
     if (status != OK)
       return status;
 
@@ -772,7 +783,7 @@ JSON_STATUS CJSONServiceDescription::checkParameter(const CVariant &requestParam
   return OK;
 }
 
-JSON_STATUS CJSONServiceDescription::checkType(const CVariant &value, const JSONSchemaTypeDefinition &type, CVariant &outputValue, CVariant &errorData)
+JSONRPC_STATUS CJSONServiceDescription::checkType(const CVariant &value, const JSONSchemaTypeDefinition &type, CVariant &outputValue, CVariant &errorData)
 {
   if (!type.name.empty())
     errorData["name"] = type.name;
@@ -825,7 +836,7 @@ JSON_STATUS CJSONServiceDescription::checkType(const CVariant &value, const JSON
   {
     for (unsigned int extendsIndex = 0; extendsIndex < type.extends.size(); extendsIndex++)
     {
-      JSON_STATUS status = checkType(value, type.extends.at(extendsIndex), outputValue, errorData);
+      JSONRPC_STATUS status = checkType(value, type.extends.at(extendsIndex), outputValue, errorData);
 
       if (status != OK)
       {
@@ -869,7 +880,7 @@ JSON_STATUS CJSONServiceDescription::checkType(const CVariant &value, const JSON
       for (unsigned int arrayIndex = 0; arrayIndex < value.size(); arrayIndex++)
       {
         CVariant temp;
-        JSON_STATUS status = checkType(value[arrayIndex], itemType, temp, errorData["property"]);
+        JSONRPC_STATUS status = checkType(value[arrayIndex], itemType, temp, errorData["property"]);
         outputValue.push_back(temp);
         if (status != OK)
         {
@@ -905,7 +916,7 @@ JSON_STATUS CJSONServiceDescription::checkType(const CVariant &value, const JSON
       unsigned int arrayIndex;
       for (arrayIndex = 0; arrayIndex < min(type.items.size(), (size_t)value.size()); arrayIndex++)
       {
-        JSON_STATUS status = checkType(value[arrayIndex], type.items.at(arrayIndex), outputValue[arrayIndex], errorData["property"]);
+        JSONRPC_STATUS status = checkType(value[arrayIndex], type.items.at(arrayIndex), outputValue[arrayIndex], errorData["property"]);
         if (status != OK)
         {
           CLog::Log(LOGDEBUG, "JSONRPC: Array element at index %u does not match with items schema in type %s", arrayIndex, type.name.c_str());
@@ -975,7 +986,7 @@ JSON_STATUS CJSONServiceDescription::checkType(const CVariant &value, const JSON
     {
       if (value.isMember(propertiesIterator->second.name))
       {
-        JSON_STATUS status = checkType(value[propertiesIterator->second.name], propertiesIterator->second, outputValue[propertiesIterator->second.name], errorData["property"]);
+        JSONRPC_STATUS status = checkType(value[propertiesIterator->second.name], propertiesIterator->second, outputValue[propertiesIterator->second.name], errorData["property"]);
         if (status != OK)
         {
           CLog::Log(LOGDEBUG, "JSONRPC: Invalid property \"%s\" in type %s", propertiesIterator->second.name.c_str(), type.name.c_str());
@@ -1018,7 +1029,7 @@ JSON_STATUS CJSONServiceDescription::checkType(const CVariant &value, const JSON
             continue;
           }
 
-          JSON_STATUS status = checkType(value[iter->first], *(type.additionalProperties), outputValue[iter->first], errorData["property"]);
+          JSONRPC_STATUS status = checkType(value[iter->first], *(type.additionalProperties), outputValue[iter->first], errorData["property"]);
           if (status != OK)
           {
             CLog::Log(LOGDEBUG, "JSONRPC: Invalid additional property \"%s\" in type %s", iter->first.c_str(), type.name.c_str());
index 38cbbb6..7fbc666 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 /*
- *      Copyright (C) 2005-2010 Team XBMC
+ *      Copyright (C) 2005-2012 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
@@ -23,6 +23,7 @@
 #include <string>
 #include <vector>
 #include <limits>
+
 #include "JSONUtils.h"
 
 namespace JSONRPC
@@ -334,7 +335,7 @@ namespace JSONRPC
      \param printMetadata Whether to print XBMC specific data or not
      \param filterByTransport Whether to filter by transport or not
      */
-    static JSON_STATUS Print(CVariant &result, ITransportLayer *transport, IClient *client, bool printDescriptions = true, bool printMetadata = false, bool filterByTransport = true, std::string filterByName = "", std::string filterByType = "", bool printReferences = true);
+    static JSONRPC_STATUS Print(CVariant &result, ITransportLayer *transport, IClient *client, bool printDescriptions = true, bool printMetadata = false, bool filterByTransport = true, std::string filterByName = "", std::string filterByType = "", bool printReferences = true);
 
     /*!
      \brief Checks the given parameters from the request against the
@@ -352,14 +353,14 @@ namespace JSONRPC
      actual C/C++ implementation of the method to the "methodCall" parameter and checks the
      given parameters from the request against the json schema description for the given method.
      */
-    static JSON_STATUS CheckCall(const char* const method, const CVariant &requestParameters, ITransportLayer *transport, IClient *client, bool notification, MethodCall &methodCall, CVariant &outputParameters);
+    static JSONRPC_STATUS CheckCall(const char* const method, const CVariant &requestParameters, ITransportLayer *transport, IClient *client, bool notification, MethodCall &methodCall, CVariant &outputParameters);
 
   private:
     static bool prepareDescription(std::string &description, CVariant &descriptionObject, std::string &name);
     static bool addMethod(std::string &jsonMethod, MethodCall method);
     static void printType(const JSONSchemaTypeDefinition &type, bool isParameter, bool isGlobal, bool printDefault, bool printDescriptions, CVariant &output);
-    static JSON_STATUS checkParameter(const CVariant &requestParameters, const JSONSchemaTypeDefinition &type, unsigned int position, CVariant &outputParameters, unsigned int &handled, CVariant &errorData);
-    static JSON_STATUS checkType(const CVariant &value, const JSONSchemaTypeDefinition &type, CVariant &outputValue, CVariant &errorData);
+    static JSONRPC_STATUS checkParameter(const CVariant &requestParameters, const JSONSchemaTypeDefinition &type, unsigned int position, CVariant &outputParameters, unsigned int &handled, CVariant &errorData);
+    static JSONRPC_STATUS checkType(const CVariant &value, const JSONSchemaTypeDefinition &type, CVariant &outputValue, CVariant &errorData);
     static void parseHeader(const CVariant &descriptionObject);
     static bool parseMethod(const CVariant &value, JsonRpcMethod &method);
     static bool parseParameter(CVariant &value, JSONSchemaTypeDefinition &parameter);
index 984f576..4b8d955 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 /*
- *      Copyright (C) 2005-2010 Team XBMC
+ *      Copyright (C) 2005-2012 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
 
 #include <string.h>
 #include <stdlib.h>
-#include "utils/StdString.h"
+
+#include "JSONRPCUtils.h"
 #include "interfaces/IAnnouncer.h"
-#include "interfaces/AnnouncementUtils.h"
-#include "ITransportLayer.h"
-#include "utils/Variant.h"
 #include "utils/JSONVariantWriter.h"
 #include "utils/JSONVariantParser.h"
 
-
 namespace JSONRPC
 {
   /*!
-   \ingroup jsonrpc
-   \brief Possible statuc codes of a response
-   to a JSON RPC request
-   */
-  enum JSON_STATUS
-  {
-    OK = 0,
-    ACK = -1,
-    InvalidRequest = -32600,
-    MethodNotFound = -32601,
-    InvalidParams = -32602,
-    InternalError = -32603,
-    ParseError = -32700,
-    //-32099..-32000 Reserved for implementation-defined server-errors.
-    BadPermission = -32099,
-    FailedToExecute = -32100
-  };
-
-  /*!
-   \brief Function pointer for json rpc methods
-   */
-  typedef JSON_STATUS (*MethodCall) (const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
-
-  /*!
-   \ingroup jsonrpc
-   \brief Permission categories for json rpc methods
-   
-   A json rpc method will only be called if the caller 
-   has the correct permissions to exectue the method.
-   The method call needs to be perfectly threadsafe.
-  */
-  enum OperationPermission
-  {
-    ReadData        =   0x1,
-    ControlPlayback =   0x2,
-    ControlNotify   =   0x4,
-    ControlPower    =   0x8,
-    UpdateData      =  0x10,
-    RemoveData      =  0x20,
-    Navigate        =  0x40,
-    WriteFile       =  0x80
-  };
-
-  static const int OPERATION_PERMISSION_ALL = (ReadData | ControlPlayback | ControlNotify | ControlPower | UpdateData | RemoveData | Navigate | WriteFile);
-
-  static const int OPERATION_PERMISSION_NOTIFICATION = (ControlPlayback | ControlNotify | ControlPower | UpdateData | RemoveData | Navigate | WriteFile);
-
-  /*!
    \brief Possible value types of a parameter or return type
    */
   enum JSONSchemaType
@@ -194,63 +143,6 @@ namespace JSONRPC
     }
 
     /*!
-     \brief Returns a string representation for the 
-     given OperationPermission
-     \param permission Specific OperationPermission
-     \return String representation of the given OperationPermission
-     */
-    static inline const char *PermissionToString(const OperationPermission &permission)
-    {
-      switch (permission)
-      {
-      case ReadData:
-        return "ReadData";
-      case ControlPlayback:
-        return "ControlPlayback";
-      case ControlNotify:
-        return "ControlNotify";
-      case ControlPower:
-        return "ControlPower";
-      case UpdateData:
-        return "UpdateData";
-      case RemoveData:
-        return "RemoveData";
-      case Navigate:
-        return "Navigate";
-      case WriteFile:
-        return "WriteFile";
-      default:
-        return "Unknown";
-      }
-    }
-
-    /*!
-     \brief Returns a OperationPermission value for the given
-     string representation
-     \param permission String representation of the OperationPermission
-     \return OperationPermission value of the given string representation
-     */
-    static inline OperationPermission StringToPermission(std::string permission)
-    {
-      if (permission.compare("ControlPlayback") == 0)
-        return ControlPlayback;
-      if (permission.compare("ControlNotify") == 0)
-        return ControlNotify;
-      if (permission.compare("ControlPower") == 0)
-        return ControlPower;
-      if (permission.compare("UpdateData") == 0)
-        return UpdateData;
-      if (permission.compare("RemoveData") == 0)
-        return RemoveData;
-      if (permission.compare("Navigate") == 0)
-        return Navigate;
-      if (permission.compare("WriteFile") == 0)
-        return WriteFile;
-
-      return ReadData;
-    }
-
-    /*!
      \brief Returns a TransportLayerCapability value of the
      given string representation
      \param transport String representation of the TransportLayerCapability
@@ -477,25 +369,10 @@ namespace JSONRPC
           value = CVariant(CVariant::VariantTypeObject);
           break;
         default:
-          value = CVariant(CVariant::VariantTypeConstNull);
+          value = CVariant(CVariant::VariantTypeNull);
       }
     }
 
     static inline bool HasType(JSONSchemaType typeObject, JSONSchemaType type) { return (typeObject & type) == type; }
-
-    static std::string AnnouncementToJSON(ANNOUNCEMENT::EAnnouncementFlag flag, const char *sender, const char *method, const CVariant &data, bool compactOutput)
-    {
-      CVariant root;
-      root["jsonrpc"] = "2.0";
-
-      CStdString namespaceMethod;
-      namespaceMethod.Format("%s.%s", ANNOUNCEMENT::CAnnouncementUtils::AnnouncementFlagToString(flag), method);
-      root["method"]  = namespaceMethod.c_str();
-
-      root["params"]["data"] = data;
-      root["params"]["sender"] = sender;
-
-      return CJSONVariantWriter::Write(root, compactOutput);
-    }
   };
 }
index 648ec24..5c722a4 100644 (file)
@@ -2,6 +2,7 @@ SRCS=ApplicationOperations.cpp \
      AudioLibrary.cpp \
      FileItemHandler.cpp \
      FileOperations.cpp \
+                GUIOperations.cpp \
      JSONRPC.cpp \
      JSONServiceDescription.cpp \
      PlayerOperations.cpp \
index b05bea0..e02d1f0 100644 (file)
 #include "VideoLibrary.h"
 #include "video/VideoDatabase.h"
 #include "AudioLibrary.h"
+#include "GUIInfoManager.h"
 
 using namespace JSONRPC;
 using namespace PLAYLIST;
 
-JSON_STATUS CPlayerOperations::GetActivePlayers(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::GetActivePlayers(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int activePlayers = GetActivePlayers();
   result = CVariant(CVariant::VariantTypeArray);
@@ -68,7 +69,7 @@ JSON_STATUS CPlayerOperations::GetActivePlayers(const CStdString &method, ITrans
   return OK;
 }
 
-JSON_STATUS CPlayerOperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   PlayerType player = GetPlayer(parameterObject["playerid"]);
 
@@ -77,7 +78,7 @@ JSON_STATUS CPlayerOperations::GetProperties(const CStdString &method, ITranspor
   {
     CStdString propertyName = parameterObject["properties"][index].asString();
     CVariant property;
-    JSON_STATUS ret;
+    JSONRPC_STATUS ret;
     if ((ret = GetPropertyValue(player, propertyName, property)) != OK)
       return ret;
 
@@ -89,7 +90,7 @@ JSON_STATUS CPlayerOperations::GetProperties(const CStdString &method, ITranspor
   return OK;
 }
 
-JSON_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   PlayerType player = GetPlayer(parameterObject["playerid"]);
   CFileItemPtr fileItem;
@@ -101,11 +102,23 @@ JSON_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLayer
     {
       if (g_application.CurrentFileItem().GetLabel().empty())
       {
-        CFileItem tmpItem;
+        CFileItem tmpItem = g_application.CurrentFileItem();
         if (player == Video)
-          CVideoLibrary::FillFileItem(g_application.CurrentFile(), tmpItem);
+        {
+          if (!CVideoLibrary::FillFileItem(g_application.CurrentFile(), tmpItem))
+          {
+            tmpItem = CFileItem(*g_infoManager.GetCurrentMovieTag());
+            tmpItem.SetPath(g_application.CurrentFileItem().GetPath());
+          }
+        }
         else
-          CAudioLibrary::FillFileItem(g_application.CurrentFile(), tmpItem);
+        {
+          if (!CAudioLibrary::FillFileItem(g_application.CurrentFile(), tmpItem))
+          {
+            tmpItem = CFileItem(*g_infoManager.GetCurrentSongTag());
+            tmpItem.SetPath(g_application.CurrentFileItem().GetPath());
+          }
+        }
 
         fileItem = CFileItemPtr(new CFileItem(tmpItem));
       }
@@ -175,20 +188,30 @@ JSON_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLayer
   return OK;
 }
 
-JSON_STATUS CPlayerOperations::PlayPause(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::PlayPause(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CGUIWindowSlideShow *slideshow = NULL;
   switch (GetPlayer(parameterObject["playerid"]))
   {
     case Video:
     case Audio:
-      CBuiltins::Execute("playercontrol(play)");
+      if (parameterObject["play"].isString())
+        CBuiltins::Execute("playercontrol(play)");
+      else
+      {
+        if (parameterObject["play"].asBoolean() == g_application.IsPaused())
+          g_application.getApplicationMessenger().MediaPause();
+      }
       result["speed"] = g_application.IsPaused() ? 0 : g_application.GetPlaySpeed();
       return OK;
 
     case Picture:
-      SendSlideshowAction(ACTION_PAUSE);
       slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
+      if (slideshow && slideshow->IsPlaying() &&
+         (parameterObject["play"].isString() ||
+         (parameterObject["play"].isBoolean() && parameterObject["play"].asBoolean() == slideshow->IsPaused())))
+        SendSlideshowAction(ACTION_PAUSE);
+
       if (slideshow && slideshow->IsPlaying() && !slideshow->IsPaused())
         result["speed"] = slideshow->GetDirection();
       else
@@ -201,7 +224,7 @@ JSON_STATUS CPlayerOperations::PlayPause(const CStdString &method, ITransportLay
   }
 }
 
-JSON_STATUS CPlayerOperations::Stop(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::Stop(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -220,7 +243,7 @@ JSON_STATUS CPlayerOperations::Stop(const CStdString &method, ITransportLayer *t
   }
 }
 
-JSON_STATUS CPlayerOperations::SetSpeed(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::SetSpeed(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int speed;
   switch (GetPlayer(parameterObject["playerid"]))
@@ -261,7 +284,7 @@ JSON_STATUS CPlayerOperations::SetSpeed(const CStdString &method, ITransportLaye
   }
 }
 
-JSON_STATUS CPlayerOperations::Seek(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::Seek(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   PlayerType player = GetPlayer(parameterObject["playerid"]);
   switch (player)
@@ -269,8 +292,7 @@ JSON_STATUS CPlayerOperations::Seek(const CStdString &method, ITransportLayer *t
     case Video:
     case Audio:
       if (parameterObject["value"].isObject())
-        g_application.SeekTime(((parameterObject["value"]["hours"].asInteger() * 60) + parameterObject["value"]["minutes"].asInteger()) * 60 + 
-          parameterObject["value"]["seconds"].asInteger() + ((double)parameterObject["value"]["milliseconds"].asInteger() / 1000.0));
+        g_application.SeekTime(ParseTimeInSeconds(parameterObject["value"]));
       else if (IsType(parameterObject["value"], NumberValue))
         g_application.SeekPercentage(parameterObject["value"].asFloat());
       else if (parameterObject["value"].isString())
@@ -302,7 +324,7 @@ JSON_STATUS CPlayerOperations::Seek(const CStdString &method, ITransportLayer *t
   }
 }
 
-JSON_STATUS CPlayerOperations::MoveLeft(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::MoveLeft(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -318,7 +340,7 @@ JSON_STATUS CPlayerOperations::MoveLeft(const CStdString &method, ITransportLaye
   }
 }
 
-JSON_STATUS CPlayerOperations::MoveRight(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::MoveRight(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -334,7 +356,7 @@ JSON_STATUS CPlayerOperations::MoveRight(const CStdString &method, ITransportLay
   }
 }
 
-JSON_STATUS CPlayerOperations::MoveDown(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::MoveDown(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -350,7 +372,7 @@ JSON_STATUS CPlayerOperations::MoveDown(const CStdString &method, ITransportLaye
   }
 }
 
-JSON_STATUS CPlayerOperations::MoveUp(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::MoveUp(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -366,7 +388,7 @@ JSON_STATUS CPlayerOperations::MoveUp(const CStdString &method, ITransportLayer
   }
 }
 
-JSON_STATUS CPlayerOperations::ZoomOut(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::ZoomOut(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -382,7 +404,7 @@ JSON_STATUS CPlayerOperations::ZoomOut(const CStdString &method, ITransportLayer
   }
 }
 
-JSON_STATUS CPlayerOperations::ZoomIn(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::ZoomIn(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -398,7 +420,7 @@ JSON_STATUS CPlayerOperations::ZoomIn(const CStdString &method, ITransportLayer
   }
 }
 
-JSON_STATUS CPlayerOperations::Zoom(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::Zoom(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -414,7 +436,7 @@ JSON_STATUS CPlayerOperations::Zoom(const CStdString &method, ITransportLayer *t
   }
 }
 
-JSON_STATUS CPlayerOperations::Rotate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::Rotate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -430,21 +452,29 @@ JSON_STATUS CPlayerOperations::Rotate(const CStdString &method, ITransportLayer
   }
 }
 
-JSON_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
+  CVariant optionShuffled = parameterObject["options"]["shuffled"];
+  CVariant optionRepeat = parameterObject["options"]["repeat"];
+  CVariant optionResume = parameterObject["options"]["resume"];
+
   if (parameterObject["item"].isObject() && parameterObject["item"].isMember("playlistid"))
   {
     int playlistid = (int)parameterObject["item"]["playlistid"].asInteger();
+
+    if (playlistid < PLAYLIST_PICTURE)
+    {
+      // Apply the "shuffled" option if available
+      if (optionShuffled.isBoolean())
+        g_playlistPlayer.SetShuffle(playlistid, optionShuffled.asBoolean(), false);
+      // Apply the "repeat" option if available
+      if (!optionRepeat.isNull())
+        g_playlistPlayer.SetRepeat(playlistid, (REPEAT_STATE)ParseRepeatState(optionRepeat), false);
+    }
+
     switch (playlistid)
     {
       case PLAYLIST_MUSIC:
-        if (g_playlistPlayer.GetCurrentPlaylist() != playlistid)
-          g_playlistPlayer.SetCurrentPlaylist(playlistid);
-
-        g_application.getApplicationMessenger().PlayListPlayerPlay((int)parameterObject["item"]["position"].asInteger());
-        OnPlaylistChanged();
-        break;
-
       case PLAYLIST_VIDEO:
         g_application.getApplicationMessenger().MediaPlay(playlistid, (int)parameterObject["item"]["position"].asInteger());
         OnPlaylistChanged();
@@ -463,7 +493,8 @@ JSON_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer *t
 
     exec += parameterObject["item"]["path"].asString();
 
-    if (parameterObject["item"]["random"].asBoolean())
+    if ((optionShuffled.isBoolean() && optionShuffled.asBoolean()) ||
+       (!optionShuffled.isBoolean() && parameterObject["item"]["random"].asBoolean()))
       exec += ", random";
     else
       exec += ", notrandom";
@@ -485,7 +516,7 @@ JSON_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer *t
       bool slideshow = true;
       for (int index = 0; index < list.Size(); index++)
       {
-        if (!list[index]->HasPictureInfoTag())
+        if (!list[index]->IsPicture())
         {
           slideshow = false;
           break;
@@ -503,10 +534,32 @@ JSON_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer *t
         for (int index = 0; index < list.Size(); index++)
           slideshow->Add(list[index].get());
 
+        if (optionShuffled.isBoolean() && optionShuffled.asBoolean())
+          slideshow->Shuffle();
+
         return StartSlideshow();
       }
       else
+      {
+        // Handle "shuffled" option
+        if (optionShuffled.isBoolean())
+          list.SetProperty("shuffled", optionShuffled);
+        // Handle "repeat" option
+        if (!optionRepeat.isNull())
+          list.SetProperty("repeat", ParseRepeatState(optionRepeat));
+        // Handle "resume" option
+        if (list.Size() == 1)
+        {
+          if (optionResume.isBoolean() && optionResume.asBoolean())
+            list[0]->m_lStartOffset = STARTOFFSET_RESUME;
+          else if (optionResume.isDouble())
+            list[0]->SetProperty("StartPercent", optionResume);
+          else if (optionResume.isObject())
+            list[0]->m_lStartOffset = (int)(ParseTimeInSeconds(optionResume) * 75.0);
+        }
+
         g_application.getApplicationMessenger().MediaPlay(list);
+      }
 
       return ACK;
     }
@@ -517,7 +570,7 @@ JSON_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer *t
   return InvalidParams;
 }
 
-JSON_STATUS CPlayerOperations::GoPrevious(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::GoPrevious(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -536,7 +589,7 @@ JSON_STATUS CPlayerOperations::GoPrevious(const CStdString &method, ITransportLa
   }
 }
 
-JSON_STATUS CPlayerOperations::GoNext(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::GoNext(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -555,7 +608,7 @@ JSON_STATUS CPlayerOperations::GoNext(const CStdString &method, ITransportLayer
   }
 }
 
-JSON_STATUS CPlayerOperations::GoTo(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::GoTo(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int position = (int)parameterObject["position"].asInteger();
   switch (GetPlayer(parameterObject["playerid"]))
@@ -575,7 +628,7 @@ JSON_STATUS CPlayerOperations::GoTo(const CStdString &method, ITransportLayer *t
   return ACK;
 }
 
-JSON_STATUS CPlayerOperations::Shuffle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::Shuffle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CGUIWindowSlideShow *slideshow = NULL;
   switch (GetPlayer(parameterObject["playerid"]))
@@ -600,7 +653,7 @@ JSON_STATUS CPlayerOperations::Shuffle(const CStdString &method, ITransportLayer
   return ACK;
 }
 
-JSON_STATUS CPlayerOperations::UnShuffle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::UnShuffle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -617,21 +670,13 @@ JSON_STATUS CPlayerOperations::UnShuffle(const CStdString &method, ITransportLay
   return ACK;
 }
 
-JSON_STATUS CPlayerOperations::Repeat(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::Repeat(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  REPEAT_STATE state = REPEAT_NONE;
-  std::string strState = parameterObject["state"].asString();
-  
   switch (GetPlayer(parameterObject["playerid"]))
   {
     case Video:
     case Audio:
-      if (strState.compare("one") == 0)
-        state = REPEAT_ONE;
-      else if (strState.compare("all") == 0)
-        state = REPEAT_ALL;
-
-      g_application.getApplicationMessenger().PlayListPlayerRepeat(GetPlaylist(GetPlayer(parameterObject["playerid"])), state);
+      g_application.getApplicationMessenger().PlayListPlayerRepeat(GetPlaylist(GetPlayer(parameterObject["playerid"])), (REPEAT_STATE)ParseRepeatState(parameterObject["state"]));
       OnPlaylistChanged();
       break;
 
@@ -643,7 +688,7 @@ JSON_STATUS CPlayerOperations::Repeat(const CStdString &method, ITransportLayer
   return ACK;
 }
 
-JSON_STATUS CPlayerOperations::SetAudioStream(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::SetAudioStream(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -690,7 +735,7 @@ JSON_STATUS CPlayerOperations::SetAudioStream(const CStdString &method, ITranspo
   return ACK;
 }
 
-JSON_STATUS CPlayerOperations::SetSubtitle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::SetSubtitle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   switch (GetPlayer(parameterObject["playerid"]))
   {
@@ -733,6 +778,10 @@ JSON_STATUS CPlayerOperations::SetSubtitle(const CStdString &method, ITransportL
           return InvalidParams;
 
         g_application.m_pPlayer->SetSubtitle(index);
+
+        // Check if we need to enable subtitles to be displayed
+        if (parameterObject["enable"].asBoolean() && !g_application.m_pPlayer->GetSubtitleVisible())
+          g_application.m_pPlayer->SetSubtitleVisible(true);
       }
       else
         return FailedToExecute;
@@ -816,10 +865,10 @@ int CPlayerOperations::GetPlaylist(PlayerType player)
   }
 }
 
-JSON_STATUS CPlayerOperations::StartSlideshow()
+JSONRPC_STATUS CPlayerOperations::StartSlideshow()
 {
   CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
-  if (!slideshow && slideshow->NumSlides() <= 0)
+  if (!slideshow || slideshow->NumSlides() <= 0)
     return FailedToExecute;
 
   if (g_application.IsPlayingVideo())
@@ -849,7 +898,7 @@ void CPlayerOperations::OnPlaylistChanged()
   g_windowManager.SendThreadMessage(msg);
 }
 
-JSON_STATUS CPlayerOperations::GetPropertyValue(PlayerType player, const CStdString &property, CVariant &result)
+JSONRPC_STATUS CPlayerOperations::GetPropertyValue(PlayerType player, const CStdString &property, CVariant &result)
 {
   if (player == None)
     return FailedToExecute;
@@ -1304,3 +1353,34 @@ JSON_STATUS CPlayerOperations::GetPropertyValue(PlayerType player, const CStdStr
 
   return OK;
 }
+
+int CPlayerOperations::ParseRepeatState(const CVariant &repeat)
+{
+  REPEAT_STATE state = REPEAT_NONE;
+  std::string strState = repeat.asString();
+
+  if (strState.compare("one") == 0)
+    state = REPEAT_ONE;
+  else if (strState.compare("all") == 0)
+    state = REPEAT_ALL;
+
+  return state;
+}
+
+double CPlayerOperations::ParseTimeInSeconds(const CVariant &time)
+{
+  double seconds = 0.0;
+  if (time.isObject())
+  {
+    if (time.isMember("hours"))
+      seconds += time["hours"].asInteger() * 60 * 60;
+    if (time.isMember("minutes"))
+      seconds += time["minutes"].asInteger() * 60;
+    if (time.isMember("seconds"))
+      seconds += time["seconds"].asInteger();
+    if (time.isMember("milliseconds"))
+      seconds += time["milliseconds"].asDouble() / 1000.0;
+  }
+
+  return seconds;
+}
index 5a40a3e..ebe45e2 100644 (file)
@@ -39,42 +39,45 @@ namespace JSONRPC
   class CPlayerOperations : CFileItemHandler
   {
   public:
-    static JSON_STATUS GetActivePlayers(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetItem(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetActivePlayers(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetItem(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS PlayPause(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Stop(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS SetSpeed(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Seek(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS PlayPause(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Stop(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS SetSpeed(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Seek(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS MoveLeft(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS MoveRight(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS MoveDown(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS MoveUp(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS MoveLeft(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS MoveRight(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS MoveDown(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS MoveUp(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS ZoomOut(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS ZoomIn(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Zoom(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Rotate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS ZoomOut(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS ZoomIn(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Zoom(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Rotate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
     
-    static JSON_STATUS Open(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GoPrevious(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GoNext(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GoTo(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Shuffle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS UnShuffle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Repeat(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Open(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GoPrevious(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GoNext(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GoTo(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Shuffle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS UnShuffle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Repeat(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
     
-    static JSON_STATUS SetAudioStream(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS SetSubtitle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS SetAudioStream(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS SetSubtitle(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
   private:
     static int GetActivePlayers();
     static PlayerType GetPlayer(const CVariant &player);
     static int GetPlaylist(PlayerType player);
-    static JSON_STATUS StartSlideshow();
+    static JSONRPC_STATUS StartSlideshow();
     static void SendSlideshowAction(int actionID);
     static void OnPlaylistChanged();
-    static JSON_STATUS GetPropertyValue(PlayerType player, const CStdString &property, CVariant &result);
+    static JSONRPC_STATUS GetPropertyValue(PlayerType player, const CStdString &property, CVariant &result);
+
+    static int ParseRepeatState(const CVariant &repeat);
+    static double ParseTimeInSeconds(const CVariant &time);
   };
 }
index 79831b5..9d07201 100644 (file)
@@ -33,7 +33,7 @@ using namespace JSONRPC;
 using namespace PLAYLIST;
 using namespace std;
 
-JSON_STATUS CPlaylistOperations::GetPlaylists(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlaylistOperations::GetPlaylists(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   result = CVariant(CVariant::VariantTypeArray);
   CVariant playlist = CVariant(CVariant::VariantTypeObject);
@@ -53,14 +53,14 @@ JSON_STATUS CPlaylistOperations::GetPlaylists(const CStdString &method, ITranspo
   return OK;
 }
 
-JSON_STATUS CPlaylistOperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlaylistOperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int playlist = GetPlaylist(parameterObject["playlistid"]);
   for (unsigned int index = 0; index < parameterObject["properties"].size(); index++)
   {
     CStdString propertyName = parameterObject["properties"][index].asString();
     CVariant property;
-    JSON_STATUS ret;
+    JSONRPC_STATUS ret;
     if ((ret = GetPropertyValue(playlist, propertyName, property)) != OK)
       return ret;
 
@@ -70,7 +70,7 @@ JSON_STATUS CPlaylistOperations::GetProperties(const CStdString &method, ITransp
   return OK;
 }
 
-JSON_STATUS CPlaylistOperations::GetItems(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlaylistOperations::GetItems(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CFileItemList list;
   int playlist = GetPlaylist(parameterObject["playlistid"]);
@@ -95,7 +95,7 @@ JSON_STATUS CPlaylistOperations::GetItems(const CStdString &method, ITransportLa
   return OK;
 }
 
-JSON_STATUS CPlaylistOperations::Add(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlaylistOperations::Add(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int playlist = GetPlaylist(parameterObject["playlistid"]);
   CFileItemList list;
@@ -145,7 +145,7 @@ JSON_STATUS CPlaylistOperations::Add(const CStdString &method, ITransportLayer *
   return ACK;
 }
 
-JSON_STATUS CPlaylistOperations::Insert(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlaylistOperations::Insert(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int playlist = GetPlaylist(parameterObject["playlistid"]);
   if (playlist == PLAYLIST_PICTURE)
@@ -169,7 +169,7 @@ JSON_STATUS CPlaylistOperations::Insert(const CStdString &method, ITransportLaye
   return ACK;
 }
 
-JSON_STATUS CPlaylistOperations::Remove(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlaylistOperations::Remove(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int playlist = GetPlaylist(parameterObject["playlistid"]);
   if (playlist == PLAYLIST_PICTURE)
@@ -185,7 +185,7 @@ JSON_STATUS CPlaylistOperations::Remove(const CStdString &method, ITransportLaye
   return ACK;
 }
 
-JSON_STATUS CPlaylistOperations::Clear(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlaylistOperations::Clear(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int playlist = GetPlaylist(parameterObject["playlistid"]);
   CGUIWindowSlideShow *slideshow = NULL;
@@ -209,7 +209,7 @@ JSON_STATUS CPlaylistOperations::Clear(const CStdString &method, ITransportLayer
   return ACK;
 }
 
-JSON_STATUS CPlaylistOperations::Swap(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CPlaylistOperations::Swap(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int playlist = GetPlaylist(parameterObject["playlistid"]);
   if (playlist == PLAYLIST_PICTURE)
@@ -236,7 +236,7 @@ void CPlaylistOperations::NotifyAll()
   g_windowManager.SendThreadMessage(msg);
 }
 
-JSON_STATUS CPlaylistOperations::GetPropertyValue(int playlist, const CStdString &property, CVariant &result)
+JSONRPC_STATUS CPlaylistOperations::GetPropertyValue(int playlist, const CStdString &property, CVariant &result)
 {
   if (property.Equals("type"))
   {
index a86ed90..f89ef39 100644 (file)
@@ -29,18 +29,18 @@ namespace JSONRPC
   class CPlaylistOperations : public CFileItemHandler
   {
   public:
-    static JSON_STATUS GetPlaylists(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetPlaylists(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS GetItems(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Add(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Remove(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result); 
-    static JSON_STATUS Insert(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Clear(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Swap(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetItems(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Add(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Remove(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result); 
+    static JSONRPC_STATUS Insert(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Clear(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Swap(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
   private:
     static int GetPlaylist(const CVariant &playlist);
     static inline void NotifyAll();
-    static JSON_STATUS GetPropertyValue(int playlist, const CStdString &property, CVariant &result);
+    static JSONRPC_STATUS GetPropertyValue(int playlist, const CStdString &property, CVariant &result);
   };
 }
index ca4d4cc..be71f5e 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 /*
- *      Copyright (C) 2005-2010 Team XBMC
+ *      Copyright (C) 2005-2012 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
@@ -23,7 +23,7 @@
 namespace JSONRPC
 {
   const char* const JSONRPC_SERVICE_ID          = "http://www.xbmc.org/jsonrpc/ServiceDescription.json";
-  const int         JSONRPC_SERVICE_VERSION     = 4;
+  const int         JSONRPC_SERVICE_VERSION     = 5;
   const char* const JSONRPC_SERVICE_DESCRIPTION = "JSON-RPC API of XBMC";
 
   const char* const JSONRPC_SERVICE_TYPES[] = {  
@@ -49,6 +49,16 @@ namespace JSONRPC
       "},"
       "\"additionalProperties\": false"
     "}",
+    "\"Global.IncrementDecrement\": {"
+      "\"type\": \"string\","
+      "\"enum\": [ \"increment\", \"decrement\" ]"
+    "}",
+    "\"Global.Toggle\": {"
+      "\"type\": ["
+        "{ \"type\": \"boolean\", \"required\": true },"
+        "{ \"type\": \"string\", \"enum\": [ \"toggle\" ], \"required\": true }"
+      "]"
+    "}",
     "\"Configuration.Notifications\": {"
       "\"type\": \"object\","
       "\"properties\": {"
@@ -126,6 +136,16 @@ namespace JSONRPC
       "\"minimum\": 0.0,"
       "\"maximum\": 100.0"
     "}",
+    "\"Player.Position.Time\": {"
+      "\"type\": \"object\","
+      "\"additionalProperties\": false,"
+      "\"properties\": {"
+        "\"hours\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 23, \"default\": 0 },"
+        "\"minutes\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 59, \"default\": 0 },"
+        "\"seconds\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 59, \"default\": 0 },"
+        "\"milliseconds\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 999, \"default\": 0 }"
+      "}"
+    "}",
     "\"Player.Speed\": {"
       "\"type\": \"object\","
       "\"required\": true,"
@@ -403,7 +423,7 @@ namespace JSONRPC
                   "\"playcount\", \"writer\", \"studio\", \"mpaa\", \"cast\", \"country\","
                   "\"imdbnumber\", \"premiered\", \"productioncode\", \"runtime\", \"set\","
                   "\"showlink\", \"streamdetails\", \"top250\", \"votes\", \"fanart\","
-                  "\"thumbnail\", \"file\", \"sorttitle\", \"resume\", \"setid\" ]"
+                  "\"thumbnail\", \"file\", \"sorttitle\", \"resume\", \"setid\", \"dateadded\" ]"
       "}"
     "}",
     "\"Video.Fields.MovieSet\": {"
@@ -420,13 +440,15 @@ namespace JSONRPC
                   "\"studio\", \"mpaa\", \"cast\", \"playcount\", \"episode\","
                   "\"imdbnumber\", \"premiered\", \"votes\", \"lastplayed\","
                   "\"fanart\", \"thumbnail\", \"file\", \"originaltitle\","
-                  "\"sorttitle\", \"episodeguide\" ]"
+                  "\"sorttitle\", \"episodeguide\", \"season\", \"watchedepisodes\","
+                  "\"dateadded\"]"
       "}"
     "}",
     "\"Video.Fields.Season\": {"
       "\"extends\": \"Item.Fields.Base\","
       "\"items\": { \"type\": \"string\","
-        "\"enum\": [ \"season\", \"showtitle\", \"playcount\", \"episode\", \"fanart\", \"thumbnail\", \"tvshowid\" ]"
+        "\"enum\": [ \"season\", \"showtitle\", \"playcount\", \"episode\", \"fanart\", \"thumbnail\", \"tvshowid\","
+                  "\"watchedepisodes\" ]"
       "}"
     "}",
     "\"Video.Fields.Episode\": {"
@@ -437,7 +459,7 @@ namespace JSONRPC
                   "\"firstaired\", \"playcount\", \"runtime\", \"director\","
                   "\"productioncode\", \"season\", \"episode\", \"originaltitle\","
                   "\"showtitle\", \"cast\", \"streamdetails\", \"lastplayed\", \"fanart\","
-                  "\"thumbnail\", \"file\", \"resume\", \"tvshowid\" ]"
+                  "\"thumbnail\", \"file\", \"resume\", \"tvshowid\", \"dateadded\" ]"
       "}"
     "}",
     "\"Video.Fields.MusicVideo\": {"
@@ -447,7 +469,7 @@ namespace JSONRPC
         "\"enum\": [ \"title\", \"playcount\", \"runtime\", \"director\","
                   "\"studio\", \"year\", \"plot\", \"album\", \"artist\","
                   "\"genre\", \"track\", \"streamdetails\", \"lastplayed\","
-                  "\"fanart\", \"thumbnail\", \"file\", \"resume\" ]"
+                  "\"fanart\", \"thumbnail\", \"file\", \"resume\", \"dateadded\" ]"
       "}"
     "}",
     "\"Video.Cast\": {"
@@ -522,7 +544,8 @@ namespace JSONRPC
       "\"properties\": {"
         "\"file\": { \"type\": \"string\" },"
         "\"plot\": { \"type\": \"string\" },"
-        "\"lastplayed\": { \"type\": \"string\" }"
+        "\"lastplayed\": { \"type\": \"string\" },"
+        "\"dateadded\": { \"type\": \"string\" }"
       "}"
     "}",
     "\"Video.Details.File\": {"
@@ -588,10 +611,12 @@ namespace JSONRPC
         "\"mpaa\": { \"type\": \"string\" },"
         "\"cast\": { \"$ref\": \"Video.Cast\" },"
         "\"episode\": { \"type\": \"integer\" },"
+        "\"watchedepisodes\": { \"type\": \"integer\" },"
         "\"imdbnumber\": { \"type\": \"string\" },"
         "\"premiered\": { \"type\": \"string\" },"
         "\"votes\": { \"type\": \"string\" },"
-        "\"episodeguide\": { \"type\": \"string\" }"
+        "\"episodeguide\": { \"type\": \"string\" },"
+        "\"season\": { \"type\": \"integer\" }"
       "}"
     "}",
     "\"Video.Details.Season\": {"
@@ -600,6 +625,7 @@ namespace JSONRPC
         "\"season\": { \"type\": \"integer\", \"required\": true },"
         "\"showtitle\": { \"type\": \"string\" },"
         "\"episode\": { \"type\": \"integer\" },"
+        "\"watchedepisodes\": { \"type\": \"integer\" },"
         "\"tvshowid\": { \"$ref\": \"Library.Id\" }"
       "}"
     "}",
@@ -645,7 +671,7 @@ namespace JSONRPC
       "\"type\": \"object\","
       "\"properties\": {"
         "\"start\": { \"type\": \"integer\", \"minimum\": 0, \"default\": 0 },"
-        "\"end\": { \"type\": \"integer\", \"minimum\": 0, \"default\": -1 }"
+        "\"end\": { \"type\": \"integer\", \"minimum\": 0, \"default\": -1, \"description\": \"The number of items in the list being returned\" }"
       "},"
       "\"additionalProperties\": false"
     "}",
@@ -654,9 +680,9 @@ namespace JSONRPC
       "\"properties\": {"
         "\"method\": { \"type\": \"string\", \"default\": \"none\","
           "\"enum\": [ \"none\", \"label\", \"date\", \"size\", \"file\", \"drivetype\", \"track\", \"duration\", \"title\", \"artist\","
-                    "\"album\", \"genre\", \"year\", \"videorating\", \"programcount\", \"playlist\", \"episode\", \"videotitle\","
-                    "\"sorttitle\", \"productioncode\", \"songrating\", \"mpaarating\", \"videoruntime\", \"studio\", \"fullpath\","
-                    "\"lastplayed\", \"unsorted\" ]"
+                    "\"album\", \"genre\", \"country\", \"year\", \"videorating\", \"dateadded\", \"programcount\", \"playlist\","
+                    "\"episode\", \"videotitle\", \"sorttitle\", \"productioncode\", \"songrating\", \"mpaarating\", \"videoruntime\","
+                    "\"studio\", \"fullpath\", \"lastplayed\", \"playcount\", \"listeners\", \"bitrate\", \"unsorted\" ]"
         "},"
         "\"order\": { \"type\": \"string\", \"default\": \"ascending\", \"enum\": [ \"ascending\", \"descending\" ] },"
         "\"ignorearticle\": { \"type\": \"boolean\", \"default\": false }"
@@ -682,7 +708,7 @@ namespace JSONRPC
                   "\"mpaa\", \"cast\", \"country\", \"imdbnumber\", \"premiered\", \"productioncode\","
                   "\"runtime\", \"set\", \"showlink\", \"streamdetails\", \"top250\", \"votes\","
                   "\"firstaired\", \"season\", \"episode\", \"showtitle\", \"thumbnail\", \"file\","
-                  "\"resume\", \"artistid\", \"albumid\", \"tvshowid\", \"setid\" ]"
+                  "\"resume\", \"artistid\", \"albumid\", \"tvshowid\", \"setid\", \"watchedepisodes\" ]"
       "}"
     "}",
     "\"List.Item.All\": {"
@@ -721,14 +747,33 @@ namespace JSONRPC
         "\"artistid\": { \"$ref\": \"Library.Id\" },"
         "\"albumid\": { \"$ref\": \"Library.Id\" },"
         "\"setid\": { \"$ref\": \"Array.Integer\" },"
-        "\"tvshowid\": { \"$ref\": \"Library.Id\" }"
+        "\"tvshowid\": { \"$ref\": \"Library.Id\" },"
+        "\"watchedepisodes\": { \"type\": \"integer\" }"
+      "}"
+    "}",
+    "\"List.Fields.Files\": {"
+      "\"extends\": \"Item.Fields.Base\","
+      "\"items\": { \"type\": \"string\","
+        "\"enum\": [ \"title\", \"artist\", \"albumartist\", \"genre\", \"year\", \"rating\","
+                  "\"album\", \"track\", \"duration\", \"comment\", \"lyrics\", \"musicbrainztrackid\","
+                  "\"musicbrainzartistid\", \"musicbrainzalbumid\", \"musicbrainzalbumartistid\","
+                  "\"playcount\", \"fanart\", \"director\", \"trailer\", \"tagline\", \"plot\","
+                  "\"plotoutline\", \"originaltitle\", \"lastplayed\", \"writer\", \"studio\","
+                  "\"mpaa\", \"cast\", \"country\", \"imdbnumber\", \"premiered\", \"productioncode\","
+                  "\"runtime\", \"set\", \"showlink\", \"streamdetails\", \"top250\", \"votes\","
+                  "\"firstaired\", \"season\", \"episode\", \"showtitle\", \"thumbnail\", \"file\","
+                  "\"resume\", \"artistid\", \"albumid\", \"tvshowid\", \"setid\", \"size\","
+                  "\"lastmodified\", \"mimetype\", \"watchedepisodes\" ]"
       "}"
     "}",
     "\"List.Item.File\": {"
       "\"extends\": \"List.Item.All\","
       "\"properties\": {"
         "\"file\": { \"type\": \"string\", \"required\": true },"
-        "\"filetype\": { \"type\": \"string\", \"enum\": [ \"file\", \"directory\" ], \"required\": true }"
+        "\"filetype\": { \"type\": \"string\", \"enum\": [ \"file\", \"directory\" ], \"required\": true },"
+        "\"size\": { \"type\": \"integer\", \"description\": \"Size of the file in kB (1000 Byte)\" },"
+        "\"lastmodified\": { \"type\": \"string\" },"
+        "\"mimetype\": { \"type\": \"string\" }"
       "}"
     "}",
     "\"List.Items.Sources\": {"
@@ -740,6 +785,33 @@ namespace JSONRPC
         "}"
       "}"
     "}",
+    "\"GUI.Property.Name\": {"
+      "\"type\": \"string\","
+      "\"enum\": [ \"currentwindow\", \"currentcontrol\", \"skin\", \"fullscreen\" ]"
+    "}",
+    "\"GUI.Property.Value\": {"
+      "\"type\": \"object\","
+      "\"properties\": {"
+        "\"currentwindow\": { \"type\": \"object\","
+          "\"properties\": {"
+            "\"id\": { \"type\": \"integer\", \"required\": true },"
+            "\"label\": { \"type\": \"string\", \"required\": true }"
+          "}"
+        "},"
+        "\"currentcontrol\": { \"type\": \"object\","
+          "\"properties\": {"
+            "\"label\": { \"type\": \"string\", \"required\": true }"
+          "}"
+        "},"
+        "\"skin\": { \"type\": \"object\","
+          "\"properties\": {"
+            "\"id\": { \"type\": \"string\", \"required\": true, \"minLength\": 1 },"
+            "\"name\": { \"type\": \"string\" }"
+          "}"
+        "},"
+        "\"fullscreen\": { \"type\": \"boolean\" }"
+      "}"
+    "}",
     "\"System.Property.Name\": {"
       "\"type\": \"string\","
       "\"enum\": [ \"canshutdown\", \"cansuspend\", \"canhibernate\", \"canreboot\" ]"
@@ -760,7 +832,7 @@ namespace JSONRPC
     "\"Application.Property.Value\": {"
       "\"type\": \"object\","
       "\"properties\": {"
-        "\"volume\": { \"type\": \"integer\" },"
+        "\"volume\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 100 },"
         "\"muted\": { \"type\": \"boolean\" },"
         "\"name\": { \"type\": \"string\", \"minLength\": 1 },"
         "\"version\": { \"type\": \"object\","
@@ -819,7 +891,9 @@ namespace JSONRPC
           "\"UpdateData\": { \"type\": \"boolean\", \"required\": true },"
           "\"RemoveData\": { \"type\": \"boolean\", \"required\": true },"
           "\"Navigate\": { \"type\": \"boolean\", \"required\": true },"
-          "\"WriteFile\": { \"type\": \"boolean\", \"required\": true }"
+          "\"WriteFile\": { \"type\": \"boolean\", \"required\": true },"
+          "\"ControlSystem\": { \"type\": \"boolean\", \"required\": true },"
+          "\"ControlGUI\": { \"type\": \"boolean\", \"required\": true }"
         "}"
       "}"
     "}",
@@ -852,6 +926,7 @@ namespace JSONRPC
             "\"System\": { \"$ref\": \"Optional.Boolean\" },"
             "\"AudioLibrary\": { \"$ref\": \"Optional.Boolean\" },"
             "\"VideoLibrary\": { \"$ref\": \"Optional.Boolean\" },"
+            "\"Application\": { \"$ref\": \"Optional.Boolean\" },"
             "\"Other\": { \"$ref\": \"Optional.Boolean\" }"
           "}"
         "}"
@@ -876,7 +951,7 @@ namespace JSONRPC
       "\"transport\": \"Response\","
       "\"permission\": \"ControlPlayback\","
       "\"params\": ["
-        "{ \"name\": \"item\", "
+        "{ \"name\": \"item\","
           "\"type\": ["
             "{ \"type\": \"object\", \"required\": true, \"additionalProperties\": false,"
               "\"properties\": {"
@@ -888,11 +963,24 @@ namespace JSONRPC
             "{ \"type\": \"object\", \"required\": true, \"additionalProperties\": false,"
               "\"properties\": {"
                 "\"path\": { \"type\": \"string\", \"required\": true },"
-                "\"random\": { \"type\": \"boolean\", \"default\": true },"
+                "\"random\": { \"type\": \"boolean\", \"default\": true, \"description\": \"Deprecated, use the shuffled property of the options parameter instead\" },"
                 "\"recursive\": { \"type\": \"boolean\", \"default\": true }"
               "}"
             "}"
           "]"
+        "},"
+        "{ \"name\": \"options\", \"type\": \"object\", \"additionalProperties\": false,"
+          "\"properties\": {"
+            "\"shuffled\": { \"$ref\": \"Optional.Boolean\" },"
+            "\"repeat\": { \"type\": [ \"null\", \"Player.Repeat\" ], \"default\": null },"
+            "\"resume\": { \"type\": ["
+                "{ \"type\": \"boolean\", \"required\": true, \"description\": \"Whether to resume from the resume point or not\" },"
+                "{ \"$ref\": \"Player.Position.Percentage\", \"required\": true, \"description\": \"Percentage value to start from\" },"
+                "{ \"$ref\": \"Player.Position.Time\", \"required\": true, \"description\": \"Time to start from\" }"
+              "],"
+              "\"default\": false"
+            "}"
+          "}"
         "}"
       "],"
       "\"returns\": \"string\""
@@ -906,7 +994,7 @@ namespace JSONRPC
       "\"returns\": {"
         "\"type\": \"array\","
         "\"uniqueItems\": true,"
-        "\"items\": { "
+        "\"items\": {"
           "\"type\": \"object\","
           "\"properties\": {"
             "\"playerid\": { \"$ref\": \"Player.Id\", \"required\": true },"
@@ -947,7 +1035,8 @@ namespace JSONRPC
       "\"transport\": \"Response\","
       "\"permission\": \"ControlPlayback\","
       "\"params\": ["
-        "{ \"name\": \"playerid\", \"$ref\": \"Player.Id\", \"required\": true }"
+        "{ \"name\": \"playerid\", \"$ref\": \"Player.Id\", \"required\": true },"
+        "{ \"name\": \"play\", \"$ref\": \"Global.Toggle\", \"default\": \"toggle\" }"
       "],"
       "\"returns\": { \"$ref\": \"Player.Speed\" }"
     "}",
@@ -970,7 +1059,7 @@ namespace JSONRPC
         "{ \"name\": \"playerid\", \"$ref\": \"Player.Id\", \"required\": true },"
         "{ \"name\": \"speed\", \"type\": ["
             "{ \"type\": \"integer\", \"required\": true, \"enum\": [ -32, -16, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 32 ] },"
-            "{ \"type\": \"string\", \"required\": true, \"enum\": [ \"increment\", \"decrement\" ] } "
+            "{ \"$ref\": \"Global.IncrementDecrement\", \"required\": true }"
           "],"
           "\"required\": true"
         "}"
@@ -986,14 +1075,7 @@ namespace JSONRPC
         "{ \"name\": \"playerid\", \"$ref\": \"Player.Id\", \"required\": true },"
         "{ \"name\": \"value\", \"required\": true, \"type\": ["
             "{ \"$ref\": \"Player.Position.Percentage\", \"required\": true, \"description\": \"Percentage value to seek to\" },"
-            "{ \"type\": \"object\", \"additionalProperties\": false, \"required\": true, \"description\": \"Time to seek to\","
-              "\"properties\": {"
-                "\"hours\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 23 },"
-                "\"minutes\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 59 },"
-                "\"seconds\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 59 },"
-                "\"milliseconds\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 999 }"
-              "}"
-            "},"
+            "{ \"$ref\": \"Player.Position.Time\", \"required\": true, \"description\": \"Time to seek to\" },"
             "{ \"type\": \"string\", \"enum\": [ \"smallforward\", \"smallbackward\", \"bigforward\", \"bigbackward\" ], \"required\": true, \"description\": \"Seek by predefined jumps\" }"
           "]"
         "}"
@@ -1176,7 +1258,8 @@ namespace JSONRPC
             "{ \"type\": \"string\", \"enum\": [ \"previous\", \"next\", \"off\", \"on\" ] },"
             "{ \"type\": \"integer\", \"minimum\": 0, \"description\": \"Index of the subtitle to display\" }"
           "]"
-        "}"
+        "},"
+        "{ \"name\": \"enable\", \"type\": \"boolean\", \"default\": false, \"description\": \"Whether to enable subtitles to be displayed after setting the new subtitle\" }"
       "],"
       "\"returns\": \"string\""
     "}",
@@ -1189,7 +1272,7 @@ namespace JSONRPC
       "\"returns\": {"
         "\"type\": \"array\","
         "\"uniqueItems\": true,"
-        "\"items\": { "
+        "\"items\": {"
           "\"type\": \"object\","
           "\"properties\": {"
             "\"playlistid\": { \"$ref\": \"Playlist.Id\", \"required\": true },"
@@ -1336,7 +1419,7 @@ namespace JSONRPC
       "\"params\": ["
         "{ \"name\": \"directory\", \"type\": \"string\", \"required\": true },"
         "{ \"name\": \"media\", \"$ref\": \"Files.Media\", \"default\": \"files\" },"
-        "{ \"name\": \"properties\", \"$ref\": \"List.Fields.All\" },"
+        "{ \"name\": \"properties\", \"$ref\": \"List.Fields.Files\" },"
         "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" }"
       "],"
       "\"returns\": {"
@@ -1500,6 +1583,46 @@ namespace JSONRPC
         "}"
       "}"
     "}",
+      "\"AudioLibrary.GetRecentlyPlayedAlbums\": {"
+      "\"type\": \"method\","
+      "\"description\": \"Retrieve recently played albums\","
+      "\"transport\": \"Response\","
+      "\"permission\": \"ReadData\","
+      "\"params\": ["
+        "{ \"name\": \"properties\", \"$ref\": \"Audio.Fields.Album\" },"
+        "{ \"name\": \"limits\", \"$ref\": \"List.Limits\" },"
+        "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" }"
+      "],"
+      "\"returns\": {"
+        "\"type\": \"object\","
+        "\"properties\": {"
+          "\"limits\": { \"$ref\": \"List.LimitsReturned\", \"required\": true },"
+          "\"albums\": { \"type\": \"array\","
+            "\"items\": { \"$ref\": \"Audio.Details.Album\" }"
+          "}"
+        "}"
+      "}"
+    "}",
+    "\"AudioLibrary.GetRecentlyPlayedSongs\": {"
+      "\"type\": \"method\","
+      "\"description\": \"Retrieve recently played songs\","
+      "\"transport\": \"Response\","
+      "\"permission\": \"ReadData\","
+      "\"params\": ["
+        "{ \"name\": \"properties\", \"$ref\": \"Audio.Fields.Song\" },"
+        "{ \"name\": \"limits\", \"$ref\": \"List.Limits\" },"
+        "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" }"
+      "],"
+      "\"returns\": {"
+        "\"type\": \"object\","
+        "\"properties\": {"
+          "\"limits\": { \"$ref\": \"List.LimitsReturned\", \"required\": true },"
+          "\"songs\": { \"type\": \"array\","
+            "\"items\": { \"$ref\": \"Audio.Details.Song\" }"
+          "}"
+        "}"
+      "}"
+    "}",
     "\"AudioLibrary.GetGenres\": {"
       "\"type\": \"method\","
       "\"description\": \"Retrieve all genres\","
@@ -1525,7 +1648,9 @@ namespace JSONRPC
       "\"description\": \"Scans the audio sources for new library items\","
       "\"transport\": \"Response\","
       "\"permission\": \"UpdateData\","
-      "\"params\": [],"
+      "\"params\": ["
+        "{ \"name\": \"directory\", \"type\": \"string\", \"default\": \"\" }"
+      "],"
       "\"returns\": \"string\""
     "}",
     "\"AudioLibrary.Export\": {"
@@ -1844,7 +1969,9 @@ namespace JSONRPC
       "\"description\": \"Scans the video sources for new library items\","
       "\"transport\": \"Response\","
       "\"permission\": \"UpdateData\","
-      "\"params\": [],"
+      "\"params\": ["
+        "{ \"name\": \"directory\", \"type\": \"string\", \"default\": \"\" }"
+      "],"
       "\"returns\": \"string\""
     "}",
     "\"VideoLibrary.Export\": {"
@@ -1879,6 +2006,43 @@ namespace JSONRPC
       "\"params\": [ ],"
       "\"returns\": \"string\""
     "}",
+    "\"GUI.ShowNotification\": {"
+      "\"type\": \"method\","
+      "\"description\": \"Shows a GUI notification\","
+      "\"transport\": \"Response\","
+      "\"permission\": \"ControlGUI\","
+      "\"params\": ["
+        "{ \"name\": \"title\", \"type\": \"string\", \"required\": true },"
+        "{ \"name\": \"message\", \"type\": \"string\", \"required\": true },"
+        "{ \"name\": \"image\", \"type\": ["
+            "{ \"type\": \"string\", \"required\": true, \"enum\": [ \"info\", \"warning\", \"error\" ] },"
+            "{ \"type\": \"string\", \"required\": true }"
+          "], \"default\": \"\""
+        "},"
+        "{ \"name\": \"displaytime\", \"type\": \"integer\", \"minimum\": 1500, \"default\": 5000, \"description\": \"The time in milliseconds the notification will be visible\" }"
+      "],"
+      "\"returns\":  { \"$ref\": \"System.Property.Value\", \"required\": true }"
+    "}",
+    "\"GUI.GetProperties\": {"
+      "\"type\": \"method\","
+      "\"description\": \"Retrieves the values of the given properties\","
+      "\"transport\": \"Response\","
+      "\"permission\": \"ReadData\","
+      "\"params\": ["
+        "{ \"name\": \"properties\", \"type\": \"array\", \"uniqueItems\": true, \"required\": true, \"items\": { \"$ref\": \"GUI.Property.Name\" } }"
+      "],"
+      "\"returns\":  { \"$ref\": \"GUI.Property.Value\", \"required\": true }"
+    "}",
+    "\"GUI.SetFullscreen\": {"
+      "\"type\": \"method\","
+      "\"description\": \"Toggle fullscreen/GUI\","
+      "\"transport\": \"Response\","
+      "\"permission\": \"ControlGUI\","
+      "\"params\": ["
+        "{ \"name\": \"fullscreen\", \"required\": true, \"$ref\": \"Global.Toggle\" }"
+      "],"
+      "\"returns\": { \"type\": \"boolean\", \"description\": \"Fullscreen state\" }"
+    "}",
     "\"System.GetProperties\": {"
       "\"type\": \"method\","
       "\"description\": \"Retrieves the values of the given properties\","
@@ -1889,6 +2053,14 @@ namespace JSONRPC
       "],"
       "\"returns\":  { \"$ref\": \"System.Property.Value\", \"required\": true }"
     "}",
+    "\"System.EjectOpticalDrive\": {"
+      "\"type\": \"method\","
+      "\"description\": \"Ejects or closes the optical disc drive (if available)\","
+      "\"transport\": \"Response\","
+      "\"permission\": \"ControlSystem\","
+      "\"params\": [ ],"
+      "\"returns\":  \"string\""
+    "}",
     "\"System.Shutdown\": {"
       "\"type\": \"method\","
       "\"description\": \"Shuts the system running XBMC down\","
@@ -1969,6 +2141,22 @@ namespace JSONRPC
       "\"params\": [],"
       "\"returns\": \"string\""
     "}",
+    "\"Input.ContextMenu\": {"
+      "\"type\": \"method\","
+      "\"description\": \"Shows the context menu\","
+      "\"transport\": \"Response\","
+      "\"permission\": \"Navigate\","
+      "\"params\": [],"
+      "\"returns\": \"string\""
+    "}",
+    "\"Input.Info\": {"
+      "\"type\": \"method\","
+      "\"description\": \"Shows the information dialog\","
+      "\"transport\": \"Response\","
+      "\"permission\": \"Navigate\","
+      "\"params\": [],"
+      "\"returns\": \"string\""
+    "}",
     "\"Input.Home\": {"
       "\"type\": \"method\","
       "\"description\": \"Goes to home window in GUI\","
@@ -1993,7 +2181,12 @@ namespace JSONRPC
       "\"transport\": \"Response\","
       "\"permission\": \"ControlPlayback\","
       "\"params\": ["
-        "{ \"name\": \"volume\", \"type\": \"integer\", \"minimum\": 0, \"maximum\": 100, \"required\": true }"
+        "{ \"name\": \"volume\", \"type\": ["
+            "{ \"type\": \"integer\", \"minimum\": 0, \"maximum\": 100, \"required\": true },"
+            "{ \"$ref\": \"Global.IncrementDecrement\", \"required\": true }"
+          "],"
+          "\"required\": true"
+        "}"
       "],"
       "\"returns\": \"integer\""
     "}",
@@ -2003,11 +2196,7 @@ namespace JSONRPC
       "\"transport\": \"Response\","
       "\"permission\": \"ControlPlayback\","
       "\"params\": ["
-        "{ \"name\": \"mute\", \"required\": true, \"type\": ["
-            "{ \"type\": \"boolean\", \"required\": true },"
-            "{ \"type\": \"string\", \"enum\": [ \"toggle\" ], \"required\": true }"
-          "]"
-        "}"
+        "{ \"name\": \"mute\", \"required\": true, \"$ref\": \"Global.Toggle\" }"
       "],"
       "\"returns\": { \"type\": \"boolean\", \"description\": \"Mute state\" }"
     "}",
@@ -2203,6 +2392,20 @@ namespace JSONRPC
         "{ \"name\": \"data\", \"type\": \"null\", \"required\": true }"
       "],"
       "\"returns\": null"
+    "}",
+    "\"Application.OnVolumeChanged\": {"
+      "\"type\": \"notification\","
+      "\"description\": \"The volume of the application has changed.\","
+      "\"params\": ["
+        "{ \"name\": \"sender\", \"type\": \"string\", \"required\": true },"
+        "{ \"name\": \"data\", \"type\": \"object\", \"required\": true,"
+          "\"properties\": {"
+            "\"volume\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 100, \"required\": true },"
+            "\"muted\": { \"type\": \"boolean\", \"required\": true }"
+          "}"
+        "}"
+      "],"
+      "\"returns\": null"
     "}"
   };
 }
index 525b41a..58df809 100644 (file)
 
 #include "SystemOperations.h"
 #include "Application.h"
+#include "interfaces/Builtins.h"
 #include "utils/Variant.h"
 #include "powermanagement/PowerManager.h"
 
 using namespace JSONRPC;
 
-JSON_STATUS CSystemOperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CSystemOperations::GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CVariant properties = CVariant(CVariant::VariantTypeObject);
   for (unsigned int index = 0; index < parameterObject["properties"].size(); index++)
   {
     CStdString propertyName = parameterObject["properties"][index].asString();
     CVariant property;
-    JSON_STATUS ret;
+    JSONRPC_STATUS ret;
     if ((ret = GetPropertyValue(client->GetPermissionFlags(), propertyName, property)) != OK)
       return ret;
 
@@ -45,7 +46,12 @@ JSON_STATUS CSystemOperations::GetProperties(const CStdString &method, ITranspor
   return OK;
 }
 
-JSON_STATUS CSystemOperations::Shutdown(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CSystemOperations::EjectOpticalDrive(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+{
+  return CBuiltins::Execute("EjectTray") == 0 ? ACK : FailedToExecute;
+}
+
+JSONRPC_STATUS CSystemOperations::Shutdown(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   if (g_powerManager.CanPowerdown())
   {
@@ -56,7 +62,7 @@ JSON_STATUS CSystemOperations::Shutdown(const CStdString &method, ITransportLaye
     return FailedToExecute;
 }
 
-JSON_STATUS CSystemOperations::Suspend(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CSystemOperations::Suspend(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   if (g_powerManager.CanSuspend())
   {
@@ -67,7 +73,7 @@ JSON_STATUS CSystemOperations::Suspend(const CStdString &method, ITransportLayer
     return FailedToExecute;
 }
 
-JSON_STATUS CSystemOperations::Hibernate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CSystemOperations::Hibernate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   if (g_powerManager.CanHibernate())
   {
@@ -78,7 +84,7 @@ JSON_STATUS CSystemOperations::Hibernate(const CStdString &method, ITransportLay
     return FailedToExecute;
 }
 
-JSON_STATUS CSystemOperations::Reboot(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CSystemOperations::Reboot(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   if (g_powerManager.CanReboot())
   {
@@ -89,7 +95,7 @@ JSON_STATUS CSystemOperations::Reboot(const CStdString &method, ITransportLayer
     return FailedToExecute;
 }
 
-JSON_STATUS CSystemOperations::GetPropertyValue(int permissions, const CStdString &property, CVariant &result)
+JSONRPC_STATUS CSystemOperations::GetPropertyValue(int permissions, const CStdString &property, CVariant &result)
 {
   if (property.Equals("canshutdown"))
     result = g_powerManager.CanPowerdown() && (permissions & ControlPower);
index f8d00c4..50fa2ce 100644 (file)
@@ -28,13 +28,15 @@ namespace JSONRPC
   class CSystemOperations
   {
   public:
-    static JSON_STATUS GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetProperties(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS Shutdown(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Suspend(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Hibernate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Reboot(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS EjectOpticalDrive(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+
+    static JSONRPC_STATUS Shutdown(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Suspend(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Hibernate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Reboot(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
   private:
-    static JSON_STATUS GetPropertyValue(int permissions, const CStdString &property, CVariant &result);
+    static JSONRPC_STATUS GetPropertyValue(int permissions, const CStdString &property, CVariant &result);
   };
 }
index 00bde03..c9d5485 100644 (file)
  */
 
 #include "VideoLibrary.h"
-#include "JSONUtils.h"
-#include "video/VideoDatabase.h"
+#include "Application.h"
 #include "Util.h"
 #include "utils/URIUtils.h"
-#include "Application.h"
+#include "video/VideoDatabase.h"
 
 using namespace JSONRPC;
 
-JSON_STATUS CVideoLibrary::GetMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CVideoDatabase videodatabase;
   if (!videodatabase.Open())
     return InternalError;
 
   CFileItemList items;
-  JSON_STATUS ret = OK;
+  JSONRPC_STATUS ret = OK;
   if (videodatabase.GetMoviesByWhere("videodb://1/", "", "", items))
     ret = GetAdditionalMovieDetails(parameterObject, items, result, videodatabase);
 
@@ -43,7 +42,7 @@ JSON_STATUS CVideoLibrary::GetMovies(const CStdString &method, ITransportLayer *
   return ret;
 }
 
-JSON_STATUS CVideoLibrary::GetMovieDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetMovieDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int id = (int)parameterObject["movieid"].asInteger();
 
@@ -65,7 +64,7 @@ JSON_STATUS CVideoLibrary::GetMovieDetails(const CStdString &method, ITransportL
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetMovieSets(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetMovieSets(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CVideoDatabase videodatabase;
   if (!videodatabase.Open())
@@ -79,7 +78,7 @@ JSON_STATUS CVideoLibrary::GetMovieSets(const CStdString &method, ITransportLaye
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetMovieSetDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetMovieSetDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int id = (int)parameterObject["setid"].asInteger();
 
@@ -100,7 +99,7 @@ JSON_STATUS CVideoLibrary::GetMovieSetDetails(const CStdString &method, ITranspo
 
   // Get movies from the set
   CFileItemList items;
-  JSON_STATUS ret = OK;
+  JSONRPC_STATUS ret = OK;
   if (videodatabase.GetMoviesNav("", items, -1, -1, -1, -1, -1, -1, id))
     ret = GetAdditionalMovieDetails(parameterObject["movies"], items, result["setdetails"]["items"], videodatabase);
 
@@ -108,7 +107,7 @@ JSON_STATUS CVideoLibrary::GetMovieSetDetails(const CStdString &method, ITranspo
   return ret;
 }
 
-JSON_STATUS CVideoLibrary::GetTVShows(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetTVShows(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CVideoDatabase videodatabase;
   if (!videodatabase.Open())
@@ -137,7 +136,7 @@ JSON_STATUS CVideoLibrary::GetTVShows(const CStdString &method, ITransportLayer
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetTVShowDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetTVShowDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int id = (int)parameterObject["tvshowid"].asInteger();
 
@@ -159,7 +158,7 @@ JSON_STATUS CVideoLibrary::GetTVShowDetails(const CStdString &method, ITransport
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetSeasons(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetSeasons(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int tvshowID = (int)parameterObject["tvshowid"].asInteger();
 
@@ -177,7 +176,7 @@ JSON_STATUS CVideoLibrary::GetSeasons(const CStdString &method, ITransportLayer
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int tvshowID = (int)parameterObject["tvshowid"].asInteger();
   int season   = (int)parameterObject["season"].asInteger();
@@ -196,7 +195,7 @@ JSON_STATUS CVideoLibrary::GetEpisodes(const CStdString &method, ITransportLayer
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetEpisodeDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetEpisodeDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int id = (int)parameterObject["episodeid"].asInteger();
 
@@ -225,7 +224,7 @@ JSON_STATUS CVideoLibrary::GetEpisodeDetails(const CStdString &method, ITranspor
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int artistID = (int)parameterObject["artistid"].asInteger();
   int albumID  = (int)parameterObject["albumid"].asInteger();
@@ -242,7 +241,7 @@ JSON_STATUS CVideoLibrary::GetMusicVideos(const CStdString &method, ITransportLa
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetMusicVideoDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetMusicVideoDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   int id = (int)parameterObject["musicvideoid"].asInteger();
 
@@ -264,7 +263,7 @@ JSON_STATUS CVideoLibrary::GetMusicVideoDetails(const CStdString &method, ITrans
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetRecentlyAddedMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetRecentlyAddedMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CVideoDatabase videodatabase;
   if (!videodatabase.Open())
@@ -278,7 +277,7 @@ JSON_STATUS CVideoLibrary::GetRecentlyAddedMovies(const CStdString &method, ITra
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetRecentlyAddedEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetRecentlyAddedEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CVideoDatabase videodatabase;
   if (!videodatabase.Open())
@@ -292,7 +291,7 @@ JSON_STATUS CVideoLibrary::GetRecentlyAddedEpisodes(const CStdString &method, IT
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetRecentlyAddedMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetRecentlyAddedMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CVideoDatabase videodatabase;
   if (!videodatabase.Open())
@@ -306,7 +305,7 @@ JSON_STATUS CVideoLibrary::GetRecentlyAddedMusicVideos(const CStdString &method,
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetGenres(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::GetGenres(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CStdString media = parameterObject["type"].asString();
   media = media.ToLower();
@@ -349,13 +348,20 @@ JSON_STATUS CVideoLibrary::GetGenres(const CStdString &method, ITransportLayer *
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
-  g_application.getApplicationMessenger().ExecBuiltIn("updatelibrary(video)");
+  std::string directory = parameterObject["directory"].asString();
+  CStdString cmd;
+  if (directory.empty())
+    cmd = "updatelibrary(video)";
+  else
+    cmd.Format("updatelibrary(video, %s)", directory.c_str());
+
+  g_application.getApplicationMessenger().ExecBuiltIn(cmd);
   return ACK;
 }
 
-JSON_STATUS CVideoLibrary::Export(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::Export(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   CStdString cmd;
   if (parameterObject["options"].isMember("path"))
@@ -370,7 +376,7 @@ JSON_STATUS CVideoLibrary::Export(const CStdString &method, ITransportLayer *tra
   return ACK;
 }
 
-JSON_STATUS CVideoLibrary::Clean(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CVideoLibrary::Clean(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   g_application.getApplicationMessenger().ExecBuiltIn("cleanlibrary(video)");
   return ACK;
@@ -450,7 +456,7 @@ bool CVideoLibrary::FillFileItemList(const CVariant &parameterObject, CFileItemL
   return false;
 }
 
-JSON_STATUS CVideoLibrary::GetAdditionalMovieDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase)
+JSONRPC_STATUS CVideoLibrary::GetAdditionalMovieDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase)
 {
   if (!videodatabase.Open())
     return InternalError;
@@ -473,7 +479,7 @@ JSON_STATUS CVideoLibrary::GetAdditionalMovieDetails(const CVariant &parameterOb
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetAdditionalEpisodeDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase)
+JSONRPC_STATUS CVideoLibrary::GetAdditionalEpisodeDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase)
 {
   if (!videodatabase.Open())
     return InternalError;
@@ -496,7 +502,7 @@ JSON_STATUS CVideoLibrary::GetAdditionalEpisodeDetails(const CVariant &parameter
   return OK;
 }
 
-JSON_STATUS CVideoLibrary::GetAdditionalMusicVideoDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase)
+JSONRPC_STATUS CVideoLibrary::GetAdditionalMusicVideoDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase)
 {
   if (!videodatabase.Open())
     return InternalError;
index fa9dbc4..e1cc0e6 100644 (file)
@@ -31,36 +31,36 @@ namespace JSONRPC
   class CVideoLibrary : public CFileItemHandler
   {
   public:
-    static JSON_STATUS GetMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetMovieDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetMovieSets(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetMovieSetDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetMovieDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetMovieSets(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetMovieSetDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS GetTVShows(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetTVShowDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetSeasons(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetEpisodeDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetTVShows(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetTVShowDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetSeasons(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetEpisodeDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS GetMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetMusicVideoDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetMusicVideoDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS GetRecentlyAddedMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetRecentlyAddedEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetRecentlyAddedMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetRecentlyAddedMovies(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetRecentlyAddedEpisodes(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetRecentlyAddedMusicVideos(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
     
-    static JSON_STATUS GetGenres(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetGenres(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
-    static JSON_STATUS Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Export(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS Clean(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Scan(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Export(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS Clean(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
 
     static bool FillFileItem(const CStdString &strFilename, CFileItem &item);
     static bool FillFileItemList(const CVariant &parameterObject, CFileItemList &list);
 
   private:
-    static JSON_STATUS GetAdditionalMovieDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase);
-    static JSON_STATUS GetAdditionalEpisodeDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase);
-    static JSON_STATUS GetAdditionalMusicVideoDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase);
+    static JSONRPC_STATUS GetAdditionalMovieDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase);
+    static JSONRPC_STATUS GetAdditionalEpisodeDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase);
+    static JSONRPC_STATUS GetAdditionalMusicVideoDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase);
   };
 }
index a7e81a0..beac445 100644 (file)
@@ -28,7 +28,7 @@
 
 using namespace JSONRPC;
 
-JSON_STATUS CXBMCOperations::GetInfoLabels(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CXBMCOperations::GetInfoLabels(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   std::vector<CStdString> info;
 
@@ -54,7 +54,7 @@ JSON_STATUS CXBMCOperations::GetInfoLabels(const CStdString &method, ITransportL
   return OK;
 }
 
-JSON_STATUS CXBMCOperations::GetInfoBooleans(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
+JSONRPC_STATUS CXBMCOperations::GetInfoBooleans(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
 {
   std::vector<CStdString> info;
 
index d76b560..3bbf1c9 100644 (file)
@@ -28,7 +28,7 @@ namespace JSONRPC
   class CXBMCOperations
   {
   public:
-    static JSON_STATUS GetInfoLabels(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
-    static JSON_STATUS GetInfoBooleans(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetInfoLabels(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
+    static JSONRPC_STATUS GetInfoBooleans(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
   };
 }
index 5e2a5a6..4d42417 100644 (file)
@@ -42,7 +42,9 @@
         "UpdateData": { "type": "boolean", "required": true },
         "RemoveData": { "type": "boolean", "required": true },
         "Navigate": { "type": "boolean", "required": true },
-        "WriteFile": { "type": "boolean", "required": true }
+        "WriteFile": { "type": "boolean", "required": true },
+        "ControlSystem": { "type": "boolean", "required": true },
+        "ControlGUI": { "type": "boolean", "required": true }
       }
     }
   },
@@ -75,6 +77,7 @@
           "System": { "$ref": "Optional.Boolean" },
           "AudioLibrary": { "$ref": "Optional.Boolean" },
           "VideoLibrary": { "$ref": "Optional.Boolean" },
+          "Application": { "$ref": "Optional.Boolean" },
           "Other": { "$ref": "Optional.Boolean" }
         }
       }
     "transport": "Response",
     "permission": "ControlPlayback",
     "params": [
-      { "name": "item", 
+      { "name": "item",
         "type": [
           { "type": "object", "required": true, "additionalProperties": false,
             "properties": {
           { "type": "object", "required": true, "additionalProperties": false,
             "properties": {
               "path": { "type": "string", "required": true },
-              "random": { "type": "boolean", "default": true },
+              "random": { "type": "boolean", "default": true, "description": "Deprecated, use the shuffled property of the options parameter instead" },
               "recursive": { "type": "boolean", "default": true }
             }
           }
         ]
+      },
+      { "name": "options", "type": "object", "additionalProperties": false,
+        "properties": {
+          "shuffled": { "$ref": "Optional.Boolean" },
+          "repeat": { "type": [ "null", "Player.Repeat" ], "default": null },
+          "resume": { "type": [
+              { "type": "boolean", "required": true, "description": "Whether to resume from the resume point or not" },
+              { "$ref": "Player.Position.Percentage", "required": true, "description": "Percentage value to start from" },
+              { "$ref": "Player.Position.Time", "required": true, "description": "Time to start from" }
+            ],
+            "default": false
+          }
+        }
       }
     ],
     "returns": "string"
     "returns": {
       "type": "array",
       "uniqueItems": true,
-      "items": { 
+      "items": {
         "type": "object",
         "properties": {
           "playerid": { "$ref": "Player.Id", "required": true },
     "transport": "Response",
     "permission": "ControlPlayback",
     "params": [
-      { "name": "playerid", "$ref": "Player.Id", "required": true }
+      { "name": "playerid", "$ref": "Player.Id", "required": true },
+      { "name": "play", "$ref": "Global.Toggle", "default": "toggle" }
     ],
     "returns": { "$ref": "Player.Speed" }
   },
       { "name": "playerid", "$ref": "Player.Id", "required": true },
       { "name": "speed", "type": [
           { "type": "integer", "required": true, "enum": [ -32, -16, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 32 ] },
-          { "type": "string", "required": true, "enum": [ "increment", "decrement" ] } 
+          { "$ref": "Global.IncrementDecrement", "required": true }
         ],
         "required": true
       }
       { "name": "playerid", "$ref": "Player.Id", "required": true },
       { "name": "value", "required": true, "type": [
           { "$ref": "Player.Position.Percentage", "required": true, "description": "Percentage value to seek to" },
-          { "type": "object", "additionalProperties": false, "required": true, "description": "Time to seek to",
-            "properties": {
-              "hours": { "type": "integer", "minimum": 0, "maximum": 23 },
-              "minutes": { "type": "integer", "minimum": 0, "maximum": 59 },
-              "seconds": { "type": "integer", "minimum": 0, "maximum": 59 },
-              "milliseconds": { "type": "integer", "minimum": 0, "maximum": 999 }
-            }
-          },
+          { "$ref": "Player.Position.Time", "required": true, "description": "Time to seek to" },
           { "type": "string", "enum": [ "smallforward", "smallbackward", "bigforward", "bigbackward" ], "required": true, "description": "Seek by predefined jumps" }
         ]
       }
           { "type": "string", "enum": [ "previous", "next", "off", "on" ] },
           { "type": "integer", "minimum": 0, "description": "Index of the subtitle to display" }
         ]
-      }
+      },
+      { "name": "enable", "type": "boolean", "default": false, "description": "Whether to enable subtitles to be displayed after setting the new subtitle" }
     ],
     "returns": "string"
   },
     "returns": {
       "type": "array",
       "uniqueItems": true,
-      "items": { 
+      "items": {
         "type": "object",
         "properties": {
           "playlistid": { "$ref": "Playlist.Id", "required": true },
     "params": [
       { "name": "directory", "type": "string", "required": true },
       { "name": "media", "$ref": "Files.Media", "default": "files" },
-      { "name": "properties", "$ref": "List.Fields.All" },
+      { "name": "properties", "$ref": "List.Fields.Files" },
       { "name": "sort", "$ref": "List.Sort" }
     ],
     "returns": {
       }
     }
   },
+    "AudioLibrary.GetRecentlyPlayedAlbums": {
+    "type": "method",
+    "description": "Retrieve recently played albums",
+    "transport": "Response",
+    "permission": "ReadData",
+    "params": [
+      { "name": "properties", "$ref": "Audio.Fields.Album" },
+      { "name": "limits", "$ref": "List.Limits" },
+      { "name": "sort", "$ref": "List.Sort" }
+    ],
+    "returns": {
+      "type": "object",
+      "properties": {
+        "limits": { "$ref": "List.LimitsReturned", "required": true },
+        "albums": { "type": "array",
+          "items": { "$ref": "Audio.Details.Album" }
+        }
+      }
+    }
+  },
+  "AudioLibrary.GetRecentlyPlayedSongs": {
+    "type": "method",
+    "description": "Retrieve recently played songs",
+    "transport": "Response",
+    "permission": "ReadData",
+    "params": [
+      { "name": "properties", "$ref": "Audio.Fields.Song" },
+      { "name": "limits", "$ref": "List.Limits" },
+      { "name": "sort", "$ref": "List.Sort" }
+    ],
+    "returns": {
+      "type": "object",
+      "properties": {
+        "limits": { "$ref": "List.LimitsReturned", "required": true },
+        "songs": { "type": "array",
+          "items": { "$ref": "Audio.Details.Song" }
+        }
+      }
+    }
+  },
   "AudioLibrary.GetGenres": {
     "type": "method",
     "description": "Retrieve all genres",
     "description": "Scans the audio sources for new library items",
     "transport": "Response",
     "permission": "UpdateData",
-    "params": [],
+    "params": [
+      { "name": "directory", "type": "string", "default": "" }
+    ],
     "returns": "string"
   },
   "AudioLibrary.Export": {
     "description": "Scans the video sources for new library items",
     "transport": "Response",
     "permission": "UpdateData",
-    "params": [],
+    "params": [
+      { "name": "directory", "type": "string", "default": "" }
+    ],
     "returns": "string"
   },
   "VideoLibrary.Export": {
     "params": [ ],
     "returns": "string"
   },
+  "GUI.ShowNotification": {
+    "type": "method",
+    "description": "Shows a GUI notification",
+    "transport": "Response",
+    "permission": "ControlGUI",
+    "params": [
+      { "name": "title", "type": "string", "required": true },
+      { "name": "message", "type": "string", "required": true },
+      { "name": "image", "type": [
+          { "type": "string", "required": true, "enum": [ "info", "warning", "error" ] },
+          { "type": "string", "required": true }
+        ], "default": ""
+      },
+      { "name": "displaytime", "type": "integer", "minimum": 1500, "default": 5000, "description": "The time in milliseconds the notification will be visible" }
+    ],
+    "returns":  { "$ref": "System.Property.Value", "required": true }
+  },
+  "GUI.GetProperties": {
+    "type": "method",
+    "description": "Retrieves the values of the given properties",
+    "transport": "Response",
+    "permission": "ReadData",
+    "params": [
+      { "name": "properties", "type": "array", "uniqueItems": true, "required": true, "items": { "$ref": "GUI.Property.Name" } }
+    ],
+    "returns":  { "$ref": "GUI.Property.Value", "required": true }
+  },
+  "GUI.SetFullscreen": {
+    "type": "method",
+    "description": "Toggle fullscreen/GUI",
+    "transport": "Response",
+    "permission": "ControlGUI",
+    "params": [
+      { "name": "fullscreen", "required": true, "$ref": "Global.Toggle" }
+    ],
+    "returns": { "type": "boolean", "description": "Fullscreen state" }
+  },
   "System.GetProperties": {
     "type": "method",
     "description": "Retrieves the values of the given properties",
     ],
     "returns":  { "$ref": "System.Property.Value", "required": true }
   },
+  "System.EjectOpticalDrive": {
+    "type": "method",
+    "description": "Ejects or closes the optical disc drive (if available)",
+    "transport": "Response",
+    "permission": "ControlSystem",
+    "params": [ ],
+    "returns":  "string"
+  },
   "System.Shutdown": {
     "type": "method",
     "description": "Shuts the system running XBMC down",
     "params": [],
     "returns": "string"
   },
+  "Input.ContextMenu": {
+    "type": "method",
+    "description": "Shows the context menu",
+    "transport": "Response",
+    "permission": "Navigate",
+    "params": [],
+    "returns": "string"
+  },
+  "Input.Info": {
+    "type": "method",
+    "description": "Shows the information dialog",
+    "transport": "Response",
+    "permission": "Navigate",
+    "params": [],
+    "returns": "string"
+  },
   "Input.Home": {
     "type": "method",
     "description": "Goes to home window in GUI",
     "transport": "Response",
     "permission": "ControlPlayback",
     "params": [
-      { "name": "volume", "type": "integer", "minimum": 0, "maximum": 100, "required": true }
+      { "name": "volume", "type": [
+          { "type": "integer", "minimum": 0, "maximum": 100, "required": true },
+          { "$ref": "Global.IncrementDecrement", "required": true }
+        ],
+        "required": true
+      }
     ],
     "returns": "integer"
   },
     "transport": "Response",
     "permission": "ControlPlayback",
     "params": [
-      { "name": "mute", "required": true, "type": [
-          { "type": "boolean", "required": true },
-          { "type": "string", "enum": [ "toggle" ], "required": true }
-        ]
-      }
+      { "name": "mute", "required": true, "$ref": "Global.Toggle" }
     ],
     "returns": { "type": "boolean", "description": "Mute state" }
   },
       "description": "List of key-value pairs of the retrieved info booleans"
     }
   }
-}
\ No newline at end of file
+}
index 27bc0c0..d39760b 100644 (file)
       { "name": "data", "type": "null", "required": true }
     ],
     "returns": null
+  },
+  "Application.OnVolumeChanged": {
+    "type": "notification",
+    "description": "The volume of the application has changed.",
+    "params": [
+      { "name": "sender", "type": "string", "required": true },
+      { "name": "data", "type": "object", "required": true,
+        "properties": {
+          "volume": { "type": "integer", "minimum": 0, "maximum": 100, "required": true },
+          "muted": { "type": "boolean", "required": true }
+        }
+      }
+    ],
+    "returns": null
   }
 }
\ No newline at end of file
index 24fd9f8..975ef9c 100644 (file)
     },
     "additionalProperties": false
   },
+  "Global.IncrementDecrement": {
+    "type": "string",
+    "enum": [ "increment", "decrement" ]
+  },
+  "Global.Toggle": {
+    "type": [
+      { "type": "boolean", "required": true },
+      { "type": "string", "enum": [ "toggle" ], "required": true }
+    ]
+  },
   "Configuration.Notifications": {
     "type": "object",
     "properties": {
     "minimum": 0.0,
     "maximum": 100.0
   },
+  "Player.Position.Time": {
+    "type": "object",
+    "additionalProperties": false,
+    "properties": {
+      "hours": { "type": "integer", "minimum": 0, "maximum": 23, "default": 0 },
+      "minutes": { "type": "integer", "minimum": 0, "maximum": 59, "default": 0 },
+      "seconds": { "type": "integer", "minimum": 0, "maximum": 59, "default": 0 },
+      "milliseconds": { "type": "integer", "minimum": 0, "maximum": 999, "default": 0 }
+    }
+  },
   "Player.Speed": {
     "type": "object",
     "required": true,
                 "playcount", "writer", "studio", "mpaa", "cast", "country",
                 "imdbnumber", "premiered", "productioncode", "runtime", "set",
                 "showlink", "streamdetails", "top250", "votes", "fanart",
-                "thumbnail", "file", "sorttitle", "resume", "setid" ]
+                "thumbnail", "file", "sorttitle", "resume", "setid", "dateadded" ]
     }
   },
   "Video.Fields.MovieSet": {
                 "studio", "mpaa", "cast", "playcount", "episode",
                 "imdbnumber", "premiered", "votes", "lastplayed",
                 "fanart", "thumbnail", "file", "originaltitle",
-                "sorttitle", "episodeguide" ]
+                "sorttitle", "episodeguide", "season", "watchedepisodes",
+                "dateadded"]
     }
   },
   "Video.Fields.Season": {
     "extends": "Item.Fields.Base",
     "items": { "type": "string",
-      "enum": [ "season", "showtitle", "playcount", "episode", "fanart", "thumbnail", "tvshowid" ]
+      "enum": [ "season", "showtitle", "playcount", "episode", "fanart", "thumbnail", "tvshowid",
+                "watchedepisodes" ]
     }
   },
   "Video.Fields.Episode": {
                 "firstaired", "playcount", "runtime", "director",
                 "productioncode", "season", "episode", "originaltitle",
                 "showtitle", "cast", "streamdetails", "lastplayed", "fanart",
-                "thumbnail", "file", "resume", "tvshowid" ]
+                "thumbnail", "file", "resume", "tvshowid", "dateadded" ]
     }
   },
   "Video.Fields.MusicVideo": {
       "enum": [ "title", "playcount", "runtime", "director",
                 "studio", "year", "plot", "album", "artist",
                 "genre", "track", "streamdetails", "lastplayed",
-                "fanart", "thumbnail", "file", "resume" ]
+                "fanart", "thumbnail", "file", "resume", "dateadded" ]
     }
   },
   "Video.Cast": {
     "properties": {
       "file": { "type": "string" },
       "plot": { "type": "string" },
-      "lastplayed": { "type": "string" }
+      "lastplayed": { "type": "string" },
+      "dateadded": { "type": "string" }
     }
   },
   "Video.Details.File": {
       "mpaa": { "type": "string" },
       "cast": { "$ref": "Video.Cast" },
       "episode": { "type": "integer" },
+      "watchedepisodes": { "type": "integer" },
       "imdbnumber": { "type": "string" },
       "premiered": { "type": "string" },
       "votes": { "type": "string" },
-      "episodeguide": { "type": "string" }
+      "episodeguide": { "type": "string" },
+      "season": { "type": "integer" }
     }
   },
   "Video.Details.Season": {
       "season": { "type": "integer", "required": true },
       "showtitle": { "type": "string" },
       "episode": { "type": "integer" },
+      "watchedepisodes": { "type": "integer" },
       "tvshowid": { "$ref": "Library.Id" }
     }
   },
     "type": "object",
     "properties": {
       "start": { "type": "integer", "minimum": 0, "default": 0 },
-      "end": { "type": "integer", "minimum": 0, "default": -1 }
+      "end": { "type": "integer", "minimum": 0, "default": -1, "description": "The number of items in the list being returned" }
     },
     "additionalProperties": false
   },
     "properties": {
       "method": { "type": "string", "default": "none",
         "enum": [ "none", "label", "date", "size", "file", "drivetype", "track", "duration", "title", "artist",
-                  "album", "genre", "year", "videorating", "programcount", "playlist", "episode", "videotitle",
-                  "sorttitle", "productioncode", "songrating", "mpaarating", "videoruntime", "studio", "fullpath",
-                  "lastplayed", "unsorted" ]
+                  "album", "genre", "country", "year", "videorating", "dateadded", "programcount", "playlist",
+                  "episode", "videotitle", "sorttitle", "productioncode", "songrating", "mpaarating", "videoruntime",
+                  "studio", "fullpath", "lastplayed", "playcount", "listeners", "bitrate", "unsorted" ]
       },
       "order": { "type": "string", "default": "ascending", "enum": [ "ascending", "descending" ] },
       "ignorearticle": { "type": "boolean", "default": false }
                 "mpaa", "cast", "country", "imdbnumber", "premiered", "productioncode",
                 "runtime", "set", "showlink", "streamdetails", "top250", "votes",
                 "firstaired", "season", "episode", "showtitle", "thumbnail", "file",
-                "resume", "artistid", "albumid", "tvshowid", "setid" ]
+                "resume", "artistid", "albumid", "tvshowid", "setid", "watchedepisodes" ]
     }
   },
   "List.Item.All": {
       "artistid": { "$ref": "Library.Id" },
       "albumid": { "$ref": "Library.Id" },
       "setid": { "$ref": "Array.Integer" },
-      "tvshowid": { "$ref": "Library.Id" }
+      "tvshowid": { "$ref": "Library.Id" },
+      "watchedepisodes": { "type": "integer" }
+    }
+  },
+  "List.Fields.Files": {
+    "extends": "Item.Fields.Base",
+    "items": { "type": "string",
+      "enum": [ "title", "artist", "albumartist", "genre", "year", "rating",
+                "album", "track", "duration", "comment", "lyrics", "musicbrainztrackid",
+                "musicbrainzartistid", "musicbrainzalbumid", "musicbrainzalbumartistid",
+                "playcount", "fanart", "director", "trailer", "tagline", "plot",
+                "plotoutline", "originaltitle", "lastplayed", "writer", "studio",
+                "mpaa", "cast", "country", "imdbnumber", "premiered", "productioncode",
+                "runtime", "set", "showlink", "streamdetails", "top250", "votes",
+                "firstaired", "season", "episode", "showtitle", "thumbnail", "file",
+                "resume", "artistid", "albumid", "tvshowid", "setid", "size",
+                "lastmodified", "mimetype", "watchedepisodes" ]
     }
   },
   "List.Item.File": {
     "extends": "List.Item.All",
     "properties": {
       "file": { "type": "string", "required": true },
-      "filetype": { "type": "string", "enum": [ "file", "directory" ], "required": true }
+      "filetype": { "type": "string", "enum": [ "file", "directory" ], "required": true },
+      "size": { "type": "integer", "description": "Size of the file in kB (1000 Byte)" },
+      "lastmodified": { "type": "string" },
+      "mimetype": { "type": "string" }
     }
   },
   "List.Items.Sources": {
       }
     }
   },
+  "GUI.Property.Name": {
+    "type": "string",
+    "enum": [ "currentwindow", "currentcontrol", "skin", "fullscreen" ]
+  },
+  "GUI.Property.Value": {
+    "type": "object",
+    "properties": {
+      "currentwindow": { "type": "object",
+        "properties": {
+          "id": { "type": "integer", "required": true },
+          "label": { "type": "string", "required": true }
+        }
+      },
+      "currentcontrol": { "type": "object",
+        "properties": {
+          "label": { "type": "string", "required": true }
+        }
+      },
+      "skin": { "type": "object",
+        "properties": {
+          "id": { "type": "string", "required": true, "minLength": 1 },
+          "name": { "type": "string" }
+        }
+      },
+      "fullscreen": { "type": "boolean" }
+    }
+  },
   "System.Property.Name": {
     "type": "string",
     "enum": [ "canshutdown", "cansuspend", "canhibernate", "canreboot" ]
   "Application.Property.Value": {
     "type": "object",
     "properties": {
-      "volume": { "type": "integer" },
+      "volume": { "type": "integer", "minimum": 0, "maximum": 100 },
       "muted": { "type": "boolean" },
       "name": { "type": "string", "minLength": 1 },
       "version": { "type": "object",
index d3c616f..78b6ad5 100644 (file)
@@ -154,7 +154,7 @@ void XBPyThread::Process()
   // get path from script file name and add python path's
   // this is used for python so it will search modules from script path first
   CStdString scriptDir;
-  URIUtils::GetDirectory(_P(m_source), scriptDir);
+  URIUtils::GetDirectory(CSpecialProtocol::TranslatePath(m_source), scriptDir);
   URIUtils::RemoveSlashAtEnd(scriptDir);
   CStdString path = scriptDir;
 
@@ -164,12 +164,12 @@ void XBPyThread::Process()
   for (unsigned int i = 0; i < addons.size(); ++i)
 #ifdef TARGET_WINDOWS
   {
-    CStdString strTmp(_P(addons[i]->LibPath()));
+    CStdString strTmp(CSpecialProtocol::TranslatePath(addons[i]->LibPath()));
     g_charsetConverter.utf8ToSystem(strTmp);
     path += PY_PATH_SEP + strTmp;
   }
 #else
-    path += PY_PATH_SEP + _P(addons[i]->LibPath());
+    path += PY_PATH_SEP + CSpecialProtocol::TranslatePath(addons[i]->LibPath());
 #endif
 
   // and add on whatever our default path is
@@ -234,12 +234,12 @@ void XBPyThread::Process()
       // We need to have python open the file because on Windows the DLL that python
       //  is linked against may not be the DLL that xbmc is linked against so
       //  passing a FILE* to python from an fopen has the potential to crash.
-      PyObject* file = PyFile_FromString((char *) _P(m_source).c_str(), (char*)"r");
+      PyObject* file = PyFile_FromString((char *) CSpecialProtocol::TranslatePath(m_source).c_str(), (char*)"r");
       FILE *fp = PyFile_AsFile(file);
 
       if (fp)
       {
-        PyObject *f = PyString_FromString(_P(m_source).c_str());
+        PyObject *f = PyString_FromString(CSpecialProtocol::TranslatePath(m_source).c_str());
         PyDict_SetItemString(moduleDict, "__file__", f);
         if (addon.get() != NULL)
         {
@@ -253,7 +253,7 @@ void XBPyThread::Process()
           CLog::Log(LOGDEBUG,"Instantiating addon using automatically obtained id of \"%s\" dependent on version %s of the xbmc.python api",addon->ID().c_str(),version.c_str());
         }
         Py_DECREF(f);
-        PyRun_FileExFlags(fp, _P(m_source).c_str(), m_Py_file_input, moduleDict, moduleDict,1,NULL);
+        PyRun_FileExFlags(fp, CSpecialProtocol::TranslatePath(m_source).c_str(), m_Py_file_input, moduleDict, moduleDict,1,NULL);
       }
       else
         CLog::Log(LOGERROR, "%s not found!", m_source);
index 9f43894..8efcd7f 100644 (file)
@@ -344,10 +344,10 @@ void XBPython::Initialize()
       {
         // using external python, it's build looking for xxx/lib/python2.6
         // so point it to frameworks which is where python2.6 is located
-        setenv("PYTHONHOME", _P("special://frameworks").c_str(), 1);
-        setenv("PYTHONPATH", _P("special://frameworks").c_str(), 1);
-        CLog::Log(LOGDEBUG, "PYTHONHOME -> %s", _P("special://frameworks").c_str());
-        CLog::Log(LOGDEBUG, "PYTHONPATH -> %s", _P("special://frameworks").c_str());
+        setenv("PYTHONHOME", CSpecialProtocol::TranslatePath("special://frameworks").c_str(), 1);
+        setenv("PYTHONPATH", CSpecialProtocol::TranslatePath("special://frameworks").c_str(), 1);
+        CLog::Log(LOGDEBUG, "PYTHONHOME -> %s", CSpecialProtocol::TranslatePath("special://frameworks").c_str());
+        CLog::Log(LOGDEBUG, "PYTHONPATH -> %s", CSpecialProtocol::TranslatePath("special://frameworks").c_str());
       }
       setenv("PYTHONCASEOK", "1", 1); //This line should really be removed
 #elif defined(_WIN32)
@@ -356,11 +356,11 @@ void XBPython::Initialize()
       // buf is corrupted after putenv and might need a strdup but it seems to
       // work this way
       CStdString buf;
-      buf = "PYTHONPATH=" + _P("special://xbmc/system/python/DLLs") + ";" + _P("special://xbmc/system/python/Lib");
+      buf = "PYTHONPATH=" + CSpecialProtocol::TranslatePath("special://xbmc/system/python/DLLs") + ";" + CSpecialProtocol::TranslatePath("special://xbmc/system/python/Lib");
       pgwin32_putenv(buf.c_str());
       buf = "PYTHONOPTIMIZE=1";
       pgwin32_putenv(buf.c_str());
-      buf = "PYTHONHOME=" + _P("special://xbmc/system/python");
+      buf = "PYTHONHOME=" + CSpecialProtocol::TranslatePath("special://xbmc/system/python");
       pgwin32_putenv(buf.c_str());
       buf = "OS=win32";
       pgwin32_putenv(buf.c_str());
@@ -465,7 +465,7 @@ void XBPython::Process()
     m_bLogin = false;
 
     // autoexec.py - profile
-    CStdString strAutoExecPy = _P("special://profile/autoexec.py");
+    CStdString strAutoExecPy = CSpecialProtocol::TranslatePath("special://profile/autoexec.py");
 
     if ( XFILE::CFile::Exists(strAutoExecPy) )
       evalFile(strAutoExecPy,ADDON::AddonPtr());
@@ -521,7 +521,6 @@ int XBPython::evalFile(const CStdString &src, ADDON::AddonPtr addon)
 int XBPython::evalFile(const CStdString &src, const std::vector<CStdString> &argv, ADDON::AddonPtr addon)
 {
   CSingleExit ex(g_graphicsContext);
-  CSingleLock lock(m_critSection);
   // return if file doesn't exist
   if (!XFILE::CFile::Exists(src))
   {
@@ -533,6 +532,7 @@ int XBPython::evalFile(const CStdString &src, const std::vector<CStdString> &arg
   if (g_settings.GetCurrentProfile().programsLocked() && !g_passwordManager.IsMasterLockUnlocked(true))
     return -1;
 
+  CSingleLock lock(m_critSection);
   Initialize();
 
   if (!m_bInitialized) return -1;
index f5d1153..fb2aed8 100644 (file)
@@ -469,18 +469,28 @@ namespace PYXBMC
         return NULL;
     }
 
-    PyXBMCGUILock();
-    CGUIDialogProgress* pDialog= (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
-    if (PyXBMCWindowIsNull(pDialog)) return NULL;
-    ((DialogProgress*)self)->dlg = pDialog;
+    CGUIDialogProgress* pDialog;
+    {
+      CPyThreadState releaseGil;
+      CSingleLock glock(g_graphicsContext);
 
-    pDialog->SetHeading(utf8Line[0]);
+      pDialog= (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
+      if (!pDialog)
+      {
+        glock.Leave();
+        releaseGil.Restore();
+        PyErr_SetString(PyExc_SystemError, "Error: Window is NULL, this is not possible :-)");
+        return NULL;
+      }
+      ((DialogProgress*)self)->dlg = pDialog;
 
-    for (int i = 1; i < 4; i++)
-      pDialog->SetLine(i - 1,utf8Line[i]);
+      pDialog->SetHeading(utf8Line[0]);
 
-    PyXBMCGUIUnlock();
-    pDialog->StartModal();
+      for (int i = 1; i < 4; i++)
+        pDialog->SetLine(i - 1,utf8Line[i]);
+
+      pDialog->StartModal();
+    }
 
     Py_INCREF(Py_None);
     return Py_None;
@@ -568,9 +578,10 @@ namespace PYXBMC
     CGUIDialogProgress* pDialog= ((DialogProgress*)self)->dlg;
     if (PyXBMCWindowIsNull(pDialog)) return NULL;
 
-    PyXBMCGUILock();
-    pDialog->Close();
-    PyXBMCGUIUnlock();
+    {
+      CPyThreadState state;
+      pDialog->Close();
+    }
 
     Py_INCREF(Py_None);
     return Py_None;
@@ -579,9 +590,12 @@ namespace PYXBMC
   static void Dialog_ProgressDealloc(PyObject *self)
   {
     CGUIDialogProgress* pDialog= ((DialogProgress*)self)->dlg;
-    if(pDialog)
+    if (pDialog)
+    {
+      CPyThreadState state;
       pDialog->Close();
-
+    }
+    
     self->ob_type->tp_free((PyObject*)self);
   }
 
index f116674..e704484 100644 (file)
@@ -610,6 +610,122 @@ namespace PYXBMC
     return Py_None;
   }
 
+  PyDoc_STRVAR(addStreamInfo__doc__,
+    "addStreamInfo(type, values) -- Add a stream with details.\n"
+    "\n"
+    "type              : string - type of stream(video/audio/subtitle).\n"
+    "values            : dictionary - pairs of { label: value }.\n"
+    "\n"
+    "Video Values:\n"
+    "    codec         : string (h264)\n"
+    "    aspect        : float (1.78)\n"
+    "    width         : integer (1280)\n"
+    "    height        : integer (720)\n"
+    "    duration      : integer (seconds)\n"
+    "\n"
+    "Audio Values:\n"
+    "    codec         : string (dts)\n"
+    "    language      : string (en)\n"
+    "    channels      : integer (2)\n"
+    "\n"
+    "Subtitle Values:\n"
+    "    language      : string (en)\n"
+    "\n"
+    "example:\n"
+    "  - self.list.getSelectedItem().addStreamInfo('video', { 'Codec': 'h264', 'Width' : 1280 })\n");
+
+  PyObject* ListItem_AddStreamInfo(ListItem *self, PyObject *args, PyObject *kwds)
+  {
+    static const char *keywords[] = { "type", "values", NULL };
+    char *cType = NULL;
+    PyObject *pValues = NULL;
+    if (!PyArg_ParseTupleAndKeywords(
+      args,
+      kwds,
+      (char*)"sO",
+      (char**)keywords,
+      &cType,
+      &pValues))
+    {
+      return NULL;
+    }
+    if (!PyObject_TypeCheck(pValues, &PyDict_Type))
+    {
+      PyErr_SetString(PyExc_TypeError, "values object should be of type Dict");
+      return NULL;
+    }
+    if (PyDict_Size(pValues) == 0)
+    {
+      PyErr_SetString(PyExc_ValueError, "Empty values dictionary");
+      return NULL;
+    }
+
+    PyObject *key, *value;
+    Py_ssize_t pos = 0;
+
+    PyXBMCGUILock();
+
+    CStdString tmp;
+    if (strcmpi(cType, "video") == 0)
+    {
+      CStreamDetailVideo* video = new CStreamDetailVideo;
+      while (PyDict_Next(pValues, &pos, &key, &value))
+      {
+        if (strcmpi(PyString_AsString(key), "codec") == 0)
+        {
+          if (!PyXBMCGetUnicodeString(video->m_strCodec, value, 1)) 
+            continue;
+        }
+        else if (strcmpi(PyString_AsString(key), "aspect") == 0)
+          video->m_fAspect = (float)PyFloat_AsDouble(value);
+        else if (strcmpi(PyString_AsString(key), "width") == 0)
+          video->m_iWidth = PyInt_AsLong(value);
+        else if (strcmpi(PyString_AsString(key), "height") == 0)
+          video->m_iHeight = PyInt_AsLong(value);
+        else if (strcmpi(PyString_AsString(key), "duration") == 0)
+          video->m_iDuration = PyInt_AsLong(value);
+      }
+      self->item->GetVideoInfoTag()->m_streamDetails.AddStream(video);
+    }
+    else if (strcmpi(cType, "audio") == 0)
+    {
+      CStreamDetailAudio* audio = new CStreamDetailAudio;
+      while (PyDict_Next(pValues, &pos, &key, &value))
+      {
+        if (strcmpi(PyString_AsString(key), "codec") == 0)
+        {
+          if (!PyXBMCGetUnicodeString(audio->m_strCodec, value, 1)) 
+            continue;
+        }
+        else if (strcmpi(PyString_AsString(key), "language") == 0)
+        {
+          if (!PyXBMCGetUnicodeString(audio->m_strLanguage, value, 1)) 
+            continue;
+        }
+        else if (strcmpi(PyString_AsString(key), "channels") == 0)
+          audio ->m_iChannels = PyInt_AsLong(value);
+      }
+      self->item->GetVideoInfoTag()->m_streamDetails.AddStream(audio);
+    }
+    else if (strcmpi(cType, "subtitle") == 0)
+    {
+      CStreamDetailSubtitle* subtitle = new CStreamDetailSubtitle;
+      while (PyDict_Next(pValues, &pos, &key, &value))
+      {
+        if (strcmpi(PyString_AsString(key), "language") == 0)
+        {
+          if (!PyXBMCGetUnicodeString(subtitle->m_strLanguage, value, 1)) 
+            continue;
+        }
+      }
+      self->item->GetVideoInfoTag()->m_streamDetails.AddStream(subtitle);
+    }
+    PyXBMCGUIUnlock();
+
+    Py_INCREF(Py_None);
+    return Py_None;
+  }
+
   PyDoc_STRVAR(setProperty__doc__,
     "setProperty(key, value) -- Sets a listitem property, similar to an infolabel.\n"
     "\n"
@@ -858,6 +974,7 @@ namespace PYXBMC
     {(char*)"setProperty", (PyCFunction)ListItem_SetProperty, METH_VARARGS|METH_KEYWORDS, setProperty__doc__},
     {(char*)"getProperty", (PyCFunction)ListItem_GetProperty, METH_VARARGS|METH_KEYWORDS, getProperty__doc__},
     {(char*)"addContextMenuItems", (PyCFunction)ListItem_AddContextMenuItems, METH_VARARGS|METH_KEYWORDS, addContextMenuItems__doc__},
+    {(char*)"addStreamInfo", (PyCFunction)ListItem_AddStreamInfo, METH_VARARGS|METH_KEYWORDS, addStreamInfo__doc__},
     {(char*)"setPath" , (PyCFunction)ListItem_SetPath, METH_VARARGS|METH_KEYWORDS, setPath__doc__},
     {NULL, NULL, 0, NULL}
   };
index 9b9184a..9788686 100644 (file)
@@ -573,28 +573,68 @@ namespace PYXBMC
 
   PyObject* Window_AddControl(Window *self, PyObject *args)
   {
-    Control* pControl;
+    PyObject* object;
 
-    if (!PyArg_ParseTuple(args, (char*)"O", &pControl)) return NULL;
-    // type checking, object should be of type Control
-    if(!Control_Check(pControl))
+    if (!PyArg_ParseTuple(args, (char*)"O", &object)) return NULL;
+
+    if (!Window_AddSingleControl(self, object, true))
+      return NULL;
+
+    Py_INCREF(Py_None);
+    return Py_None;
+  }
+
+  PyDoc_STRVAR(addControls__doc__,
+    "addControls(self, List) -- Add a list of Controls to this window.\n"
+    "\n"
+    "Throws: TypeError, if supplied argument is not of List type, or a control is not of Control type\n"
+    "        ReferenceError, if control is already used in another window\n"
+    "        RuntimeError, should not happen :-)\n");
+
+  PyObject* Window_AddControls(Window *self, PyObject *args)
+  {
+    PyObject* object;
+
+    if (!PyArg_ParseTuple(args, (char*)"O", &object)) return NULL;
+
+    if (!PyList_Check(object))
     {
       PyErr_SetString(PyExc_TypeError, "Object should be of type Control");
       return NULL;
     }
+    for (int i = 0; i < PyList_Size(object); i++)
+    {
+      if (!Window_AddSingleControl(self, PyList_GetItem(object,i), i+1 == PyList_Size(object)))
+        return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+  }
+
+  bool Window_AddSingleControl(Window *self, PyObject *control, bool wait)
+  {
+    // type checking, object should be of type Control
+    if(!Control_Check(control))
+    {
+      PyErr_SetString(PyExc_TypeError, "Object should be of type Control");
+      return false;
+    }
+    Control *pControl = (Control *)control;
 
     if(pControl->iControlId != 0)
     {
       PyErr_SetString(PyExc_ReferenceError, "Control is already used");
-      return NULL;
+      return false;
     }
 
-    // lock xbmc GUI before accessing data from it
-    GilSafeSingleLock lock(g_graphicsContext);
     pControl->iParentId = self->iWindowId;
-    // assign control id, if id is already in use, try next id
-    do pControl->iControlId = ++self->iCurrentControlId;
-    while (self->pWindow->GetControl(pControl->iControlId));
+
+    { // assign control id, if id is already in use, try next id
+      GilSafeSingleLock lock(g_graphicsContext);
+      do pControl->iControlId = ++self->iCurrentControlId;
+      while (self->pWindow->GetControl(pControl->iControlId));
+    }
 
     // Control Label
     if (ControlLabel_Check(pControl))
@@ -646,7 +686,7 @@ namespace PYXBMC
     else
     {
       PyErr_SetString(PyExc_RuntimeError, "Object is a Control, but can't be added to a window");
-      return NULL;
+      return false;
     }
 
     Py_INCREF(pControl);
@@ -658,15 +698,63 @@ namespace PYXBMC
     pControl->iControlRight = pControl->iControlId;
 
     pControl->pGUIControl->SetNavigation(pControl->iControlUp,
-      pControl->iControlDown, pControl->iControlLeft, pControl->iControlRight);
+                                         pControl->iControlDown, pControl->iControlLeft, pControl->iControlRight);
 
-    // add control to list and allocate recources for the control
     self->vecControls.push_back(pControl);
-    pControl->pGUIControl->AllocResources();
-    self->pWindow->AddControl(pControl->pGUIControl);
+    {
+      CPyThreadState state;
+      CGUIMessage msg(GUI_MSG_ADD_CONTROL, 0, 0);
+      msg.SetPointer(pControl->pGUIControl);
+      g_application.getApplicationMessenger().SendGUIMessage(msg, self->iWindowId, wait);
+    }
+    return true;
+  }
 
-    Py_INCREF(Py_None);
-    return Py_None;
+  bool Window_RemoveSingleControl(Window *self, PyObject *object, bool wait)
+  {
+    // type checking, object should be of type Control
+    if(!Control_Check(object))
+    {
+      PyErr_SetString(PyExc_TypeError, "Object should be of type Control");
+      return false;
+    }
+    Control *pControl = (Control *)object;
+
+    {
+      CPyThreadState state;
+      CSingleLock lock(g_graphicsContext);
+      if(!self->pWindow->GetControl(pControl->iControlId))
+      {
+        lock.Leave();
+        state.Restore();
+        PyErr_SetString(PyExc_RuntimeError, "Control does not exist in window");
+        return false;
+      }
+    }
+
+    // delete control from vecControls in window object
+    for (vector<Control*>::iterator it = self->vecControls.begin(); it != self->vecControls.end(); ++it)
+    {
+      if ((*it)->iControlId == pControl->iControlId)
+      {
+        self->vecControls.erase(it);
+        break;
+      }
+    }
+
+    {
+      CPyThreadState state;
+      CGUIMessage msg(GUI_MSG_REMOVE_CONTROL, 0, 0);
+      msg.SetPointer(pControl->pGUIControl);
+      g_application.getApplicationMessenger().SendGUIMessage(msg, self->iWindowId, wait);
+    }
+
+    // initialize control to zero
+    pControl->pGUIControl = NULL;
+    pControl->iControlId = 0;
+    pControl->iParentId = 0;
+    Py_DECREF(pControl);
+    return true;
   }
 
   PyDoc_STRVAR(getControl__doc__,
@@ -783,42 +871,39 @@ namespace PYXBMC
 
   PyObject* Window_RemoveControl(Window *self, PyObject *args)
   {
-    Control* pControl;
-    if (!PyArg_ParseTuple(args, (char*)"O", &pControl)) return NULL;
-    // type checking, object should be of type Control
-    if(!Control_Check(pControl))
-    {
-      PyErr_SetString(PyExc_TypeError, "Object should be of type Control");
+    PyObject* object;
+    if (!PyArg_ParseTuple(args, (char*)"O", &object)) return NULL;
+
+    if (!Window_RemoveSingleControl(self, object, true))
       return NULL;
-    }
-    GilSafeSingleLock lock(g_graphicsContext);
-    if(!self->pWindow->GetControl(pControl->iControlId))
+
+    Py_INCREF(Py_None);
+    return Py_None;
+  }
+  PyDoc_STRVAR(removeControls__doc__,
+    "removeControls(self, List) -- Removes a list of controls from this window.\n"
+    "\n"
+    "Throws: TypeError, if supplied argument is not a Control type\n"
+    "        RuntimeError, if control is not added to this window\n"
+    "\n"
+    "This will not delete the controls. They are only removed from the window.");
+
+  PyObject* Window_RemoveControls(Window *self, PyObject *args)
+  {
+    PyObject* object;
+    if (!PyArg_ParseTuple(args, (char*)"O", &object)) return NULL;
+
+    if (!PyList_Check(object))
     {
-      PyErr_SetString(PyExc_RuntimeError, "Control does not exist in window");
+      PyErr_SetString(PyExc_TypeError, "Object should be of type List");
       return NULL;
     }
-
-    // delete control from vecControls in window object
-    vector<Control*>::iterator it = self->vecControls.begin();
-    while (it != self->vecControls.end())
+    for (int i = 0; i < PyList_Size(object); i++)
     {
-      Control* control = *it;
-      if (control->iControlId == pControl->iControlId)
-      {
-        it = self->vecControls.erase(it);
-      } else ++it;
+      if (!Window_RemoveSingleControl(self, PyList_GetItem(object,i), i+1 == PyList_Size(object)))
+        return NULL;
     }
 
-    self->pWindow->RemoveControl(pControl->pGUIControl);
-    pControl->pGUIControl->FreeResources();
-    delete pControl->pGUIControl;
-
-    // initialize control to zero
-    pControl->pGUIControl = NULL;
-    pControl->iControlId = 0;
-    pControl->iParentId = 0;
-    Py_DECREF(pControl);
-
     Py_INCREF(Py_None);
     return Py_None;
   }
@@ -930,10 +1015,13 @@ namespace PYXBMC
     if (!PyXBMCGetUnicodeString(uText, value, 1))
       return NULL;
 
-    GilSafeSingleLock lock(g_graphicsContext);
     CStdString lowerKey = key;
-
-    self->pWindow->SetProperty(lowerKey.ToLower(), uText);
+    {
+      CPyThreadState gil;
+      CSingleLock lock(g_graphicsContext);
+      
+      self->pWindow->SetProperty(lowerKey.ToLower(), uText);
+    }
 
     Py_INCREF(Py_None);
     return Py_None;
@@ -1037,8 +1125,10 @@ namespace PYXBMC
     {(char*)"show", (PyCFunction)Window_Show, METH_VARARGS, show__doc__},
     {(char*)"close", (PyCFunction)Window_Close, METH_VARARGS, close__doc__},
     {(char*)"addControl", (PyCFunction)Window_AddControl, METH_VARARGS, addControl__doc__},
+    {(char*)"addControls", (PyCFunction)Window_AddControls, METH_VARARGS, addControls__doc__},
     {(char*)"getControl", (PyCFunction)Window_GetControl, METH_VARARGS, getControl__doc__},
     {(char*)"removeControl", (PyCFunction)Window_RemoveControl, METH_VARARGS, removeControl__doc__},
+    {(char*)"removeControls", (PyCFunction)Window_RemoveControls, METH_VARARGS, removeControls__doc__},
     {(char*)"setFocus", (PyCFunction)Window_SetFocus, METH_VARARGS, setFocus__doc__},
     {(char*)"setFocusId", (PyCFunction)Window_SetFocusId, METH_VARARGS, setFocusId__doc__},
     {(char*)"getFocus", (PyCFunction)Window_GetFocus, METH_VARARGS, getFocus__doc__},
index fa8cdfd..7c7e344 100644 (file)
@@ -70,6 +70,8 @@ namespace PYXBMC
   void initWindow_Type();
 
   bool Window_CreateNewWindow(Window* pWindow, bool bAsDialog);
+  bool Window_AddSingleControl(Window* self, PyObject *object, bool wait = true);
+  bool Window_RemoveSingleControl(Window* self, PyObject *object, bool wait = true);
   void Window_Dealloc(Window* self);
   PyObject* Window_Close(Window *self, PyObject *args);
 }
index 37ce244..7690686 100644 (file)
@@ -74,18 +74,27 @@ namespace PYXBMC
 
     if (!XFILE::CFile::Exists(strSkinPath))
     {
-      // Check for the matching folder for the skin in the fallback skins folder
+      CStdString str("none");
+      AddonProps props(str, ADDON_SKIN, "", "");
+      CSkinInfo::TranslateResolution(resolution, res);
+
       CStdString fallbackPath = URIUtils::AddFileToFolder(strFallbackPath, "resources");
       fallbackPath = URIUtils::AddFileToFolder(fallbackPath, "skins");
       CStdString basePath = URIUtils::AddFileToFolder(fallbackPath, g_SkinInfo->ID());
-      strSkinPath = g_SkinInfo->GetSkinPath(strXMLname, &res, basePath);
+
+      // Check for the matching folder for the skin in the fallback skins folder (if it exists)
+      if (XFILE::CFile::Exists(basePath))
+      {
+        props.path = basePath;
+        CSkinInfo skinInfo(props, res);
+        skinInfo.Start();
+        strSkinPath = skinInfo.GetSkinPath(strXMLname, &res);
+      }
+      
       if (!XFILE::CFile::Exists(strSkinPath))
       {
         // Finally fallback to the DefaultSkin as it didn't exist in either the XBMC Skin folder or the fallback skin folder
-        CStdString str("none");
-        AddonProps props(str, ADDON_SKIN, "", "");
         props.path = URIUtils::AddFileToFolder(fallbackPath, strDefault);
-        CSkinInfo::TranslateResolution(resolution, res);
         CSkinInfo skinInfo(props, res);
 
         skinInfo.Start();
index da8719c..76aeb6b 100644 (file)
@@ -75,22 +75,31 @@ namespace PYXBMC
 
     if (!XFILE::CFile::Exists(strSkinPath))
     {
-      // Check for the matching folder for the skin in the fallback skins folder
+      CStdString str("none");
+      AddonProps props(str, ADDON_SKIN, "", "");
+      CSkinInfo::TranslateResolution(resolution, res);
+
       CStdString fallbackPath = URIUtils::AddFileToFolder(strFallbackPath, "resources");
       fallbackPath = URIUtils::AddFileToFolder(fallbackPath, "skins");
       CStdString basePath = URIUtils::AddFileToFolder(fallbackPath, g_SkinInfo->ID());
-      strSkinPath = g_SkinInfo->GetSkinPath(strXMLname, &res, basePath);
+
+      // Check for the matching folder for the skin in the fallback skins folder (if it exists)
+      if (XFILE::CFile::Exists(basePath))
+      {
+        props.path = basePath;
+        CSkinInfo skinInfo(props, res);
+        skinInfo.Start();
+        strSkinPath = skinInfo.GetSkinPath(strXMLname, &res);
+      }
+
       if (!XFILE::CFile::Exists(strSkinPath))
       {
         // Finally fallback to the DefaultSkin as it didn't exist in either the XBMC Skin folder or the fallback skin folder
-        CStdString str("none");
-        AddonProps props(str, ADDON_SKIN, "", "");
         props.path = URIUtils::AddFileToFolder(fallbackPath, strDefault);
-        CSkinInfo::TranslateResolution(resolution, res);
         CSkinInfo skinInfo(props, res);
 
         skinInfo.Start();
-        strSkinPath = skinInfo.GetSkinPath(strXMLname, &res);        
+        strSkinPath = skinInfo.GetSkinPath(strXMLname, &res);
         if (!XFILE::CFile::Exists(strSkinPath))
         {
           PyErr_SetString(PyExc_TypeError, "XML File for Window is missing");
index 0de5cca..ced6bc9 100644 (file)
@@ -609,11 +609,15 @@ namespace PYXBMC
     char *cLine = NULL;
     if (!PyArg_ParseTuple(args, (char*)"s", &cLine)) return NULL;
 
-    PyXBMCGUILock();
-    int id = g_windowManager.GetTopMostModalDialogID();
-    if (id == WINDOW_INVALID) id = g_windowManager.GetActiveWindow();
-    bool ret = g_infoManager.EvaluateBool(cLine,id);
-    PyXBMCGUIUnlock();
+    bool ret;
+    {
+      CPyThreadState gilRelease;
+      CSingleLock gc(g_graphicsContext);
+
+      int id = g_windowManager.GetTopMostModalDialogID();
+      if (id == WINDOW_INVALID) id = g_windowManager.GetActiveWindow();
+      ret = g_infoManager.EvaluateBool(cLine,id);
+    }
 
     return Py_BuildValue((char*)"b", ret);
   }
@@ -718,9 +722,6 @@ namespace PYXBMC
     if (!PyXBMCGetUnicodeString(strText, pObjectText, 1)) return NULL;
 
     CStdString strPath;
-    if (URIUtils::IsDOSPath(strText))
-      strText = CSpecialProtocol::ReplaceOldPath(strText, 0);
-
     strPath = CSpecialProtocol::TranslatePath(strText);
 
     return Py_BuildValue((char*)"s", strPath.c_str());
index 372befb..ec47408 100644 (file)
 #include <ctype.h>
 #include <errno.h>
 
-
-/*
- ** The following two functions together make up an itoa()
- ** implementation. Function i2a() is a 'private' function
- ** called by the public itoa() function.
- **
- ** itoa() takes three arguments:
- ** 1) the integer to be converted,
- ** 2) a pointer to a character conversion buffer,
- ** 3) the radix for the conversion
- ** which can range between 2 and 36 inclusive
- ** range errors on the radix default it to base10
- */
-
-static char *i2a(unsigned i, char *a, unsigned r)
-{
-  if (i/r > 0) a = i2a(i/r,a,r);
-  *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r];
-  return a+1;
-}
-
-char *itoa(int i, char *a, int r)
-{
-  if ((r < 2) || (r > 36)) r = 10;
-  if (i<0) {
-    *a = '-';
-    *i2a(-(unsigned)i,a+1,r) = 0;
-  } else *i2a(i,a,r) = 0;
-  return a;
-}
-
 void OutputDebugString(LPCTSTR lpOuputString)
 {
 }
 
-void strlwr( char* string )
-{
-  while ( *string )
-  {
-    *string = (char)tolower( *string );
-    string++;
-  }
-}
-
-void strupr( char* string )
-{
-  while ( *string )
-  {
-    *string = (char)toupper( *string );
-    string++;
-  }
-}
-
 LONGLONG Int32x32To64(LONG Multiplier, LONG Multiplicand)
 {
   LONGLONG result = Multiplier;
@@ -87,35 +38,6 @@ LONGLONG Int32x32To64(LONG Multiplier, LONG Multiplicand)
   return result;
 }
 
-int WideCharToMultiByte(
-  UINT CodePage,
-  DWORD dwFlags,
-  LPCWSTR lpWideCharStr,
-  int cchWideChar,
-  LPSTR lpMultiByteStr,
-  int cbMultiByte,
-  LPCSTR lpDefaultChar,
-  LPBOOL lpUsedDefaultChar
-) {
-
-  // TODO: need to implement WideCharToMultiByte
-  return 0;
-}
-
-int MultiByteToWideChar(
-  UINT CodePage,
-  DWORD dwFlags,
-  LPCSTR lpMultiByteStr,
-  int cbMultiByte,
-  LPWSTR lpWideCharStr,
-  int cchWideChar
-) {
-
-  // TODO: need to implement MultiByteToWideChar
-  return 0;
-
-}
-
 DWORD GetLastError()
 {
   return errno;
index 3d1cacf..c1ff56e 100644 (file)
  */
 #include "PlatformDefs.h" // UINT DWORD LPCSTR LPSTR LPBOOL ...
 
-int WideCharToMultiByte(
-  UINT CodePage,
-  DWORD dwFlags,
-  LPCWSTR lpWideCharStr,
-  int cchWideChar,
-  LPSTR lpMultiByteStr,
-  int cbMultiByte,
-  LPCSTR lpDefaultChar,
-  LPBOOL lpUsedDefaultChar
-);
-
-int MultiByteToWideChar(
-  UINT CodePage,
-  DWORD dwFlags,
-  LPCSTR lpMultiByteStr,
-  int cbMultiByte,
-  LPWSTR lpWideCharStr,
-  int cchWideChar
-);
-
-
 DWORD GetLastError();
 VOID  SetLastError(DWORD dwErrCode);
 
index d660a4e..78f0edc 100644 (file)
@@ -511,19 +511,9 @@ void CHALManager::AddDevice(const char *udi)
         if(m_Joysticks.size() < 2 || m_bMultipleJoysticksSupport)
         {
           // Restart SDL joystick subsystem
-          SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
-          if (SDL_WasInit(SDL_INIT_JOYSTICK) !=  0)
-          {
-            CLog::Log(LOGERROR, "HAL: Stop joystick subsystem failed");
-            break;
-          }
-          if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0)
-          {
-            CLog::Log(LOGERROR, "HAL: Restart joystick subsystem failed : %s",SDL_GetError());
+          if (!g_Joystick.Reinitialize())
             break;
-          }
 
-          g_Joystick.Initialize();
           if (m_Notifications)
             CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(13024), dev.FriendlyName.c_str(), TOAST_DISPLAY_TIME, false);
         }
@@ -576,20 +566,11 @@ bool CHALManager::RemoveDevice(const char *udi)
       if(m_Joysticks.size() < 3 || m_bMultipleJoysticksSupport)
       {
         // Restart SDL joystick subsystem
-        SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
-        if (SDL_WasInit(SDL_INIT_JOYSTICK) !=  0)
-        {
-          CLog::Log(LOGERROR, "HAL: Stop joystick subsystem failed");
+        if (!g_Joystick.Reinitialize())
           return false;
-        }
-        if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0)
-        {
-          CLog::Log(LOGERROR, "HAL: Restart joystick subsystem failed : %s",SDL_GetError());
-          return false;
-        }
 
-        g_Joystick.Initialize();
-        CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(13025), m_Joysticks[i].FriendlyName.c_str(), TOAST_DISPLAY_TIME, false);
+        if (m_Notifications)
+          CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(13025), m_Joysticks[i].FriendlyName.c_str(), TOAST_DISPLAY_TIME, false);
       }
       m_Joysticks.erase(m_Joysticks.begin() + i);
       return true;
index 33d1c96..d04830c 100644 (file)
@@ -588,12 +588,6 @@ typedef struct _D3DMATRIX {
 #define FILE_SHARE_WRITE                 0x00000002
 #define FILE_SHARE_DELETE                0x00000004
 
-
-// String
-char *itoa(int i, char *a, int r);
-void strlwr(char* string);
-void strupr(char* string);
-
 // Audio stuff
 typedef struct tWAVEFORMATEX
 {
index 0545f0d..2f69500 100644 (file)
@@ -251,7 +251,7 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess,
   {
     // Failed to open file. maybe due to case sensitivity.
     // Try opening the same name in lower case.
-    CStdString igFileName = PTH_IC(lpFileName);
+    CStdString igFileName = CSpecialProtocol::TranslatePathConvertCase(lpFileName);
     fd = open(igFileName.c_str(), flags, mode);
     if (fd != -1)
     {
@@ -576,7 +576,7 @@ BOOL GetDiskFreeSpaceEx(
 
 {
   struct statfs64 fsInfo;
-  if (statfs64(_P(lpDirectoryName), &fsInfo) != 0)
+  if (statfs64(CSpecialProtocol::TranslatePath(lpDirectoryName), &fsInfo) != 0)
     return false;
 
   if (lpFreeBytesAvailable)
index 700f28a..cd16165 100644 (file)
@@ -29,7 +29,7 @@
 #include "pictures/Picture.h"
 #include "utils/md5.h"
 #include "filesystem/File.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 #include "GUIInfoManager.h"
 #include "MusicDatabase.h"
 #include "music/tags/MusicInfoTag.h"
@@ -130,7 +130,7 @@ bool CLastFmManager::RadioHandShake()
 
   m_RadioSession = "";
 
-  CFileCurl http;
+  CCurlFile http;
   CStdString html;
 
   CStdString strPassword = g_guiSettings.GetString("scrobbler.lastfmpass");
@@ -221,7 +221,7 @@ bool CLastFmManager::ChangeStation(const CURL& stationUrl)
 
   UpdateProgressDialog(15252); // Selecting station...
 
-  CFileCurl http;
+  CCurlFile http;
   CStdString url;
   CStdString html;
 
@@ -274,7 +274,7 @@ bool CLastFmManager::RequestRadioTracks()
   CStdString html;
   url.Format("http://" + m_RadioBaseUrl + m_RadioBasePath + "/xspf.php?sk=%s&discovery=0&desktop=", m_RadioSession);
   {
-    CFileCurl http;
+    CCurlFile http;
     if (!http.Get(url, html))
     {
       m_RadioSession.empty();
@@ -418,7 +418,7 @@ void CLastFmManager::CacheTrackThumb(const int nrInitialTracksToAdd)
   unsigned int start = XbmcThreads::SystemClockMillis();
   CSingleLock lock(m_lockCache);
   int iNrCachedTracks = m_RadioTrackQueue->size();
-  CFileCurl http;
+  CCurlFile http;
   for (int i = 0; i < nrInitialTracksToAdd && i < iNrCachedTracks; i++)
   {
     CFileItemPtr item = (*m_RadioTrackQueue)[i];
@@ -775,7 +775,7 @@ bool CLastFmManager::CallXmlRpc(const CStdString& action, const CStdString& arti
   CStdString strBody;
   strBody << doc;
 
-  CFileCurl http;
+  CCurlFile http;
   CStdString html;
   CStdString url = "http://ws.audioscrobbler.com/1.0/rw/xmlrpc.php";
   http.SetMimeType("text/xml");
index 5dfe4ab..c75a8df 100644 (file)
@@ -31,7 +31,7 @@
 #include "music/tags/MusicInfoTag.h"
 #include "guilib/GUIWindowManager.h"
 #include "filesystem/File.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 #include "FileItem.h"
 #include "settings/Settings.h"
 #include "settings/AdvancedSettings.h"
@@ -212,7 +212,7 @@ bool CGUIDialogSongInfo::DownloadThumbnail(const CStdString &thumbFile)
 {
   // TODO: Obtain the source...
   CStdString source;
-  CFileCurl http;
+  CCurlFile http;
   http.Download(source, thumbFile);
   return true;
 }
index c1f20a5..a18a1d7 100644 (file)
@@ -53,7 +53,7 @@ void CMusicAlbumInfo::SetAlbum(CAlbum& album)
   m_bLoaded = true;
 }
 
-bool CMusicAlbumInfo::Load(XFILE::CFileCurl& http, const ADDON::ScraperPtr& scraper)
+bool CMusicAlbumInfo::Load(XFILE::CCurlFile& http, const ADDON::ScraperPtr& scraper)
 {
   bool fSuccess = scraper->GetAlbumDetails(http, m_albumURL, m_album);
   if (fSuccess && m_strTitle2.empty())
index f2eba09..7aad893 100644 (file)
@@ -28,7 +28,7 @@
 
 class TiXmlDocument;
 
-namespace XFILE { class CFileCurl; }
+namespace XFILE { class CCurlFile; }
 
 namespace MUSIC_GRABBER
 {
@@ -52,7 +52,7 @@ public:
   float GetRelevance() const { return m_relevance; }
   void SetRelevance(float relevance) { m_relevance = relevance; }
 
-  bool Load(XFILE::CFileCurl& http, const ADDON::ScraperPtr& scraper);
+  bool Load(XFILE::CCurlFile& http, const ADDON::ScraperPtr& scraper);
 
 protected:
   bool m_bLoaded;
index c9b7b47..7d1b900 100644 (file)
@@ -40,7 +40,7 @@ void CMusicArtistInfo::SetArtist(const CArtist& artist)
   m_bLoaded = true;
 }
 
-bool CMusicArtistInfo::Load(CFileCurl& http, const ADDON::ScraperPtr& scraper,
+bool CMusicArtistInfo::Load(CCurlFile& http, const ADDON::ScraperPtr& scraper,
   const CStdString &strSearch)
 {
   return m_bLoaded = scraper->GetArtistDetails(http, m_artistURL, strSearch, m_artist);
index e7106ad..a6d4bd1 100644 (file)
@@ -42,7 +42,7 @@ public:
   const CArtist& GetArtist() const { return m_artist; }
   CArtist& GetArtist() { return m_artist; }
   const CScraperUrl& GetArtistURL() const { return m_artistURL; }
-  bool Load(XFILE::CFileCurl& http, const ADDON::ScraperPtr& scraper,
+  bool Load(XFILE::CCurlFile& http, const ADDON::ScraperPtr& scraper,
     const CStdString &strSearch);
 
 protected:
index ed34d53..6a0c863 100644 (file)
@@ -25,7 +25,7 @@
 #include "MusicArtistInfo.h"
 #include "addons/Scraper.h"
 #include "threads/Thread.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 
 namespace MUSIC_GRABBER
 {
@@ -82,7 +82,7 @@ protected:
   int m_iArtist;
   bool m_bSucceeded;
   bool m_bCanceled;
-  XFILE::CFileCurl m_http;
+  XFILE::CCurlFile m_http;
   ADDON::ScraperPtr m_scraper;
 };
 
index 99db6b4..dbc604d 100644 (file)
@@ -132,8 +132,7 @@ void CGUIWindowKaraokeLyrics::newSong(CKaraokeLyrics * lyrics)
   CSingleLock lock (m_CritSection);
   m_Lyrics = lyrics;
 
-  if ( m_Lyrics )
-    m_Lyrics->InitGraphics();
+  m_Lyrics->InitGraphics();
 
   // Set up current background mode
   if ( m_Lyrics->HasVideo() )
index 4b499bc..0bf1092 100644 (file)
@@ -76,7 +76,7 @@ BYTE CKaraokeLyricsCDG::getPixel( int x, int y )
   if ( x >= (int) CDG_FULL_WIDTH || y >= (int) CDG_FULL_HEIGHT )
          return m_borderColor;
   
-  if ( x < 0 || y < 0 || offset > CDG_FULL_HEIGHT * CDG_FULL_WIDTH )
+  if ( x < 0 || y < 0 || offset >= CDG_FULL_HEIGHT * CDG_FULL_WIDTH )
   {
        CLog::Log( LOGERROR, "CDG renderer: requested pixel (%d,%d) is out of boundary", x, y );
        return 0;
index fd571e4..1515221 100644 (file)
@@ -52,7 +52,7 @@ bool CMusicInfoTagLoaderMod::Load(const CStdString& strFileName, CMusicInfoTag&
       tag.SetLoaded(false);
       return( false );
     }
-    ifstream inMDZ(_P(strMDZ.c_str()));
+    ifstream inMDZ(CSpecialProtocol::TranslatePath(strMDZ.c_str()));
     char temp[8192];
     char temp2[8192];
 
index ec23334..ee5d71e 100644 (file)
@@ -61,6 +61,7 @@
 #include "utils/TimeUtils.h"
 #include "utils/log.h"
 #include "utils/URIUtils.h"
+#include "video/VideoInfoTag.h"
 #include "ThumbnailCache.h"
 
 using namespace std;
index b8f1a05..d87e326 100644 (file)
@@ -559,6 +559,9 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
         if (idArtist == -1)
           return false;
         CStdString path; path.Format("musicdb://2/%ld/", idArtist);
+        CArtist artist;
+        m_musicdatabase.GetArtistInfo(idArtist,artist,false);
+        *item = CFileItem(artist);
         item->SetPath(path);
         CGUIWindowMusicBase::OnContextButton(itemNumber,button);
         Update(m_vecItems->GetPath());
@@ -573,6 +576,9 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
         if (idAlbum == -1)
           return false;
         CStdString path; path.Format("musicdb://3/%ld/", idAlbum);
+        CAlbum album;
+        m_musicdatabase.GetAlbumInfo(idAlbum,album,NULL);
+        *item = CFileItem(path,album);
         item->SetPath(path);
         CGUIWindowMusicBase::OnContextButton(itemNumber,button);
         Update(m_vecItems->GetPath());
@@ -774,8 +780,8 @@ void CGUIWindowMusicNav::FrameMove()
   // update our searching
   if (m_searchTimer.IsRunning() && m_searchTimer.GetElapsedMilliseconds() > search_timeout)
   {
-    OnSearchUpdate();
     m_searchTimer.Stop();
+    OnSearchUpdate();
   }
   if (m_bDisplayEmptyDatabaseMessage)
     SET_CONTROL_LABEL(CONTROL_LABELEMPTY,g_localizeStrings.Get(745)+'\n'+g_localizeStrings.Get(746));
index 49f2315..ea8bb24 100644 (file)
@@ -25,6 +25,7 @@
 #include <arpa/inet.h>
 #include "DllLibPlist.h"
 #include "utils/log.h"
+#include "utils/URIUtils.h"
 #include "utils/StringUtils.h"
 #include "threads/SingleLock.h"
 #include "filesystem/File.h"
@@ -699,8 +700,11 @@ int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
       {
         int oldVolume = g_application.GetVolume();
         volume *= 100;
-        g_application.SetVolume(volume);
-        g_application.getApplicationMessenger().ShowVolumeBar(oldVolume < volume);
+        if(oldVolume != (int)volume)
+        {
+          g_application.SetVolume(volume);          
+          g_application.getApplicationMessenger().ShowVolumeBar(oldVolume < volume);
+        }
       }
   }
 
@@ -790,7 +794,11 @@ int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
 
     if (status != AIRPLAY_STATUS_NEED_AUTH)
     {
-      CFileItem fileToPlay(location + "|User-Agent=AppleCoreMedia/1.0.0.8F455 (Apple†TV; U; CPU OS 4_3 like Mac OS X; de_de)", false);
+      CStdString userAgent="AppleCoreMedia/1.0.0.8F455 (AppleTV; U; CPU OS 4_3 like Mac OS X; de_de)";
+      CURL::Encode(userAgent);
+      location += "|User-Agent=" + userAgent;
+
+      CFileItem fileToPlay(location, false);
       fileToPlay.SetProperty("StartPercent", position*100.0f);
       g_application.getApplicationMessenger().MediaPlay(fileToPlay);
       ComposeReverseEvent(reverseHeader, reverseBody, sessionId, EVENT_PLAYING);
@@ -832,7 +840,7 @@ int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
       
       if (found && g_application.m_pPlayer)
       {
-        __int64 position = (__int64) (atof(found + strlen("position=")) * 1000.0);
+        int64_t position = (int64_t) (atof(found + strlen("position=")) * 1000.0);
         g_application.m_pPlayer->SeekTime(position);
         CLog::Log(LOGDEBUG, "AIRPLAY: got POST request %s with pos %"PRId64, uri.c_str(), position);
       }
@@ -873,7 +881,17 @@ int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
     else if (m_httpParser->getContentLength() > 0)
     {
       XFILE::CFile tmpFile;
-      if (tmpFile.OpenForWrite("special://temp/airplay_photo.jpg", true))
+      CStdString tmpFileName = "special://temp/airplay_photo.jpg";
+
+      if( m_httpParser->getContentLength() > 3 &&
+          m_httpParser->getBody()[1] == 'P' &&
+          m_httpParser->getBody()[2] == 'N' &&
+          m_httpParser->getBody()[3] == 'G')
+      {
+        tmpFileName = "special://temp/airplay_photo.png";
+      }
+
+      if (tmpFile.OpenForWrite(tmpFileName, true))
       {
         int writtenBytes=0;
         writtenBytes = tmpFile.Write(m_httpParser->getBody(), m_httpParser->getContentLength());
@@ -881,7 +899,7 @@ int CAirPlayServer::CTCPClient::ProcessRequest( CStdString& responseHeader,
 
         if (writtenBytes > 0 && (unsigned int)writtenBytes == m_httpParser->getContentLength())
         {
-          g_application.getApplicationMessenger().PictureShow("special://temp/airplay_photo.jpg");
+          g_application.getApplicationMessenger().PictureShow(tmpFileName);
         }
         else
         {
index 8779c7c..8f97309 100644 (file)
@@ -31,7 +31,7 @@
 #include "utils/StdString.h"
 #include "network/Zeroconf.h"
 #include "ApplicationMessenger.h"
-#include "filesystem/FilePipe.h"
+#include "filesystem/PipeFile.h"
 #include "Application.h"
 #include "cores/paplayer/BXAcodec.h"
 #include "music/tags/MusicInfoTag.h"
@@ -48,7 +48,7 @@ CStdString CAirTunesServer::m_macAddress;
 
 struct ao_device_xbmc
 {
-  XFILE::CFilePipe *pipe;
+  XFILE::CPipeFile *pipe;
 };
 
 //audio output interface
@@ -94,7 +94,7 @@ ao_device* CAirTunesServer::AudioOutputFunctions::ao_open_live(int driver_id, ao
 {
   ao_device_xbmc* device = new ao_device_xbmc();
 
-  device->pipe = new XFILE::CFilePipe;
+  device->pipe = new XFILE::CPipeFile;
   device->pipe->OpenForWrite(XFILE::PipesManager::GetInstance().GetUniquePipeName());
   device->pipe->SetOpenThreashold(300);
 
@@ -115,9 +115,6 @@ ao_device* CAirTunesServer::AudioOutputFunctions::ao_open_live(int driver_id, ao
   CFileItem item;
   item.SetPath(device->pipe->GetName());
   item.SetMimeType("audio/x-xbmc-pcm");
-  item.SetProperty("isradio", true);
-  item.SetProperty("no-skip", true);
-  item.SetProperty("no-pause", true);
 
   if (ao_get_option(option, "artist"))
     item.GetMusicInfoTag()->SetArtist(ao_get_option(option, "artist"));
index 08d1d59..da893df 100644 (file)
@@ -37,7 +37,7 @@
 #include "threads/CriticalSection.h"
 #include "utils/HttpParser.h"
 #include "utils/StdString.h"
-#include "filesystem/FilePipe.h"
+#include "filesystem/PipeFile.h"
 
 class DllLibShairport;
 
index 2546b48..81ad974 100644 (file)
@@ -98,8 +98,8 @@ bool CEventPacket::Parse(int datasize, const void *data)
     }
     memcpy(m_pPayload, buf, (size_t)m_iPayloadSize);
   }
-
-  return  (m_bValid = true);
+  m_bValid = true;
+  return true;
 }
 
 #endif // HAS_EVENT_SERVER
index 4b0d9ad..3094583 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *      Copyright (C) 2005-2011 Team XBMC
+ *      Copyright (C) 2005-2012 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
@@ -32,6 +32,7 @@
 #include "utils/log.h"
 #include "utils/Variant.h"
 #include "threads/SingleLock.h"
+#include "websocket/WebSocketManager.h"
 
 static const char     bt_service_name[] = "XBMC JSON-RPC";
 static const char     bt_service_desc[] = "Interface for XBMC remote control over bluetooth";
@@ -112,9 +113,9 @@ void CTCPServer::Process()
 
     for (unsigned int i = 0; i < m_connections.size(); i++)
     {
-      FD_SET(m_connections[i].m_socket, &rfds);
-      if ((intptr_t)m_connections[i].m_socket > (intptr_t)max_fd)
-        max_fd = m_connections[i].m_socket;
+      FD_SET(m_connections[i]->m_socket, &rfds);
+      if ((intptr_t)m_connections[i]->m_socket > (intptr_t)max_fd)
+        max_fd = m_connections[i]->m_socket;
     }
 
     int res = select((intptr_t)max_fd+1, &rfds, NULL, NULL, &to);
@@ -128,7 +129,7 @@ void CTCPServer::Process()
     {
       for (int i = m_connections.size() - 1; i >= 0; i--)
       {
-        int socket = m_connections[i].m_socket;
+        int socket = m_connections[i]->m_socket;
         if (FD_ISSET(socket, &rfds))
         {
           char buffer[RECEIVEBUFFER] = {};
@@ -136,12 +137,33 @@ void CTCPServer::Process()
           nread = recv(socket, (char*)&buffer, RECEIVEBUFFER, 0);
           if (nread > 0)
           {
-            m_connections[i].PushBuffer(this, buffer, nread);
+            std::string response;
+            if (m_connections[i]->IsNew())
+            {
+              CWebSocket *websocket = CWebSocketManager::Handle(buffer, nread, response);
+
+              if (response.size() > 0)
+                m_connections[i]->Send(response.c_str(), response.size());
+
+              if (websocket != NULL)
+              {
+                // Replace the CTCPClient with a CWebSocketClient
+                CWebSocketClient *websocketClient = new CWebSocketClient(websocket, *(m_connections[i]));
+                delete m_connections[i];
+                m_connections.erase(m_connections.begin() + i);
+                m_connections.insert(m_connections.begin() + i, websocketClient);
+              }
+            }
+
+            if (response.size() <= 0)
+              m_connections[i]->PushBuffer(this, buffer, nread);
+
           }
           if (nread <= 0)
           {
             CLog::Log(LOGINFO, "JSONRPC Server: Disconnection detected");
-            m_connections[i].Disconnect();
+            m_connections[i]->Disconnect();
+            delete m_connections[i];
             m_connections.erase(m_connections.begin() + i);
           }
         }
@@ -152,10 +174,10 @@ void CTCPServer::Process()
         if (FD_ISSET(*it, &rfds))
         {
           CLog::Log(LOGDEBUG, "JSONRPC Server: New connection detected");
-          CTCPClient newconnection;
-          newconnection.m_socket = accept(*it, (sockaddr*)&newconnection.m_cliaddr, &newconnection.m_addrlen);
+          CTCPClient *newconnection = new CTCPClient();
+          newconnection->m_socket = accept(*it, (sockaddr*)&newconnection->m_cliaddr, &newconnection->m_addrlen);
 
-          if (newconnection.m_socket == INVALID_SOCKET)
+          if (newconnection->m_socket == INVALID_SOCKET)
             CLog::Log(LOGERROR, "JSONRPC Server: Accept of new connection failed");
           else
           {
@@ -185,24 +207,19 @@ int CTCPServer::GetCapabilities()
   return Response | Announcing;
 }
 
-void CTCPServer::Announce(EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
+void CTCPServer::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
 {
-  std::string str = AnnouncementToJSON(flag, sender, message, data, g_advancedSettings.m_jsonOutputCompact);
+  std::string str = IJSONRPCAnnouncer::AnnouncementToJSONRPC(flag, sender, message, data, g_advancedSettings.m_jsonOutputCompact);
 
   for (unsigned int i = 0; i < m_connections.size(); i++)
   {
     {
-      CSingleLock lock (m_connections[i].m_critSection);
-      if ((m_connections[i].GetAnnouncementFlags() & flag) == 0)
+      CSingleLock lock (m_connections[i]->m_critSection);
+      if ((m_connections[i]->GetAnnouncementFlags() & flag) == 0)
         continue;
     }
 
-    unsigned int sent = 0;
-    do
-    {
-      CSingleLock lock (m_connections[i].m_critSection);
-      sent += send(m_connections[i].m_socket, str.c_str(), str.size() - sent, sent);
-    } while (sent < str.size());
+    m_connections[i]->Send(str.c_str(), str.size());
   }
 }
 
@@ -447,7 +464,10 @@ bool CTCPServer::InitializeTCP()
 void CTCPServer::Deinitialize()
 {
   for (unsigned int i = 0; i < m_connections.size(); i++)
-    m_connections[i].Disconnect();
+  {
+    m_connections[i]->Disconnect();
+    delete m_connections[i];
+  }
 
   m_connections.clear();
 
@@ -467,6 +487,7 @@ void CTCPServer::Deinitialize()
 
 CTCPServer::CTCPClient::CTCPClient()
 {
+  m_new = true;
   m_announcementflags = ANNOUNCE_ALL;
   m_socket = INVALID_SOCKET;
   m_beginBrackets = 0;
@@ -504,8 +525,20 @@ bool CTCPServer::CTCPClient::SetAnnouncementFlags(int flags)
   return true;
 }
 
+void CTCPServer::CTCPClient::Send(const char *data, unsigned int size)
+{
+  unsigned int sent = 0;
+  do
+  {
+    CSingleLock lock (m_critSection);
+    sent += send(m_socket, data, size - sent, 0);
+  } while (sent < size);
+}
+
 void CTCPServer::CTCPClient::PushBuffer(CTCPServer *host, const char *buffer, int length)
 {
+  m_new = false;
+
   for (int i = 0; i < length; i++)
   {
     char c = buffer[i];
@@ -531,8 +564,7 @@ void CTCPServer::CTCPClient::PushBuffer(CTCPServer *host, const char *buffer, in
       if (m_beginBrackets > 0 && m_endBrackets > 0 && m_beginBrackets == m_endBrackets)
       {
         std::string line = CJSONRPC::MethodCall(m_buffer, host, this);
-        CSingleLock lock (m_critSection);
-        send(m_socket, line.c_str(), line.size(), 0);
+        Send(line.c_str(), line.size());
         m_beginChar = m_beginBrackets = m_endBrackets = 0;
         m_buffer.clear();
       }
@@ -553,6 +585,7 @@ void CTCPServer::CTCPClient::Disconnect()
 
 void CTCPServer::CTCPClient::Copy(const CTCPClient& client)
 {
+  m_new               = client.m_new;
   m_socket            = client.m_socket;
   m_cliaddr           = client.m_cliaddr;
   m_addrlen           = client.m_addrlen;
@@ -564,3 +597,88 @@ void CTCPServer::CTCPClient::Copy(const CTCPClient& client)
   m_buffer            = client.m_buffer;
 }
 
+CTCPServer::CWebSocketClient::CWebSocketClient(CWebSocket *websocket)
+{
+  m_websocket = websocket;
+}
+
+CTCPServer::CWebSocketClient::CWebSocketClient(const CWebSocketClient& client)
+{
+  Copy(client);
+
+  m_websocket = client.m_websocket; // TODO
+}
+
+CTCPServer::CWebSocketClient::CWebSocketClient(CWebSocket *websocket, const CTCPClient& client)
+{
+  Copy(client);
+
+  m_websocket = websocket;
+}
+
+CTCPServer::CWebSocketClient::~CWebSocketClient()
+{
+  delete m_websocket;
+}
+
+CTCPServer::CWebSocketClient& CTCPServer::CWebSocketClient::operator=(const CWebSocketClient& client)
+{
+  Copy(client);
+
+  m_websocket = client.m_websocket; // TODO
+
+  return *this;
+}
+
+void CTCPServer::CWebSocketClient::Send(const char *data, unsigned int size)
+{
+  const CWebSocketMessage *msg = m_websocket->Send(WebSocketTextFrame, data, size);
+  if (msg == NULL || !msg->IsComplete())
+    return;
+
+  std::vector<const CWebSocketFrame *> frames = msg->GetFrames();
+  for (unsigned int index = 0; index < frames.size(); index++)
+    CTCPClient::Send(frames.at(index)->GetFrameData(), (unsigned int)frames.at(index)->GetFrameLength());
+}
+
+void CTCPServer::CWebSocketClient::PushBuffer(CTCPServer *host, const char *buffer, int length)
+{
+  bool send;
+  const CWebSocketMessage *msg;
+  if ((msg = m_websocket->Handle(buffer, length, send)) != NULL && msg->IsComplete())
+  {
+    std::vector<const CWebSocketFrame *> frames = msg->GetFrames();
+    if (send)
+    {
+      for (unsigned int index = 0; index < frames.size(); index++)
+        Send(frames.at(index)->GetFrameData(), (unsigned int)frames.at(index)->GetFrameLength());
+    }
+    else
+    {
+      for (unsigned int index = 0; index < frames.size(); index++)
+        CTCPClient::PushBuffer(host, frames.at(index)->GetApplicationData(), (int)frames.at(index)->GetLength());
+    }
+
+    if (m_websocket->GetState() == WebSocketStateClosed)
+      Disconnect();
+
+    delete msg;
+  }
+}
+
+void CTCPServer::CWebSocketClient::Disconnect()
+{
+  if (m_socket > 0)
+  {
+    if (m_websocket->GetState() != WebSocketStateClosed && m_websocket->GetState() != WebSocketStateNotConnected)
+    {
+      const CWebSocketFrame *closeFrame = m_websocket->Close();
+      if (closeFrame)
+        Send(closeFrame->GetFrameData(), (unsigned int)closeFrame->GetFrameLength());
+    }
+
+    if (m_websocket->GetState() == WebSocketStateClosed)
+      CTCPClient::Disconnect();
+  }
+}
+
index 1d82097..a893e9f 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 /*
- *      Copyright (C) 2005-2011 Team XBMC
+ *      Copyright (C) 2005-2012 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
 
 #include <vector>
 #include <sys/socket.h>
-#include "interfaces/IAnnouncer.h"
+
+#include "interfaces/json-rpc/IClient.h"
+#include "interfaces/json-rpc/IJSONRPCAnnouncer.h"
 #include "interfaces/json-rpc/ITransportLayer.h"
-#include "threads/Thread.h"
 #include "threads/CriticalSection.h"
-#include "interfaces/json-rpc/JSONUtils.h"
+#include "threads/Thread.h"
+#include "websocket/WebSocket.h"
 
 namespace JSONRPC
 {
-  class CTCPServer : public ITransportLayer, public ANNOUNCEMENT::IAnnouncer, public CThread, protected CJSONUtils
+  class CTCPServer : public ITransportLayer, public JSONRPC::IJSONRPCAnnouncer, public CThread
   {
   public:
     static bool StartServer(int port, bool nonlocal);
@@ -40,7 +42,7 @@ namespace JSONRPC
     virtual bool Download(const char *path, CVariant &result);
     virtual int GetCapabilities();
 
-    virtual void Announce(ANNOUNCEMENT::EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data);
+    virtual void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data);
   protected:
     void Process();
   private:
@@ -58,26 +60,53 @@ namespace JSONRPC
       //when adding a member variable, make sure to copy it in CTCPClient::Copy
       CTCPClient(const CTCPClient& client);
       CTCPClient& operator=(const CTCPClient& client);
+      virtual ~CTCPClient() { };
+
       virtual int  GetPermissionFlags();
       virtual int  GetAnnouncementFlags();
       virtual bool SetAnnouncementFlags(int flags);
-      void PushBuffer(CTCPServer *host, const char *buffer, int length);
-      void Disconnect();
+
+      virtual void Send(const char *data, unsigned int size);
+      virtual void PushBuffer(CTCPServer *host, const char *buffer, int length);
+      virtual void Disconnect();
+
+      virtual bool IsNew() const { return m_new; }
 
       SOCKET           m_socket;
       sockaddr_storage m_cliaddr;
       socklen_t        m_addrlen;
       CCriticalSection m_critSection;
 
-    private:
+    protected:
       void Copy(const CTCPClient& client);
+    private:
+      bool m_new;
       int m_announcementflags;
       int m_beginBrackets, m_endBrackets;
       char m_beginChar, m_endChar;
       std::string m_buffer;
     };
 
-    std::vector<CTCPClient> m_connections;
+    class CWebSocketClient : public CTCPClient
+    {
+    public:
+      CWebSocketClient(CWebSocket *websocket);
+      CWebSocketClient(const CWebSocketClient& client);
+      CWebSocketClient(CWebSocket *websocket, const CTCPClient& client);
+      CWebSocketClient& operator=(const CWebSocketClient& client);
+      ~CWebSocketClient();
+
+      virtual void Send(const char *data, unsigned int size);
+      virtual void PushBuffer(CTCPServer *host, const char *buffer, int length);
+      virtual void Disconnect();
+
+      virtual bool IsNew() const { return m_websocket == NULL; }
+
+    private:
+      CWebSocket *m_websocket;
+    };
+
+    std::vector<CTCPClient*> m_connections;
     std::vector<SOCKET> m_servers;
     int m_port;
     bool m_nonlocal;
index 8eee7d7..b6db9b7 100644 (file)
@@ -221,7 +221,7 @@ class CUPnPServer : public PLT_MediaConnect
 {
 public:
     CUPnPServer(const char* friendly_name, const char* uuid = NULL, int port = 0) :
-        PLT_MediaConnect("", friendly_name, true, uuid, port) {
+        PLT_MediaConnect("", friendly_name, false, uuid, port) {
         // hack: override path to make sure it's empty
         // urls will contain full paths to local files
         m_Path = "";
@@ -929,14 +929,15 @@ CUPnPServer::Build(CFileItemPtr                  item,
         }
     }
 
-    // remap Root virtualpath://upnproot/ to id "0"
-    if (object->m_ObjectID == "virtualpath://upnproot/")
-        object->m_ObjectID = "0";
-
-    // remap Parent Root virtualpath://upnproot/ to id "0"
-    if (object->m_ParentID == "virtualpath://upnproot/")
-        object->m_ParentID = "0";
+    if (object) {
+        // remap Root virtualpath://upnproot/ to id "0"
+        if (object->m_ObjectID == "virtualpath://upnproot/")
+            object->m_ObjectID = "0";
 
+        // remap Parent Root virtualpath://upnproot/ to id "0"
+        if (object->m_ParentID == "virtualpath://upnproot/")
+            object->m_ParentID = "0";
+    }
     return object;
 
 failure:
index dd48642..fa4cee4 100644 (file)
 
 #include "WebServer.h"
 #ifdef HAS_WEB_SERVER
-#include "interfaces/http-api/HttpApi.h"
-#include "interfaces/json-rpc/JSONRPC.h"
 #include "filesystem/File.h"
-#include "filesystem/Directory.h"
-#include "URL.h"
 #include "utils/log.h"
 #include "utils/URIUtils.h"
 #include "utils/Variant.h"
+#include "utils/Base64.h"
 #include "threads/SingleLock.h"
 #include "XBDateTime.h"
-#include "addons/AddonManager.h"
 
 #ifdef _WIN32
 #pragma comment(lib, "libmicrohttpd.dll.lib")
 #endif
 
-#define MAX_STRING_POST_SIZE 20000
+#define MAX_POST_BUFFER_SIZE 2048
+
 #define PAGE_FILE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
-#define PAGE_JSONRPC_INFO   "<html><head><title>JSONRPC</title></head><body>JSONRPC active and working</body></html>"
 #define NOT_SUPPORTED       "<html><head><title>Not Supported</title></head><body>The method you are trying to use is not supported by this server</body></html>"
-#define DEFAULT_PAGE        "index.html"
 
-using namespace ADDON;
 using namespace XFILE;
 using namespace std;
 using namespace JSONRPC;
 
+vector<IHTTPRequestHandler *> CWebServer::m_requestHandlers;
+
 CWebServer::CWebServer()
 {
   m_running = false;
@@ -58,8 +54,15 @@ CWebServer::CWebServer()
 
 int CWebServer::FillArgumentMap(void *cls, enum MHD_ValueKind kind, const char *key, const char *value) 
 {
-  map<CStdString, CStdString> *arguments = (map<CStdString, CStdString> *)cls;
-  arguments->insert( pair<CStdString,CStdString>(key,value) );
+  map<string, string> *arguments = (map<string, string> *)cls;
+  arguments->insert(pair<string,string>(key,value));
+  return MHD_YES; 
+}
+
+int CWebServer::FillArgumentMultiMap(void *cls, enum MHD_ValueKind kind, const char *key, const char *value) 
+{
+  multimap<string, string> *arguments = (multimap<string, string> *)cls;
+  arguments->insert(pair<string,string>(key,value));
   return MHD_YES; 
 }
 
@@ -100,7 +103,7 @@ bool CWebServer::IsAuthenticated(CWebServer *server, struct MHD_Connection *conn
   if (strncmp (headervalue, strbase, strlen(strbase)))
     return false;
 
-  return server->m_Credentials64Encoded.Equals(headervalue + strlen(strbase));
+  return (server->m_Credentials64Encoded.compare(headervalue + strlen(strbase)) == 0);
 }
 
 #if (MHD_VERSION >= 0x00040001)
@@ -116,100 +119,215 @@ int CWebServer::AnswerToConnection(void *cls, struct MHD_Connection *connection,
 #endif
 {
   CWebServer *server = (CWebServer *)cls;
-  CStdString strURL = url;
-  CStdString originalURL = url;
   HTTPMethod methodType = GetMethod(method);
-  
+  HTTPRequest request = { connection, url, methodType, version, server };
+
   if (!IsAuthenticated(server, connection)) 
     return AskForAuthentication(connection);
 
-//  if (methodType != GET && methodType != POST) /* Only GET and POST supported, catch other method types here to avoid continual checking later on */
-//    return CreateErrorResponse(connection, MHD_HTTP_NOT_IMPLEMENTED, methodType);
-
-#ifdef HAS_JSONRPC
-  if (strURL.Equals("/jsonrpc"))
+  // Check if this is the first call to
+  // AnswerToConnection for this request
+  if (*con_cls == NULL)
   {
-    if (methodType == POST)
-      return JSONRPC(server, con_cls, connection, upload_data, upload_data_size);
-    else
-      return CreateMemoryDownloadResponse(connection, (void *)PAGE_JSONRPC_INFO, strlen(PAGE_JSONRPC_INFO));
+    // Look for a IHTTPRequestHandler which can
+    // take care of the current request
+    for (vector<IHTTPRequestHandler *>::const_iterator it = m_requestHandlers.begin(); it != m_requestHandlers.end(); it++)
+    {
+      IHTTPRequestHandler *requestHandler = *it;
+      if (requestHandler->CheckHTTPRequest(request))
+      {
+        // We found a matching IHTTPRequestHandler
+        // so let's get a new instance for this request
+        IHTTPRequestHandler *handler = requestHandler->GetInstance();
+
+        // If we got a POST request we need to take
+        // care of the POST data
+        if (methodType == POST)
+        {
+          ConnectionHandler *conHandler = new ConnectionHandler();
+          conHandler->requestHandler = handler;
+
+          // Get the content-type of the POST data
+          const char *contentType = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_CONTENT_TYPE);
+          // If the content-type is application/x-ww-form-urlencoded or multipart/form-data
+          // we can use MHD's POST processor
+          if (contentType != NULL && 
+             (stricmp(contentType, MHD_HTTP_POST_ENCODING_FORM_URLENCODED) == 0 || stricmp(contentType, MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA) == 0))
+          {
+            // Get a new MHD_PostProcessor
+            conHandler->postprocessor = MHD_create_post_processor(connection, MAX_POST_BUFFER_SIZE, &CWebServer::HandlePostField, (void*)conHandler);
+
+            // MHD doesn't seem to be able to handle
+            // this post request
+            if (conHandler->postprocessor == NULL)
+            {
+              delete conHandler->requestHandler;
+              delete conHandler;
+
+              return SendErrorResponse(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, methodType);
+            }
+          }
+          // otherwise we need to handle the POST data ourselves
+          // which is done in the next call to AnswerToConnection
+
+          *con_cls = (void*)conHandler;
+          return MHD_YES;
+        }
+        // No POST request so nothing special to handle
+        else
+          return HandleRequest(handler, request);
+      }
+    }
   }
-#endif
+  // This is a subsequent call to
+  // AnswerToConnection for this request
+  else
+  {
+    // Again we need to take special care
+    // of the POST data
+    if (methodType == POST)
+    {
+      ConnectionHandler *conHandler = (ConnectionHandler *)*con_cls;
+      if (conHandler->requestHandler == NULL)
+        return SendErrorResponse(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, methodType);
 
-#ifdef HAS_HTTPAPI
-  if ((methodType == GET || methodType == POST) && strURL.Left(18).Equals("/xbmcCmds/xbmcHttp"))
-    return HttpApi(connection);
-#endif
+      // We only need to handle POST data
+      // if there actually is data left to handle
+      if (*upload_data_size > 0)
+      {
+        // Either use MHD's POST processor
+        if (conHandler->postprocessor != NULL)
+          MHD_post_process(conHandler->postprocessor, upload_data, *upload_data_size);
+        // or simply copy the data to the handler
+        else
+          conHandler->requestHandler->AddPostData(upload_data, *upload_data_size);
 
-  if (strURL.Left(4).Equals("/vfs"))
-  {
-    strURL = strURL.Right(strURL.length() - 5);
-    CURL::Decode(strURL);
-    return CreateFileDownloadResponse(connection, strURL, methodType);
-  }
+        // Signal that we have handled the data
+        *upload_data_size = 0;
 
-#ifdef HAS_WEB_INTERFACE
-  AddonPtr addon;
-  CStdString addonPath;
-  bool useDefaultWebInterface = true;
-  if (strURL.Left(8).Equals("/addons/") || (strURL == "/addons"))
-  {
-    CStdStringArray components;
-    CUtil::Tokenize(strURL,components,"/");
-    if (components.size() > 1)
-    {
-      CAddonMgr::Get().GetAddon(components.at(1),addon);
-      if (addon)
+        return MHD_YES;
+      }
+      // We have handled all POST data
+      // so it's time to invoke the IHTTPRequestHandler
+      else
       {
-        size_t pos;
-        pos = strURL.find('/', 8); // /addons/ = 8 characters +1 to start behind the last slash
-        if (pos != CStdString::npos)
-          strURL = strURL.substr(pos);
-        else // missing trailing slash
-          return CreateRedirect(connection, originalURL += "/");
-
-        useDefaultWebInterface = false;
-        addonPath = addon->Path();
-        if (addon->Type() != ADDON_WEB_INTERFACE) // No need to append /htdocs for web interfaces
-          addonPath = URIUtils::AddFileToFolder(addonPath, "/htdocs/");
+        if (conHandler->postprocessor != NULL)
+          MHD_destroy_post_processor(conHandler->postprocessor);
+        *con_cls = NULL;
+
+        int ret = HandleRequest(conHandler->requestHandler, request);
+        delete conHandler;
+        return ret;
       }
     }
+    // It's unusual to get more than one call
+    // to AnswerToConnection for none-POST
+    // requests, but let's handle it anyway
     else
     {
-      if (strURL.length() < 8) // missing trailing slash
-        return CreateRedirect(connection, originalURL += "/");
-      else
-        return CreateAddonsListResponse(connection);
+      for (vector<IHTTPRequestHandler *>::const_iterator it = m_requestHandlers.begin(); it != m_requestHandlers.end(); it++)
+      {
+        IHTTPRequestHandler *requestHandler = *it;
+        if (requestHandler->CheckHTTPRequest(request))
+          return HandleRequest(requestHandler->GetInstance(), request);
+      }
     }
   }
 
-  if (strURL.Equals("/"))
-    strURL.Format("/%s", DEFAULT_PAGE);
+  return SendErrorResponse(connection, MHD_HTTP_NOT_FOUND, methodType);
+}
+
+#if (MHD_VERSION >= 0x00040001)
+int CWebServer::HandlePostField(void *cls, enum MHD_ValueKind kind, const char *key,
+                                const char *filename, const char *content_type,
+                                const char *transfer_encoding, const char *data, uint64_t off,
+                                size_t size)
+#else
+int CWebServer::HandlePostField(void *cls, enum MHD_ValueKind kind, const char *key,
+                                const char *filename, const char *content_type,
+                                const char *transfer_encoding, const char *data, uint64_t off,
+                                unsigned int size)
+#endif
+{
+  ConnectionHandler *conHandler = (ConnectionHandler *)cls;
+
+  if (conHandler == NULL || conHandler->requestHandler == NULL || size == 0)
+    return MHD_NO;
+
+  conHandler->requestHandler->AddPostField(key, string(data, size));
+  return MHD_YES;
+}
+
+int CWebServer::HandleRequest(IHTTPRequestHandler *handler, const HTTPRequest &request)
+{
+  if (handler == NULL)
+    return SendErrorResponse(request.connection, MHD_HTTP_INTERNAL_SERVER_ERROR, request.method);
+
+  int ret = handler->HandleHTTPRequest(request);
+  if (ret == MHD_NO)
+  {
+    delete handler;
+    return SendErrorResponse(request.connection, MHD_HTTP_INTERNAL_SERVER_ERROR, request.method);
+  }
 
-  if (useDefaultWebInterface)
+  struct MHD_Response *response = NULL;
+  switch (handler->GetHTTPResponseType())
   {
-    CAddonMgr::Get().GetDefault(ADDON_WEB_INTERFACE,addon);
-    if (addon)
-      addonPath = addon->Path();
+    case HTTPNone:
+      delete handler;
+      return MHD_NO;
+
+    case HTTPRedirect:
+      ret = CreateRedirect(request.connection, handler->GetHTTPRedirectUrl(), response);
+      break;
+
+    case HTTPFileDownload:
+      ret = CreateFileDownloadResponse(request.connection, handler->GetHTTPResponseFile(), request.method, response);
+      break;
+
+    case HTTPMemoryDownloadNoFreeNoCopy:
+      ret = CreateMemoryDownloadResponse(request.connection, handler->GetHTTPResponseData(), handler->GetHTTPResonseDataLength(), false, false, response);
+      break;
+
+    case HTTPMemoryDownloadNoFreeCopy:
+      ret = CreateMemoryDownloadResponse(request.connection, handler->GetHTTPResponseData(), handler->GetHTTPResonseDataLength(), false, true, response);
+      break;
+
+    case HTTPMemoryDownloadFreeNoCopy:
+      ret = CreateMemoryDownloadResponse(request.connection, handler->GetHTTPResponseData(), handler->GetHTTPResonseDataLength(), true, false, response);
+      break;
+
+    case HTTPMemoryDownloadFreeCopy:
+      ret = CreateMemoryDownloadResponse(request.connection, handler->GetHTTPResponseData(), handler->GetHTTPResonseDataLength(), true, true, response);
+      break;
+
+    case HTTPError:
+      ret = CreateErrorResponse(request.connection, handler->GetHTTPResonseCode(), request.method, response);
+      break;
+
+    default:
+      delete handler;
+      return SendErrorResponse(request.connection, MHD_HTTP_INTERNAL_SERVER_ERROR, request.method);
   }
 
-  if (addon)
-    strURL = URIUtils::AddFileToFolder(addon->Path(),strURL);
-  if (CDirectory::Exists(strURL))
+  if (ret == MHD_NO)
   {
-    if (strURL.Right(1).Equals("/"))
-      strURL += DEFAULT_PAGE;
-    else
-      return CreateRedirect(connection, originalURL += "/");
+    delete handler;
+    return SendErrorResponse(request.connection, MHD_HTTP_INTERNAL_SERVER_ERROR, request.method);
   }
-  return CreateFileDownloadResponse(connection, strURL, methodType);
 
-#endif
+  multimap<string, string> header = handler->GetHTTPResponseHeaderFields();
+  for (multimap<string, string>::const_iterator it = header.begin(); it != header.end(); it++)
+    MHD_add_response_header(response, it->first.c_str(), it->second.c_str());
 
-  return MHD_NO;
+  MHD_queue_response(request.connection, handler->GetHTTPResonseCode(), response);
+  MHD_destroy_response(response);
+  delete handler;
+
+  return MHD_YES;
 }
 
-CWebServer::HTTPMethod CWebServer::GetMethod(const char *method)
+HTTPMethod CWebServer::GetMethod(const char *method)
 {
   if (strcmp(method, "GET") == 0)
     return GET;
@@ -221,102 +339,42 @@ CWebServer::HTTPMethod CWebServer::GetMethod(const char *method)
   return UNKNOWN;
 }
 
-#if (MHD_VERSION >= 0x00040001)
-int CWebServer::JSONRPC(CWebServer *server, void **con_cls, struct MHD_Connection *connection, const char *upload_data, size_t *upload_data_size)
-#else
-int CWebServer::JSONRPC(CWebServer *server, void **con_cls, struct MHD_Connection *connection, const char *upload_data, unsigned int *upload_data_size)
-#endif
+int CWebServer::CreateRedirect(struct MHD_Connection *connection, const string &strURL, struct MHD_Response *&response)
 {
-#ifdef HAS_JSONRPC
-  if ((*con_cls) == NULL)
+  response = MHD_create_response_from_data (0, NULL, MHD_NO, MHD_NO);
+  if (response)
   {
-    *con_cls = new CStdString();
-
+    MHD_add_response_header(response, "Location", strURL.c_str());
     return MHD_YES;
   }
-  if (*upload_data_size) 
-  {
-    CStdString *post = (CStdString *)(*con_cls);
-    if (*upload_data_size + post->size() > MAX_STRING_POST_SIZE)
-    {
-      CLog::Log(LOGERROR, "WebServer: Stopped uploading post since it exceeded size limitations");
-      return MHD_NO;
-    }
-    else
-    {
-      post->append(upload_data, *upload_data_size);
-      *upload_data_size = 0;
-      return MHD_YES;
-    }
-  }
-  else
-  {
-    CStdString *jsoncall = (CStdString *)(*con_cls);
-
-    CHTTPClient client;
-    CStdString jsonresponse = CJSONRPC::MethodCall(*jsoncall, server, &client);
-
-    struct MHD_Response *response = MHD_create_response_from_data(jsonresponse.length(), (void *) jsonresponse.c_str(), MHD_NO, MHD_YES);
-    int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
-    MHD_add_response_header(response, "Content-Type", "application/json");
-    MHD_destroy_response(response);
-
-    delete jsoncall;
-    return ret;
-  }
-#else
   return MHD_NO;
-#endif
 }
 
-int CWebServer::HttpApi(struct MHD_Connection *connection)
+int CWebServer::CreateFileDownloadResponse(struct MHD_Connection *connection, const string &strURL, HTTPMethod methodType, struct MHD_Response *&response)
 {
-#ifdef HAS_HTTPAPI
-  map<CStdString, CStdString> arguments;
-  if (MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, FillArgumentMap, &arguments) > 0)
-  {
-    CStdString httpapiresponse = CHttpApi::WebMethodCall(arguments["command"], arguments["parameter"]);
-
-    struct MHD_Response *response = MHD_create_response_from_data(httpapiresponse.length(), (void *) httpapiresponse.c_str(), MHD_NO, MHD_YES);
-    int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
-    MHD_destroy_response(response);
-
-    return ret;
-  }
-#endif
-  return MHD_NO;
-}
-
-int CWebServer::CreateRedirect(struct MHD_Connection *connection, const CStdString &strURL)
-{
-  struct MHD_Response *response = MHD_create_response_from_data (0, NULL, MHD_NO, MHD_NO);
-  int ret = MHD_queue_response (connection, MHD_HTTP_FOUND, response);
-  MHD_add_response_header(response, "Location", strURL);
-  MHD_destroy_response (response);
-  return ret;
-}
-
-int CWebServer::CreateFileDownloadResponse(struct MHD_Connection *connection, const CStdString &strURL, HTTPMethod methodType)
-{
-  int ret = MHD_NO;
   CFile *file = new CFile();
 
   if (file->Open(strURL, READ_NO_CACHE))
   {
-    struct MHD_Response *response;
     if (methodType != HEAD)
     {
       response = MHD_create_response_from_callback ( file->GetLength(),
                                                      2048,
                                                      &CWebServer::ContentReaderCallback, file,
-                                                     &CWebServer::ContentReaderFreeCallback); 
-    } else {
+                                                     &CWebServer::ContentReaderFreeCallback);
+      if (response == NULL)
+        return MHD_NO;
+    }
+    else
+    {
       CStdString contentLength;
       contentLength.Format("%I64d", file->GetLength());
       file->Close();
       delete file;
 
       response = MHD_create_response_from_data (0, NULL, MHD_NO, MHD_NO);
+      if (response == NULL)
+        return MHD_NO;
       MHD_add_response_header(response, "Content-Length", contentLength);
     }
 
@@ -329,23 +387,18 @@ int CWebServer::CreateFileDownloadResponse(struct MHD_Connection *connection, co
     CDateTime expiryTime = CDateTime::GetCurrentDateTime();
     expiryTime += CDateTimeSpan(1, 0, 0, 0);
     MHD_add_response_header(response, "Expires", expiryTime.GetAsRFC1123DateTime());
-
-    ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
-
-    MHD_destroy_response(response);
   }
   else
   {
     delete file;
     CLog::Log(LOGERROR, "WebServer: Failed to open %s", strURL.c_str());
-    return CreateErrorResponse(connection, MHD_HTTP_NOT_FOUND, GET); /* GET Assumed Temporarily */
+    return SendErrorResponse(connection, MHD_HTTP_NOT_FOUND, GET); /* GET Assumed Temporarily */
   }
-  return ret;
+  return MHD_YES;
 }
 
-int CWebServer::CreateErrorResponse(struct MHD_Connection *connection, int responseType, HTTPMethod method)
+int CWebServer::CreateErrorResponse(struct MHD_Connection *connection, int responseType, HTTPMethod method, struct MHD_Response *&response)
 {
-  int ret = MHD_NO;
   size_t payloadSize = 0;
   void *payload = NULL;
 
@@ -364,37 +417,30 @@ int CWebServer::CreateErrorResponse(struct MHD_Connection *connection, int respo
     }
   }
 
-  struct MHD_Response *response = MHD_create_response_from_data (payloadSize, payload, MHD_NO, MHD_NO);
-  ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
-  MHD_destroy_response (response);
-  return ret;
+  response = MHD_create_response_from_data (payloadSize, payload, MHD_NO, MHD_NO);
+  if (response)
+    return MHD_YES;
+  return MHD_NO;
 }
 
-int CWebServer::CreateMemoryDownloadResponse(struct MHD_Connection *connection, void *data, size_t size)
+int CWebServer::CreateMemoryDownloadResponse(struct MHD_Connection *connection, void *data, size_t size, bool free, bool copy, struct MHD_Response *&response)
 {
-  struct MHD_Response *response = MHD_create_response_from_data (size, data, MHD_NO, MHD_NO);
-  int ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
-  MHD_destroy_response (response);
-  return ret;
+  response = MHD_create_response_from_data (size, data, free ? MHD_YES : MHD_NO, copy ? MHD_YES : MHD_NO);
+  if (response)
+    return MHD_YES;
+  return MHD_NO;
 }
 
-int CWebServer::CreateAddonsListResponse(struct MHD_Connection *connection)
+int CWebServer::SendErrorResponse(struct MHD_Connection *connection, int errorType, HTTPMethod method)
 {
-  CStdString responseData = "<html><head><title>Add-on List</title></head><body>\n<h1>Available web interfaces:</h1>\n<ul>\n";
-  VECADDONS addons;
-  CAddonMgr::Get().GetAddons(ADDON_WEB_INTERFACE, addons);
-  IVECADDONS addons_it;
-  for (addons_it=addons.begin(); addons_it!=addons.end(); addons_it++)
-    responseData += "<li><a href=/addons/"+ (*addons_it)->ID() + "/>" + (*addons_it)->Name() + "</a></li>\n";
-
-  responseData += "</ul>\n</body></html>";
-
-  struct MHD_Response *response = MHD_create_response_from_data (responseData.length(), (void *)responseData.c_str(), MHD_NO, MHD_YES);
-  if (!response)
-    return MHD_NO;
+  struct MHD_Response *response = NULL;
+  int ret = CreateErrorResponse(connection, errorType, method, response);
+  if (ret == MHD_YES)
+  {
+    ret = MHD_queue_response (connection, errorType, response);
+    MHD_destroy_response (response);
+  }
 
-  int ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
-  MHD_destroy_response (response);
   return ret;
 }
 
@@ -439,14 +485,14 @@ struct MHD_Daemon* CWebServer::StartMHD(unsigned int flags, int port)
                           &CWebServer::AnswerToConnection,
                           this,
 #if (MHD_VERSION >= 0x00040002)
-                          MHD_OPTION_THREAD_POOL_SIZE, 1,
+                          MHD_OPTION_THREAD_POOL_SIZE, 4,
 #endif
                           MHD_OPTION_CONNECTION_LIMIT, 512,
                           MHD_OPTION_CONNECTION_TIMEOUT, timeout,
                           MHD_OPTION_END);
 }
 
-bool CWebServer::Start(int port, const CStdString &username, const CStdString &password)
+bool CWebServer::Start(int port, const string &username, const string &password)
 {
   SetCredentials(username, password);
   if (!m_running)
@@ -480,45 +526,13 @@ bool CWebServer::IsStarted()
   return m_running;
 }
 
-void CWebServer::StringToBase64(const char *input, CStdString &output)
-{
-  const char *lookup = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  unsigned long l;
-  size_t length = strlen (input);
-  output = "";
-
-  for (unsigned int i = 0; i < length; i += 3)
-  {
-    l = (((unsigned long) input[i]) << 16)
-      | (((i + 1) < length) ? (((unsigned long) input[i + 1]) << 8) : 0)
-      | (((i + 2) < length) ? ((unsigned long) input[i + 2]) : 0);
-
-
-    output.push_back(lookup[(l >> 18) & 0x3F]);
-    output.push_back(lookup[(l >> 12) & 0x3F]);
-
-    if (i + 1 < length)
-      output.push_back(lookup[(l >> 6) & 0x3F]);
-    if (i + 2 < length)
-      output.push_back(lookup[l & 0x3F]);
-  }
-
-  int left = 3 - (length % 3);
-
-  if (length % 3)
-  {
-    for (int i = 0; i < left; i++)
-      output.push_back('=');
-  }
-}
-
-void CWebServer::SetCredentials(const CStdString &username, const CStdString &password)
+void CWebServer::SetCredentials(const string &username, const string &password)
 {
   CSingleLock lock (m_critSection);
   CStdString str = username + ":" + password;
 
-  StringToBase64(str.c_str(), m_Credentials64Encoded);
-  m_needcredentials = !password.IsEmpty();
+  Base64::Encode(str.c_str(), m_Credentials64Encoded);
+  m_needcredentials = !password.empty();
 }
 
 bool CWebServer::PrepareDownload(const char *path, CVariant &details, std::string &protocol)
@@ -556,6 +570,65 @@ int CWebServer::GetCapabilities()
   return Response | FileDownloadRedirect;
 }
 
+void CWebServer::RegisterRequestHandler(IHTTPRequestHandler *handler)
+{
+  if (handler == NULL)
+    return;
+
+  for (vector<IHTTPRequestHandler *>::iterator it = m_requestHandlers.begin(); it != m_requestHandlers.end(); it++)
+  {
+    if (*it == handler)
+      return;
+
+    if ((*it)->GetPriority() < handler->GetPriority())
+    {
+      m_requestHandlers.insert(it, handler);
+      return;
+    }
+  }
+
+  m_requestHandlers.push_back(handler);
+}
+
+void CWebServer::UnregisterRequestHandler(IHTTPRequestHandler *handler)
+{
+  if (handler == NULL)
+    return;
+
+  for (vector<IHTTPRequestHandler *>::iterator it = m_requestHandlers.begin(); it != m_requestHandlers.end(); it++)
+  {
+    if (*it == handler)
+    {
+      m_requestHandlers.erase(it);
+      return;
+    }
+  }
+}
+
+std::string CWebServer::GetRequestHeaderValue(struct MHD_Connection *connection, enum MHD_ValueKind kind, const std::string &key)
+{
+  if (connection == NULL)
+    return "";
+
+  return MHD_lookup_connection_value(connection, kind, key.c_str());
+}
+
+int CWebServer::GetRequestHeaderValues(struct MHD_Connection *connection, enum MHD_ValueKind kind, std::map<std::string, std::string> &headerValues)
+{
+  if (connection == NULL)
+    return -1;
+
+  return MHD_get_connection_values(connection, kind, FillArgumentMap, &headerValues);
+}
+
+int CWebServer::GetRequestHeaderValues(struct MHD_Connection *connection, enum MHD_ValueKind kind, std::multimap<std::string, std::string> &headerValues)
+{
+  if (connection == NULL)
+    return -1;
+
+  return MHD_get_connection_values(connection, kind, FillArgumentMultiMap, &headerValues);
+}
+
 const char *CWebServer::CreateMimeTypeFromExtension(const char *ext)
 {
   if (strcmp(ext, ".aif") == 0)   return "audio/aiff";
@@ -612,20 +685,4 @@ const char *CWebServer::CreateMimeTypeFromExtension(const char *ext)
   if (strcmp(ext, ".css") == 0)   return "text/css";
   return NULL;
 }
-
-int CWebServer::CHTTPClient::GetPermissionFlags()
-{
-  return OPERATION_PERMISSION_ALL;
-}
-
-int CWebServer::CHTTPClient::GetAnnouncementFlags()
-{
-  // Does not support broadcast
-  return 0;
-}
-
-bool CWebServer::CHTTPClient::SetAnnouncementFlags(int flags)
-{
-  return false;
-}
 #endif
index ab97956..099d07c 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 /*
- *      Copyright (C) 2005-2010 Team XBMC
+ *      Copyright (C) 2005-2012 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
@@ -22,7 +22,6 @@
 
 #include "system.h"
 #ifdef HAS_WEB_SERVER
-#include "utils/StdString.h"
 #include <sys/types.h>
 #include <sys/select.h>
 #include <sys/socket.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdint.h>
-#ifdef __APPLE__
-#include "lib/libmicrohttpd/src/include/microhttpd.h"
-#else
-#include <microhttpd.h>
-#endif
+#include <vector>
 #include "interfaces/json-rpc/ITransportLayer.h"
 #include "threads/CriticalSection.h"
+#include "httprequesthandler/IHTTPRequestHandler.h"
 
 class CWebServer : public JSONRPC::ITransportLayer
 {
 public:
   CWebServer();
+  virtual ~CWebServer() { }
 
-  bool Start(int port, const CStdString &username, const CStdString &password);
+  bool Start(int port, const std::string &username, const std::string &password);
   bool Stop();
   bool IsStarted();
-  void SetCredentials(const CStdString &username, const CStdString &password);
+  void SetCredentials(const std::string &username, const std::string &password);
 
   virtual bool PrepareDownload(const char *path, CVariant &details, std::string &protocol);
   virtual bool Download(const char *path, CVariant &result);
   virtual int GetCapabilities();
+
+  static void RegisterRequestHandler(IHTTPRequestHandler *handler);
+  static void UnregisterRequestHandler(IHTTPRequestHandler *handler);
+
+  static std::string GetRequestHeaderValue(struct MHD_Connection *connection, enum MHD_ValueKind kind, const std::string &key);
+  static int GetRequestHeaderValues(struct MHD_Connection *connection, enum MHD_ValueKind kind, std::map<std::string, std::string> &headerValues);
+  static int GetRequestHeaderValues(struct MHD_Connection *connection, enum MHD_ValueKind kind, std::multimap<std::string, std::string> &headerValues);
 private:
-  enum HTTPMethod
-  {
-    UNKNOWN,
-    POST,
-    GET,
-    HEAD
-  };
   struct MHD_Daemon* StartMHD(unsigned int flags, int port);
   static int AskForAuthentication (struct MHD_Connection *connection);
   static bool IsAuthenticated (CWebServer *server, struct MHD_Connection *connection);
@@ -72,43 +69,49 @@ private:
 #endif
 
 #if (MHD_VERSION >= 0x00040001)
-  static int JSONRPC(CWebServer *server, void **con_cls, struct MHD_Connection *connection, const char *upload_data, size_t *upload_data_size);
   static int AnswerToConnection (void *cls, struct MHD_Connection *connection,
                         const char *url, const char *method,
                         const char *version, const char *upload_data,
                         size_t *upload_data_size, void **con_cls);
+  static int HandlePostField(void *cls, enum MHD_ValueKind kind, const char *key,
+                             const char *filename, const char *content_type,
+                             const char *transfer_encoding, const char *data, uint64_t off,
+                             size_t size);
 #else   //libmicrohttpd < 0.4.0
-  static int JSONRPC(CWebServer *server, void **con_cls, struct MHD_Connection *connection, const char *upload_data, unsigned int *upload_data_size);
   static int AnswerToConnection (void *cls, struct MHD_Connection *connection,
                         const char *url, const char *method,
                         const char *version, const char *upload_data,
                         unsigned int *upload_data_size, void **con_cls);
+  static int HandlePostField(void *cls, enum MHD_ValueKind kind, const char *key,
+                             const char *filename, const char *content_type,
+                             const char *transfer_encoding, const char *data, uint64_t off,
+                             unsigned int size);
 #endif
+  static int HandleRequest(IHTTPRequestHandler *handler, const HTTPRequest &request);
   static void ContentReaderFreeCallback (void *cls);
-  static int HttpApi(struct MHD_Connection *connection);
-  static HTTPMethod GetMethod(const char *method);
-  static int CreateRedirect(struct MHD_Connection *connection, const CStdString &strURL);
-  static int CreateFileDownloadResponse(struct MHD_Connection *connection, const CStdString &strURL, HTTPMethod methodType);
-  static int CreateErrorResponse(struct MHD_Connection *connection, int responseType, HTTPMethod method);
-  static int CreateMemoryDownloadResponse(struct MHD_Connection *connection, void *data, size_t size);
-  static int CreateAddonsListResponse(struct MHD_Connection *connection);
+  static int CreateRedirect(struct MHD_Connection *connection, const std::string &strURL, struct MHD_Response *&response);
+  static int CreateFileDownloadResponse(struct MHD_Connection *connection, const std::string &strURL, HTTPMethod methodType, struct MHD_Response *&response);
+  static int CreateErrorResponse(struct MHD_Connection *connection, int responseType, HTTPMethod method, struct MHD_Response *&response);
+  static int CreateMemoryDownloadResponse(struct MHD_Connection *connection, void *data, size_t size, bool free, bool copy, struct MHD_Response *&response);
 
+  static int SendErrorResponse(struct MHD_Connection *connection, int errorType, HTTPMethod method);
+  
+  static HTTPMethod GetMethod(const char *method);
   static int FillArgumentMap(void *cls, enum MHD_ValueKind kind, const char *key, const char *value);
-  static void StringToBase64(const char *input, CStdString &output);
+  static int FillArgumentMultiMap(void *cls, enum MHD_ValueKind kind, const char *key, const char *value);
 
   static const char *CreateMimeTypeFromExtension(const char *ext);
 
   struct MHD_Daemon *m_daemon;
   bool m_running, m_needcredentials;
-  CStdString m_Credentials64Encoded;
+  std::string m_Credentials64Encoded;
   CCriticalSection m_critSection;
+  static std::vector<IHTTPRequestHandler *> m_requestHandlers;
 
-  class CHTTPClient : public JSONRPC::IClient
+  typedef struct ConnectionHandler
   {
-  public:
-    virtual int  GetPermissionFlags();
-    virtual int  GetAnnouncementFlags();
-    virtual bool SetAnnouncementFlags(int flags);
-  };
+    IHTTPRequestHandler *requestHandler;
+    struct MHD_PostProcessor *postprocessor;
+  } ConnectionHandler;
 };
 #endif
index 238111d..443b6ea 100644 (file)
@@ -399,41 +399,21 @@ void Xcddb::addTitle(const char *buffer)
   }
 
   // track artist" / "track title
-  char artist[1024];
-  char title[1024];
-  unsigned int len = (unsigned int)strlen(value);
-  bool found = false;
-  unsigned int index;
-  for (index = 0;index < len;index++)
-  {
-    if ((index + 2) <= len && value[index] == ' ' && value[index + 1] == '/' && value[index + 2] == ' ')
-    {
-      // Jep found
-      found = true;
-      break;
-    }
-  }
-  if (found)
+  CStdString strValue = value;
+  CStdStringArray values;
+  StringUtils::SplitString(value, " / ", values);
+  if (values.size() > 1)
   {
-    strncpy(artist, value, index);
-    artist[index] = '\0';
-    strcpy(title, value + index + 3);
+    g_charsetConverter.unknownToUTF8(values[0]);
+    m_mapArtists[trk_nr] += values[0];
+    g_charsetConverter.unknownToUTF8(values[1]);
+    m_mapTitles[trk_nr] += values[1];
   }
   else
   {
-    artist[0] = '\0';
-    strcpy(title, value);
+    g_charsetConverter.unknownToUTF8(values[0]);
+    m_mapTitles[trk_nr] += values[0];
   }
-
-  CStdString strArtist=artist;
-  // You never know if you really get UTF-8 strings from cddb
-  g_charsetConverter.unknownToUTF8(artist, strArtist);
-  m_mapArtists[trk_nr] += strArtist;
-
-  CStdString strTitle=title;
-  // You never know if you really get UTF-8 strings from cddb
-  g_charsetConverter.unknownToUTF8(title, strTitle);
-  m_mapTitles[trk_nr] += strTitle;
 }
 
 //-------------------------------------------------------------------------------------------------------------------
diff --git a/xbmc/network/httprequesthandler/HTTPApiHandler.cpp b/xbmc/network/httprequesthandler/HTTPApiHandler.cpp
new file mode 100644 (file)
index 0000000..64f6eb3
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <map>
+
+#include "HTTPApiHandler.h"
+#include "interfaces/http-api/HttpApi.h"
+#include "network/WebServer.h"
+
+using namespace std;
+
+bool CHTTPApiHandler::CheckHTTPRequest(const HTTPRequest &request)
+{
+  return ((request.method == GET || request.method == POST) && request.url.find("/xbmcCmds/xbmcHttp") == 0);
+}
+
+int CHTTPApiHandler::HandleHTTPRequest(const HTTPRequest &request)
+{
+  map<string, string> arguments;
+  if (CWebServer::GetRequestHeaderValues(request.connection, MHD_GET_ARGUMENT_KIND, arguments) > 0)
+  {
+    m_responseCode = MHD_HTTP_OK;
+    m_responseType = HTTPMemoryDownloadNoFreeCopy;
+    CStdString command = arguments["command"];
+    CStdString parameter = arguments["parameter"];
+    m_response = CHttpApi::WebMethodCall(command, parameter);
+
+    return MHD_YES;
+  }
+
+  return MHD_NO;
+}
diff --git a/xbmc/network/httprequesthandler/HTTPApiHandler.h b/xbmc/network/httprequesthandler/HTTPApiHandler.h
new file mode 100644 (file)
index 0000000..f05bd7f
--- /dev/null
@@ -0,0 +1,41 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IHTTPRequestHandler.h"
+
+class CHTTPApiHandler : public IHTTPRequestHandler
+{
+public:
+  CHTTPApiHandler() { };
+
+  virtual IHTTPRequestHandler* GetInstance() { return new CHTTPApiHandler(); }
+  virtual bool CheckHTTPRequest(const HTTPRequest &request);
+  virtual int HandleHTTPRequest(const HTTPRequest &request);
+
+  virtual void* GetHTTPResponseData() const { return (void *)m_response.c_str(); };
+  virtual size_t GetHTTPResonseDataLength() const { return m_response.size(); }
+
+  virtual int GetPriority() const { return 2; }
+
+private:
+  std::string m_response;
+};
diff --git a/xbmc/network/httprequesthandler/HTTPJsonRpcHandler.cpp b/xbmc/network/httprequesthandler/HTTPJsonRpcHandler.cpp
new file mode 100644 (file)
index 0000000..b7385af
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "HTTPJsonRpcHandler.h"
+#include "network/WebServer.h"
+#include "utils/log.h"
+#include "interfaces/json-rpc/JSONRPC.h"
+#include "interfaces/json-rpc/JSONUtils.h"
+
+#define MAX_STRING_POST_SIZE 20000
+#define PAGE_JSONRPC_INFO   "<html><head><title>JSONRPC</title></head><body>JSONRPC active and working</body></html>"
+
+using namespace std;
+using namespace JSONRPC;
+
+bool CHTTPJsonRpcHandler::CheckHTTPRequest(const HTTPRequest &request)
+{
+  return (request.url.compare("/jsonrpc") == 0);
+}
+
+int CHTTPJsonRpcHandler::HandleHTTPRequest(const HTTPRequest &request)
+{
+  if (request.method == POST)
+  {
+    // The content-type of the request must be application/json
+    if (CWebServer::GetRequestHeaderValue(request.connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_CONTENT_TYPE).compare("application/json") != 0)
+    {
+      m_responseType = HTTPError;
+      m_responseCode = MHD_HTTP_UNSUPPORTED_MEDIA_TYPE;
+      return MHD_YES;
+    }
+
+    CHTTPClient client;
+    m_response = CJSONRPC::MethodCall(m_request, request.webserver, &client);
+
+    m_responseHeaderFields.insert(pair<string, string>("Content-Type", "application/json"));
+
+    m_request.clear();
+  }
+  else
+    m_response = PAGE_JSONRPC_INFO;
+  
+  m_responseType = HTTPMemoryDownloadNoFreeCopy;
+  m_responseCode = MHD_HTTP_OK;
+
+  return MHD_YES;
+}
+
+#if (MHD_VERSION >= 0x00040001)
+bool CHTTPJsonRpcHandler::appendPostData(const char *data, size_t size)
+#else
+bool CHTTPJsonRpcHandler::appendPostData(const char *data, unsigned int size)
+#endif
+{
+  if (m_request.size() + size > MAX_STRING_POST_SIZE)
+  {
+    CLog::Log(LOGERROR, "WebServer: Stopped uploading post since it exceeded size limitations");
+    return false;
+  }
+
+  m_request.append(data, size);
+
+  return true;
+}
+
+int CHTTPJsonRpcHandler::CHTTPClient::GetPermissionFlags()
+{
+  return OPERATION_PERMISSION_ALL;
+}
+
+int CHTTPJsonRpcHandler::CHTTPClient::GetAnnouncementFlags()
+{
+  // Does not support broadcast
+  return 0;
+}
+
+bool CHTTPJsonRpcHandler::CHTTPClient::SetAnnouncementFlags(int flags)
+{
+  return false;
+}
diff --git a/xbmc/network/httprequesthandler/HTTPJsonRpcHandler.h b/xbmc/network/httprequesthandler/HTTPJsonRpcHandler.h
new file mode 100644 (file)
index 0000000..e8c5453
--- /dev/null
@@ -0,0 +1,58 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IHTTPRequestHandler.h"
+#include "interfaces/json-rpc/IClient.h"
+
+class CHTTPJsonRpcHandler : public IHTTPRequestHandler
+{
+public:
+  CHTTPJsonRpcHandler() { };
+  
+  virtual IHTTPRequestHandler* GetInstance() { return new CHTTPJsonRpcHandler(); }
+  virtual bool CheckHTTPRequest(const HTTPRequest &request);
+  virtual int HandleHTTPRequest(const HTTPRequest &request);
+
+  virtual void* GetHTTPResponseData() const { return (void *)m_response.c_str(); };
+  virtual size_t GetHTTPResonseDataLength() const { return m_response.size(); }
+
+  virtual int GetPriority() const { return 2; }
+
+protected:
+#if (MHD_VERSION >= 0x00040001)
+  virtual bool appendPostData(const char *data, size_t size);
+#else
+  virtual bool appendPostData(const char *data, unsigned int size);
+#endif
+
+private:
+  std::string m_request;
+  std::string m_response;
+
+  class CHTTPClient : public JSONRPC::IClient
+  {
+  public:
+    virtual int  GetPermissionFlags();
+    virtual int  GetAnnouncementFlags();
+    virtual bool SetAnnouncementFlags(int flags);
+  };
+};
diff --git a/xbmc/network/httprequesthandler/HTTPVfsHandler.cpp b/xbmc/network/httprequesthandler/HTTPVfsHandler.cpp
new file mode 100644 (file)
index 0000000..4c83459
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "HTTPVfsHandler.h"
+#include "network/WebServer.h"
+#include "URL.h"
+#include "filesystem/File.h"
+
+using namespace std;
+
+bool CHTTPVfsHandler::CheckHTTPRequest(const HTTPRequest &request)
+{
+  return (request.url.find("/vfs") == 0);
+}
+
+int CHTTPVfsHandler::HandleHTTPRequest(const HTTPRequest &request)
+{
+  if (request.url.size() > 5)
+  {
+    m_path = request.url.substr(5);
+
+    if (XFILE::CFile::Exists(m_path))
+    {
+      m_responseCode = MHD_HTTP_OK;
+      m_responseType = HTTPFileDownload;
+    }
+    else
+    {
+      m_responseCode = MHD_HTTP_NOT_FOUND;
+      m_responseType = HTTPError;
+    }
+  }
+  else
+  {
+    m_responseCode = MHD_HTTP_BAD_REQUEST;
+    m_responseType = HTTPError;
+  }
+
+  return MHD_YES;
+}
diff --git a/xbmc/network/httprequesthandler/HTTPVfsHandler.h b/xbmc/network/httprequesthandler/HTTPVfsHandler.h
new file mode 100644 (file)
index 0000000..c6efbf6
--- /dev/null
@@ -0,0 +1,42 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IHTTPRequestHandler.h"
+
+#include "utils/StdString.h"
+
+class CHTTPVfsHandler : public IHTTPRequestHandler
+{
+public:
+  CHTTPVfsHandler() { };
+  
+  virtual IHTTPRequestHandler* GetInstance() { return new CHTTPVfsHandler(); }
+  virtual bool CheckHTTPRequest(const HTTPRequest &request);
+  virtual int HandleHTTPRequest(const HTTPRequest &request);
+
+  virtual std::string GetHTTPResponseFile() const { return m_path; }
+
+  virtual int GetPriority() const { return 2; }
+
+private:
+  CStdString m_path;
+};
diff --git a/xbmc/network/httprequesthandler/HTTPWebinterfaceAddonsHandler.cpp b/xbmc/network/httprequesthandler/HTTPWebinterfaceAddonsHandler.cpp
new file mode 100644 (file)
index 0000000..d1e8723
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "HTTPWebinterfaceAddonsHandler.h"
+#include "network/WebServer.h"
+#include "addons/AddonManager.h"
+
+#define ADDON_HEADER      "<html><head><title>Add-on List</title></head><body>\n<h1>Available web interfaces:</h1>\n<ul>\n"
+
+using namespace std;
+using namespace ADDON;
+
+bool CHTTPWebinterfaceAddonsHandler::CheckHTTPRequest(const HTTPRequest &request)
+{
+  return (request.url.compare("/addons") == 0 || request.url.compare("/addons/") == 0);
+}
+
+int CHTTPWebinterfaceAddonsHandler::HandleHTTPRequest(const HTTPRequest &request)
+{
+  m_response = ADDON_HEADER;
+  VECADDONS addons;
+  CAddonMgr::Get().GetAddons(ADDON_WEB_INTERFACE, addons);
+  IVECADDONS addons_it;
+  for (addons_it=addons.begin(); addons_it!=addons.end(); addons_it++)
+    m_response += "<li><a href=/addons/"+ (*addons_it)->ID() + "/>" + (*addons_it)->Name() + "</a></li>\n";
+
+  m_response += "</ul>\n</body></html>";
+
+  m_responseType = HTTPMemoryDownloadNoFreeCopy;
+  m_responseCode = MHD_HTTP_OK;
+
+  return MHD_YES;
+}
+
+
diff --git a/xbmc/network/httprequesthandler/HTTPWebinterfaceAddonsHandler.h b/xbmc/network/httprequesthandler/HTTPWebinterfaceAddonsHandler.h
new file mode 100644 (file)
index 0000000..0c0eedc
--- /dev/null
@@ -0,0 +1,41 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IHTTPRequestHandler.h"
+
+class CHTTPWebinterfaceAddonsHandler : public IHTTPRequestHandler
+{
+public:
+  CHTTPWebinterfaceAddonsHandler() { };
+  
+  virtual IHTTPRequestHandler* GetInstance() { return new CHTTPWebinterfaceAddonsHandler(); }
+  virtual bool CheckHTTPRequest(const HTTPRequest &request);
+  virtual int HandleHTTPRequest(const HTTPRequest &request);
+
+  virtual void* GetHTTPResponseData() const { return (void *)m_response.c_str(); };
+  virtual size_t GetHTTPResonseDataLength() const { return m_response.size(); }
+
+  virtual int GetPriority() const { return 1; }
+
+private:
+  std::string m_response;
+};
diff --git a/xbmc/network/httprequesthandler/HTTPWebinterfaceHandler.cpp b/xbmc/network/httprequesthandler/HTTPWebinterfaceHandler.cpp
new file mode 100644 (file)
index 0000000..6dd2c5c
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "HTTPWebinterfaceHandler.h"
+#include "network/WebServer.h"
+#include "addons/AddonManager.h"
+#include "utils/URIUtils.h"
+#include "filesystem/Directory.h"
+#include "filesystem/File.h"
+
+#define DEFAULT_PAGE        "index.html"
+
+using namespace std;
+using namespace ADDON;
+using namespace XFILE;
+
+bool CHTTPWebinterfaceHandler::CheckHTTPRequest(const HTTPRequest &request)
+{
+  return true;
+}
+
+int CHTTPWebinterfaceHandler::HandleHTTPRequest(const HTTPRequest &request)
+{
+  m_responseCode = ResolveUrl(request.url, m_url);
+  if (m_responseCode != MHD_HTTP_OK)
+  {
+    if (m_responseCode == MHD_HTTP_FOUND)
+      m_responseType = HTTPRedirect;
+    else
+      m_responseType = HTTPError;
+
+    return MHD_YES;
+  }
+
+  m_responseType = HTTPFileDownload;
+
+  return MHD_YES;
+}
+
+int CHTTPWebinterfaceHandler::ResolveUrl(const std::string &url, std::string &path)
+{
+  AddonPtr dummyAddon;
+  return ResolveUrl(url, path, dummyAddon);
+}
+
+int CHTTPWebinterfaceHandler::ResolveUrl(const std::string &url, std::string &path, AddonPtr &addon)
+{
+  string addonPath;
+  bool useDefaultWebInterface = true;
+
+  path = url;
+  if (url.find("/addons/") == 0 && url.size() > 8)
+  {
+    CStdStringArray components;
+    CUtil::Tokenize(path, components, "/");
+    if (components.size() > 1)
+    {
+      CAddonMgr::Get().GetAddon(components.at(1), addon);
+      if (addon)
+      {
+        size_t pos;
+        pos = path.find('/', 8); // /addons/ = 8 characters +1 to start behind the last slash
+        if (pos != string::npos)
+          path = path.substr(pos);
+        else // missing trailing slash
+        {
+          path = url + "/";
+          return MHD_HTTP_FOUND;
+        }
+
+        useDefaultWebInterface = false;
+        addonPath = addon->Path();
+        if (addon->Type() != ADDON_WEB_INTERFACE) // No need to append /htdocs for web interfaces
+          addonPath = URIUtils::AddFileToFolder(addonPath, "/htdocs/");
+      }
+    }
+    else
+      return MHD_HTTP_NOT_FOUND;
+  }
+
+  if (path.compare("/") == 0)
+    path.append(DEFAULT_PAGE);
+
+  if (useDefaultWebInterface)
+  {
+    CAddonMgr::Get().GetDefault(ADDON_WEB_INTERFACE, addon);
+    if (addon)
+      addonPath = addon->Path();
+  }
+
+  if (addon)
+    path = URIUtils::AddFileToFolder(addon->Path(), path);
+  
+  if (CDirectory::Exists(path))
+  {
+    if (path.at(path.size() -1) == '/')
+      path.append(DEFAULT_PAGE);
+    else
+    {
+      path = url + "/";
+      return MHD_HTTP_FOUND;
+    }
+  }
+
+  if (!CFile::Exists(path))
+    return MHD_HTTP_NOT_FOUND;
+
+  return MHD_HTTP_OK;
+}
diff --git a/xbmc/network/httprequesthandler/HTTPWebinterfaceHandler.h b/xbmc/network/httprequesthandler/HTTPWebinterfaceHandler.h
new file mode 100644 (file)
index 0000000..328077a
--- /dev/null
@@ -0,0 +1,43 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IHTTPRequestHandler.h"
+#include "addons/IAddon.h"
+
+class CHTTPWebinterfaceHandler : public IHTTPRequestHandler
+{
+public:
+  CHTTPWebinterfaceHandler() { };
+  
+  virtual IHTTPRequestHandler* GetInstance() { return new CHTTPWebinterfaceHandler(); }
+  virtual bool CheckHTTPRequest(const HTTPRequest &request);
+  virtual int HandleHTTPRequest(const HTTPRequest &request);
+
+  virtual std::string GetHTTPRedirectUrl() const { return m_url; }
+  virtual std::string GetHTTPResponseFile() const { return m_url; }
+  
+  static int ResolveUrl(const std::string &url, std::string &path);
+  static int ResolveUrl(const std::string &url, std::string &path, ADDON::AddonPtr &addon);
+
+private:
+  std::string m_url;
+};
diff --git a/xbmc/network/httprequesthandler/IHTTPRequestHandler.cpp b/xbmc/network/httprequesthandler/IHTTPRequestHandler.cpp
new file mode 100644 (file)
index 0000000..c69ffa7
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "IHTTPRequestHandler.h"
+
+void IHTTPRequestHandler::AddPostField(const std::string &key, const std::string &value)
+{
+  if (key.empty())
+    return;
+
+  std::map<std::string, std::string>::iterator field = m_postFields.find(key);
+  if (field == m_postFields.end())
+    m_postFields[key] = value;
+  else
+    m_postFields[key].append(value);
+}
+
+#if (MHD_VERSION >= 0x00040001)
+bool IHTTPRequestHandler::AddPostData(const char *data, size_t size)
+#else
+bool IHTTPRequestHandler::AddPostData(const char *data, unsigned int size)
+#endif
+{
+  if (size > 0)
+    return appendPostData(data, size);
+  
+  return true;
+}
\ No newline at end of file
diff --git a/xbmc/network/httprequesthandler/IHTTPRequestHandler.h b/xbmc/network/httprequesthandler/IHTTPRequestHandler.h
new file mode 100644 (file)
index 0000000..3d71621
--- /dev/null
@@ -0,0 +1,111 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <string>
+#include <map>
+
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+#ifdef __APPLE__
+#include "lib/libmicrohttpd/src/include/microhttpd.h"
+#else
+#include <microhttpd.h>
+#endif
+
+class CWebServer;
+
+enum HTTPMethod
+{
+  UNKNOWN,
+  POST,
+  GET,
+  HEAD
+};
+
+enum HTTPResponseType
+{
+  HTTPNone,
+  HTTPError,
+  HTTPRedirect,
+  HTTPFileDownload,
+  HTTPMemoryDownloadNoFreeNoCopy,
+  HTTPMemoryDownloadNoFreeCopy,
+  HTTPMemoryDownloadFreeNoCopy,
+  HTTPMemoryDownloadFreeCopy
+};
+
+typedef struct HTTPRequest
+{
+  struct MHD_Connection *connection;
+  std::string url;
+  HTTPMethod method;
+  std::string version;
+  CWebServer *webserver;
+} HTTPRequest;
+
+class IHTTPRequestHandler
+{
+public:
+  virtual ~IHTTPRequestHandler() { }
+
+  virtual IHTTPRequestHandler* GetInstance() = 0;
+  virtual bool CheckHTTPRequest(const HTTPRequest &request) = 0;
+  virtual int HandleHTTPRequest(const HTTPRequest &request) = 0;
+  
+  virtual void* GetHTTPResponseData() const { return NULL; };
+  virtual size_t GetHTTPResonseDataLength() const { return 0; }
+  virtual std::string GetHTTPRedirectUrl() const { return ""; }
+  virtual std::string GetHTTPResponseFile() const { return ""; }
+
+  // The higher the more important
+  virtual int GetPriority() const { return 0; }
+
+  void AddPostField(const std::string &key, const std::string &value);
+#if (MHD_VERSION >= 0x00040001)
+  bool AddPostData(const char *data, size_t size);
+#else
+  bool AddPostData(const char *data, unsigned int size);
+#endif
+
+  int GetHTTPResonseCode() const { return m_responseCode; }
+  HTTPResponseType GetHTTPResponseType() const { return m_responseType; }
+  const std::multimap<std::string, std::string>& GetHTTPResponseHeaderFields() const { return m_responseHeaderFields; };
+
+protected:
+#if (MHD_VERSION >= 0x00040001)
+  virtual bool appendPostData(const char *data, size_t size)
+#else
+  virtual bool appendPostData(const char *data, unsigned int size)
+#endif
+  { return true; }
+
+  int m_responseCode;
+  HTTPResponseType m_responseType;
+  std::multimap<std::string, std::string> m_responseHeaderFields;
+
+  std::map<std::string, std::string> m_postFields;
+};
diff --git a/xbmc/network/httprequesthandler/Makefile b/xbmc/network/httprequesthandler/Makefile
new file mode 100644 (file)
index 0000000..1840dd9
--- /dev/null
@@ -0,0 +1,11 @@
+SRCS=HTTPApiHandler.cpp \
+     HTTPJsonRpcHandler.cpp \
+     HTTPVfsHandler.cpp \
+     HTTPWebinterfaceAddonsHandler.cpp \
+     HTTPWebinterfaceHandler.cpp \
+     IHTTPRequestHandler.cpp \
+
+LIB=httprequesthandlers.a
+
+include ../../../Makefile.include
+-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
\ No newline at end of file
index cb08d1b..0756a40 100644 (file)
@@ -33,7 +33,7 @@
 #include "threads/SingleLock.h"
 #include "guilib/LocalizeStrings.h"
 #include "filesystem/File.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 
 #define SCROBBLER_CLIENT              "xbm"
 //#define SCROBBLER_CLIENT              "tst"     // For testing ONLY!
@@ -626,8 +626,8 @@ void CScrobbler::Process()
   CLog::Log(LOGDEBUG, "%s: Thread started.", m_strLogPrefix.c_str());
   if (!m_pHttp)
   {
-    // Hack since CFileCurl isn't threadsafe
-    if (!(m_pHttp = new XFILE::CFileCurl))
+    // Hack since CCurlFile isn't threadsafe
+    if (!(m_pHttp = new XFILE::CCurlFile))
       return;
   }
   while (!m_bStop)
index 560a794..cff0494 100644 (file)
@@ -38,7 +38,7 @@ namespace MUSIC_INFO
 
 namespace XFILE
 {
-  class CFileCurl;
+  class CCurlFile;
 }
 
 /* The following structure describes an entry in the scrobbler submission
@@ -134,7 +134,7 @@ protected:
   CStdString m_strHandshakeTimeStamp;
   SubmissionJournalEntry m_CurrentTrack;
   CEvent m_hEvent;
-  XFILE::CFileCurl  *m_pHttp;
+  XFILE::CCurlFile  *m_pHttp;
   CCriticalSection  m_queueLock;
   CCriticalSection  m_actionLock;
   std::vector<SubmissionJournalEntry> m_vecSubmissionQueue;
index a419d59..927f87c 100644 (file)
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#ifndef __APPLE__
-#include <linux/if.h>
-#include <linux/wireless.h>
-#include <linux/sockios.h>
+#if defined(TARGET_LINUX)
+  #include <linux/if.h>
+  #include <linux/wireless.h>
+  #include <linux/sockios.h>
 #endif
 #include <errno.h>
 #include <resolv.h>
-#if defined(__APPLE__)
-#include <sys/sockio.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <ifaddrs.h>
+#if defined(TARGET_DARWIN)
+  #include <sys/sockio.h>
+  #include <net/if.h>
+  #include <net/if_dl.h>
+  #include <ifaddrs.h>
 #else
-#include <net/if_arp.h>
+  #include <net/if_arp.h>
 #endif
 #include "PlatformDefs.h"
 #include "NetworkLinux.h"
@@ -64,7 +64,7 @@ CStdString& CNetworkInterfaceLinux::GetName(void)
 
 bool CNetworkInterfaceLinux::IsWireless()
 {
-#ifdef __APPLE__
+#if defined(TARGET_DARWIN)
   return false;
 #else
   struct iwreq wrq;
@@ -144,7 +144,7 @@ CStdString CNetworkInterfaceLinux::GetCurrentWirelessEssId(void)
 {
    CStdString result = "";
 
-#ifndef __APPLE__
+#if defined(TARGET_LINUX)
    char essid[IW_ESSID_MAX_SIZE + 1];
    memset(&essid, 0, sizeof(essid));
 
@@ -166,7 +166,24 @@ CStdString CNetworkInterfaceLinux::GetCurrentDefaultGateway(void)
 {
    CStdString result = "";
 
-#ifndef __APPLE__
+#if defined(TARGET_DARWIN)
+  FILE* pipe = popen("echo \"show State:/Network/Global/IPv4\" | scutil | grep Router", "r");
+  if (pipe)
+  {
+    CStdString tmpStr;
+    char buffer[256] = {'\0'};
+    if (fread(buffer, sizeof(char), sizeof(buffer), pipe) > 0 && !ferror(pipe))
+    {
+      tmpStr = buffer;
+      result = tmpStr.Mid(11);
+    }
+    else
+    {
+      CLog::Log(LOGWARNING, "Unable to determine gateway");
+    }
+    pclose(pipe);
+  }
+#else
    FILE* fp = fopen("/proc/net/route", "r");
    if (!fp)
    {
@@ -242,7 +259,7 @@ std::vector<CNetworkInterface*>& CNetworkLinux::GetInterfaceList(void)
    return m_interfaces;
 }
 
-#if defined(__APPLE__) && defined(__arm__)
+#if defined(TARGET_DARWIN_IOS)
 // on iOS, overwrite the GetFirstConnectedInterface and requery
 // the interface list if no connected device is found
 // this fixes a bug when no network is available after first start of xbmc after reboot
@@ -267,9 +284,9 @@ CNetworkInterface* CNetworkLinux::GetFirstConnectedInterface(void)
 CStdString CNetworkLinux::GetMacAddress(CStdString interfaceName)
 {
   CStdString result = "00:00:00:00:00:00";
-#ifdef __APPLE__
+#if defined(TARGET_DARWIN)
 
-#if ! defined(IFT_ETHER)
+#if !defined(IFT_ETHER)
 #define IFT_ETHER 0x6/* Ethernet CSMACD */
 #endif
   const struct sockaddr_dl* dlAddr = NULL;
@@ -333,7 +350,7 @@ void CNetworkLinux::queryInterfaceList()
   CStdString macAddr = "";
   m_interfaces.clear();
 
-#ifdef __APPLE__
+#if defined(TARGET_DARWIN)
 
    // Query the list of interfaces.
    struct ifaddrs *list;
@@ -394,7 +411,26 @@ void CNetworkLinux::queryInterfaceList()
 std::vector<CStdString> CNetworkLinux::GetNameServers(void)
 {
    std::vector<CStdString> result;
-#ifndef __APPLE__
+
+#if defined(TARGET_DARWIN)
+  //only finds the primary dns (0 :)
+  FILE* pipe = popen("echo \"show State:/Network/Global/DNS\" | scutil | grep \"0 :\" | tail -n1", "r");
+  if (pipe)
+  {
+    CStdString tmpStr;
+    char buffer[256] = {'\0'};
+    if (fread(buffer, sizeof(char), sizeof(buffer), pipe) > 0 && !ferror(pipe))
+    {
+      tmpStr = buffer;
+      result.push_back(tmpStr.Mid(8));
+    }
+    else
+    {
+      CLog::Log(LOGWARNING, "Unable to determine nameserver");
+    }
+    pclose(pipe);
+  } 
+#else
    res_init();
 
    for (int i = 0; i < _res.nscount; i ++)
@@ -430,7 +466,7 @@ std::vector<NetworkAccessPoint> CNetworkInterfaceLinux::GetAccessPoints(void)
    if (!IsWireless())
       return result;
 
-#ifndef __APPLE__
+#if defined(TARGET_LINUX)
    // Query the wireless extentsions version number. It will help us when we
    // parse the resulting events
    struct iwreq iwr;
@@ -616,7 +652,7 @@ void CNetworkInterfaceLinux::GetSettings(NetworkAssignment& assignment, CStdStri
    encryptionMode = ENC_NONE;
    assignment = NETWORK_DISABLED;
 
-#ifndef __APPLE__
+#if defined(TARGET_LINUX)
    FILE* fp = fopen("/etc/network/interfaces", "r");
    if (!fp)
    {
@@ -692,7 +728,7 @@ void CNetworkInterfaceLinux::GetSettings(NetworkAssignment& assignment, CStdStri
 
 void CNetworkInterfaceLinux::SetSettings(NetworkAssignment& assignment, CStdString& ipAddress, CStdString& networkMask, CStdString& defaultGateway, CStdString& essId, CStdString& key, EncMode& encryptionMode)
 {
-#ifndef __APPLE__
+#if defined(TARGET_LINUX)
    FILE* fr = fopen("/etc/network/interfaces", "r");
    if (!fr)
    {
diff --git a/xbmc/network/websocket/Makefile b/xbmc/network/websocket/Makefile
new file mode 100644 (file)
index 0000000..f3d9d41
--- /dev/null
@@ -0,0 +1,9 @@
+SRCS=WebSocket.cpp \
+     WebSocketManager.cpp \
+     WebSocketV8.cpp \
+     WebSocketV13.cpp \
+
+LIB=websocket.a
+
+include ../../../Makefile.include
+-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
diff --git a/xbmc/network/websocket/WebSocket.cpp b/xbmc/network/websocket/WebSocket.cpp
new file mode 100644 (file)
index 0000000..8b6a3a7
--- /dev/null
@@ -0,0 +1,432 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <string>
+#include <sstream>
+
+#include "WebSocket.h"
+#include "utils/EndianSwap.h"
+#include "utils/log.h"
+#include "utils/HttpParser.h"
+#include "utils/Base64.h"
+#include "utils/StdString.h"
+#include "utils/StringUtils.h"
+#include "utils/HttpResponse.h"
+
+#define MASK_FIN      0x80
+#define MASK_RSV1     0x40
+#define MASK_RSV2     0x20
+#define MASK_RSV3     0x10
+#define MASK_RSV      (MASK_RSV1 | MASK_RSV2 | MASK_RSV3)
+#define MASK_OPCODE   0x0F
+#define MASK_MASK     0x80
+#define MASK_LENGTH   0x7F
+
+#define CONTROL_FRAME 0x08
+
+#define LENGTH_MIN    0x2
+
+using namespace std;
+
+CWebSocketFrame::CWebSocketFrame(const char* data, uint64_t length)
+{
+  reset();
+
+  if (data == NULL || length < LENGTH_MIN)
+    return;
+
+  m_free = false;
+  m_data = data;
+  m_lengthFrame = length;
+
+  // Get the FIN flag
+  m_final = ((m_data[0] & MASK_FIN) == MASK_FIN);
+  // Get the RSV1 - RSV3 flags
+  m_extension |= m_data[0] & MASK_RSV1;
+  m_extension |= (m_data[0] & MASK_RSV2) << 1;
+  m_extension |= (m_data[0] & MASK_RSV3) << 2;
+  // Get the opcode
+  m_opcode = (WebSocketFrameOpcode)(m_data[0] & MASK_OPCODE);
+  if (m_opcode >= WebSocketUnknownFrame)
+  {
+    CLog::Log(LOGINFO, "WebSocket: Frame with invalid opcode %2X received", m_opcode);
+    reset();
+    return;
+  }
+  if ((m_opcode & CONTROL_FRAME) == CONTROL_FRAME && !m_final)
+  {
+    CLog::Log(LOGINFO, "WebSocket: Fragmented control frame (opcode %2X) received", m_opcode);
+    reset();
+    return;
+  }
+
+  // Get the MASK flag
+  m_masked = ((m_data[1] & MASK_MASK) == MASK_MASK);
+
+  // Get the playload length
+  m_length = (uint64_t)(m_data[1] & MASK_LENGTH);
+  if ((m_length <= 125 && length  < m_length + LENGTH_MIN) ||
+      (m_length == 126 && length < LENGTH_MIN + 2) ||
+      (m_length == 127 && length < LENGTH_MIN + 8))
+  {
+    CLog::Log(LOGINFO, "WebSocket: Frame with invalid length received");
+    reset();
+    return;
+  }
+
+  if (IsControlFrame() && (m_length > 125 || !m_final))
+  {
+    CLog::Log(LOGWARNING, "WebSocket: Invalid control frame received");
+    reset();
+    return;
+  }
+
+  int offset = 0;
+  if (m_length == 126)
+  {
+    m_length = (uint64_t)Endian_SwapBE16(*(uint16_t *)(m_data + 2));
+    offset = 2;
+  }
+  else if (m_length == 127)
+  {
+    m_length = Endian_SwapBE64(*(uint64_t *)(m_data + 2));
+    offset = 8;
+  }
+
+  if (length < LENGTH_MIN + offset + m_length)
+  {
+    CLog::Log(LOGINFO, "WebSocket: Frame with invalid length received");
+    reset();
+    return;
+  }
+
+  // Get the mask
+  if (m_masked)
+  {
+    m_mask = *(uint32_t *)(m_data + LENGTH_MIN + offset);
+    offset += 4;
+  }
+
+  if (length != LENGTH_MIN + offset + m_length)
+  {
+    CLog::Log(LOGINFO, "WebSocket: Frame with invalid length received");
+    reset();
+    return;
+  }
+
+  // Get application data
+  if (m_length > 0)
+    m_applicationData = (char *)(m_data + LENGTH_MIN + offset);
+  else
+    m_applicationData = NULL;
+
+  // Unmask the application data if necessary
+  if (m_masked)
+  {
+    for (uint64_t index = 0; index < m_length; index++)
+      m_applicationData[index] = m_applicationData[index] ^ ((char *)(&m_mask))[index % 4];
+  }
+
+  m_valid = true;
+}
+
+CWebSocketFrame::CWebSocketFrame(WebSocketFrameOpcode opcode, const char* data /* = NULL */, uint32_t length /* = 0 */,
+                                 bool final /* = true */, bool masked /* = false */, int32_t mask /* = 0 */, int8_t extension /* = 0 */)
+{
+  reset();
+
+  if (opcode >= WebSocketUnknownFrame)
+    return;
+
+  m_free = true;
+  m_opcode = opcode;
+
+  if (length >= 0)
+    m_length = length;
+
+  m_masked = masked;
+  m_mask = mask;
+  m_final = final;
+  m_extension = extension;
+
+  string buffer;
+  char dataByte = 0;
+
+  // Set the FIN flag
+  if (m_final)
+    dataByte |= MASK_FIN;
+
+  // Set RSV1 - RSV3 flags
+  if (m_extension != 0)
+    dataByte |= (m_extension << 4) & MASK_RSV;
+
+  // Set opcode flag
+  dataByte |= opcode & MASK_OPCODE;
+
+  buffer.push_back(dataByte);
+  dataByte = 0;
+
+  // Set MASK flag
+  if (m_masked)
+    dataByte |= MASK_MASK;
+
+  // Set payload length
+  if (m_length < 126)
+  {
+    dataByte |= m_length & MASK_LENGTH;
+    buffer.push_back(dataByte);
+  }
+  else if (m_length <= 65535)
+  {
+    dataByte |= 126 & MASK_LENGTH;
+    buffer.push_back(dataByte);
+
+    uint16_t dataLength = Endian_SwapBE16((uint16_t)m_length);
+    buffer.append((const char*)&dataLength, 2);
+  }
+  else
+  {
+    dataByte |= 127 & MASK_LENGTH;
+    buffer.push_back(dataByte);
+    
+    uint64_t dataLength = Endian_SwapBE64(m_length);
+    buffer.append((const char*)&dataLength, 8);
+  }
+
+  uint64_t applicationDataOffset = 0;
+  if (data)
+  {
+    // Set masking key
+    if (m_masked)
+    {
+      buffer.append((char *)&m_mask, sizeof(m_mask));
+      applicationDataOffset = buffer.size();
+
+      for (uint64_t index = 0; index < m_length; index++)
+        buffer.push_back(data[index] ^ ((char *)(&m_mask))[index % 4]);
+    }
+    else
+    {
+      applicationDataOffset = buffer.size();
+      buffer.append(data, (unsigned int)length);
+    }
+  }
+
+  // Get the whole data
+  m_lengthFrame = buffer.size();
+  m_data = new char[(uint32_t)m_lengthFrame];
+  strncpy((char *)m_data, buffer.c_str(), (uint32_t)m_lengthFrame);
+
+  if (data)
+  {
+    m_applicationData = (char *)m_data;
+    m_applicationData += applicationDataOffset;
+  }
+
+  m_valid = true;
+}
+
+CWebSocketFrame::~CWebSocketFrame()
+{
+  if (!m_valid)
+    return;
+
+  if (m_free && m_data != NULL)
+  {
+    delete m_data;
+    m_data = NULL;
+  }
+}
+
+void CWebSocketFrame::reset()
+{
+  m_free = false;
+  m_data = NULL;
+  m_lengthFrame = 0;
+  m_length = 0;
+  m_valid = false;
+  m_final = false;
+  m_extension = 0;
+  m_opcode = WebSocketUnknownFrame;
+  m_masked = false;
+  m_mask = 0;
+  m_applicationData = NULL;
+}
+
+CWebSocketMessage::CWebSocketMessage()
+{
+  Clear();
+}
+
+CWebSocketMessage::~CWebSocketMessage()
+{
+  for (unsigned int index = 0; index < m_frames.size(); index++)
+    delete m_frames[index];
+
+  m_frames.clear();
+}
+
+bool CWebSocketMessage::AddFrame(const CWebSocketFrame *frame)
+{
+  if (!frame->IsValid() || m_complete)
+    return false;
+
+  if (frame->IsFinal())
+    m_complete = true;
+  else
+    m_fragmented = true;
+
+  m_frames.push_back(frame);
+
+  return true;
+}
+
+void CWebSocketMessage::Clear()
+{
+  m_fragmented = false;
+  m_complete = false;
+
+  m_frames.clear();
+}
+
+const CWebSocketMessage* CWebSocket::Handle(const char *buffer, size_t length, bool &send)
+{
+  send = false;
+
+  switch (m_state)
+  {
+    case WebSocketStateConnected:
+    {
+      CWebSocketFrame *frame = GetFrame(buffer, length);
+      if (!frame->IsValid())
+      {
+        CLog::Log(LOGINFO, "WebSocket: Invalid frame received");
+        delete frame;
+        return NULL;
+      }
+
+      if (frame->IsControlFrame())
+      {
+        if (!frame->IsFinal())
+        {
+          delete frame;
+          return NULL;
+        }
+
+        CWebSocketMessage *msg = NULL;
+        switch (frame->GetOpcode())
+        {
+          case WebSocketPing:
+            msg = GetMessage();
+            if (msg != NULL)
+              msg->AddFrame(Pong(frame->GetApplicationData()));
+            break;
+            
+          case WebSocketConnectionClose:
+            CLog::Log(LOGINFO, "WebSocket: connection closed by client");
+
+            msg = GetMessage();
+            if (msg != NULL)
+              msg->AddFrame(Close());
+
+            m_state = WebSocketStateClosed;
+            break;
+
+          case WebSocketContinuationFrame:
+          case WebSocketTextFrame:
+          case WebSocketBinaryFrame:
+          case WebSocketPong:
+          case WebSocketUnknownFrame:
+          default:
+            break;
+        }
+
+        delete frame;
+
+        if (msg != NULL)
+          send = true;
+
+        return msg;
+      }
+
+      if (m_message == NULL && (m_message = GetMessage()) == NULL)
+      {
+        CLog::Log(LOGINFO, "WebSocket: Could not allocate a new websocket message");
+        delete frame;
+        return NULL;
+      }
+
+      m_message->AddFrame(frame);
+      if (!m_message->IsComplete())
+        return NULL;
+
+      CWebSocketMessage *msg = m_message;
+      m_message = NULL;
+      return msg;
+    }
+
+    case WebSocketStateClosing:
+    {
+      CWebSocketFrame *frame = GetFrame(buffer, length);
+      if (!frame->IsValid() || frame->GetOpcode() == WebSocketConnectionClose)
+      {
+        CLog::Log(LOGINFO, "WebSocket: Invalid or unexpected frame received (only closing handshake expected)");
+        delete frame;
+        return NULL;
+      }
+
+      m_state = WebSocketStateClosed;
+      return NULL;
+    }
+
+    case WebSocketStateNotConnected:
+    case WebSocketStateClosed:
+    case WebSocketStateHandshaking:
+    default:
+      CLog::Log(LOGINFO, "WebSocket: No frame expected in the current state");
+      return NULL;
+  }
+
+  return NULL;
+}
+
+const CWebSocketMessage* CWebSocket::Send(WebSocketFrameOpcode opcode, const char* data /* = NULL */, uint32_t length /* = 0 */)
+{
+  CWebSocketFrame *frame = GetFrame(opcode, data, length);
+  if (frame == NULL || !frame->IsValid())
+  {
+    CLog::Log(LOGINFO, "WebSocket: Trying to send an invalid frame");
+    return NULL;
+  }
+
+  CWebSocketMessage *msg = GetMessage();
+  if (msg == NULL)
+  {
+    CLog::Log(LOGINFO, "WebSocket: Could not allocate a message");
+    return NULL;
+  }
+
+  msg->AddFrame(frame);
+  if (msg->IsComplete())
+    return msg;
+
+  return NULL;
+}
diff --git a/xbmc/network/websocket/WebSocket.h b/xbmc/network/websocket/WebSocket.h
new file mode 100644 (file)
index 0000000..69556ae
--- /dev/null
@@ -0,0 +1,141 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+#include <stdint.h>
+#include <vector>
+
+enum WebSocketFrameOpcode
+{
+  WebSocketContinuationFrame  = 0x00,
+  WebSocketTextFrame          = 0x01,
+  WebSocketBinaryFrame        = 0x02,
+  //0x3 - 0x7 are reserved for non-control frames
+  WebSocketConnectionClose    = 0x08,
+  WebSocketPing               = 0x09,
+  WebSocketPong               = 0x0A,
+  //0xB - 0xF are reserved for control frames
+  WebSocketUnknownFrame       = 0x10
+};
+
+enum WebSocketState
+{
+  WebSocketStateNotConnected    = 0,
+  WebSocketStateHandshaking     = 1,
+  WebSocketStateConnected       = 2,
+  WebSocketStateClosing         = 3,
+  WebSocketStateClosed          = 4
+};
+
+enum WebSocketCloseReason
+{
+  WebSocketCloseNormal          = 1000,
+  WebSocketCloseLeaving         = 1001,
+  WebSocketCloseProtocolError   = 1002,
+  WebSocketCloseInvalidData     = 1003,
+  WebSocketCloseFrameTooLarge   = 1004,
+  // Reserved status code       = 1005,
+  // Reserved status code       = 1006,
+  WebSocketCloseInvalidUtf8     = 1007
+};
+
+class CWebSocketFrame
+{
+public:
+  CWebSocketFrame(const char* data, uint64_t length);
+  CWebSocketFrame(WebSocketFrameOpcode opcode, const char* data = NULL, uint32_t length = 0, bool final = true, bool masked = false, int32_t mask = 0, int8_t extension = 0);
+  virtual ~CWebSocketFrame();
+
+  virtual bool IsValid() const { return m_valid; }
+  virtual uint64_t GetFrameLength() const { return m_lengthFrame; }
+  virtual bool IsFinal() const { return m_final; }
+  virtual int8_t GetExtension() const { return m_extension; }
+  virtual WebSocketFrameOpcode GetOpcode() const { return m_opcode; }
+  virtual bool IsControlFrame() const { return (m_valid && (m_opcode & 0x8) == 0x8); }
+  virtual bool IsMasekd() const { return m_masked; }
+  virtual uint64_t GetLength() const { return m_length; }
+  virtual int32_t GetMask() const { return m_mask; }
+  virtual const char* GetFrameData() const { return m_data; }
+  virtual const char* GetApplicationData() const { return m_applicationData; }
+
+protected:
+  bool m_free;
+  const char *m_data;
+  uint64_t m_lengthFrame;
+  uint64_t m_length;
+  bool m_valid;
+  bool m_final;
+  int8_t m_extension;
+  WebSocketFrameOpcode m_opcode;
+  bool m_masked;
+  int32_t m_mask;
+  char *m_applicationData;
+
+private:
+  void reset();
+};
+
+class CWebSocketMessage
+{
+public:
+  CWebSocketMessage();
+  virtual ~CWebSocketMessage();
+
+  virtual bool IsFragmented() const { return m_fragmented; }
+  virtual bool IsComplete() const { return m_complete; }
+
+  virtual bool AddFrame(const CWebSocketFrame* frame);
+  virtual const std::vector<const CWebSocketFrame *>& GetFrames() const { return m_frames; }
+
+  virtual void Clear();
+
+protected:
+  std::vector<const CWebSocketFrame *> m_frames;
+  bool m_fragmented;
+  bool m_complete;
+};
+
+class CWebSocket
+{
+public:
+  CWebSocket() { m_state = WebSocketStateNotConnected; m_message = NULL; }
+  virtual ~CWebSocket() { if (m_message) delete m_message; };
+
+  int GetVersion() { return m_version; }
+  WebSocketState GetState() { return m_state; }
+
+  virtual bool Handshake(const char* data, size_t length, std::string &response) = 0;
+  virtual const CWebSocketMessage* Handle(const char *buffer, size_t length, bool &send); // TODO
+  virtual const CWebSocketMessage* Send(WebSocketFrameOpcode opcode, const char* data = NULL, uint32_t length = 0);
+  virtual const CWebSocketFrame* Ping(const char* data = NULL) const = 0;
+  virtual const CWebSocketFrame* Pong(const char* data = NULL) const = 0;
+  virtual const CWebSocketFrame* Close(WebSocketCloseReason reason = WebSocketCloseNormal, const std::string &message = "") = 0;
+  virtual void Fail() = 0;
+
+protected:
+  int m_version;
+  WebSocketState m_state;
+  CWebSocketMessage *m_message;
+
+  virtual CWebSocketFrame* GetFrame(const char* data, uint64_t length) = 0;
+  virtual CWebSocketFrame* GetFrame(WebSocketFrameOpcode opcode, const char* data = NULL, uint32_t length = 0, bool final = true, bool masked = false, int32_t mask = 0, int8_t extension = 0) = 0;
+  virtual CWebSocketMessage* GetMessage() = 0;
+};
diff --git a/xbmc/network/websocket/WebSocketManager.cpp b/xbmc/network/websocket/WebSocketManager.cpp
new file mode 100644 (file)
index 0000000..1fd15ad
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <string>
+
+#include "WebSocketManager.h"
+#include "WebSocket.h"
+#include "WebSocketV8.h"
+#include "WebSocketV13.h"
+#include "utils/HttpParser.h"
+#include "utils/HttpResponse.h"
+#include "utils/log.h"
+
+#define WS_HTTP_METHOD          "GET"
+#define WS_HTTP_TAG             "HTTP/"
+#define WS_SUPPORTED_VERSIONS   "8, 13"
+
+#define WS_HEADER_VERSION       "Sec-WebSocket-Version"
+#define WS_HEADER_VERSION_LC    "sec-websocket-version"     // "Sec-WebSocket-Version"
+
+using namespace std;
+
+CWebSocket* CWebSocketManager::Handle(const char* data, unsigned int length, string &response)
+{
+  if (data == NULL || length <= 0)
+    return NULL;
+
+  HttpParser header;
+  HttpParser::status_t status = header.addBytes(data, length);
+  switch (status)
+  {
+    case HttpParser::Error:
+    case HttpParser::Incomplete:
+      response.clear();
+      return NULL;
+
+    case HttpParser::Done:
+    default:
+      break;
+  }
+
+  // There must be a "Sec-WebSocket-Version" header
+  const char* value = header.getValue(WS_HEADER_VERSION_LC);
+  if (value == NULL)
+  {
+    CLog::Log(LOGINFO, "WebSocket: missing Sec-WebSocket-Version");
+    CHttpResponse httpResponse(HTTP::Get, HTTP::BadRequest, HTTP::Version1_1);
+    char *responseBuffer;
+    int responseLength = httpResponse.Create(responseBuffer);
+    response = std::string(responseBuffer, responseLength);
+
+    return NULL;
+  }
+  
+  CWebSocket *websocket = NULL;
+  if (strncmp(value, "8", 1) == 0)
+    websocket = new CWebSocketV8();
+  else if (strncmp(value, "13", 2) == 0)
+    websocket = new CWebSocketV13();
+
+  if (websocket == NULL)
+  {
+    CLog::Log(LOGINFO, "WebSocket: Unsupported Sec-WebSocket-Version %s", value);
+    CHttpResponse httpResponse(HTTP::Get, HTTP::UpgradeRequired, HTTP::Version1_1);
+    httpResponse.AddHeader(WS_HEADER_VERSION, WS_SUPPORTED_VERSIONS);
+    char *responseBuffer;
+    int responseLength = httpResponse.Create(responseBuffer);
+    response = std::string(responseBuffer, responseLength);
+
+    return NULL;
+  }
+
+  if (websocket->Handshake(data, length, response))
+    return websocket;
+
+  return NULL;
+}
diff --git a/xbmc/network/websocket/WebSocketManager.h b/xbmc/network/websocket/WebSocketManager.h
new file mode 100644 (file)
index 0000000..4d20306
--- /dev/null
@@ -0,0 +1,29 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+class CWebSocket;
+
+class CWebSocketManager
+{
+public:
+  static CWebSocket* Handle(const char* data, unsigned int length, std::string &response);
+};
diff --git a/xbmc/network/websocket/WebSocketV13.cpp b/xbmc/network/websocket/WebSocketV13.cpp
new file mode 100644 (file)
index 0000000..2ef51b3
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <string>
+#include <sstream>
+
+#include "WebSocketV13.h"
+#include "WebSocket.h"
+#include "utils/Base64.h"
+#include "utils/CharsetConverter.h"
+#include "utils/HttpParser.h"
+#include "utils/HttpResponse.h"
+#include "utils/log.h"
+#include "utils/StringUtils.h"
+
+#define WS_HTTP_METHOD          "GET"
+#define WS_HTTP_TAG             "HTTP/"
+
+#define WS_HEADER_UPGRADE       "Upgrade"
+#define WS_HEADER_UPGRADE_LC    "upgrade"
+#define WS_HEADER_CONNECTION    "Connection"
+#define WS_HEADER_CONNECTION_LC "connection"
+
+#define WS_HEADER_KEY_LC        "sec-websocket-key"         // "Sec-WebSocket-Key"
+#define WS_HEADER_ACCEPT        "Sec-WebSocket-Accept"
+#define WS_HEADER_PROTOCOL      "Sec-WebSocket-Protocol"
+#define WS_HEADER_PROTOCOL_LC   "sec-websocket-protocol"    // "Sec-WebSocket-Protocol"
+
+#define WS_PROTOCOL_JSONRPC     "jsonrpc.xbmc.org"
+#define WS_HEADER_UPGRADE_VALUE "websocket"
+
+using namespace std;
+
+bool CWebSocketV13::Handshake(const char* data, size_t length, std::string &response)
+{
+  string strHeader(data, length);
+  const char *value;
+  HttpParser header;
+  if (header.addBytes(data, length) != HttpParser::Done)
+  {
+    CLog::Log(LOGINFO, "WebSocket [RFC6455]: incomplete handshake received");
+    return false;
+  }
+
+  // The request must be GET
+  value = header.getMethod();
+  if (value == NULL || strnicmp(value, WS_HTTP_METHOD, strlen(WS_HTTP_METHOD)) != 0)
+  {
+    CLog::Log(LOGINFO, "WebSocket [RFC6455]: invalid HTTP method received (GET expected)");
+    return false;
+  }
+
+  // The request must be HTTP/1.1 or higher
+  size_t pos;
+  if ((pos = strHeader.find(WS_HTTP_TAG)) == string::npos)
+  {
+    CLog::Log(LOGINFO, "WebSocket [RFC6455]: invalid handshake received");
+    return false;
+  }
+
+  pos += strlen(WS_HTTP_TAG);
+  istringstream converter(strHeader.substr(pos, strHeader.find_first_of(" \r\n\t", pos) - pos));
+  float fVersion;
+  converter >> fVersion;
+
+  if (fVersion < 1.1f)
+  {
+    CLog::Log(LOGINFO, "WebSocket [RFC6455]: invalid HTTP version %f (1.1 or higher expected)", fVersion);
+    return false;
+  }
+
+  string websocketKey, websocketProtocol;
+  // There must be a "Host" header
+  value = header.getValue("host");
+  if (value == NULL || strlen(value) == 0)
+  {
+    CLog::Log(LOGINFO, "WebSocket [RFC6455]: \"Host\" header missing");
+    return true;
+  }
+
+  // There must be a "Upgrade" header with the value "websocket"
+  value = header.getValue(WS_HEADER_UPGRADE_LC);
+  if (value == NULL || strcmp(value, WS_HEADER_UPGRADE_VALUE) != 0)
+  {
+    CLog::Log(LOGINFO, "WebSocket [RFC6455]: invalid \"%s\" received", WS_HEADER_UPGRADE);
+    return true;
+  }
+
+  // There must be a "Connection" header with the value "Upgrade"
+  value = header.getValue(WS_HEADER_CONNECTION_LC);
+  if (value == NULL || strcmp(value, WS_HEADER_UPGRADE) != 0)
+  {
+    CLog::Log(LOGINFO, "WebSocket [RFC6455]: invalid \"%s\" received", WS_HEADER_CONNECTION_LC);
+    return true;
+  }
+
+  // There must be a base64 encoded 16 byte (=> 24 byte as base62) "Sec-WebSocket-Key" header
+  value = header.getValue(WS_HEADER_KEY_LC);
+  if (value == NULL || (websocketKey = value).size() != 24)
+  {
+    CLog::Log(LOGINFO, "WebSocket [RFC6455]: invalid \"Sec-WebSocket-Key\" received");
+    return true;
+  }
+
+  // There might be a "Sec-WebSocket-Protocol" header
+  value = header.getValue(WS_HEADER_PROTOCOL_LC);
+  if (value && strlen(value) > 0)
+  {
+    CStdStringArray protocols;
+    StringUtils::SplitString(value, ",", protocols);
+    for (unsigned int index = 0; index < protocols.size(); index++)
+    {
+      if (protocols.at(index).Trim().Equals(WS_PROTOCOL_JSONRPC))
+      {
+        websocketProtocol = WS_PROTOCOL_JSONRPC;
+        break;
+      }
+    }
+  }
+
+  CHttpResponse httpResponse(HTTP::Get, HTTP::SwitchingProtocols, HTTP::Version1_1);
+  httpResponse.AddHeader(WS_HEADER_UPGRADE, WS_HEADER_UPGRADE_VALUE);
+  httpResponse.AddHeader(WS_HEADER_CONNECTION, WS_HEADER_UPGRADE);
+  std::string responseKey = calculateKey(websocketKey);
+  httpResponse.AddHeader(WS_HEADER_ACCEPT, responseKey);
+  if (!websocketProtocol.empty())
+    httpResponse.AddHeader(WS_HEADER_PROTOCOL, websocketProtocol);
+
+  char *responseBuffer;
+  int responseLength = httpResponse.Create(responseBuffer);
+  response = std::string(responseBuffer, responseLength);
+  
+  m_state = WebSocketStateConnected;
+
+  return true;
+}
+
+const CWebSocketFrame* CWebSocketV13::Close(WebSocketCloseReason reason /* = WebSocketCloseNormal */, const std::string &message /* = "" */)
+{
+  if (m_state == WebSocketStateNotConnected || m_state == WebSocketStateHandshaking || m_state == WebSocketStateClosed)
+  {
+    CLog::Log(LOGINFO, "WebSocket [RFC6455]: Cannot send a closing handshake if no connection has been established");
+    return NULL;
+  }
+
+  return close(reason, message);
+}
diff --git a/xbmc/network/websocket/WebSocketV13.h b/xbmc/network/websocket/WebSocketV13.h
new file mode 100644 (file)
index 0000000..254d648
--- /dev/null
@@ -0,0 +1,32 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "WebSocketV8.h"
+
+class CWebSocketV13 : public CWebSocketV8
+{
+public:
+  CWebSocketV13() { m_version = 13; }
+
+  virtual bool Handshake(const char* data, size_t length, std::string &response);
+  virtual const CWebSocketFrame* Close(WebSocketCloseReason reason = WebSocketCloseNormal, const std::string &message = "");
+};
diff --git a/xbmc/network/websocket/WebSocketV8.cpp b/xbmc/network/websocket/WebSocketV8.cpp
new file mode 100644 (file)
index 0000000..9161b83
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <string>
+#include <sstream>
+#include <boost/uuid/sha1.hpp>
+
+#include "WebSocketV8.h"
+#include "WebSocket.h"
+#include "utils/Base64.h"
+#include "utils/CharsetConverter.h"
+#include "utils/EndianSwap.h"
+#include "utils/HttpParser.h"
+#include "utils/HttpResponse.h"
+#include "utils/log.h"
+#include "utils/StringUtils.h"
+
+#define WS_HTTP_METHOD          "GET"
+#define WS_HTTP_TAG             "HTTP/"
+
+#define WS_HEADER_UPGRADE       "Upgrade"
+#define WS_HEADER_CONNECTION    "Connection"
+
+#define WS_HEADER_KEY_LC        "sec-websocket-key"         // "Sec-WebSocket-Key"
+#define WS_HEADER_ACCEPT        "Sec-WebSocket-Accept"
+#define WS_HEADER_PROTOCOL      "Sec-WebSocket-Protocol"
+#define WS_HEADER_PROTOCOL_LC   "sec-websocket-protocol"    // "Sec-WebSocket-Protocol"
+
+#define WS_PROTOCOL_JSONRPC     "jsonrpc.xbmc.org"
+#define WS_HEADER_UPGRADE_VALUE "websocket"
+#define WS_KEY_MAGICSTRING      "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
+
+using namespace std;
+
+bool CWebSocketV8::Handshake(const char* data, size_t length, std::string &response)
+{
+  string strHeader(data, length);
+  const char *value;
+  HttpParser header;
+  if (header.addBytes(data, length) != HttpParser::Done)
+  {
+    CLog::Log(LOGINFO, "WebSocket [hybi-10]: incomplete handshake received");
+    return false;
+  }
+
+  // The request must be GET
+  value = header.getMethod();
+  if (value == NULL || strnicmp(value, WS_HTTP_METHOD, strlen(WS_HTTP_METHOD)) != 0)
+  {
+    CLog::Log(LOGINFO, "WebSocket [hybi-10]: invalid HTTP method received (GET expected)");
+    return false;
+  }
+
+  // The request must be HTTP/1.1 or higher
+  size_t pos;
+  if ((pos = strHeader.find(WS_HTTP_TAG)) == string::npos)
+  {
+    CLog::Log(LOGINFO, "WebSocket [hybi-10]: invalid handshake received");
+    return false;
+  }
+
+  pos += strlen(WS_HTTP_TAG);
+  istringstream converter(strHeader.substr(pos, strHeader.find_first_of(" \r\n\t", pos) - pos));
+  float fVersion;
+  converter >> fVersion;
+
+  if (fVersion < 1.1f)
+  {
+    CLog::Log(LOGINFO, "WebSocket [hybi-10]: invalid HTTP version %f (1.1 or higher expected)", fVersion);
+    return false;
+  }
+
+  string websocketKey, websocketProtocol;
+  // There must be a "Host" header
+  value = header.getValue("host");
+  if (value == NULL || strlen(value) == 0)
+  {
+    CLog::Log(LOGINFO, "WebSocket [hybi-10]: \"Host\" header missing");
+    return true;
+  }
+
+  // There must be a base64 encoded 16 byte (=> 24 byte as base64) "Sec-WebSocket-Key" header
+  value = header.getValue(WS_HEADER_KEY_LC);
+  if (value == NULL || (websocketKey = value).size() != 24)
+  {
+    CLog::Log(LOGINFO, "WebSocket [hybi-10]: invalid \"Sec-WebSocket-Key\" received");
+    return true;
+  }
+
+  // There might be a "Sec-WebSocket-Protocol" header
+  value = header.getValue(WS_HEADER_PROTOCOL_LC);
+  if (value && strlen(value) > 0)
+  {
+    CStdStringArray protocols;
+    StringUtils::SplitString(value, ",", protocols);
+    for (unsigned int index = 0; index < protocols.size(); index++)
+    {
+      if (protocols.at(index).Trim().Equals(WS_PROTOCOL_JSONRPC))
+      {
+        websocketProtocol = WS_PROTOCOL_JSONRPC;
+        break;
+      }
+    }
+  }
+
+  CHttpResponse httpResponse(HTTP::Get, HTTP::SwitchingProtocols, HTTP::Version1_1);
+  httpResponse.AddHeader(WS_HEADER_UPGRADE, WS_HEADER_UPGRADE_VALUE);
+  httpResponse.AddHeader(WS_HEADER_CONNECTION, WS_HEADER_UPGRADE);
+  httpResponse.AddHeader(WS_HEADER_ACCEPT, calculateKey(websocketKey));
+  if (!websocketProtocol.empty())
+    httpResponse.AddHeader(WS_HEADER_PROTOCOL, websocketProtocol);
+
+  char *responseBuffer;
+  int responseLength = httpResponse.Create(responseBuffer);
+  response = std::string(responseBuffer, responseLength);
+  
+  m_state = WebSocketStateConnected;
+
+  return true;
+}
+
+const CWebSocketFrame* CWebSocketV8::Close(WebSocketCloseReason reason /* = WebSocketCloseNormal */, const std::string &message /* = "" */)
+{
+  if (m_state == WebSocketStateNotConnected || m_state == WebSocketStateHandshaking || m_state == WebSocketStateClosed)
+  {
+    CLog::Log(LOGINFO, "WebSocket [hybi-10]: Cannot send a closing handshake if no connection has been established");
+    return NULL;
+  }
+
+  return close(reason, message);
+}
+
+void CWebSocketV8::Fail()
+{
+  m_state = WebSocketStateClosed;
+}
+
+CWebSocketFrame* CWebSocketV8::GetFrame(const char* data, uint64_t length)
+{
+  return new CWebSocketFrame(data, length);
+}
+
+CWebSocketFrame* CWebSocketV8::GetFrame(WebSocketFrameOpcode opcode, const char* data /* = NULL */, uint32_t length /* = 0 */,
+                                        bool final /* = true */, bool masked /* = false */, int32_t mask /* = 0 */, int8_t extension /* = 0 */)
+{
+  return new CWebSocketFrame(opcode, data, length, final, masked, mask, extension);
+}
+
+CWebSocketMessage* CWebSocketV8::GetMessage()
+{
+  return new CWebSocketMessage();
+}
+
+const CWebSocketFrame* CWebSocketV8::close(WebSocketCloseReason reason /* = WebSocketCloseNormal */, const std::string &message /* = "" */)
+{
+  size_t length = 2 + message.size();
+
+  char* data = new char[length + 1];
+  memset(data, 0, sizeof(data));
+  unsigned short iReason = Endian_SwapBE16((uint16_t)reason);
+  data[0] = ((char *)&iReason)[0];
+  data[1] = ((char *)&iReason)[1];
+  message.copy(data + 2, message.size());
+
+  if (m_state == WebSocketStateConnected)
+    m_state = WebSocketStateClosing;
+  else
+    m_state = WebSocketStateClosed;
+
+  return new CWebSocketFrame(WebSocketConnectionClose, data, length);
+}
+
+std::string CWebSocketV8::calculateKey(const std::string &key)
+{
+  string acceptKey = key;
+  acceptKey.append(WS_KEY_MAGICSTRING);
+
+  boost::uuids::detail::sha1 hash;
+  hash.process_bytes(acceptKey.c_str(), acceptKey.size());
+
+  unsigned int digest[5];
+  hash.get_digest(digest);
+
+  for (unsigned int index = 0; index < 5; index++)
+    digest[index] = Endian_SwapBE32(digest[index]);
+
+  return Base64::Encode((const char*)digest, sizeof(digest));
+}
diff --git a/xbmc/network/websocket/WebSocketV8.h b/xbmc/network/websocket/WebSocketV8.h
new file mode 100644 (file)
index 0000000..11601a2
--- /dev/null
@@ -0,0 +1,43 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "WebSocket.h"
+
+class CWebSocketV8 : public CWebSocket
+{
+public:
+  CWebSocketV8() { m_version = 8; }
+
+  virtual bool Handshake(const char* data, size_t length, std::string &response);
+  virtual const CWebSocketFrame* Ping(const char* data = NULL) const { return new CWebSocketFrame(WebSocketPing, data); }
+  virtual const CWebSocketFrame* Pong(const char* data = NULL) const { return new CWebSocketFrame(WebSocketPong, data); }
+  virtual const CWebSocketFrame* Close(WebSocketCloseReason reason = WebSocketCloseNormal, const std::string &message = "");
+  virtual void Fail();
+
+protected:
+  virtual CWebSocketFrame* GetFrame(const char* data, uint64_t length);
+  virtual CWebSocketFrame* GetFrame(WebSocketFrameOpcode opcode, const char* data = NULL, uint32_t length = 0, bool final = true, bool masked = false, int32_t mask = 0, int8_t extension = 0);
+  virtual CWebSocketMessage* GetMessage();
+  virtual const CWebSocketFrame* close(WebSocketCloseReason reason = WebSocketCloseNormal, const std::string &message = "");
+
+  std::string calculateKey(const std::string &key);
+};
index a3ef2d3..2b29cdf 100644 (file)
@@ -40,6 +40,8 @@
 
 #import "AutoPool.h"
 
+#import "CoreAudio.h"
+
 // hack for Cocoa_GL_ResizeWindow
 //extern "C" void SDL_SetWidthHeight(int w, int h);
 
@@ -670,170 +672,50 @@ OSStatus SendAppleEventToSystemProcess(AEEventID EventToSend)
   return(error); 
 }
 
-// All this just to reset all audio devices to default :)
-static AudioStreamBasicDescription* FormatsAudioList(AudioStreamID s)
-{
-  OSStatus ret;
-  UInt32   listSize;
-  AudioDevicePropertyID p;
-  AudioStreamBasicDescription *list;
-
-  // This is deprecated for kAudioStreamPropertyAvailablePhysicalFormats,
-  // but compiling on 10.3 requires the older constant
-  p = kAudioStreamPropertyPhysicalFormats;
-
-  // Retrieve all the stream formats supported by this output stream
-  ret = AudioStreamGetPropertyInfo(s, 0, p, &listSize, NULL);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioHardware::FormatsList: "
-      "could not get list size: Error = 0x%08x",
-      (unsigned int)ret);
-    return NULL;
-  }
-
-  // Space for a terminating ID:
-  listSize += sizeof(AudioStreamBasicDescription);
-  list      = (AudioStreamBasicDescription *)malloc(listSize);
-
-  if (list == NULL)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioHardware::FormatsList(): out of memory?");
-    return NULL;
-  }
-
-  ret = AudioStreamGetProperty(s, 0, p, &listSize, list);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioHardware::FormatsList: "
-      "could not get list: Error = 0x%08x",
-      (unsigned int)ret);
-    free(list);
-    return NULL;
-  }
-
-  // Add a terminating ID:
-  list[listSize/sizeof(AudioStreamID)].mFormatID = 0;
-
-  return list;
-}
-
-static void ResetAudioStream(AudioStreamID s)
+void Cocoa_ResetAudioDevices()
 {
-  OSStatus ret;
-  UInt32   paramSize;
-  AudioStreamBasicDescription currentFormat;
-
-  // Find the streams current physical format
-  paramSize = sizeof(currentFormat);
-  AudioStreamGetProperty(s, 0, 
-    kAudioStreamPropertyPhysicalFormat, &paramSize, &currentFormat);
-
-  // If it's currently AC-3/SPDIF then reset it to some mixable format
-  if (currentFormat.mFormatID == 'IAC3' ||
-      currentFormat.mFormatID == kAudioFormat60958AC3)
+  // Reset any devices with an AC3/DTS/SPDIF stream back to a Linear PCM
+  // so that they can become a default output device
+  CoreAudioDeviceList deviceList;
+  CCoreAudioHardware::GetOutputDevices(&deviceList);
+  for (CoreAudioDeviceList::iterator d = deviceList.begin(); d != deviceList.end(); d++)
   {
-    bool streamReset = false;
-    AudioStreamBasicDescription *formats = FormatsAudioList(s);
-
-    if (!formats)
-      return;
-
-    for (int i = 0; !streamReset && formats[i].mFormatID != 0; i++)
+    CCoreAudioDevice device(*d);
+    AudioStreamIdList streamList;
+    if (device.GetStreams(&streamList))
     {
-      if (formats[i].mFormatID == kAudioFormatLinearPCM)
+      for (AudioStreamIdList::iterator s = streamList.begin(); s != streamList.end(); s++)
       {
-        ret = AudioStreamSetProperty(s, NULL, 0,
-          kAudioStreamPropertyPhysicalFormat, sizeof(formats[i]), &(formats[i]));
-        if (ret != noErr)
-        {
-          CLog::Log(LOGWARNING, "ResetAudioStream: "
-            "could not set physical format: Error = 0x%08x",
-            (unsigned int)ret);
-          continue;
-        }
-        else
+        CCoreAudioStream stream;
+        if (stream.Open(*s))
         {
-          streamReset = true;
-          sleep(1);   // For the change to take effect
+          AudioStreamBasicDescription currentFormat;
+          if (stream.GetPhysicalFormat(&currentFormat))
+          {
+            if (currentFormat.mFormatID == 'IAC3' || currentFormat.mFormatID == kAudioFormat60958AC3)
+            {
+              StreamFormatList formatList;
+              if (stream.GetAvailablePhysicalFormats(&formatList))
+              {
+                for (StreamFormatList::iterator f = formatList.begin(); f != formatList.end(); f++)
+                {
+                  if ((*f).mFormat.mFormatID == kAudioFormatLinearPCM)
+                  {
+                    if (stream.SetPhysicalFormat(&(*f).mFormat))
+                    {
+                      sleep(1);
+                      break;
+                    }
+                  }
+                }
+              }
+            }              
+          }
+          stream.Close();
         }
       }
     }
-    free(formats);
-  }
-}
-
-static AudioStreamID* AudioStreamsList(AudioDeviceID d)
-{
-  OSStatus ret;
-  UInt32   listSize;
-  AudioStreamID *list;
-
-  ret = AudioDeviceGetPropertyInfo(d, 0, FALSE,
-    kAudioDevicePropertyStreams, &listSize, NULL);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioHardware::StreamsList: "
-      "could not get list size: Error = 0x%08x",
-      (unsigned int)ret);
-    return NULL;
-  }
-
-  // Space for a terminating ID:
-  listSize += sizeof(AudioStreamID);
-  list      = (AudioStreamID *)malloc(listSize);
-
-  if (list == NULL)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioHardware::StreamsList(): out of memory?");
-    return NULL;
-  }
-
-  ret = AudioDeviceGetProperty(d, 0, FALSE,
-    kAudioDevicePropertyStreams, &listSize, list);
-  if (ret != noErr)
-  {
-    CLog::Log(LOGERROR, "CCoreAudioHardware::StreamsList: "
-      "could not get list: Error = 0x%08x",
-      (unsigned int)ret);
-    return NULL;
-  }
-  // Add a terminating ID:
-  list[listSize/sizeof(AudioStreamID)] = kAudioHardwareBadStreamError;
-
-  return list;
-}
-
-void Cocoa_ResetAudioDevices()
-{
-  // Reset any devices with an AC3/DTS/SPDIF stream back to a Linear PCM
-  // so that they can become a default output device
-  UInt32 size;
-  int    numDevices;
-  AudioDeviceID *devices;
-
-  AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, NULL);
-  devices = (AudioDeviceID*)malloc(size);
-  if (!devices)
-  {
-    CLog::Log(LOGERROR, "ResetAudioDevices: out of memory?");
-    return;
-  }
-  numDevices = size / sizeof(AudioDeviceID);
-  AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices);
-
-  for (int i = 0; i < numDevices; i++)
-  {
-    AudioStreamID *streams;
-    streams = AudioStreamsList(devices[i]);
-    if (!streams)
-      continue;
-    for (int j = 0; streams[j] != kAudioHardwareBadStreamError; j++)
-      ResetAudioStream(streams[j]);
-
-    free(streams);
-  }
-  free(devices);
+  }  
 }
 
 #endif
index ca682a0..81ce999 100644 (file)
@@ -149,7 +149,25 @@ bool CCoreAudioChannelLayout::CopyLayout(AudioChannelLayout& layout)
   
   return (ret == noErr);
 }
-                   
+
+bool CCoreAudioChannelLayout::SetLayout(AudioChannelLayoutTag layoutTag)
+{
+  UInt32 propSize = 0;
+  AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForTag, sizeof(layoutTag), &layoutTag, &propSize);
+  m_pLayout = (AudioChannelLayout*)malloc(propSize);
+  OSStatus ret = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag, sizeof(layoutTag), &layoutTag, &propSize, m_pLayout);
+  m_pLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
+  return (ret == noErr);  
+}
+
+AudioChannelLabel CCoreAudioChannelLayout::GetChannelLabel(UInt32 index)
+{
+  if (!m_pLayout || (index >= m_pLayout->mNumberChannelDescriptions))
+    return kAudioChannelLabel_Unknown;
+  
+  return m_pLayout->mChannelDescriptions[index].mChannelLabel;
+}
+
 UInt32 CCoreAudioChannelLayout::GetChannelCountForLayout(AudioChannelLayout& layout)
 {
     UInt32 channels = 0;
@@ -171,6 +189,13 @@ UInt32 CCoreAudioChannelLayout::GetChannelCountForLayout(AudioChannelLayout& lay
     return channels;
 }
 
+UInt32 CCoreAudioChannelLayout::GetChannelCount()
+{
+  if (m_pLayout)
+    return GetChannelCountForLayout(*m_pLayout);
+  return 0;
+}
+
 const char* CCoreAudioChannelLayout::ChannelLabelToString(UInt32 label)
 {
   if (label > MAX_CHANNEL_LABEL)
@@ -501,6 +526,13 @@ const char* CCoreAudioDevice::GetName(CStdString& name)
   return name.c_str();
 }
 
+const char* CCoreAudioDevice::GetName()
+{
+  // Use internal storage
+  return GetName(m_Name);
+}
+
+
 UInt32 CCoreAudioDevice::GetTotalOutputChannels()
 {
   if (!m_DeviceId)
index d8ff928..73764a0 100644 (file)
@@ -76,6 +76,9 @@ public:
   virtual ~CCoreAudioChannelLayout();
   operator AudioChannelLayout*() {return m_pLayout;}
   bool CopyLayout(AudioChannelLayout& layout);
+  bool SetLayout(AudioChannelLayoutTag layoutTag);
+  UInt32 GetChannelCount();
+  AudioChannelLabel GetChannelLabel(UInt32 index);
   static UInt32 GetChannelCountForLayout(AudioChannelLayout& layout);
   static const char* ChannelLabelToString(UInt32 label);
   static const char* ChannelLayoutToString(AudioChannelLayout& layout, CStdString& str);
@@ -100,6 +103,7 @@ public:
   
   AudioDeviceID GetId() {return m_DeviceId;}
   const char* GetName(CStdString& name);
+  const char* GetName();
   UInt32 GetTotalOutputChannels();
   bool GetStreams(AudioStreamIdList* pList);
   bool IsRunning();
@@ -122,6 +126,7 @@ protected:
   AudioDeviceIOProc m_IoProc;
   Float64 m_SampleRateRestore;
   UInt32 m_BufferSizeRestore;
+  CStdString m_Name;
 };
 
 typedef std::list<AudioStreamRangedDescription> StreamFormatList;
index 1c1447a..8b86d43 100644 (file)
 #import "XBMCEAGLView.h"
 #import "XBMCDebugHelpers.h"
 
+//start repeating after 0.5s
+#define REPEATED_KEYPRESS_DELAY_S     0.5
+//pause 0.01s (10ms) between keypresses
+#define REPEATED_KEYPRESS_PAUSE_S 0.01
+
 typedef enum {
 
   ATV_BUTTON_UP                 = 1,
-  ATV_BUTTON_UP_RELEASE         = 1,
   ATV_BUTTON_DOWN               = 2,
-  ATV_BUTTON_DOWN_RELEASE       = 2,
   ATV_BUTTON_LEFT               = 3,
-  ATV_BUTTON_LEFT_RELEASE       = 3,
   ATV_BUTTON_RIGHT              = 4,
-  ATV_BUTTON_RIGHT_RELEASE      = 4,
   ATV_BUTTON_PLAY               = 5,
   ATV_BUTTON_MENU               = 6,
   ATV_BUTTON_PLAY_H             = 7,
   ATV_BUTTON_MENU_H             = 8,
   ATV_BUTTON_LEFT_H             = 9,
-  ATV_BUTTON_LEFT_H_RELEASE     = 9,
   ATV_BUTTON_RIGHT_H            = 10,
-  ATV_BUTTON_RIGHT_H_RELEASE    = 10,
 
   //new aluminium remote buttons
   ATV_ALUMINIUM_PLAY            = 12,
@@ -194,10 +193,15 @@ extern NSString* kBRScreenSaverDismissed;
 @interface XBMCController (PrivateMethods)
 UIWindow      *m_window;
 XBMCEAGLView  *m_glView;
+NSTimer       *m_keyTimer;
 int           m_screensaverTimeout;
 int           m_systemsleepTimeout;
 
 - (void) observeDefaultCenterStuff: (NSNotification *) notification;
+- (void) keyPressTimerCallback: (NSTimer*)theTimer;
+- (void) startKeyPressTimer: (int) keyId;
+- (void) stopKeyPressTimer;
+- (void) setUserEvent:(int) id withHoldTime:(unsigned int) holdTime;
 @end
 //
 //
@@ -337,39 +341,40 @@ int           m_systemsleepTimeout;
   return YES;
 }
 
-- (eATVClientEvent) ATVClientEventFromBREvent:(BREvent*) f_event
+- (eATVClientEvent) ATVClientEventFromBREvent:(BREvent*) f_event 
+                    Repeatable:(bool &) isRepeatable
+                    ButtonState:(bool &) isPressed
 {
   int remoteAction = [f_event remoteAction];
   CLog::Log(LOGDEBUG,"XBMCPureController: Button press remoteAction = %i", remoteAction);
+  isRepeatable = false;
+  isPressed = false;
 
   switch (remoteAction)
   {
     // tap up
     case kBREventRemoteActionUp:
     case 65676:
+      isRepeatable = true;
       if([f_event value] == 1)
-        return ATV_BUTTON_UP;
-      else
-        return ATV_INVALID_BUTTON;
-        //return ATV_BUTTON_UP_RELEASE;
+        isPressed = true;
+      return ATV_BUTTON_UP;
 
     // tap down
     case kBREventRemoteActionDown:
     case 65677:
+      isRepeatable = true;
       if([f_event value] == 1)
-        return ATV_BUTTON_DOWN;
-      else
-        return ATV_INVALID_BUTTON;
-        //return ATV_BUTTON_DOWN_RELEASE;
+        isPressed = true;
+      return ATV_BUTTON_DOWN;
 
     // tap left
     case kBREventRemoteActionLeft:
     case 65675:
+      isRepeatable = true;
       if([f_event value] == 1)
-        return ATV_BUTTON_LEFT;
-      else
-        return ATV_INVALID_BUTTON;
-        //return ATV_BUTTON_LEFT_RELEASE;
+        isPressed = true;
+      return ATV_BUTTON_LEFT;
 
     // hold left
     case 786612:
@@ -377,16 +382,14 @@ int           m_systemsleepTimeout;
         return ATV_LEARNED_REWIND;
       else
         return ATV_INVALID_BUTTON;
-        //return ATV_LEARNED_REWIND_RELEASE;
 
     // tap right
     case kBREventRemoteActionRight:
     case 65674:
+      isRepeatable = true;
       if ([f_event value] == 1)
-        return ATV_BUTTON_RIGHT;
-      else
-        return ATV_INVALID_BUTTON;
-        //return ATV_BUTTON_RIGHT_RELEASE;
+        isPressed = true;
+      return ATV_BUTTON_RIGHT;
 
     // hold right
     case 786611:
@@ -394,7 +397,6 @@ int           m_systemsleepTimeout;
         return ATV_LEARNED_FORWARD;
       else
         return ATV_INVALID_BUTTON;
-        //return ATV_LEARNED_FORWARD_RELEASE;
 
     // tap play
     case kBREventRemoteActionPlay:
@@ -457,69 +459,39 @@ int           m_systemsleepTimeout;
 
     // PageUp
     case kBREventRemoteActionPageUp:
-      if ([f_event value] == 1)
-        return ATV_BUTTON_PAGEUP;
-      else
-        return ATV_INVALID_BUTTON;
+      return ATV_BUTTON_PAGEUP;
 
     // PageDown
     case kBREventRemoteActionPageDown:
-      if ([f_event value] == 1)
-        return ATV_BUTTON_PAGEDOWN;
-      else
-        return ATV_INVALID_BUTTON;
+      return ATV_BUTTON_PAGEDOWN;
 
     // Pause
     case kBREventRemoteActionPause:
-      if ([f_event value] == 1)
-        return ATV_BUTTON_PAUSE;
-      else
-        return ATV_INVALID_BUTTON;
+      return ATV_BUTTON_PAUSE;
 
     // Play2
     case kBREventRemoteActionPlay2:
-      if ([f_event value] == 1)
-        return ATV_BUTTON_PLAY2;
-      else
-        return ATV_INVALID_BUTTON;
+      return ATV_BUTTON_PLAY2;
 
     // Stop
     case kBREventRemoteActionStop:
-      if ([f_event value] == 1)
-        return ATV_BUTTON_STOP;
-      else
-        return ATV_INVALID_BUTTON;
-        //return ATV_BUTTON_STOP_RELEASE;
+      return ATV_BUTTON_STOP;
 
     // Fast Forward
     case kBREventRemoteActionFastFwd:
-      if ([f_event value] == 1)
-        return ATV_BUTTON_FASTFWD;
-      else
-        return ATV_INVALID_BUTTON;
-        //return ATV_BUTTON_FASTFWD_RELEASE;
+      return ATV_BUTTON_FASTFWD;
 
     // Rewind
     case kBREventRemoteActionRewind:
-      if ([f_event value] == 1)
-        return ATV_BUTTON_REWIND;
-      else
-        return ATV_INVALID_BUTTON;
-        //return ATV_BUTTON_REWIND_RELEASE;
+      return ATV_BUTTON_REWIND;
 
     // Skip Forward
     case kBREventRemoteActionSkipFwd:
-      if ([f_event value] == 1)
-        return ATV_BUTTON_SKIPFWD;
-      else
-        return ATV_INVALID_BUTTON;
+      return ATV_BUTTON_SKIPFWD;
 
     // Skip Back
     case kBREventRemoteActionSkipBack:
-      if ([f_event value] == 1)
-        return ATV_BUTTON_SKIPBACK;
-      else
-        return ATV_INVALID_BUTTON;
+      return ATV_BUTTON_SKIPBACK;
 
     // Gesture Swipe Left
     case kBREventRemoteActionSwipeLeft:
@@ -585,6 +557,17 @@ int           m_systemsleepTimeout;
   }
 }
 
+- (void)setUserEvent:(int) id withHoldTime:(unsigned int) holdTime
+{
+  XBMC_Event newEvent;
+  memset(&newEvent, 0, sizeof(newEvent));
+
+  newEvent.type = XBMC_USEREVENT;
+  newEvent.jbutton.which = id;
+  newEvent.jbutton.holdTime = holdTime;
+  CWinEventsIOS::MessagePush(&newEvent);
+}
+
 - (BOOL)brEventAction:(BREvent*)event
 {
   //NSLog(@"%s", __PRETTY_FUNCTION__);
@@ -592,15 +575,19 @@ int           m_systemsleepTimeout;
        if ([m_glView isAnimating])
   {
     BOOL is_handled = NO;
-    eATVClientEvent xbmc_ir_key = [self ATVClientEventFromBREvent:event];
+    bool isRepeatable = false;
+    bool isPressed = false;
+    eATVClientEvent xbmc_ir_key = [self ATVClientEventFromBREvent:event 
+                                        Repeatable:isRepeatable
+                                        ButtonState:isPressed];
     
     if ( xbmc_ir_key != ATV_INVALID_BUTTON )
     {
-      XBMC_Event newEvent;
-      memset(&newEvent, 0, sizeof(newEvent));
-
       if (xbmc_ir_key == ATV_BTKEYPRESS && [event value] == 1)
       {
+        XBMC_Event newEvent;
+        memset(&newEvent, 0, sizeof(newEvent));
+
         NSDictionary *dict = [event eventDictionary];
         NSString *key_nsstring = [dict objectForKey:@"kBRKeyEventCharactersKey"];
         
@@ -636,9 +623,23 @@ int           m_systemsleepTimeout;
       }
       else
       {
-        newEvent.type = XBMC_USEREVENT;
-        newEvent.user.code = xbmc_ir_key;
-        CWinEventsIOS::MessagePush(&newEvent);
+        if(isRepeatable)
+        {
+          if(isPressed)
+          {
+            [self setUserEvent:xbmc_ir_key withHoldTime:0]; //fire event
+            [self startKeyPressTimer:xbmc_ir_key];//start repeat timer
+          }
+          else
+          {
+            //stop the timer
+            [self stopKeyPressTimer];
+          }
+        }
+        else
+        {
+          [self setUserEvent:xbmc_ir_key  withHoldTime:0];
+        }
         is_handled = TRUE;
       }
     }
@@ -652,6 +653,54 @@ int           m_systemsleepTimeout;
 
 #pragma mark -
 #pragma mark private helper methods
+- (void)startKeyPressTimer: (int) keyId
+{ 
+  NSNumber *number = [NSNumber numberWithInt:keyId]; 
+  NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSDate date], @"StartDate", 
+                                                                  number, @"keyId", nil];
+  
+  NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:REPEATED_KEYPRESS_DELAY_S]; 
+
+  [self stopKeyPressTimer];
+
+  //schedule repeated timer which starts after REPEATED_KEYPRESS_DELAY_S and fires
+  //every REPEATED_KEYPRESS_PAUSE_S
+  m_keyTimer       = [[NSTimer alloc] initWithFireDate:fireDate 
+                                      interval:REPEATED_KEYPRESS_PAUSE_S 
+                                      target:self 
+                                      selector:@selector(keyPressTimerCallback:) 
+                                      userInfo:dict 
+                                      repeats:YES]; 
+  //schedule the timer to the runloop
+  NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 
+  [runLoop addTimer:m_keyTimer forMode:NSDefaultRunLoopMode]; 
+} 
+
+- (void)stopKeyPressTimer
+{
+  if(m_keyTimer != nil)
+  {
+    [m_keyTimer invalidate];
+    [m_keyTimer release];
+    m_keyTimer = nil;
+  }
+}
+
+- (void)keyPressTimerCallback:(NSTimer*)theTimer 
+{ 
+  //if queue is empty - skip this timer event
+  //for letting it process
+  if(CWinEventsIOS::GetQueueSize())
+    return;
+  NSDate *startDate = [[theTimer userInfo] objectForKey:@"StartDate"];
+  int keyId = [[[theTimer userInfo] objectForKey:@"keyId"] intValue];
+  //calc the holdTime - timeIntervalSinceNow gives the
+  //passed time since startDate in seconds as negative number
+  //so multiply with -1000 for getting the positive ms
+  NSTimeInterval holdTime = [startDate timeIntervalSinceNow] * -1000.0f;
+  [self setUserEvent:keyId withHoldTime:(unsigned int)holdTime];
+} 
+
 //
 - (void)observeDefaultCenterStuff: (NSNotification *) notification
 {
@@ -993,3 +1042,4 @@ int           m_systemsleepTimeout;
 }
 
 @end
+
index 45e6a83..45028c1 100644 (file)
@@ -36,6 +36,7 @@
   CGPoint lastGesturePoint;
   CGFloat lastPinchScale;
   CGFloat currentPinchScale;  
+  CGFloat screenScale;
   bool touchBeginSignaled;
        
   UIInterfaceOrientation orientation;
@@ -46,6 +47,7 @@
 @property CGPoint lastGesturePoint;
 @property CGFloat lastPinchScale;
 @property CGFloat currentPinchScale;
+@property CGFloat screenScale;
 @property bool touchBeginSignaled;
 @property CGSize screensize;
 @property XBMC_Event lastEvent;
index 63eefa5..0d14fee 100644 (file)
@@ -66,6 +66,7 @@ XBMCEAGLView  *m_glView;
 @synthesize lastGesturePoint;
 @synthesize lastPinchScale;
 @synthesize currentPinchScale;
+@synthesize screenScale;
 @synthesize lastEvent;
 @synthesize touchBeginSignaled;
 @synthesize screensize;
@@ -169,6 +170,8 @@ XBMCEAGLView  *m_glView;
   if( [m_glView isXBMCAlive] )//NO GESTURES BEFORE WE ARE UP AND RUNNING
   {
     CGPoint point = [sender locationOfTouch:0 inView:m_glView];  
+    point.x *= screenScale;
+    point.y *= screenScale;
     currentPinchScale += [sender scale] - lastPinchScale;
     lastPinchScale = [sender scale];  
   
@@ -193,6 +196,8 @@ XBMCEAGLView  *m_glView;
     if( [sender state] == UIGestureRecognizerStateBegan )
     {
       CGPoint point = [sender locationOfTouch:0 inView:m_glView];  
+      point.x *= screenScale;
+      point.y *= screenScale;
       touchBeginSignaled = false;
       lastGesturePoint = point;
     }
@@ -200,6 +205,8 @@ XBMCEAGLView  *m_glView;
     if( [sender state] == UIGestureRecognizerStateChanged )
     {
       CGPoint point = [sender locationOfTouch:0 inView:m_glView];    
+      point.x *= screenScale;
+      point.y *= screenScale;
       bool bNotify = false;
       CGFloat yMovement=point.y - lastGesturePoint.y;
       CGFloat xMovement=point.x - lastGesturePoint.x;
@@ -247,7 +254,8 @@ XBMCEAGLView  *m_glView;
 - (IBAction)handleDoubleFingerSingleTap:(UIGestureRecognizer *)sender 
 {
   CGPoint point = [sender locationOfTouch:0 inView:m_glView];
-  
+  point.x *= screenScale;
+  point.y *= screenScale;
   //NSLog(@"%s toubleTap", __PRETTY_FUNCTION__);
   
   XBMC_Event newEvent;
@@ -278,6 +286,8 @@ XBMCEAGLView  *m_glView;
     if( [touches count] == 1 && [touch tapCount] == 1)
     {
       lastGesturePoint = [touch locationInView:m_glView];    
+      lastGesturePoint.x *= screenScale;
+      lastGesturePoint.y *= screenScale;  
       XBMC_Event newEvent;
       memset(&newEvent, 0, sizeof(newEvent));
       
@@ -333,6 +343,12 @@ XBMCEAGLView  *m_glView;
                  name: nil
                object: nil];
   
+  /* Check if screen is Retina */
+  if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
+    screenScale = [[UIScreen mainScreen] scale];
+  else
+    screenScale = 1.0;
+  
   /* We start in landscape mode */
   CGRect srect = frame;
   srect.size = CGSizeMake( frame.size.height, frame.size.width );
@@ -426,8 +442,8 @@ XBMCEAGLView  *m_glView;
 //--------------------------------------------------------------
 - (CGSize) getScreenSize
 {
-  screensize.width  = m_glView.bounds.size.width;
-  screensize.height = m_glView.bounds.size.height;  
+  screensize.width  = m_glView.bounds.size.width * screenScale;
+  screensize.height = m_glView.bounds.size.height * screenScale;  
   return screensize;
 }
 //--------------------------------------------------------------
index f5994c8..8c13d66 100644 (file)
     // Get the layer
     CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
     
+    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
+    {
+      eaglLayer.contentsScale = [[UIScreen mainScreen] scale];
+      self.contentScaleFactor = [[UIScreen mainScreen] scale];
+    }
     eaglLayer.opaque = TRUE;
     eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
       [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking,
     
     glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
     
-    CGRect rect = self.bounds; 
-    
-    if(rect.size.height > rect.size.width) {
-      glViewport(0, 0, rect.size.height, rect.size.width);
-      glScissor(0, 0, rect.size.height, rect.size.width);
+    if(framebufferHeight > framebufferWidth) {
+      glViewport(0, 0, framebufferHeight, framebufferWidth);
+      glScissor(0, 0, framebufferHeight, framebufferWidth);
     } 
     else
     {
-      glViewport(0, 0, rect.size.width, rect.size.height);
-      glScissor(0, 0, rect.size.width, rect.size.height);
+      glViewport(0, 0, framebufferWidth, framebufferHeight);
+      glScissor(0, 0, framebufferWidth, framebufferHeight);
     }
   }
 }
index 3868cc7..9fbe952 100644 (file)
@@ -27,9 +27,7 @@
 #include "devices/PeripheralNIC.h"
 #include "devices/PeripheralNyxboard.h"
 #include "devices/PeripheralTuner.h"
-#if defined(HAVE_LIBCEC)
 #include "devices/PeripheralCecAdapter.h"
-#endif
 #include "bus/PeripheralBusUSB.h"
 #include "dialogs/GUIDialogPeripheralManager.h"
 
@@ -43,6 +41,7 @@
 #include "guilib/LocalizeStrings.h"
 #include "dialogs/GUIDialogKaiToast.h"
 #include "utils/StringUtils.h"
+#include "guilib/Key.h"
 
 using namespace PERIPHERALS;
 using namespace XFILE;
@@ -331,9 +330,16 @@ int CPeripherals::GetMappingForDevice(const CPeripheralBus &bus, const Periphera
     PeripheralDeviceMapping mapping = m_mappings.at(iMappingPtr);
 
     bool bProductMatch = false;
-    for (unsigned int i = 0; i < mapping.m_PeripheralID.size(); i++)
-      if (mapping.m_PeripheralID[i].m_iVendorId == iVendorId && mapping.m_PeripheralID[i].m_iProductId == iProductId)
-        bProductMatch = true;
+    if (mapping.m_PeripheralID.size() == 0)
+    {
+      bProductMatch = true;
+    }
+    else
+    {
+      for (unsigned int i = 0; i < mapping.m_PeripheralID.size(); i++)
+        if (mapping.m_PeripheralID[i].m_iVendorId == iVendorId && mapping.m_PeripheralID[i].m_iProductId == iProductId)
+          bProductMatch = true;
+    }
 
     bool bBusMatch = (mapping.m_busType == PERIPHERAL_BUS_UNKNOWN || mapping.m_busType == bus.Type());
     bool bClassMatch = (mapping.m_class == PERIPHERAL_UNKNOWN || mapping.m_class == classType);
@@ -359,9 +365,16 @@ void CPeripherals::GetSettingsFromMapping(CPeripheral &peripheral) const
     const PeripheralDeviceMapping *mapping = &m_mappings.at(iMappingPtr);
 
     bool bProductMatch = false;
-    for (unsigned int i = 0; i < mapping->m_PeripheralID.size(); i++)
-      if (mapping->m_PeripheralID[i].m_iVendorId == peripheral.VendorId() && mapping->m_PeripheralID[i].m_iProductId == peripheral.ProductId())
-        bProductMatch = true;
+    if (mapping->m_PeripheralID.size() == 0)
+    {
+      bProductMatch = true;
+    }
+    else
+    {
+      for (unsigned int i = 0; i < mapping->m_PeripheralID.size(); i++)
+        if (mapping->m_PeripheralID[i].m_iVendorId == peripheral.VendorId() && mapping->m_PeripheralID[i].m_iProductId == peripheral.ProductId())
+          bProductMatch = true;
+    }
 
     bool bBusMatch = (mapping->m_busType == PERIPHERAL_BUS_UNKNOWN || mapping->m_busType == peripheral.GetBusType());
     bool bClassMatch = (mapping->m_class == PERIPHERAL_UNKNOWN || mapping->m_class == peripheral.Type());
@@ -399,29 +412,24 @@ bool CPeripherals::LoadMappings(void)
     mapping.m_strDeviceName = currentNode->Attribute("name") ? CStdString(currentNode->Attribute("name")) : StringUtils::EmptyString;
 
     // If there is no vendor_product attribute ignore this entry
-    if (!currentNode->Attribute("vendor_product"))
-    {
-      CLog::Log(LOGERROR, "%s - ignoring node \"%s\" with missing vendor_product attribute", __FUNCTION__, mapping.m_strDeviceName.c_str());
-      continue;
-    }
-
-    // The vendor_product attribute is a list of comma separated vendor:product pairs
-    StringUtils::SplitString(currentNode->Attribute("vendor_product"), ",", vpArray);
-    for (unsigned int i = 0; i < vpArray.size(); i++)
+    if (currentNode->Attribute("vendor_product"))
     {
-      StringUtils::SplitString(vpArray[i], ":", idArray);
-      if (idArray.size() != 2)
+      // The vendor_product attribute is a list of comma separated vendor:product pairs
+      StringUtils::SplitString(currentNode->Attribute("vendor_product"), ",", vpArray);
+      for (unsigned int i = 0; i < vpArray.size(); i++)
       {
-        CLog::Log(LOGERROR, "%s - ignoring node \"%s\" with invalid vendor_product attribute", __FUNCTION__, mapping.m_strDeviceName.c_str());
-        continue;
+        StringUtils::SplitString(vpArray[i], ":", idArray);
+        if (idArray.size() != 2)
+        {
+          CLog::Log(LOGERROR, "%s - ignoring node \"%s\" with invalid vendor_product attribute", __FUNCTION__, mapping.m_strDeviceName.c_str());
+          continue;
+        }
+
+        id.m_iVendorId = PeripheralTypeTranslator::HexStringToInt(idArray[0]);
+        id.m_iProductId = PeripheralTypeTranslator::HexStringToInt(idArray[1]);
+        mapping.m_PeripheralID.push_back(id);
       }
-
-      id.m_iVendorId = PeripheralTypeTranslator::HexStringToInt(idArray[0]);
-      id.m_iProductId = PeripheralTypeTranslator::HexStringToInt(idArray[1]);
-      mapping.m_PeripheralID.push_back(id);
     }
-    if (mapping.m_PeripheralID.size() == 0)
-      continue;
 
     mapping.m_busType       = PeripheralTypeTranslator::GetBusTypeFromString(currentNode->Attribute("bus"));
     mapping.m_class         = PeripheralTypeTranslator::GetTypeFromString(currentNode->Attribute("class"));
@@ -438,6 +446,8 @@ bool CPeripherals::LoadMappings(void)
 void CPeripherals::GetSettingsFromMappingsFile(TiXmlElement *xmlNode, map<CStdString, CSetting *> &m_settings)
 {
   TiXmlElement *currentNode = xmlNode->FirstChildElement("setting");
+  int iMaxOrder(0);
+
   while (currentNode)
   {
     CSetting *setting = NULL;
@@ -483,10 +493,32 @@ void CPeripherals::GetSettingsFromMappingsFile(TiXmlElement *xmlNode, map<CStdSt
     }
 
     //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;
+    setting->SetOrder(iOrder);
+    if (iOrder > iMaxOrder)
+      iMaxOrder = iOrder;
+
+    /* and add this new setting */
     m_settings[strKey] = setting;
+
     currentNode = currentNode->NextSiblingElement("setting");
   }
+
+  /* add the settings without an order attribute or an invalid order attribute set at the end */
+  for (map<CStdString, CSetting *>::iterator it = m_settings.begin(); it != m_settings.end(); it++)
+  {
+    if (it->second->GetOrder() == 0)
+      it->second->SetOrder(++iMaxOrder);
+  }
 }
 
 void CPeripherals::GetDirectory(const CStdString &strPath, CFileItemList &items) const
@@ -522,3 +554,89 @@ CPeripheral *CPeripherals::GetByPath(const CStdString &strPath) const
 
   return NULL;
 }
+
+bool CPeripherals::OnAction(const CAction &action)
+{
+  if (action.GetID() == ACTION_MUTE)
+  {
+    return ToggleMute();
+  }
+
+  if (SupportsCEC() && action.GetAmount() && (action.GetID() == ACTION_VOLUME_UP || action.GetID() == ACTION_VOLUME_DOWN))
+  {
+    vector<CPeripheral *> peripherals;
+    if (GetPeripheralsWithFeature(peripherals, FEATURE_CEC))
+    {
+      for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < peripherals.size(); iPeripheralPtr++)
+      {
+        CPeripheralCecAdapter *cecDevice = (CPeripheralCecAdapter *) peripherals.at(iPeripheralPtr);
+        if (cecDevice && cecDevice->HasConnectedAudioSystem())
+        {
+          if (action.GetID() == ACTION_VOLUME_UP)
+            cecDevice->ScheduleVolumeUp();
+          else
+            cecDevice->ScheduleVolumeDown();
+          return true;
+        }
+      }
+    }
+  }
+
+  return false;
+}
+
+bool CPeripherals::IsMuted(void)
+{
+  vector<CPeripheral *> peripherals;
+  if (SupportsCEC() && GetPeripheralsWithFeature(peripherals, FEATURE_CEC))
+  {
+    for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < peripherals.size(); iPeripheralPtr++)
+    {
+      CPeripheralCecAdapter *cecDevice = (CPeripheralCecAdapter *) peripherals.at(iPeripheralPtr);
+      if (cecDevice && cecDevice->IsMuted())
+        return true;
+    }
+  }
+
+  return false;
+}
+
+bool CPeripherals::ToggleMute(void)
+{
+  vector<CPeripheral *> peripherals;
+  if (SupportsCEC() && GetPeripheralsWithFeature(peripherals, FEATURE_CEC))
+  {
+    for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < peripherals.size(); iPeripheralPtr++)
+    {
+      CPeripheralCecAdapter *cecDevice = (CPeripheralCecAdapter *) peripherals.at(iPeripheralPtr);
+      if (cecDevice && cecDevice->HasConnectedAudioSystem())
+      {
+        cecDevice->ScheduleMute();
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+bool CPeripherals::GetNextKeypress(float frameTime, CKey &key)
+{
+  vector<CPeripheral *> peripherals;
+  if (SupportsCEC() && GetPeripheralsWithFeature(peripherals, FEATURE_CEC))
+  {
+    for (unsigned int iPeripheralPtr = 0; iPeripheralPtr < peripherals.size(); iPeripheralPtr++)
+    {
+      CPeripheralCecAdapter *cecDevice = (CPeripheralCecAdapter *) peripherals.at(iPeripheralPtr);
+      if (cecDevice && cecDevice->GetButton())
+      {
+        CKey newKey(cecDevice->GetButton(), cecDevice->GetHoldTime());
+        cecDevice->ResetButton();
+        key = newKey;
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
index a5c4ef2..a98ead5 100644 (file)
@@ -29,6 +29,8 @@ class CFileItemList;
 class CSetting;
 class CSettingsCategory;
 class TiXmlElement;
+class CAction;
+class CKey;
 
 namespace PERIPHERALS
 {
@@ -147,6 +149,54 @@ namespace PERIPHERALS
      */
     virtual CPeripheral *GetByPath(const CStdString &strPath) const;
 
+    /*!
+     * @brief Try to let one of the peripherals handle an action.
+     * @param action The change to handle.
+     * @return True when this change was handled by a peripheral (and should not be handled by anything else), false otherwise.
+     */
+    virtual bool OnAction(const CAction &action);
+
+    /*!
+     * @brief Check whether there's a peripheral that reports to be muted.
+     * @return True when at least one peripheral reports to be muted, false otherwise.
+     */
+    virtual bool IsMuted(void);
+
+    /*!
+     * @brief Try to toggle the mute status via a peripheral.
+     * @return True when this change was handled by a peripheral (and should not be handled by anything else), false otherwise.
+     */
+    virtual bool ToggleMute(void);
+
+    /*!
+     * @brief Try to mute the audio via a peripheral.
+     * @return True when this change was handled by a peripheral (and should not be handled by anything else), false otherwise.
+     */
+    virtual bool Mute(void) { return ToggleMute(); } // TODO CEC only supports toggling the mute status at this time
+
+    /*!
+     * @brief Try to unmute the audio via a peripheral.
+     * @return True when this change was handled by a peripheral (and should not be handled by anything else), false otherwise.
+     */
+    virtual bool UnMute(void) { return ToggleMute(); } // TODO CEC only supports toggling the mute status at this time
+
+    /*!
+     * @brief Try to get a keypress from a peripheral.
+     * @param frameTime The current frametime.
+     * @param key The fetched key.
+     * @return True when a keypress was fetched, false otherwise.
+     */
+    virtual bool GetNextKeypress(float frameTime, CKey &key);
+
+    bool SupportsCEC(void) const
+    {
+#if defined(HAVE_LIBCEC)
+      return true;
+#else
+      return false;
+#endif
+    }
+
   private:
     CPeripherals(void);
     bool LoadMappings(void);
index d07acaf..3d9a238 100644 (file)
 using namespace PERIPHERALS;
 using namespace std;
 
+struct SortBySettingsOrder
+{
+  bool operator()(const CSetting *left, const CSetting *right)
+  {
+    return left->GetOrder() < right->GetOrder();
+  }
+};
+
 CPeripheral::CPeripheral(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId) :
   m_type(type),
   m_busType(busType),
@@ -168,6 +176,15 @@ bool CPeripheral::IsMultiFunctional(void) const
   return m_subDevices.size() > 0;
 }
 
+vector<CSetting *> CPeripheral::GetSettings(void) const
+{
+  vector<CSetting *> settings;
+  for (map<CStdString, CSetting *>::const_iterator it = m_settings.begin(); it != m_settings.end(); it++)
+    settings.push_back(it->second);
+  sort(settings.begin(), settings.end(), SortBySettingsOrder());
+  return settings;
+}
+
 void CPeripheral::AddSetting(const CStdString &strKey, const CSetting *setting)
 {
   if (!setting)
@@ -183,7 +200,7 @@ void CPeripheral::AddSetting(const CStdString &strKey, const CSetting *setting)
     case SETTINGS_TYPE_BOOL:
       {
         const CSettingBool *mappedSetting = (const CSettingBool *) setting;
-        CSettingBool *boolSetting = new CSettingBool(0, strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData(), mappedSetting->GetControlType());
+        CSettingBool *boolSetting = new CSettingBool(mappedSetting->GetOrder(), strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData(), mappedSetting->GetControlType());
         if (boolSetting)
         {
           boolSetting->SetVisible(mappedSetting->IsVisible());
@@ -194,7 +211,7 @@ void CPeripheral::AddSetting(const CStdString &strKey, const CSetting *setting)
     case SETTINGS_TYPE_INT:
       {
         const CSettingInt *mappedSetting = (const CSettingInt *) setting;
-        CSettingInt *intSetting = new CSettingInt(0, strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData(), mappedSetting->m_iMin, mappedSetting->m_iStep, mappedSetting->m_iMax, mappedSetting->GetControlType(), mappedSetting->m_strFormat);
+        CSettingInt *intSetting = new CSettingInt(mappedSetting->GetOrder(), strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData(), mappedSetting->m_iMin, mappedSetting->m_iStep, mappedSetting->m_iMax, mappedSetting->GetControlType(), mappedSetting->m_strFormat);
         if (intSetting)
         {
           intSetting->SetVisible(mappedSetting->IsVisible());
@@ -205,7 +222,7 @@ void CPeripheral::AddSetting(const CStdString &strKey, const CSetting *setting)
     case SETTINGS_TYPE_FLOAT:
       {
         const CSettingFloat *mappedSetting = (const CSettingFloat *) setting;
-        CSettingFloat *floatSetting = new CSettingFloat(0, strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData(), mappedSetting->m_fMin, mappedSetting->m_fStep, mappedSetting->m_fMax, mappedSetting->GetControlType());
+        CSettingFloat *floatSetting = new CSettingFloat(mappedSetting->GetOrder(), strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData(), mappedSetting->m_fMin, mappedSetting->m_fStep, mappedSetting->m_fMax, mappedSetting->GetControlType());
         if (floatSetting)
         {
           floatSetting->SetVisible(mappedSetting->IsVisible());
@@ -216,7 +233,7 @@ void CPeripheral::AddSetting(const CStdString &strKey, const CSetting *setting)
     case SETTINGS_TYPE_STRING:
       {
         const CSettingString *mappedSetting = (const CSettingString *) setting;
-        CSettingString *stringSetting = new CSettingString(0, strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData().c_str(), mappedSetting->GetControlType(), mappedSetting->m_bAllowEmpty, mappedSetting->m_iHeadingString);
+        CSettingString *stringSetting = new CSettingString(mappedSetting->GetOrder(), strKey.c_str(), mappedSetting->GetLabel(), mappedSetting->GetData().c_str(), mappedSetting->GetControlType(), mappedSetting->m_bAllowEmpty, mappedSetting->m_iHeadingString);
         if (stringSetting)
         {
           stringSetting->SetVisible(mappedSetting->IsVisible());
@@ -323,7 +340,7 @@ void CPeripheral::SetSetting(const CStdString &strKey, bool bValue)
       bool bChanged(boolSetting->GetData() != bValue);
       boolSetting->SetData(bValue);
       if (bChanged && m_bInitialised)
-        m_changedSettings.push_back(strKey);
+        m_changedSettings.insert(strKey);
     }
   }
 }
@@ -339,7 +356,7 @@ void CPeripheral::SetSetting(const CStdString &strKey, int iValue)
       bool bChanged(intSetting->GetData() != iValue);
       intSetting->SetData(iValue);
       if (bChanged && m_bInitialised)
-        m_changedSettings.push_back(strKey);
+        m_changedSettings.insert(strKey);
     }
   }
 }
@@ -355,11 +372,26 @@ void CPeripheral::SetSetting(const CStdString &strKey, float fValue)
       bool bChanged(floatSetting->GetData() != fValue);
       floatSetting->SetData(fValue);
       if (bChanged && m_bInitialised)
-        m_changedSettings.push_back(strKey);
+        m_changedSettings.insert(strKey);
     }
   }
 }
 
+void CPeripheral::SetSettingVisible(const CStdString &strKey, bool bSetTo)
+{
+  map<CStdString, CSetting *>::iterator it = m_settings.find(strKey);
+  if (it != m_settings.end())
+    (*it).second->SetVisible(bSetTo);
+}
+
+bool CPeripheral::IsSettingVisible(const CStdString &strKey) const
+{
+  map<CStdString, CSetting *>::const_iterator it = m_settings.find(strKey);
+  if (it != m_settings.end())
+    return (*it).second->IsVisible();
+  return false;
+}
+
 void CPeripheral::SetSetting(const CStdString &strKey, const CStdString &strValue)
 {
   map<CStdString, CSetting *>::iterator it = m_settings.find(strKey);
@@ -373,7 +405,7 @@ void CPeripheral::SetSetting(const CStdString &strKey, const CStdString &strValu
         bool bChanged(!stringSetting->GetData().Equals(strValue));
         stringSetting->SetData(strValue);
         if (bChanged && m_bInitialised)
-          m_changedSettings.push_back(strKey);
+          m_changedSettings.insert(strKey);
       }
     }
     else if ((*it).second->GetType() == SETTINGS_TYPE_INT)
@@ -436,7 +468,7 @@ void CPeripheral::PersistSettings(bool bExiting /* = false */)
 
   if (!bExiting)
   {
-    for (vector<CStdString>::iterator it = m_changedSettings.begin(); it != m_changedSettings.end(); it++)
+    for (set<CStdString>::const_iterator it = m_changedSettings.begin(); it != m_changedSettings.end(); it++)
       OnSettingChanged(*it);
   }
   m_changedSettings.clear();
@@ -467,7 +499,7 @@ void CPeripheral::ResetDefaultSettings(void)
   map<CStdString, CSetting *>::iterator it = m_settings.begin();
   while (it != m_settings.end())
   {
-    m_changedSettings.push_back((*it).first);
+    m_changedSettings.insert((*it).first);
     ++it;
   }
 
index 7851554..1c6ca71 100644 (file)
@@ -20,7 +20,7 @@
  *
  */
 
-#include <vector>
+#include <set>
 #include "utils/StdString.h"
 #include "peripherals/PeripheralTypes.h"
 
@@ -128,6 +128,8 @@ namespace PERIPHERALS
      */
     virtual const CStdString GetSettingString(const CStdString &strKey) const;
     virtual void SetSetting(const CStdString &strKey, const CStdString &strValue);
+    virtual void SetSettingVisible(const CStdString &strKey, bool bSetTo);
+    virtual bool IsSettingVisible(const CStdString &strKey) const;
 
     virtual int GetSettingInt(const CStdString &strKey) const;
     virtual void SetSetting(const CStdString &strKey, int iValue);
@@ -142,6 +144,8 @@ namespace PERIPHERALS
     virtual void LoadPersistedSettings(void);
     virtual void ResetDefaultSettings(void);
 
+    virtual std::vector<CSetting *> GetSettings(void) const;
+
     virtual bool ErrorOccured(void) const { return m_bError; }
 
   protected:
@@ -163,6 +167,6 @@ namespace PERIPHERALS
     std::vector<PeripheralFeature>   m_features;
     std::vector<CPeripheral *>       m_subDevices;
     std::map<CStdString, CSetting *> m_settings;
-    std::vector<CStdString>          m_changedSettings;
+    std::set<CStdString>             m_changedSettings;
   };
 }
index a117d82..a898a16 100644 (file)
@@ -18,8 +18,8 @@
  *  http://www.gnu.org/copyleft/gpl.html
  *
  */
-#include "system.h"
 
+#include "system.h"
 #if defined(HAVE_LIBCEC)
 #include "PeripheralCecAdapter.h"
 #include "input/XBIRRemote.h"
 #include "peripherals/Peripherals.h"
 #include "peripherals/bus/PeripheralBus.h"
 #include "settings/GUISettings.h"
+#include "settings/Settings.h"
 #include "utils/log.h"
+#include "utils/Variant.h"
 
-#include <cec.h>
+#include <libcec/cec.h>
 
 using namespace PERIPHERALS;
 using namespace ANNOUNCEMENT;
 using namespace CEC;
 
-#define CEC_LIB_SUPPORTED_VERSION 1
+#define CEC_LIB_SUPPORTED_VERSION 0x1500
 
 /* time in seconds to ignore standby commands from devices after the screensaver has been activated */
 #define SCREENSAVER_TIMEOUT       10
+#define VOLUME_CHANGE_TIMEOUT     250
+#define VOLUME_REFRESH_TIMEOUT    100
 
 class DllLibCECInterface
 {
 public:
   virtual ~DllLibCECInterface() {}
-  virtual ICECAdapter* CECInit(const char *interfaceName, cec_device_type_list types)=0;
-  virtual void* CECDestroy(ICECAdapter *adapter)=0;
+  virtual ICECAdapter* CECInitialise(libcec_configuration *configuration)=0;
+  virtual void*        CECDestroy(ICECAdapter *adapter)=0;
 };
 
 class DllLibCEC : public DllDynamic, DllLibCECInterface
 {
   DECLARE_DLL_WRAPPER(DllLibCEC, DLL_PATH_LIBCEC)
 
-  DEFINE_METHOD2(ICECAdapter*, CECInit,   (const char *p1, cec_device_type_list p2))
-  DEFINE_METHOD1(void*       , CECDestroy,  (ICECAdapter *p1))
+  DEFINE_METHOD1(ICECAdapter*, CECInitialise, (libcec_configuration *p1))
+  DEFINE_METHOD1(void*       , CECDestroy,    (ICECAdapter *p1))
 
   BEGIN_METHOD_RESOLVE()
-    RESOLVE_METHOD_RENAME(CECInit,  CECInit)
+    RESOLVE_METHOD_RENAME(CECInitialise,  CECInitialise)
     RESOLVE_METHOD_RENAME(CECDestroy, CECDestroy)
   END_METHOD_RESOLVE()
 };
@@ -71,41 +75,19 @@ CPeripheralCecAdapter::CPeripheralCecAdapter(const PeripheralType type, const Pe
   m_bStarted(false),
   m_bHasButton(false),
   m_bIsReady(false),
+  m_bHasConnectedAudioSystem(false),
   m_strMenuLanguage("???"),
-  m_lastKeypress(0)
+  m_lastKeypress(0),
+  m_lastChange(VOLUME_CHANGE_NONE),
+  m_iExitCode(0),
+  m_bIsMuted(false) // TODO fetch the correct initial value when system audiostatus is implemented in libCEC
 {
   m_button.iButton = 0;
   m_button.iDuration = 0;
   m_screensaverLastActivated.SetValid(false);
-  m_dll = new DllLibCEC;
-  if (m_dll->Load() && m_dll->IsLoaded())
-  {
-    cec_device_type_list typeList;
-    typeList.clear();
-    typeList.add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
-    m_cecAdapter = m_dll->CECInit("XBMC", typeList);
-  }
-  else
-    m_cecAdapter = NULL;
-
-  if (!m_cecAdapter || m_cecAdapter->GetMinLibVersion() > CEC_LIB_SUPPORTED_VERSION)
-  {
-    /* unsupported libcec version */
-    CLog::Log(LOGERROR, g_localizeStrings.Get(36013).c_str(), CEC_LIB_SUPPORTED_VERSION, m_cecAdapter ? m_cecAdapter->GetMinLibVersion() : -1);
 
-    CStdString strMessage;
-    strMessage.Format(g_localizeStrings.Get(36013).c_str(), CEC_LIB_SUPPORTED_VERSION, m_cecAdapter ? m_cecAdapter->GetMinLibVersion() : -1);
-    CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(36000), strMessage);
-    m_bError = true;
-    if (m_cecAdapter)
-      m_dll->CECDestroy(m_cecAdapter);
-    m_cecAdapter = NULL;
-  }
-  else
-  {
-    CLog::Log(LOGDEBUG, "%s - using libCEC v%d.%d", __FUNCTION__, m_cecAdapter->GetLibVersionMajor(), m_cecAdapter->GetLibVersionMinor());
-    m_features.push_back(FEATURE_CEC);
-  }
+  m_configuration.Clear();
+  m_features.push_back(FEATURE_CEC);
 }
 
 CPeripheralCecAdapter::~CPeripheralCecAdapter(void)
@@ -117,7 +99,6 @@ CPeripheralCecAdapter::~CPeripheralCecAdapter(void)
 
   if (m_dll && m_cecAdapter)
   {
-    FlushLog();
     m_dll->CECDestroy(m_cecAdapter);
     m_cecAdapter = NULL;
     delete m_dll;
@@ -125,60 +106,102 @@ CPeripheralCecAdapter::~CPeripheralCecAdapter(void)
   }
 }
 
-void CPeripheralCecAdapter::Announce(EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
+void CPeripheralCecAdapter::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
 {
   if (flag == System && !strcmp(sender, "xbmc") && !strcmp(message, "OnQuit") && m_bIsReady)
   {
-    m_cecAdapter->SetInactiveView();
-    if (GetSettingBool("cec_power_off_shutdown"))
-      m_cecAdapter->StandbyDevices();
+    m_iExitCode = data.asInteger(0);
+    StopThread(false);
   }
-  else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverDeactivated") && GetSettingBool("cec_standby_screensaver") && m_bIsReady)
+  else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverDeactivated") && m_bIsReady)
   {
-    m_cecAdapter->PowerOnDevices();
+    if (m_configuration.bPowerOffScreensaver == 1)
+    {
+      // power off/on on screensaver is set, and devices to wake are set
+      if (!m_configuration.wakeDevices.IsEmpty())
+        m_cecAdapter->PowerOnDevices(CECDEVICE_BROADCAST);
+
+      // the option to make XBMC the active source is set
+      if (m_configuration.bActivateSource == 1)
+        m_cecAdapter->SetActiveSource();
+    }
   }
-  else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && GetSettingBool("cec_standby_screensaver"))
+  else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && m_bIsReady)
   {
-    m_screensaverLastActivated = CDateTime::GetCurrentDateTime();
-    m_cecAdapter->StandbyDevices();
+    // Don't put devices to standby if application is currently playing
+    if ((!g_application.IsPlaying() || g_application.IsPaused()) && m_configuration.bPowerOffScreensaver == 1)
+    {
+      m_screensaverLastActivated = CDateTime::GetCurrentDateTime();
+      // only power off when we're the active source
+      if (m_cecAdapter->IsLibCECActiveSource())
+        m_cecAdapter->StandbyDevices(CECDEVICE_BROADCAST);
+    }
   }
   else if (flag == System && !strcmp(sender, "xbmc") && !strcmp(message, "OnSleep"))
   {
-    if (GetSettingBool("cec_power_off_shutdown") && m_bIsReady)
-      m_cecAdapter->StandbyDevices();
-    CSingleLock lock(m_critSection);
-    m_bStop = true;
+    // this will also power off devices when we're the active source
+    {
+      CSingleLock lock(m_critSection);
+      m_bStop = true;
+    }
     WaitForThreadExit(0);
   }
   else if (flag == System && !strcmp(sender, "xbmc") && !strcmp(message, "OnWake"))
   {
-    CSingleLock lock(m_critSection);
-    CLog::Log(LOGDEBUG, "%s - reconnecting to the CEC adapter after standby mode", __FUNCTION__);
-    m_cecAdapter->Close();
-
-    CStdString strPort = GetComPort();
-    if (!strPort.empty())
     {
-      if (!m_cecAdapter->Open(strPort.c_str(), 10000))
-      {
-        CLog::Log(LOGERROR, "%s - failed to reconnect to the CEC adapter", __FUNCTION__);
-        FlushLog();
-        m_bStop = true;
-      }
-      else
-      {
-        if (GetSettingBool("cec_power_on_startup"))
-          PowerOnCecDevices(CECDEVICE_TV);
-        m_cecAdapter->SetActiveView();
-      }
+      // reconnect to the device
+      CSingleLock lock(m_critSection);
+      CLog::Log(LOGDEBUG, "%s - reconnecting to the CEC adapter after standby mode", __FUNCTION__);
+
+      // close the previous connection
+      m_cecAdapter->Close();
     }
+
+    // and open a new one
+    StopThread();
+    Create();
   }
 }
 
 bool CPeripheralCecAdapter::InitialiseFeature(const PeripheralFeature feature)
 {
-  if (feature == FEATURE_CEC && !m_bStarted)
+  if (feature == FEATURE_CEC && !m_bStarted && GetSettingBool("enabled"))
   {
+    SetConfigurationFromSettings();
+    m_callbacks.CBCecLogMessage           = &CecLogMessage;
+    m_callbacks.CBCecKeyPress             = &CecKeyPress;
+    m_callbacks.CBCecCommand              = &CecCommand;
+    m_callbacks.CBCecConfigurationChanged = &CecConfiguration;
+    m_configuration.callbackParam         = this;
+    m_configuration.callbacks             = &m_callbacks;
+
+    m_dll = new DllLibCEC;
+    if (m_dll->Load() && m_dll->IsLoaded())
+      m_cecAdapter = m_dll->CECInitialise(&m_configuration);
+    else
+      return false;
+
+    if (m_configuration.serverVersion < CEC_LIB_SUPPORTED_VERSION)
+    {
+      /* unsupported libcec version */
+      CLog::Log(LOGERROR, g_localizeStrings.Get(36013).c_str(), CEC_LIB_SUPPORTED_VERSION, m_cecAdapter ? m_configuration.serverVersion : -1);
+
+      CStdString strMessage;
+      strMessage.Format(g_localizeStrings.Get(36013).c_str(), CEC_LIB_SUPPORTED_VERSION, m_cecAdapter ? m_configuration.serverVersion : -1);
+      CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(36000), strMessage);
+      m_bError = true;
+      if (m_cecAdapter)
+        m_dll->CECDestroy(m_cecAdapter);
+      m_cecAdapter = NULL;
+
+      m_features.clear();
+      return false;
+    }
+    else
+    {
+      CLog::Log(LOGDEBUG, "%s - using libCEC v%s", __FUNCTION__, m_cecAdapter->ToString((cec_server_version)m_configuration.serverVersion));
+    }
+
     m_bStarted = true;
     Create();
   }
@@ -217,23 +240,20 @@ CStdString CPeripheralCecAdapter::GetComPort(void)
   return strPort;
 }
 
-void CPeripheralCecAdapter::Process(void)
+bool CPeripheralCecAdapter::OpenConnection(void)
 {
+  bool bIsOpen(false);
+
   if (!GetSettingBool("enabled"))
   {
     CLog::Log(LOGDEBUG, "%s - CEC adapter is disabled in peripheral settings", __FUNCTION__);
     m_bStarted = false;
-    return;
+    return bIsOpen;
   }
   
   CStdString strPort = GetComPort();
   if (strPort.empty())
-    return;
-
-  // set correct physical address from peripheral settings
-  int iHdmiPort = GetSettingInt("cec_hdmi_port");
-  SetHdmiPort(iHdmiPort);
-  FlushLog();
+    return bIsOpen;
 
   // open the CEC adapter
   CLog::Log(LOGDEBUG, "%s - opening a connection to the CEC adapter: %s", __FUNCTION__, strPort.c_str());
@@ -243,100 +263,221 @@ void CPeripheralCecAdapter::Process(void)
   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);
+  bool bConnectionFailedDisplayed(false);
 
-  if (GetSettingBool("cec_power_on_startup"))
+  while (!m_bStop && !bIsOpen)
   {
-    PowerOnCecDevices(CECDEVICE_TV);
-    FlushLog();
+    if ((bIsOpen = m_cecAdapter->Open(strPort.c_str(), 10000)) == false)
+    {
+      CLog::Log(LOGERROR, "%s - could not opening a connection to the CEC adapter", __FUNCTION__);
+      if (!bConnectionFailedDisplayed)
+        CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(36000), g_localizeStrings.Get(36012));
+      bConnectionFailedDisplayed = true;
+
+      Sleep(10000);
+    }
   }
 
-  if (GetSettingBool("use_tv_menu_language"))
+  if (bIsOpen)
   {
-    cec_menu_language language;
-    if (m_cecAdapter->GetDeviceMenuLanguage(CECDEVICE_TV, &language))
-      SetMenuLanguage(language.language);
+    CLog::Log(LOGDEBUG, "%s - connection to the CEC adapter opened", __FUNCTION__);
+
+    if (!m_configuration.wakeDevices.IsEmpty())
+      m_cecAdapter->PowerOnDevices(CECDEVICE_BROADCAST);
+
+    if (m_configuration.bActivateSource == 1)
+      m_cecAdapter->SetActiveSource();
   }
 
-  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));
+  return bIsOpen;
+}
+
+void CPeripheralCecAdapter::Process(void)
+{
+  if (!OpenConnection())
+    return;
+
+  CAnnouncementManager::AddAnnouncer(this);
+
+  m_queryThread = new CPeripheralCecAdapterUpdateThread(this, &m_configuration);
+  m_queryThread->Create(false);
 
   while (!m_bStop)
   {
-    FlushLog();
     if (!m_bStop)
-      ProcessNextCommand();
+      ProcessVolumeChange();
+
     if (!m_bStop)
       Sleep(5);
   }
 
+  delete m_queryThread;
+
+  if (m_iExitCode != EXITCODE_REBOOT)
+  {
+    if (m_cecAdapter->IsLibCECActiveSource())
+    {
+      if (!m_configuration.powerOffDevices.IsEmpty())
+      {
+        CLog::Log(LOGDEBUG, "%s - sending standby commands", __FUNCTION__);
+        m_cecAdapter->StandbyDevices();
+      }
+      else if (m_configuration.bSendInactiveSource == 1)
+      {
+        CLog::Log(LOGDEBUG, "%s - sending inactive source commands", __FUNCTION__);
+        m_cecAdapter->SetInactiveView();
+      }
+    }
+    else
+    {
+      CLog::Log(LOGDEBUG, "%s - XBMC is not the active source, not sending any standby commands", __FUNCTION__);
+    }
+  }
+
   m_cecAdapter->Close();
 
   CLog::Log(LOGDEBUG, "%s - CEC adapter processor thread ended", __FUNCTION__);
   m_bStarted = false;
 }
 
-bool CPeripheralCecAdapter::PowerOnCecDevices(cec_logical_address iLogicalAddress)
+bool CPeripheralCecAdapter::HasConnectedAudioSystem(void)
 {
-  bool bReturn(false);
+  CSingleLock lock(m_critSection);
+  return m_bHasConnectedAudioSystem;
+}
+
+void CPeripheralCecAdapter::SetAudioSystemConnected(bool bSetTo)
+{
+  CSingleLock lock(m_critSection);
+  m_bHasConnectedAudioSystem = bSetTo;
+}
 
-  if (m_cecAdapter && m_bIsReady)
+void CPeripheralCecAdapter::ScheduleVolumeUp(void)
+{
   {
-    CLog::Log(LOGDEBUG, "%s - powering on CEC capable device with address %1x", __FUNCTION__, iLogicalAddress);
-    bReturn = m_cecAdapter->PowerOnDevices(iLogicalAddress);
+    CSingleLock lock(m_critSection);
+    m_volumeChangeQueue.push(VOLUME_CHANGE_UP);
   }
+  Sleep(5);
+}
 
-  return bReturn;
+void CPeripheralCecAdapter::ScheduleVolumeDown(void)
+{
+  {
+    CSingleLock lock(m_critSection);
+    m_volumeChangeQueue.push(VOLUME_CHANGE_DOWN);
+  }
+  Sleep(5);
 }
 
-bool CPeripheralCecAdapter::StandbyCecDevices(cec_logical_address iLogicalAddress)
+void CPeripheralCecAdapter::ScheduleMute(void)
 {
-  bool bReturn(false);
+  {
+    CSingleLock lock(m_critSection);
+    m_volumeChangeQueue.push(VOLUME_CHANGE_MUTE);
+  }
+  Sleep(5);
+}
 
-  if (m_cecAdapter && m_bIsReady)
+void CPeripheralCecAdapter::ProcessVolumeChange(void)
+{
+  bool bSendRelease(false);
+  CecVolumeChange pendingVolumeChange = VOLUME_CHANGE_NONE;
   {
-    CLog::Log(LOGDEBUG, "%s - putting CEC capable devices with address %1x in standby mode", __FUNCTION__, iLogicalAddress);
-    bReturn = m_cecAdapter->StandbyDevices(iLogicalAddress);
+    CSingleLock lock(m_critSection);
+    if (m_volumeChangeQueue.size() > 0)
+    {
+      /* get the first change from the queue */
+      pendingVolumeChange = m_volumeChangeQueue.front();
+      m_volumeChangeQueue.pop();
+
+      /* remove all dupe entries */
+      while (m_volumeChangeQueue.size() > 0 && m_volumeChangeQueue.front() == pendingVolumeChange)
+        m_volumeChangeQueue.pop();
+
+      /* send another keypress after VOLUME_REFRESH_TIMEOUT ms */
+      bool bRefresh(m_lastKeypress + VOLUME_REFRESH_TIMEOUT < XbmcThreads::SystemClockMillis());
+
+      /* only send the keypress when it hasn't been sent yet */
+      if (pendingVolumeChange != m_lastChange)
+      {
+        m_lastKeypress = XbmcThreads::SystemClockMillis();
+        m_lastChange = pendingVolumeChange;
+      }
+      else if (bRefresh)
+      {
+        m_lastKeypress = XbmcThreads::SystemClockMillis();
+        pendingVolumeChange = m_lastChange;
+      }
+      else
+        pendingVolumeChange = VOLUME_CHANGE_NONE;
+    }
+    else if (m_lastKeypress > 0 && m_lastKeypress + VOLUME_CHANGE_TIMEOUT < XbmcThreads::SystemClockMillis())
+    {
+      /* send a key release */
+      m_lastKeypress = 0;
+      bSendRelease = true;
+      m_lastChange = VOLUME_CHANGE_NONE;
+    }
   }
 
-  return bReturn;
+  switch (pendingVolumeChange)
+  {
+  case VOLUME_CHANGE_UP:
+    m_cecAdapter->SendKeypress(CECDEVICE_AUDIOSYSTEM, CEC_USER_CONTROL_CODE_VOLUME_UP, false);
+    break;
+  case VOLUME_CHANGE_DOWN:
+    m_cecAdapter->SendKeypress(CECDEVICE_AUDIOSYSTEM, CEC_USER_CONTROL_CODE_VOLUME_DOWN, false);
+    break;
+  case VOLUME_CHANGE_MUTE:
+    m_cecAdapter->SendKeypress(CECDEVICE_AUDIOSYSTEM, CEC_USER_CONTROL_CODE_MUTE, false);
+    {
+      CSingleLock lock(m_critSection);
+      m_bIsMuted = !m_bIsMuted;
+    }
+    break;
+  case VOLUME_CHANGE_NONE:
+    if (bSendRelease)
+      m_cecAdapter->SendKeyRelease(CECDEVICE_AUDIOSYSTEM, false);
+    break;
+  }
 }
 
-bool CPeripheralCecAdapter::SendPing(void)
+void CPeripheralCecAdapter::VolumeUp(void)
 {
-  bool bReturn(false);
-  if (m_cecAdapter && m_bIsReady)
+  if (HasConnectedAudioSystem())
   {
-    CLog::Log(LOGDEBUG, "%s - sending ping to the CEC adapter", __FUNCTION__);
-    bReturn = m_cecAdapter->PingAdapter();
+    CSingleLock lock(m_critSection);
+    m_volumeChangeQueue.push(VOLUME_CHANGE_UP);
   }
+}
 
-  return bReturn;
+void CPeripheralCecAdapter::VolumeDown(void)
+{
+  if (HasConnectedAudioSystem())
+  {
+    CSingleLock lock(m_critSection);
+    m_volumeChangeQueue.push(VOLUME_CHANGE_DOWN);
+  }
 }
 
-bool CPeripheralCecAdapter::SetHdmiPort(int iHdmiPort)
+void CPeripheralCecAdapter::Mute(void)
 {
-  bool bReturn(false);
-  if (m_cecAdapter && m_bIsReady)
+  if (HasConnectedAudioSystem())
   {
-    if (iHdmiPort <= 0 || iHdmiPort > 16)
-      iHdmiPort = 1;
-    CLog::Log(LOGDEBUG, "%s - changing active HDMI port to %d", __FUNCTION__, iHdmiPort);
-    bReturn = m_cecAdapter->SetPhysicalAddress(iHdmiPort << 12);
+    CSingleLock lock(m_critSection);
+    m_volumeChangeQueue.push(VOLUME_CHANGE_MUTE);
   }
+}
 
-  return bReturn;
+bool CPeripheralCecAdapter::IsMuted(void)
+{
+  if (HasConnectedAudioSystem())
+  {
+    CSingleLock lock(m_critSection);
+    return m_bIsMuted;
+  }
+  return false;
 }
 
 void CPeripheralCecAdapter::SetMenuLanguage(const char *strLanguage)
@@ -400,10 +541,13 @@ void CPeripheralCecAdapter::SetMenuLanguage(const char *strLanguage)
     CLog::Log(LOGWARNING, "%s - TV menu language set to unknown value '%s'", __FUNCTION__, strLanguage);
 }
 
-void CPeripheralCecAdapter::ProcessNextCommand(void)
+int CPeripheralCecAdapter::CecCommand(void *cbParam, const cec_command &command)
 {
-  cec_command command;
-  if (m_cecAdapter && m_bIsReady && m_cecAdapter->GetNextCommand(&command))
+  CPeripheralCecAdapter *adapter = (CPeripheralCecAdapter *)cbParam;
+  if (!adapter)
+    return 0;
+
+  if (adapter->m_bIsReady)
   {
     CLog::Log(LOGDEBUG, "%s - processing command: initiator=%1x destination=%1x opcode=%02x", __FUNCTION__, command.initiator, command.destination, command.opcode);
 
@@ -412,21 +556,21 @@ void CPeripheralCecAdapter::ProcessNextCommand(void)
     case CEC_OPCODE_STANDBY:
       /* a device was put in standby mode */
       CLog::Log(LOGDEBUG, "%s - device %1x was put in standby mode", __FUNCTION__, command.initiator);
-      if (command.initiator == CECDEVICE_TV && GetSettingBool("standby_pc_on_tv_standby") &&
-          (!m_screensaverLastActivated.IsValid() || CDateTime::GetCurrentDateTime() - m_screensaverLastActivated > CDateTimeSpan(0, 0, 0, SCREENSAVER_TIMEOUT)))
+      if (command.initiator == CECDEVICE_TV && adapter->m_configuration.bPowerOffOnStandby == 1 &&
+          (!adapter->m_screensaverLastActivated.IsValid() || CDateTime::GetCurrentDateTime() - adapter->m_screensaverLastActivated > CDateTimeSpan(0, 0, 0, SCREENSAVER_TIMEOUT)))
       {
-        m_bStarted = false;
+        adapter->m_bStarted = false;
         g_application.getApplicationMessenger().Suspend();
       }
       break;
     case CEC_OPCODE_SET_MENU_LANGUAGE:
-      if (GetSettingBool("use_tv_menu_language") && command.initiator == CECDEVICE_TV && command.parameters.size == 3)
+      if (adapter->m_configuration.bUseTVMenuLanguage == 1 && command.initiator == CECDEVICE_TV && command.parameters.size == 3)
       {
         char strNewLanguage[4];
         for (int iPtr = 0; iPtr < 3; iPtr++)
           strNewLanguage[iPtr] = command.parameters[iPtr];
         strNewLanguage[3] = 0;
-        SetMenuLanguage(strNewLanguage);
+        adapter->SetMenuLanguage(strNewLanguage);
       }
       break;
     case CEC_OPCODE_DECK_CONTROL:
@@ -434,11 +578,11 @@ void CPeripheralCecAdapter::ProcessNextCommand(void)
           command.parameters.size == 1 &&
           command.parameters[0] == CEC_DECK_CONTROL_MODE_STOP)
       {
-        CSingleLock lock(m_critSection);
+        CSingleLock lock(adapter->m_critSection);
         cec_keypress key;
         key.duration = 500;
         key.keycode = CEC_USER_CONTROL_CODE_STOP;
-        m_buttonQueue.push(key);
+        adapter->m_buttonQueue.push(key);
       }
       break;
     case CEC_OPCODE_PLAY:
@@ -447,26 +591,58 @@ void CPeripheralCecAdapter::ProcessNextCommand(void)
       {
         if (command.parameters[0] == CEC_PLAY_MODE_PLAY_FORWARD)
         {
-          CSingleLock lock(m_critSection);
+          CSingleLock lock(adapter->m_critSection);
           cec_keypress key;
           key.duration = 500;
           key.keycode = CEC_USER_CONTROL_CODE_PLAY;
-          m_buttonQueue.push(key);
+          adapter->m_buttonQueue.push(key);
         }
         else if (command.parameters[0] == CEC_PLAY_MODE_PLAY_STILL)
         {
-          CSingleLock lock(m_critSection);
+          CSingleLock lock(adapter->m_critSection);
           cec_keypress key;
           key.duration = 500;
           key.keycode = CEC_USER_CONTROL_CODE_PAUSE;
-          m_buttonQueue.push(key);
+          adapter->m_buttonQueue.push(key);
         }
       }
       break;
+    case CEC_OPCODE_REPORT_POWER_STATUS:
+      if (command.initiator == CECDEVICE_TV &&
+          command.parameters.size == 1 &&
+          command.parameters[0] == CEC_POWER_STATUS_ON &&
+          adapter->m_queryThread)
+      {
+        adapter->m_queryThread->Signal();
+      }
+      break;
     default:
       break;
     }
   }
+  return 1;
+}
+
+int CPeripheralCecAdapter::CecConfiguration(void *cbParam, const libcec_configuration &config)
+{
+  CPeripheralCecAdapter *adapter = (CPeripheralCecAdapter *)cbParam;
+  if (!adapter)
+    return 0;
+
+  CSingleLock lock(adapter->m_critSection);
+  adapter->SetConfigurationFromLibCEC(config);
+  return 1;
+}
+
+int CPeripheralCecAdapter::CecKeyPress(void *cbParam, const cec_keypress &key)
+{
+  CPeripheralCecAdapter *adapter = (CPeripheralCecAdapter *)cbParam;
+  if (!adapter)
+    return 0;
+
+  CSingleLock lock(adapter->m_critSection);
+  adapter->m_buttonQueue.push(key);
+  return 1;
 }
 
 bool CPeripheralCecAdapter::GetNextCecKey(cec_keypress &key)
@@ -479,10 +655,6 @@ bool CPeripheralCecAdapter::GetNextCecKey(cec_keypress &key)
     m_buttonQueue.pop();
     bReturn = true;
   }
-  else if (m_cecAdapter->GetNextKeypress(&key))
-  {
-    bReturn = true;
-  }
 
   return bReturn;
 }
@@ -722,41 +894,43 @@ void CPeripheralCecAdapter::OnSettingChanged(const CStdString &strChangedSetting
     else if (bEnabled && !m_cecAdapter && m_bStarted)
       InitialiseFeature(FEATURE_CEC);
   }
-  else if (strChangedSetting.Equals("cec_hdmi_port"))
+  else
   {
-    SetHdmiPort(GetSettingInt("cec_hdmi_port"));
+    SetConfigurationFromSettings();
+    m_queryThread->UpdateConfiguration(&m_configuration);
   }
 }
 
-void CPeripheralCecAdapter::FlushLog(void)
+int CPeripheralCecAdapter::CecLogMessage(void *cbParam, const cec_log_message &message)
 {
-  cec_log_message message;
-  while (m_cecAdapter && m_cecAdapter->GetNextLogMessage(&message))
-  {
-    int iLevel = -1;
-    switch (message.level)
-    {
-    case CEC_LOG_ERROR:
-      iLevel = LOGERROR;
-      break;
-    case CEC_LOG_WARNING:
-      iLevel = LOGWARNING;
-      break;
-    case CEC_LOG_NOTICE:
-      iLevel = LOGDEBUG;
-      break;
-    case CEC_LOG_TRAFFIC:
-    case CEC_LOG_DEBUG:
-      if (GetSettingBool("cec_debug_logging"))
-        iLevel = LOGDEBUG;
-      break;
-    default:
-      break;
-    }
+  CPeripheralCecAdapter *adapter = (CPeripheralCecAdapter *)cbParam;
+  if (!adapter)
+    return 0;
 
-    if (iLevel >= 0)
-      CLog::Log(iLevel, "%s - %s", __FUNCTION__, message.message);
+  int iLevel = -1;
+  switch (message.level)
+  {
+  case CEC_LOG_ERROR:
+    iLevel = LOGERROR;
+    break;
+  case CEC_LOG_WARNING:
+    iLevel = LOGWARNING;
+    break;
+  case CEC_LOG_NOTICE:
+    iLevel = LOGDEBUG;
+    break;
+  case CEC_LOG_TRAFFIC:
+  case CEC_LOG_DEBUG:
+    iLevel = LOGDEBUG;
+    break;
+  default:
+    break;
   }
+
+  if (iLevel >= 0)
+    CLog::Log(iLevel, "%s - %s", __FUNCTION__, message.message);
+
+  return 1;
 }
 
 bool CPeripheralCecAdapter::TranslateComPort(CStdString &strLocation)
@@ -770,4 +944,301 @@ bool CPeripheralCecAdapter::TranslateComPort(CStdString &strLocation)
 
   return false;
 }
+
+void CPeripheralCecAdapter::SetConfigurationFromLibCEC(const CEC::libcec_configuration &config)
+{
+  // set the primary device type
+  m_configuration.deviceTypes.Clear();
+  m_configuration.deviceTypes.Add(config.deviceTypes[0]);
+  SetSetting("device_type", (int)config.deviceTypes[0]);
+
+  // set the connected device
+  m_configuration.baseDevice = config.baseDevice;
+  SetSetting("connected_device", (int)config.baseDevice);
+
+  // set the HDMI port number
+  m_configuration.iHDMIPort = config.iHDMIPort;
+  SetSetting("cec_hdmi_port", config.iHDMIPort);
+
+  // set the physical address, when baseDevice or iHDMIPort are not set
+  if (m_configuration.baseDevice == CECDEVICE_UNKNOWN ||
+      m_configuration.iHDMIPort == 0 || m_configuration.iHDMIPort > 4)
+  {
+    m_configuration.iPhysicalAddress = config.iPhysicalAddress;
+    CStdString strPhysicalAddress;
+    strPhysicalAddress.Format("%x", config.iPhysicalAddress);
+    SetSetting("physical_address", strPhysicalAddress);
+  }
+
+  // set the tv vendor override
+  m_configuration.tvVendor = config.tvVendor;
+  SetSetting("tv_vendor", (int)config.tvVendor);
+
+  // set the devices to wake when starting
+  m_configuration.wakeDevices = config.wakeDevices;
+  CStdString strWakeDevices;
+  for (unsigned int iPtr = 0; iPtr <= 16; iPtr++)
+    if (config.wakeDevices[iPtr])
+      strWakeDevices.AppendFormat(" %X", iPtr);
+  SetSetting("wake_devices", strWakeDevices.Trim());
+
+  // set the devices to power off when stopping
+  m_configuration.powerOffDevices = config.powerOffDevices;
+  CStdString strPowerOffDevices;
+  for (unsigned int iPtr = 0; iPtr <= 16; iPtr++)
+    if (config.powerOffDevices[iPtr])
+      strPowerOffDevices.AppendFormat(" %X", iPtr);
+  SetSetting("wake_devices", strPowerOffDevices.Trim());
+
+  // set the boolean settings
+  m_configuration.bUseTVMenuLanguage = config.bUseTVMenuLanguage;
+  SetSetting("use_tv_menu_language", m_configuration.bUseTVMenuLanguage == 1);
+
+  m_configuration.bActivateSource = config.bActivateSource;
+  SetSetting("activate_source", m_configuration.bActivateSource == 1);
+
+  m_configuration.bPowerOffScreensaver = config.bPowerOffScreensaver;
+  SetSetting("cec_standby_screensaver", m_configuration.bPowerOffScreensaver == 1);
+
+  m_configuration.bPowerOffOnStandby = config.bPowerOffOnStandby;
+  SetSetting("standby_pc_on_tv_standby", m_configuration.bPowerOffOnStandby == 1);
+
+  if (config.serverVersion >= CEC_SERVER_VERSION_1_5_1)
+    m_configuration.bSendInactiveSource = config.bSendInactiveSource;
+  SetSetting("send_inactive_source", m_configuration.bSendInactiveSource == 1);
+}
+
+void CPeripheralCecAdapter::SetConfigurationFromSettings(void)
+{
+  // client version 1.5.0
+  m_configuration.clientVersion = CEC_CLIENT_VERSION_1_5_1;
+
+  // device name 'XBMC'
+  snprintf(m_configuration.strDeviceName, 13, "%s", GetSettingString("device_name").c_str());
+
+  // set the primary device type
+  m_configuration.deviceTypes.Clear();
+  int iDeviceType = GetSettingInt("device_type");
+  if (iDeviceType != (int)CEC_DEVICE_TYPE_RECORDING_DEVICE &&
+      iDeviceType != (int)CEC_DEVICE_TYPE_PLAYBACK_DEVICE &&
+      iDeviceType != (int)CEC_DEVICE_TYPE_TUNER)
+    iDeviceType = (int)CEC_DEVICE_TYPE_RECORDING_DEVICE;
+  m_configuration.deviceTypes.Add((cec_device_type)iDeviceType);
+
+  // always try to autodetect the address.
+  // when the firmware supports this, it will override the physical address, connected device and hdmi port settings
+  m_configuration.bAutodetectAddress = 1;
+
+  // set the physical address
+  // when set, it will override the connected device and hdmi port settings
+  CStdString strPhysicalAddress = GetSettingString("physical_address");
+  int iPhysicalAddress;
+  if (sscanf(strPhysicalAddress.c_str(), "%x", &iPhysicalAddress) == 1 && iPhysicalAddress > 0 && iPhysicalAddress < 0xFFFF)
+    m_configuration.iPhysicalAddress = iPhysicalAddress;
+
+  // set the connected device
+  int iConnectedDevice = GetSettingInt("connected_device");
+  if (iConnectedDevice == 0 || iConnectedDevice == 5)
+    m_configuration.baseDevice = (cec_logical_address)iConnectedDevice;
+
+  // set the HDMI port number
+  int iHDMIPort = GetSettingInt("cec_hdmi_port");
+  if (iHDMIPort >= 0 && iHDMIPort <= 4)
+    m_configuration.iHDMIPort = iHDMIPort;
+
+  // set the tv vendor override
+  int iVendor = GetSettingInt("tv_vendor");
+  if (iVendor > 0 && iVendor < 0xFFFFFF)
+    m_configuration.tvVendor = iVendor;
+
+  // read the devices to wake when starting
+  CStdString strWakeDevices = CStdString(GetSettingString("wake_devices")).Trim();
+  m_configuration.wakeDevices.Clear();
+  ReadLogicalAddresses(strWakeDevices, m_configuration.wakeDevices);
+
+  // read the devices to power off when stopping
+  CStdString strStandbyDevices = CStdString(GetSettingString("standby_devices")).Trim();
+  m_configuration.powerOffDevices.Clear();
+  ReadLogicalAddresses(strStandbyDevices, m_configuration.powerOffDevices);
+
+  // always get the settings from the rom, when supported by the firmware
+  m_configuration.bGetSettingsFromROM = 1;
+
+  // read the boolean settings
+  m_configuration.bUseTVMenuLanguage   = GetSettingBool("use_tv_menu_language") ? 1 : 0;
+  m_configuration.bActivateSource      = GetSettingBool("activate_source") ? 1 : 0;
+  m_configuration.bPowerOffScreensaver = GetSettingBool("cec_standby_screensaver") ? 1 : 0;
+  m_configuration.bPowerOffOnStandby   = GetSettingBool("standby_pc_on_tv_standby") ? 1 : 0;
+  m_configuration.bSendInactiveSource  = GetSettingBool("send_inactive_source") ? 1 : 0;
+}
+
+void CPeripheralCecAdapter::ReadLogicalAddresses(const CStdString &strString, cec_logical_addresses &addresses)
+{
+  for (size_t iPtr = 0; iPtr < strString.size(); iPtr++)
+  {
+    CStdString strDevice = CStdString(strString.substr(iPtr, 1)).Trim();
+    if (!strDevice.IsEmpty())
+    {
+      int iDevice(0);
+      if (sscanf(strDevice.c_str(), "%x", &iDevice) == 1 && iDevice >= 0 && iDevice <= 0xF)
+        addresses.Set((cec_logical_address)iDevice);
+    }
+  }
+}
+
+CPeripheralCecAdapterUpdateThread::CPeripheralCecAdapterUpdateThread(CPeripheralCecAdapter *adapter, libcec_configuration *configuration) :
+    CThread("CEC Adapter Update Thread"),
+    m_adapter(adapter),
+    m_configuration(*configuration),
+    m_bNextConfigurationScheduled(false),
+    m_bIsUpdating(true)
+{
+  m_nextConfiguration.Clear();
+  m_event.Reset();
+}
+
+CPeripheralCecAdapterUpdateThread::~CPeripheralCecAdapterUpdateThread(void)
+{
+  StopThread(false);
+  m_event.Set();
+  StopThread(true);
+}
+
+void CPeripheralCecAdapterUpdateThread::Signal(void)
+{
+  m_event.Set();
+}
+
+bool CPeripheralCecAdapterUpdateThread::UpdateConfiguration(libcec_configuration *configuration)
+{
+  CSingleLock lock(m_critSection);
+  if (m_bIsUpdating)
+  {
+    m_bNextConfigurationScheduled = true;
+    m_nextConfiguration = *configuration;
+  }
+  else
+  {
+    m_configuration = *configuration;
+    m_event.Set();
+  }
+  return true;
+}
+
+bool CPeripheralCecAdapterUpdateThread::WaitReady(void)
+{
+  // don't wait if we're not powering up anything
+  if (m_configuration.wakeDevices.IsEmpty() && m_configuration.bActivateSource == 0)
+    return true;
+
+  // wait for the TV if we're configured to become the active source.
+  // wait for the first device in the wake list otherwise.
+  cec_logical_address waitFor = (m_configuration.bActivateSource == 1) ?
+      CECDEVICE_TV :
+      m_configuration.wakeDevices.primary;
+
+  cec_power_status powerStatus(CEC_POWER_STATUS_UNKNOWN);
+  bool bContinue(true);
+  while (bContinue && !m_adapter->m_bStop && !m_bStop && powerStatus != CEC_POWER_STATUS_ON)
+  {
+    powerStatus = m_adapter->m_cecAdapter->GetDevicePowerStatus(waitFor);
+    if (powerStatus != CEC_POWER_STATUS_ON)
+      bContinue = !m_event.WaitMSec(1000);
+  }
+
+  return powerStatus == CEC_POWER_STATUS_ON;
+}
+
+bool CPeripheralCecAdapterUpdateThread::SetInitialConfiguration(void)
+{
+  // devices to wake are set
+  if (!m_configuration.wakeDevices.IsEmpty())
+    m_adapter->m_cecAdapter->PowerOnDevices(CECDEVICE_BROADCAST);
+
+  // the option to make XBMC the active source is set
+  if (m_configuration.bActivateSource == 1)
+    m_adapter->m_cecAdapter->SetActiveSource();
+
+  // wait until devices are powered up
+  if (!WaitReady())
+    return false;
+
+  // request the menu language of the TV
+  if (m_configuration.bUseTVMenuLanguage == 1)
+  {
+    cec_menu_language language;
+    if (m_adapter->m_cecAdapter->GetDeviceMenuLanguage(CECDEVICE_TV, &language))
+      m_adapter->SetMenuLanguage(language.language);
+  }
+
+  // request the OSD name of the TV
+  CStdString strNotification;
+  cec_osd_name tvName = m_adapter->m_cecAdapter->GetDeviceOSDName(CECDEVICE_TV);
+  strNotification.Format("%s: %s", g_localizeStrings.Get(36016), tvName.name);
+
+  /* disable the mute setting when an amp is found, because the amp handles the mute setting and
+     set PCM output to 100% */
+  if (m_adapter->m_cecAdapter->IsActiveDeviceType(CEC_DEVICE_TYPE_AUDIO_SYSTEM))
+  {
+    // request the OSD name of the amp
+    cec_osd_name ampName = m_adapter->m_cecAdapter->GetDeviceOSDName(CECDEVICE_AUDIOSYSTEM);
+    CLog::Log(LOGDEBUG, "%s - CEC capable amplifier found (%s). volume will be controlled on the amp", __FUNCTION__, ampName.name);
+    strNotification.AppendFormat(" - %s", ampName.name);
+
+    // set amp present
+    m_adapter->SetAudioSystemConnected(true);
+    g_settings.m_bMute = false;
+    g_settings.m_nVolumeLevel = VOLUME_MAXIMUM;
+  }
+
+  m_adapter->m_bIsReady = true;
+
+  // try to send an OSD string to the TV
+  m_adapter->m_cecAdapter->SetOSDString(CECDEVICE_TV, CEC_DISPLAY_CONTROL_DISPLAY_FOR_DEFAULT_TIME, g_localizeStrings.Get(36016).c_str());
+  // and let the gui know that we're done
+  CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(36000), strNotification);
+
+  CSingleLock lock(m_critSection);
+  m_bIsUpdating = false;
+  return true;
+}
+
+void CPeripheralCecAdapterUpdateThread::Process(void)
+{
+  // set the initial configuration
+  if (!SetInitialConfiguration())
+    return;
+
+  // and wait for updates
+  bool bUpdate(false);
+  while (!m_bStop)
+  {
+    // update received
+    if (m_event.WaitMSec(500) || bUpdate)
+    {
+      if (m_bStop)
+        return;
+      // set the new configuration
+      bool bConfigSet(m_adapter->m_cecAdapter->SetConfiguration(&m_configuration));
+      CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(36000), g_localizeStrings.Get(bConfigSet ? 36023 : 36024));
+      {
+        CSingleLock lock(m_critSection);
+        bUpdate = m_bNextConfigurationScheduled;
+        if (bUpdate)
+        {
+          // another update is scheduled
+          m_bNextConfigurationScheduled = false;
+          m_configuration = m_nextConfiguration;
+        }
+        else
+        {
+          // nothing left to do, wait for updates
+          m_bIsUpdating = false;
+          m_event.Reset();
+        }
+      }
+    }
+  }
+}
+
 #endif
index 2fcbb1d..2ad8772 100644 (file)
  *
  */
 
-#if defined(HAVE_LIBCEC)
+#if !defined(HAVE_LIBCEC)
+#include "Peripheral.h"
+
+// an empty implementation, so CPeripherals can be compiled without a bunch of #ifdef's when libCEC is not available
+namespace PERIPHERALS
+{
+  class CPeripheralCecAdapter : public CPeripheral
+  {
+  public:
+    bool HasConnectedAudioSystem(void) { return false; }
+    void ScheduleVolumeUp(void) {}
+    void ScheduleVolumeDown(void) {}
+    bool IsMuted(void) { return false; }
+    void ScheduleMute(void) {}
+
+    WORD GetButton(void) { return 0; }
+    unsigned int GetHoldTime(void) { return 0; }
+    void ResetButton(void) {}
+  };
+}
+
+#else
 
 #include "PeripheralHID.h"
 #include "interfaces/AnnouncementManager.h"
@@ -32,7 +53,7 @@
 #ifdef isset
 #undef isset
 #endif
-#include <cectypes.h>
+#include <libcec/cectypes.h>
 
 class DllLibCEC;
 
@@ -43,25 +64,40 @@ namespace CEC
 
 namespace PERIPHERALS
 {
+  class CPeripheralCecAdapterUpdateThread;
+
   typedef struct
   {
     WORD         iButton;
     unsigned int iDuration;
   } CecButtonPress;
 
+  typedef enum
+  {
+    VOLUME_CHANGE_NONE,
+    VOLUME_CHANGE_UP,
+    VOLUME_CHANGE_DOWN,
+    VOLUME_CHANGE_MUTE
+  } CecVolumeChange;
 
   class CPeripheralCecAdapter : public CPeripheralHID, public ANNOUNCEMENT::IAnnouncer, private CThread
   {
+    friend class CPeripheralCecAdapterUpdateThread;
+
   public:
     CPeripheralCecAdapter(const PeripheralType type, const PeripheralBusType busType, const CStdString &strLocation, const CStdString &strDeviceName, int iVendorId, int iProductId);
     virtual ~CPeripheralCecAdapter(void);
 
-    virtual void Announce(ANNOUNCEMENT::EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data);
-    virtual bool PowerOnCecDevices(CEC::cec_logical_address iLogicalAddress);
-    virtual bool StandbyCecDevices(CEC::cec_logical_address iLogicalAddress);
-
-    virtual bool SendPing(void);
-    virtual bool SetHdmiPort(int iHdmiPort);
+    virtual void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data);
+    virtual bool HasConnectedAudioSystem(void);
+    virtual void SetAudioSystemConnected(bool bSetTo);
+    virtual void ScheduleVolumeUp(void);
+    virtual void VolumeUp(void);
+    virtual void ScheduleVolumeDown(void);
+    virtual void VolumeDown(void);
+    virtual void ScheduleMute(void);
+    virtual void Mute(void);
+    virtual bool IsMuted(void);
 
     virtual void OnSettingChanged(const CStdString &strChangedSetting);
 
@@ -71,27 +107,66 @@ namespace PERIPHERALS
     virtual CStdString GetComPort(void);
 
   protected:
-    virtual void FlushLog(void);
-    virtual bool GetNextCecKey(CEC::cec_keypress &key);
+    virtual bool OpenConnection(void);
+    virtual void SetConfigurationFromSettings(void);
+    virtual void SetConfigurationFromLibCEC(const CEC::libcec_configuration &config);
+    static void ReadLogicalAddresses(const CStdString &strString, CEC::cec_logical_addresses &addresses);
+    static int CecKeyPress(void *cbParam, const CEC::cec_keypress &key);
+    static int CecLogMessage(void *cbParam, const CEC::cec_log_message &message);
+    static int CecCommand(void *cbParam, const CEC::cec_command &command);
+    static int CecConfiguration(void *cbParam, const CEC::libcec_configuration &config);
+
     virtual bool GetNextKey(void);
+    virtual bool GetNextCecKey(CEC::cec_keypress &key);
     virtual bool InitialiseFeature(const PeripheralFeature feature);
     virtual void Process(void);
-    virtual void ProcessNextCommand(void);
+    virtual void ProcessVolumeChange(void);
     virtual void SetMenuLanguage(const char *strLanguage);
     static bool FindConfigLocation(CStdString &strString);
     static bool TranslateComPort(CStdString &strPort);
 
-    DllLibCEC*                    m_dll;
-    CEC::ICECAdapter*             m_cecAdapter;
-    bool                          m_bStarted;
-    bool                          m_bHasButton;
-    bool                          m_bIsReady;
-    CStdString                    m_strMenuLanguage;
-    CDateTime                     m_screensaverLastActivated;
-    CecButtonPress                m_button;
-    std::queue<CEC::cec_keypress> m_buttonQueue;
-    unsigned int                  m_lastKeypress;
-    CCriticalSection              m_critSection;
+    DllLibCEC*                        m_dll;
+    CEC::ICECAdapter*                 m_cecAdapter;
+    bool                              m_bStarted;
+    bool                              m_bHasButton;
+    bool                              m_bIsReady;
+    bool                              m_bHasConnectedAudioSystem;
+    CStdString                        m_strMenuLanguage;
+    CDateTime                         m_screensaverLastActivated;
+    CecButtonPress                    m_button;
+    std::queue<CEC::cec_keypress>     m_buttonQueue;
+    std::queue<CecVolumeChange>       m_volumeChangeQueue;
+    unsigned int                      m_lastKeypress;
+    CecVolumeChange                   m_lastChange;
+    int                               m_iExitCode;
+    bool                              m_bIsMuted;
+    CPeripheralCecAdapterUpdateThread*m_queryThread;
+    CEC::ICECCallbacks                m_callbacks;
+    CCriticalSection                  m_critSection;
+    CEC::libcec_configuration         m_configuration;
+  };
+
+  class CPeripheralCecAdapterUpdateThread : public CThread
+  {
+  public:
+    CPeripheralCecAdapterUpdateThread(CPeripheralCecAdapter *adapter, CEC::libcec_configuration *configuration);
+    virtual ~CPeripheralCecAdapterUpdateThread(void);
+
+    virtual void Signal(void);
+    virtual bool UpdateConfiguration(CEC::libcec_configuration *configuration);
+
+  protected:
+    virtual bool WaitReady(void);
+    virtual bool SetInitialConfiguration(void);
+    virtual void Process(void);
+
+    CPeripheralCecAdapter *    m_adapter;
+    CEvent                     m_event;
+    CCriticalSection           m_critSection;
+    CEC::libcec_configuration  m_configuration;
+    CEC::libcec_configuration  m_nextConfiguration;
+    bool                       m_bNextConfigurationScheduled;
+    bool                       m_bIsUpdating;
   };
 }
 
index ec0250d..48469cc 100644 (file)
@@ -37,7 +37,7 @@ CPeripheralHID::CPeripheralHID(const PeripheralType type, const PeripheralBusTyp
 
 CPeripheralHID::~CPeripheralHID(void)
 {
-  if (!m_strKeymap.IsEmpty() && GetSettingBool("keymap_enabled"))
+  if (!m_strKeymap.IsEmpty() && !GetSettingBool("do_not_use_custom_keymap"))
   {
     CLog::Log(LOGDEBUG, "%s - switching active keymapping to: default", __FUNCTION__);
     CButtonTranslator::GetInstance().RemoveDevice(m_strKeymap);
@@ -59,9 +59,12 @@ bool CPeripheralHID::InitialiseFeature(const PeripheralFeature feature)
       SetSetting("keymap", m_strKeymap);
     }
 
+    if (!IsSettingVisible("keymap"))
+      SetSettingVisible("do_not_use_custom_keymap", false);
+
     if (!m_strKeymap.IsEmpty())
     {
-      bool bKeymapEnabled(GetSettingBool("keymap_enabled"));
+      bool bKeymapEnabled(!GetSettingBool("do_not_use_custom_keymap"));
       if (bKeymapEnabled)
       {
         CLog::Log(LOGDEBUG, "%s - adding keymapping for: %s", __FUNCTION__, m_strKeymap.c_str());
@@ -82,7 +85,7 @@ bool CPeripheralHID::InitialiseFeature(const PeripheralFeature feature)
 
 void CPeripheralHID::OnSettingChanged(const CStdString &strChangedSetting)
 {
-  if (m_bInitialised && ((strChangedSetting.Equals("keymap") && GetSettingBool("keymap_enabled")) || strChangedSetting.Equals("keymap_enabled")))
+  if (m_bInitialised && ((strChangedSetting.Equals("keymap") && !GetSettingBool("do_not_use_custom_keymap")) || strChangedSetting.Equals("keymap_enabled")))
   {
     m_bInitialised = false;
     InitialiseFeature(FEATURE_HID);
index c79f961..cc801ef 100644 (file)
@@ -66,17 +66,15 @@ void CGUIDialogPeripheralSettings::CreateSettings()
 
   if (m_item)
   {
-    int iIndex = 1;
     CPeripheral *peripheral = g_peripherals.GetByPath(m_item->GetPath());
     if (peripheral)
     {
-      map<CStdString, CSetting *>::iterator it = peripheral->m_settings.begin();
-      while (it != peripheral->m_settings.end())
+      vector<CSetting *> settings = peripheral->GetSettings();
+      for (size_t iPtr = 0; iPtr < settings.size(); iPtr++)
       {
-        CSetting *setting = (*it).second;
+        CSetting *setting = settings[iPtr];
         if (!setting->IsVisible())
         {
-          ++it;
           CLog::Log(LOGDEBUG, "%s - invisible", __FUNCTION__);
           continue;
         }
@@ -89,7 +87,7 @@ void CGUIDialogPeripheralSettings::CreateSettings()
             if (boolSetting)
             {
               m_boolSettings.insert(make_pair(CStdString(boolSetting->GetSetting()), boolSetting->GetData()));
-              AddBool(iIndex++, boolSetting->GetLabel(), &m_boolSettings[boolSetting->GetSetting()], true);
+              AddBool(boolSetting->GetOrder(), boolSetting->GetLabel(), &m_boolSettings[boolSetting->GetSetting()], true);
             }
           }
           break;
@@ -99,7 +97,7 @@ void CGUIDialogPeripheralSettings::CreateSettings()
             if (intSetting)
             {
               m_intSettings.insert(make_pair(CStdString(intSetting->GetSetting()), (float) intSetting->GetData()));
-              AddSlider(iIndex++, intSetting->GetLabel(), &m_intSettings[intSetting->GetSetting()], (float)intSetting->m_iMin, (float)intSetting->m_iStep, (float)intSetting->m_iMax, CGUIDialogVideoSettings::FormatInteger, false);
+              AddSlider(intSetting->GetOrder(), intSetting->GetLabel(), &m_intSettings[intSetting->GetSetting()], (float)intSetting->m_iMin, (float)intSetting->m_iStep, (float)intSetting->m_iMax, CGUIDialogVideoSettings::FormatInteger, false);
             }
           }
           break;
@@ -109,7 +107,7 @@ void CGUIDialogPeripheralSettings::CreateSettings()
             if (floatSetting)
             {
               m_floatSettings.insert(make_pair(CStdString(floatSetting->GetSetting()), floatSetting->GetData()));
-              AddSlider(iIndex++, floatSetting->GetLabel(), &m_floatSettings[floatSetting->GetSetting()], floatSetting->m_fMin, floatSetting->m_fStep, floatSetting->m_fMax, CGUIDialogVideoSettings::FormatFloat, false);
+              AddSlider(floatSetting->GetOrder(), floatSetting->GetLabel(), &m_floatSettings[floatSetting->GetSetting()], floatSetting->m_fMin, floatSetting->m_fStep, floatSetting->m_fMax, CGUIDialogVideoSettings::FormatFloat, false);
             }
           }
           break;
@@ -119,7 +117,7 @@ void CGUIDialogPeripheralSettings::CreateSettings()
             if (stringSetting)
             {
               m_stringSettings.insert(make_pair(CStdString(stringSetting->GetSetting()), stringSetting->GetData()));
-              AddString(iIndex, stringSetting->GetLabel(), &m_stringSettings[stringSetting->GetSetting()]);
+              AddString(stringSetting->GetOrder(), stringSetting->GetLabel(), &m_stringSettings[stringSetting->GetSetting()]);
             }
           }
           break;
@@ -128,7 +126,6 @@ void CGUIDialogPeripheralSettings::CreateSettings()
           CLog::Log(LOGDEBUG, "%s - unknown type", __FUNCTION__);
           break;
         }
-        ++it;
       }
     }
     else
index c0ba078..9df0347 100644 (file)
@@ -22,6 +22,7 @@
 #include "threads/SystemClock.h"
 #include "system.h"
 #include "GUIWindowPictures.h"
+#include "URL.h"
 #include "Util.h"
 #include "Picture.h"
 #include "Application.h"
index a762031..f02d65c 100644 (file)
@@ -766,13 +766,15 @@ bool CGUIWindowSlideShow::OnMessage(CGUIMessage& message)
     {
       if(m_bSlideShow && m_bPlayingVideo)
         g_windowManager.ActivateWindow(WINDOW_FULLSCREEN_VIDEO);
-      m_bPlayingVideo = false;
     }
     break;
     case GUI_MSG_PLAYBACK_STOPPED:
     {
-      m_bSlideShow = false;
-      g_windowManager.PreviousWindow();
+      if (m_bSlideShow && m_bPlayingVideo)
+      {
+        m_bSlideShow = false;
+        g_windowManager.PreviousWindow();
+      }
     }
     break;
   }
index 54212d8..c5f2b00 100644 (file)
@@ -24,7 +24,7 @@
 #include "settings/GUISettings.h"
 #include "FileItem.h"
 #include "filesystem/File.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 #include "DllImageLib.h"
 #include "utils/log.h"
 #include "utils/URIUtils.h"
@@ -51,7 +51,7 @@ bool CPicture::CacheImage(const CStdString& sourceUrl, const CStdString& destFil
 
     if (URIUtils::IsInternetStream(sourceUrl, true))
     {
-      CFileCurl http;
+      CCurlFile http;
       CStdString data;
       if (http.Get(sourceUrl, data))
       {
index e286d7f..1acdd4c 100644 (file)
@@ -66,6 +66,7 @@ void CPictureInfoTag::Archive(CArchive& ar)
     ar << CStdString(m_exifInfo.CameraModel);
     ar << m_exifInfo.CCDWidth;
     ar << CStdString(m_exifInfo.Comments);
+    ar << CStdString(m_exifInfo.Description);
     ar << CStdString(m_exifInfo.DateTime);
     for (int i = 0; i < 10; i++)
       ar << m_exifInfo.DateTimeOffsets[i];
@@ -128,6 +129,7 @@ void CPictureInfoTag::Archive(CArchive& ar)
     GetStringFromArchive(ar, m_exifInfo.CameraModel, sizeof(m_exifInfo.CameraModel));
     ar >> m_exifInfo.CCDWidth;
     GetStringFromArchive(ar, m_exifInfo.Comments, sizeof(m_exifInfo.Comments));
+    GetStringFromArchive(ar, m_exifInfo.Description, sizeof(m_exifInfo.Description));
     GetStringFromArchive(ar, m_exifInfo.DateTime, sizeof(m_exifInfo.DateTime));
     for (int i = 0; i < 10; i++)
       ar >> m_exifInfo.DateTimeOffsets[i];
@@ -191,6 +193,7 @@ void CPictureInfoTag::Serialize(CVariant& value)
   value["cameramodel"] = CStdString(m_exifInfo.CameraModel);
   value["ccdwidth"] = m_exifInfo.CCDWidth;
   value["comments"] = CStdString(m_exifInfo.Comments);
+  value["description"] = CStdString(m_exifInfo.Description);
   value["datetime"] = CStdString(m_exifInfo.DateTime);
   for (int i = 0; i < 10; i++)
     value["datetimeoffsets"][i] = m_exifInfo.DateTimeOffsets[i];
@@ -311,9 +314,9 @@ const CStdString CPictureInfoTag::GetInfo(int info) const
       value = date.GetAsLocalizedDateTime();
     }
     break;
-//  case SLIDE_EXIF_DESCRIPTION:
-//    value = m_exifInfo.Description;
-//    break;
+  case SLIDE_EXIF_DESCRIPTION:
+    value = m_exifInfo.Description;
+    break;
   case SLIDE_EXIF_CAMERA_MAKE:
     value = m_exifInfo.CameraMake;
     break;
index f5d1ffa..c788936 100644 (file)
@@ -250,7 +250,7 @@ vector<CSmartPlaylistRule::DATABASE_FIELD> CSmartPlaylistRule::GetFields(const C
     fields.push_back(FIELD_PATH);
     fields.push_back(FIELD_STUDIO);
     fields.push_back(FIELD_MPAA);
-//    fields.push_back(FIELD_DATEADDED);  // no date added yet in db
+    fields.push_back(FIELD_DATEADDED);
   }
   else if (type == "episodes")
   {
@@ -279,8 +279,8 @@ vector<CSmartPlaylistRule::DATABASE_FIELD> CSmartPlaylistRule::GetFields(const C
     fields.push_back(FIELD_PATH);
     fields.push_back(FIELD_STUDIO);
     fields.push_back(FIELD_MPAA);
+    fields.push_back(FIELD_DATEADDED);
     isVideo = true;
-//    fields.push_back(FIELD_DATEADDED);  // no date added yet in db
   }
   else if (type == "movies")
   {
@@ -310,8 +310,8 @@ vector<CSmartPlaylistRule::DATABASE_FIELD> CSmartPlaylistRule::GetFields(const C
     fields.push_back(FIELD_PATH);
     if (!sortOrders)
       fields.push_back(FIELD_SET);
+    fields.push_back(FIELD_DATEADDED);
     isVideo = true;
-//    fields.push_back(FIELD_DATEADDED);  // no date added yet in db
   }
   else if (type == "musicvideos")
   {
@@ -328,8 +328,8 @@ vector<CSmartPlaylistRule::DATABASE_FIELD> CSmartPlaylistRule::GetFields(const C
     fields.push_back(FIELD_DIRECTOR);
     fields.push_back(FIELD_STUDIO);
     fields.push_back(FIELD_PLOT);
+    fields.push_back(FIELD_DATEADDED);
     isVideo = true;
-//    fields.push_back(FIELD_DATEADDED);  // no date added yet in db
   }
   if (isVideo)
   {
@@ -457,7 +457,7 @@ CStdString CSmartPlaylistRule::GetWhereClause(CDatabase &db, const CStdString& s
     parameter = db.PrepareSQL(operatorString.c_str(), m_parameter.c_str());
   }
 
-  if (m_field == FIELD_LASTPLAYED || m_field == FIELD_AIRDATE)
+  if (GetFieldType(m_field) == DATE_FIELD)
   {
     if (m_operator == OPERATOR_IN_THE_LAST || m_operator == OPERATOR_NOT_IN_THE_LAST)
     { // translate time period
@@ -514,8 +514,8 @@ CStdString CSmartPlaylistRule::GetWhereClause(CDatabase &db, const CStdString& s
       query = "idMovie" + negate + " in (select idMovie from countrylinkmovie join country on country.idCountry=countrylinkmovie.idCountry where country.strCountry" + parameter + ")";
     else if (m_field == FIELD_HASTRAILER)
       query = negate + GetDatabaseField(m_field, strType) + "!= ''";
-    else if (m_field == FIELD_LASTPLAYED && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
-      query = "lastPlayed is NULL or lastPlayed" + parameter;
+    else if ((m_field == FIELD_LASTPLAYED || m_field == FIELD_DATEADDED) && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
+      query = GetDatabaseField(m_field, strType) + " is NULL or " + GetDatabaseField(m_field, strType) + parameter;
     else if (m_field == FIELD_INPROGRESS)
       query = "idFile " + negate + " in (select idFile from bookmark where type = 1)";
     else if (m_field == FIELD_SET)
@@ -531,8 +531,8 @@ CStdString CSmartPlaylistRule::GetWhereClause(CDatabase &db, const CStdString& s
       query = "idMVideo" + negate + " in (select idMVideo from studiolinkmusicvideo join studio on studio.idStudio=studiolinkmusicvideo.idStudio where studio.strStudio" + parameter + ")";
     else if (m_field == FIELD_DIRECTOR)
       query = "idMVideo" + negate + " in (select idMVideo from directorlinkmusicvideo join actors on actors.idActor=directorlinkmusicvideo.idDirector where actors.strActor" + parameter + ")";
-    else if (m_field == FIELD_LASTPLAYED && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
-      query = "lastPlayed is NULL or lastPlayed" + parameter;
+    else if ((m_field == FIELD_LASTPLAYED || m_field == FIELD_DATEADDED) && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
+      query = GetDatabaseField(m_field, strType) + " is NULL or " + GetDatabaseField(m_field, strType) + parameter;
   }
   else if (strType == "tvshows")
   {
@@ -546,6 +546,8 @@ CStdString CSmartPlaylistRule::GetWhereClause(CDatabase &db, const CStdString& s
       query = "idShow" + negate + " IN (SELECT idShow FROM tvshowview WHERE " + GetDatabaseField(m_field, strType) + parameter + ")";
     else if (m_field == FIELD_MPAA)
       query = "idShow" + negate + " IN (SELECT idShow FROM tvshowview WHERE " + GetDatabaseField(m_field, strType) + parameter + ")";
+    else if (m_field == FIELD_DATEADDED && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
+      query = "dateAdded is NULL or dateAdded" + parameter;
   }
   else if (strType == "episodes")
   {
@@ -557,8 +559,8 @@ CStdString CSmartPlaylistRule::GetWhereClause(CDatabase &db, const CStdString& s
       query = "idEpisode" + negate + " in (select idEpisode from actorlinkepisode join actors on actors.idActor=actorlinkepisode.idActor where actors.strActor" + parameter + ")";
     else if (m_field == FIELD_WRITER)
       query = "idEpisode" + negate + " in (select idEpisode from writerlinkepisode join actors on actors.idActor=writerlinkepisode.idWriter where actors.strActor" + parameter + ")";
-    else if (m_field == FIELD_LASTPLAYED && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
-      query = "lastPlayed is NULL or lastPlayed" + parameter;
+    else if ((m_field == FIELD_LASTPLAYED || m_field == FIELD_DATEADDED) && (m_operator == OPERATOR_LESS_THAN || m_operator == OPERATOR_BEFORE || m_operator == OPERATOR_NOT_IN_THE_LAST))
+      query = GetDatabaseField(m_field, strType) + " is NULL or " + GetDatabaseField(m_field, strType) + parameter;
     else if (m_field == FIELD_INPROGRESS)
       query = "idFile " + negate + " in (select idFile from bookmark where type = 1)";
     else if (m_field == FIELD_STUDIO)
@@ -580,26 +582,6 @@ CStdString CSmartPlaylistRule::GetWhereClause(CDatabase &db, const CStdString& s
     query = "idFile" + negate + " in (select distinct idFile from streamdetails where strSubtitleLanguage " + parameter + ")";
   else if (m_field == FIELD_VIDEOASPECT)
     query = "idFile" + negate + " in (select distinct idFile from streamdetails where fVideoAspect " + parameter + ")";
-  else if (m_field == FIELD_PLAYLIST)
-  { // playlist field - grab our playlist and add to our where clause
-    CStdString playlistFile = CSmartPlaylistDirectory::GetPlaylistByName(m_parameter, strType);
-    if (!playlistFile.IsEmpty())
-    {
-      CSmartPlaylist playlist;
-      playlist.Load(playlistFile);
-      CStdString playlistQuery;
-      // only playlists of same type will be part of the query
-      if (playlist.GetType().Equals(strType) || (playlist.GetType().Equals("mixed") && (strType == "songs" || strType == "musicvideos")) || playlist.GetType().IsEmpty())
-      {
-        playlist.SetType(strType);
-        playlistQuery = playlist.GetWhereClause(db, false);
-      }
-      if (m_operator == OPERATOR_DOES_NOT_EQUAL && playlist.GetType().Equals(strType))
-        query.Format("NOT (%s)", playlistQuery.c_str());
-      else if (m_operator == OPERATOR_EQUALS && playlist.GetType().Equals(strType))
-        query = playlistQuery;
-    }
-  }
   if (m_field == FIELD_PLAYCOUNT && strType != "songs" && strType != "albums")
   { // playcount is stored as NULL or number in video db
     if ((m_operator == OPERATOR_EQUALS && m_parameter == "0") ||
@@ -681,7 +663,7 @@ CStdString CSmartPlaylistRule::GetDatabaseField(DATABASE_FIELD field, const CStd
     else if (field == FIELD_FILENAME) result = "strFilename";
     else if (field == FIELD_PATH) result = "strPath";
     else if (field == FIELD_RANDOM) result = "RANDOM()";      // only used for order clauses
-    else if (field == FIELD_DATEADDED) result = "idMovie";       // only used for order clauses
+    else if (field == FIELD_DATEADDED) result = "dateAdded";
     else if (field == FIELD_SET) result = "cant_order_by_set";
     return result;
   }
@@ -702,7 +684,7 @@ CStdString CSmartPlaylistRule::GetDatabaseField(DATABASE_FIELD field, const CStd
     else if (field == FIELD_STUDIO) result.Format("c%02d", VIDEODB_ID_MUSICVIDEO_STUDIOS);     // join required
     else if (field == FIELD_PLOT) result.Format("c%02d", VIDEODB_ID_MUSICVIDEO_PLOT);
     else if (field == FIELD_RANDOM) result = "RANDOM()";      // only used for order clauses
-    else if (field == FIELD_DATEADDED) result = "idMVideo";        // only used for order clauses
+    else if (field == FIELD_DATEADDED) result = "dateAdded";
     return result;
   }
   if (type == "tvshows")
@@ -723,7 +705,7 @@ CStdString CSmartPlaylistRule::GetDatabaseField(DATABASE_FIELD field, const CStd
     else if (field == FIELD_NUMWATCHED) result = "watchedcount";
     else if (field == FIELD_PLAYCOUNT) result = "watched";
     else if (field == FIELD_RANDOM) result = "RANDOM()";      // only used for order clauses
-    else if (field == FIELD_DATEADDED) result = "idShow";       // only used for order clauses
+    else if (field == FIELD_DATEADDED) result = "dateAdded";
     else if (field == FIELD_PATH) result = "strPath";
     return result;
   }
@@ -750,7 +732,7 @@ CStdString CSmartPlaylistRule::GetDatabaseField(DATABASE_FIELD field, const CStd
     else if (field == FIELD_FILENAME) result = "strFilename";
     else if (field == FIELD_PATH) result = "strPath";
     else if (field == FIELD_RANDOM) result = "RANDOM()";      // only used for order clauses
-    else if (field == FIELD_DATEADDED) result = "idEpisode";       // only used for order clauses
+    else if (field == FIELD_DATEADDED) result = "dateAdded";
     return result;
   }
 
@@ -931,7 +913,7 @@ void CSmartPlaylist::AddRule(const CSmartPlaylistRule &rule)
   m_playlistRules.push_back(rule);
 }
 
-CStdString CSmartPlaylist::GetWhereClause(CDatabase &db, bool needWhere /* = true */)
+CStdString CSmartPlaylist::GetWhereClause(CDatabase &db, set<CStdString> &referencedPlaylists, bool needWhere /* = true */)
 {
   CStdString rule, currentRule;
   for (vector<CSmartPlaylistRule>::iterator it = m_playlistRules.begin(); it != m_playlistRules.end(); ++it)
@@ -941,7 +923,33 @@ CStdString CSmartPlaylist::GetWhereClause(CDatabase &db, bool needWhere /* = tru
     else if (needWhere)
       rule += "WHERE ";
     rule += "(";
-    currentRule = (*it).GetWhereClause(db, GetType());
+    CStdString currentRule;
+    if (it->m_field == CSmartPlaylistRule::FIELD_PLAYLIST)
+    {
+      CStdString playlistFile = CSmartPlaylistDirectory::GetPlaylistByName(it->m_parameter, GetType());
+      if (!playlistFile.IsEmpty() && referencedPlaylists.find(playlistFile) == referencedPlaylists.end())
+      {
+        referencedPlaylists.insert(playlistFile);
+        CSmartPlaylist playlist;
+        playlist.Load(playlistFile);
+        CStdString playlistQuery;
+        // only playlists of same type will be part of the query
+        if (playlist.GetType().Equals(GetType()) || (playlist.GetType().Equals("mixed") && (GetType() == "songs" || GetType() == "musicvideos")) || playlist.GetType().IsEmpty())
+        {
+          playlist.SetType(GetType());
+          playlistQuery = playlist.GetWhereClause(db, referencedPlaylists, false);
+        }
+        if (playlist.GetType().Equals(GetType()))
+        {
+          if (it->m_operator == CSmartPlaylistRule::OPERATOR_DOES_NOT_EQUAL)
+            currentRule.Format("NOT (%s)", playlistQuery.c_str());
+          else
+            currentRule = playlistQuery;
+        }
+      }
+    }
+    else
+      currentRule = (*it).GetWhereClause(db, GetType());
     // if we don't get a rule, we add '1' or '0' so the query is still valid and doesn't fail
     if (currentRule.IsEmpty())
       currentRule = m_matchAllRules ? "'1'" : "'0'";
index 5359a62..4da982b 100644 (file)
@@ -23,6 +23,7 @@
 #include "utils/StdString.h"
 #include "tinyXML/tinyxml.h"
 #include <vector>
+#include <set>
 
 class CDatabase;
 
@@ -167,7 +168,16 @@ public:
   bool GetOrderAscending() const { return m_orderAscending; };
 
   void AddRule(const CSmartPlaylistRule &rule);
-  CStdString GetWhereClause(CDatabase &db, bool needWhere = true);
+
+  /*! \brief get the where clause for a playlist
+   We handle playlists inside playlists separately in order to ensure we don't introduce infinite loops
+   by playlist A including playlist B which also (perhaps via other playlists) then includes playlistA.
+   
+   \param db the database to use to format up results
+   \param referencedPlaylists a set of playlists to know when we reach a cycle
+   \param needWhere whether we need to prepend the where clause with "WHERE "
+   */
+  CStdString GetWhereClause(CDatabase &db, std::set<CStdString> &referencedPlaylists, bool needWhere = true);
   CStdString GetOrderClause(CDatabase &db);
 
   const std::vector<CSmartPlaylistRule> &GetRules() const;
index 2daaf60..970a75e 100644 (file)
@@ -99,7 +99,9 @@ void CAdvancedSettings::Initialize()
   m_DXVACheckCompatibility = false;
   m_DXVACheckCompatibilityPresent = false;
   m_DXVAForceProcessorRenderer = true;
+  m_DXVANoDeintProcForProgressive = false;
   m_videoFpsDetect = 1;
+  m_videoDefaultLatency = 0.0;
 
   m_musicUseTimeSeeking = true;
   m_musicTimeSeekForward = 10;
@@ -538,8 +540,46 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
     m_DXVACheckCompatibilityPresent = XMLUtils::GetBoolean(pElement,"checkdxvacompatibility", m_DXVACheckCompatibility);
 
     XMLUtils::GetBoolean(pElement,"forcedxvarenderer", m_DXVAForceProcessorRenderer);
+    XMLUtils::GetBoolean(pElement,"dxvanodeintforprogressive", m_DXVANoDeintProcForProgressive);
     //0 = disable fps detect, 1 = only detect on timestamps with uniform spacing, 2 detect on all timestamps
     XMLUtils::GetInt(pElement, "fpsdetect", m_videoFpsDetect, 0, 2);
+
+    // Store global display latency settings
+    TiXmlElement* pVideoLatency = pElement->FirstChildElement("latency");
+    if (pVideoLatency)
+    {
+      float refresh, refreshmin, refreshmax, delay;
+      TiXmlElement* pRefreshVideoLatency = pVideoLatency->FirstChildElement("refresh");
+
+      while (pRefreshVideoLatency)
+      {
+        RefreshVideoLatency videolatency = {0};
+
+        if (XMLUtils::GetFloat(pRefreshVideoLatency, "rate", refresh))
+        {
+          videolatency.refreshmin = refresh - 0.01f;
+          videolatency.refreshmax = refresh + 0.01f;
+        }
+        else if (XMLUtils::GetFloat(pRefreshVideoLatency, "min", refreshmin) &&
+                 XMLUtils::GetFloat(pRefreshVideoLatency, "max", refreshmax))
+        {
+          videolatency.refreshmin = refreshmin;
+          videolatency.refreshmax = refreshmax;
+        }
+        if (XMLUtils::GetFloat(pRefreshVideoLatency, "delay", delay, -600.0f, 600.0f))
+          videolatency.delay = delay;
+
+        if (videolatency.refreshmin > 0.0f && videolatency.refreshmax >= videolatency.refreshmin)
+          m_videoRefreshLatency.push_back(videolatency);
+        else
+          CLog::Log(LOGWARNING, "Ignoring malformed display latency <refresh> entry, min:%f max:%f", videolatency.refreshmin, videolatency.refreshmax);
+
+        pRefreshVideoLatency = pRefreshVideoLatency->NextSiblingElement("refresh");
+      }
+
+      // Get default global display latency
+      XMLUtils::GetFloat(pVideoLatency, "delay", m_videoDefaultLatency, -600.0f, 600.0f);
+    }
   }
 
   pElement = pRootElement->FirstChildElement("musiclibrary");
@@ -794,7 +834,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file)
       CStdString strFrom, strTo;
       TiXmlNode* pFrom = pSubstitute->FirstChild("from");
       if (pFrom)
-        strFrom = _P(pFrom->FirstChild()->Value()).c_str();
+        strFrom = CSpecialProtocol::TranslatePath(pFrom->FirstChild()->Value()).c_str();
       TiXmlNode* pTo = pSubstitute->FirstChild("to");
       if (pTo)
         strTo = pTo->FirstChild()->Value();
@@ -1055,3 +1095,16 @@ void CAdvancedSettings::AddSettingsFile(const CStdString &filename)
 {
   m_settingsFiles.push_back(filename);
 }
+
+float CAdvancedSettings::GetDisplayLatency(float refreshrate)
+{
+  float delay = m_videoDefaultLatency / 1000.0f;
+  for (int i = 0; i < (int) m_videoRefreshLatency.size(); i++)
+  {
+    RefreshVideoLatency& videolatency = m_videoRefreshLatency[i];
+    if (refreshrate >= videolatency.refreshmin && refreshrate <= videolatency.refreshmax)
+      delay = videolatency.delay / 1000.0f;
+  }
+
+  return delay; // in seconds
+}
index 1d7333c..7a9d0dc 100644 (file)
@@ -61,6 +61,15 @@ struct RefreshOverride
   bool  fallback;
 };
 
+
+struct RefreshVideoLatency
+{
+  float refreshmin;
+  float refreshmax;
+
+  float delay;
+};
+
 typedef std::vector<TVShowRegexp> SETTINGS_TVSHOWLIST;
 
 class CAdvancedSettings
@@ -127,11 +136,14 @@ class CAdvancedSettings
     bool  m_videoAllowMpeg4VDPAU;
     bool  m_videoAllowMpeg4VAAPI;
     std::vector<RefreshOverride> m_videoAdjustRefreshOverrides;
+    std::vector<RefreshVideoLatency> m_videoRefreshLatency;
+    float m_videoDefaultLatency;
     bool m_videoDisableBackgroundDeinterlace;
     int  m_videoCaptureUseOcclusionQuery;
     bool m_DXVACheckCompatibility;
     bool m_DXVACheckCompatibilityPresent;
     bool m_DXVAForceProcessorRenderer;
+    bool m_DXVANoDeintProcForProgressive;
     int  m_videoFpsDetect;
 
     CStdString m_videoDefaultPlayer;
@@ -305,6 +317,8 @@ class CAdvancedSettings
     bool m_enableMultimediaKeys;
     std::vector<CStdString> m_settingsFiles;
     void ParseSettingsFile(const CStdString &file);
+
+    float GetDisplayLatency(float refreshrate);
 };
 
 XBMC_GLOBAL(CAdvancedSettings,g_advancedSettings);
index 80ad97a..0bcb50c 100644 (file)
@@ -29,7 +29,6 @@
 #include "LinuxTimezone.h"
 #endif
 #include "Application.h"
-#include "filesystem/SpecialProtocol.h"
 #include "AdvancedSettings.h"
 #include "guilib/LocalizeStrings.h"
 #include "utils/StringUtils.h"
@@ -44,6 +43,7 @@
 #include "guilib/GUIFontManager.h"
 #include "utils/Weather.h"
 #include "LangInfo.h"
+#include "utils/XMLUtils.h"
 #if defined(__APPLE__)
   #include "osx/DarwinUtils.h"
 #endif
@@ -222,7 +222,7 @@ void CSettingsGroup::GetCategories(vecSettingsCategory &vecCategories)
   {
     vecSettings settings;
     // check whether we actually have these settings available.
-    g_guiSettings.GetSettingsGroup(m_vecCategories[i]->m_strCategory, settings);
+    g_guiSettings.GetSettingsGroup(m_vecCategories[i], settings);
     if (settings.size())
       vecCategories.push_back(m_vecCategories[i]);
   }
@@ -489,6 +489,44 @@ void CGUISettings::Initialize()
   AddBool(in, "input.enablemouse", 21369, true);
 #endif
 
+  CSettingsCategory* net = AddCategory(4, "network", 798);
+  if (g_application.IsStandAlone())
+  {
+#ifndef __APPLE__
+    AddString(NULL, "network.interface",775,"", SPIN_CONTROL_TEXT);
+
+    map<int, int> networkAssignments;
+    networkAssignments.insert(make_pair(716, NETWORK_DHCP));
+    networkAssignments.insert(make_pair(717, NETWORK_STATIC));
+    networkAssignments.insert(make_pair(787, NETWORK_DISABLED));
+    AddInt(NULL, "network.assignment", 715, NETWORK_DHCP, networkAssignments, SPIN_CONTROL_TEXT);
+    AddString(NULL, "network.ipaddress", 719, "0.0.0.0", EDIT_CONTROL_IP_INPUT);
+    AddString(NULL, "network.subnet", 720, "255.255.255.0", EDIT_CONTROL_IP_INPUT);
+    AddString(NULL, "network.gateway", 721, "0.0.0.0", EDIT_CONTROL_IP_INPUT);
+    AddString(NULL, "network.dns", 722, "0.0.0.0", EDIT_CONTROL_IP_INPUT);
+    AddString(NULL, "network.dnssuffix", 22002, "", EDIT_CONTROL_INPUT, true);
+    AddString(NULL, "network.essid", 776, "0.0.0.0", BUTTON_CONTROL_STANDARD);
+
+    map<int, int> networkEncapsulations;
+    networkEncapsulations.insert(make_pair(780, ENC_NONE));
+    networkEncapsulations.insert(make_pair(781, ENC_WEP));
+    networkEncapsulations.insert(make_pair(782, ENC_WPA));
+    networkEncapsulations.insert(make_pair(783, ENC_WPA2));
+    AddInt(NULL, "network.enc", 778, ENC_NONE, networkEncapsulations, SPIN_CONTROL_TEXT);
+    AddString(NULL, "network.key", 777, "0.0.0.0", EDIT_CONTROL_INPUT);
+#ifndef _WIN32
+    AddString(NULL, "network.save", 779, "", BUTTON_CONTROL_STANDARD);
+#endif
+    AddSeparator(NULL, "network.sep1");
+#endif
+  }
+  AddBool(net, "network.usehttpproxy", 708, false);
+  AddString(net, "network.httpproxyserver", 706, "", EDIT_CONTROL_INPUT);
+  AddString(net, "network.httpproxyport", 730, "8080", EDIT_CONTROL_NUMBER_INPUT, false, 707);
+  AddString(net, "network.httpproxyusername", 1048, "", EDIT_CONTROL_INPUT);
+  AddString(net, "network.httpproxypassword", 733, "", EDIT_CONTROL_HIDDEN_INPUT,true,733);
+  AddInt(net, "network.bandwidth", 14041, 0, 0, 512, 100*1024, SPIN_CONTROL_INT_PLUS, MASK_KBPS, TEXT_OFF);
+
   CSettingsCategory* pwm = AddCategory(4, "powermanagement", 14095);
   // Note: Application.cpp might hide powersaving settings if not supported.
   AddInt(pwm, "powermanagement.displaysoff", 1450, 0, 0, 5, 120, SPIN_CONTROL_INT_PLUS, MASK_MINS, TEXT_OFF);
@@ -708,96 +746,59 @@ void CGUISettings::Initialize()
   AddDefaultAddon(NULL, "scrapers.musicvideosdefault", 21415, "metadata.yahoomusic.com", ADDON_SCRAPER_MUSICVIDEOS);
   AddBool(NULL, "scrapers.langfallback", 21416, false);
 
-  // network settings
-  AddGroup(6, 705);
+  // service settings
+  AddGroup(6, 14036);
+
+  CSettingsCategory* srvGeneral = AddCategory(6, "general", 16000);
+  AddString(srvGeneral,"services.devicename", 1271, "XBMC", EDIT_CONTROL_INPUT);
+
+  CSettingsCategory* srvUpnp = AddCategory(6, "upnp", 20187);
+  AddBool(srvUpnp, "services.upnpserver", 21360, false);
+  AddBool(srvUpnp, "services.upnprenderer", 21881, false);
 
-  CSettingsCategory* srv = AddCategory(6, "services", 14036);
-  AddString(srv,"services.devicename", 1271, "XBMC", EDIT_CONTROL_INPUT);
-  AddSeparator(srv,"services.sep4");
-  AddBool(srv, "services.upnpserver", 21360, false);
-  AddBool(srv, "services.upnprenderer", 21881, false);
-  AddSeparator(srv,"services.sep3");
 #ifdef HAS_WEB_SERVER
-  AddBool(srv,  "services.webserver",        263, false);
+  CSettingsCategory* srvWeb = AddCategory(6, "webserver", 33101);
+  AddBool(srvWeb,  "services.webserver",        263, false);
 #ifdef _LINUX
-  AddString(srv,"services.webserverport",    730, (geteuid()==0)?"80":"8080", EDIT_CONTROL_NUMBER_INPUT, false, 730);
+  AddString(srvWeb,"services.webserverport",    730, (geteuid()==0)?"80":"8080", EDIT_CONTROL_NUMBER_INPUT, false, 730);
 #else
-  AddString(srv,"services.webserverport",    730, "80", EDIT_CONTROL_NUMBER_INPUT, false, 730);
+  AddString(srvWeb,"services.webserverport",    730, "80", EDIT_CONTROL_NUMBER_INPUT, false, 730);
 #endif
-  AddString(srv,"services.webserverusername",1048, "xbmc", EDIT_CONTROL_INPUT);
-  AddString(srv,"services.webserverpassword",733, "", EDIT_CONTROL_HIDDEN_INPUT, true, 733);
-  AddDefaultAddon(srv, "services.webskin",199, DEFAULT_WEB_INTERFACE, ADDON_WEB_INTERFACE);
+  AddString(srvWeb,"services.webserverusername",1048, "xbmc", EDIT_CONTROL_INPUT);
+  AddString(srvWeb,"services.webserverpassword",733, "", EDIT_CONTROL_HIDDEN_INPUT, true, 733);
+  AddDefaultAddon(srvWeb, "services.webskin",199, DEFAULT_WEB_INTERFACE, ADDON_WEB_INTERFACE);
 #endif
 #ifdef HAS_EVENT_SERVER
-  AddSeparator(srv,"services.sep1");
-  AddBool(srv,  "services.esenabled",         791, true);
+  CSettingsCategory* srvEvent = AddCategory(6, "remotecontrol", 790);
+  AddBool(srvEvent,  "services.esenabled",         791, true);
   AddString(NULL,"services.esport",            792, "9777", EDIT_CONTROL_NUMBER_INPUT, false, 792);
   AddInt(NULL,   "services.esportrange",       793, 10, 1, 1, 100, SPIN_CONTROL_INT);
   AddInt(NULL,   "services.esmaxclients",      797, 20, 1, 1, 100, SPIN_CONTROL_INT);
-  AddBool(srv,  "services.esallinterfaces",   794, false);
+  AddBool(srvEvent,  "services.esallinterfaces",   794, false);
   AddInt(NULL,   "services.esinitialdelay",    795, 750, 5, 5, 10000, SPIN_CONTROL_INT);
   AddInt(NULL,   "services.escontinuousdelay", 796, 25, 5, 5, 10000, SPIN_CONTROL_INT);
 #endif
 #ifdef HAS_ZEROCONF
-  AddSeparator(srv, "services.sep2");
+  CSettingsCategory* srvZeroconf = AddCategory(6, "zeroconf", 1259);
 #ifdef TARGET_WINDOWS
-  AddBool(srv, "services.zeroconf", 1260, false);
+  AddBool(srvZeroconf, "services.zeroconf", 1260, false);
 #else
-  AddBool(srv, "services.zeroconf", 1260, true);
+  AddBool(srvZeroconf, "services.zeroconf", 1260, true);
 #endif
 #endif
 
 #ifdef HAS_AIRPLAY
-  AddSeparator(srv, "services.sep5");
-  AddBool(srv, "services.airplay", 1270, false);
-  AddBool(srv, "services.useairplaypassword", 1272, false);
-  AddString(srv, "services.airplaypassword", 733, "", EDIT_CONTROL_HIDDEN_INPUT, false, 733);
-  AddSeparator(srv, "services.sep6");  
+  CSettingsCategory* srvAirplay = AddCategory(6, "airplay", 1273);
+  AddBool(srvAirplay, "services.airplay", 1270, false);
+  AddBool(srvAirplay, "services.useairplaypassword", 1272, false);
+  AddString(srvAirplay, "services.airplaypassword", 733, "", EDIT_CONTROL_HIDDEN_INPUT, false, 733); 
 #endif
 
 #ifndef _WIN32
-  CSettingsCategory* smb = AddCategory(6, "smb", 1200);
-  AddString(smb, "smb.winsserver",  1207,   "",  EDIT_CONTROL_IP_INPUT);
-  AddString(smb, "smb.workgroup",   1202,   "WORKGROUP", EDIT_CONTROL_INPUT, false, 1202);
-#endif
-
-  CSettingsCategory* net = AddCategory(6, "network", 798);
-  if (g_application.IsStandAlone())
-  {
-#ifndef __APPLE__
-    AddString(NULL, "network.interface",775,"", SPIN_CONTROL_TEXT);
-
-    map<int, int> networkAssignments;
-    networkAssignments.insert(make_pair(716, NETWORK_DHCP));
-    networkAssignments.insert(make_pair(717, NETWORK_STATIC));
-    networkAssignments.insert(make_pair(787, NETWORK_DISABLED));
-    AddInt(NULL, "network.assignment", 715, NETWORK_DHCP, networkAssignments, SPIN_CONTROL_TEXT);
-    AddString(NULL, "network.ipaddress", 719, "0.0.0.0", EDIT_CONTROL_IP_INPUT);
-    AddString(NULL, "network.subnet", 720, "255.255.255.0", EDIT_CONTROL_IP_INPUT);
-    AddString(NULL, "network.gateway", 721, "0.0.0.0", EDIT_CONTROL_IP_INPUT);
-    AddString(NULL, "network.dns", 722, "0.0.0.0", EDIT_CONTROL_IP_INPUT);
-    AddString(NULL, "network.dnssuffix", 22002, "", EDIT_CONTROL_INPUT, true);
-    AddString(NULL, "network.essid", 776, "0.0.0.0", BUTTON_CONTROL_STANDARD);
-
-    map<int, int> networkEncapsulations;
-    networkEncapsulations.insert(make_pair(780, ENC_NONE));
-    networkEncapsulations.insert(make_pair(781, ENC_WEP));
-    networkEncapsulations.insert(make_pair(782, ENC_WPA));
-    networkEncapsulations.insert(make_pair(783, ENC_WPA2));
-    AddInt(NULL, "network.enc", 778, ENC_NONE, networkEncapsulations, SPIN_CONTROL_TEXT);
-    AddString(NULL, "network.key", 777, "0.0.0.0", EDIT_CONTROL_INPUT);
-#ifndef _WIN32
-    AddString(NULL, "network.save", 779, "", BUTTON_CONTROL_STANDARD);
-#endif
-    AddSeparator(NULL, "network.sep1");
+  CSettingsCategory* srvSmb = AddCategory(6, "smb", 1200);
+  AddString(srvSmb, "smb.winsserver",  1207,   "",  EDIT_CONTROL_IP_INPUT);
+  AddString(srvSmb, "smb.workgroup",   1202,   "WORKGROUP", EDIT_CONTROL_INPUT, false, 1202);
 #endif
-  }
-  AddBool(net, "network.usehttpproxy", 708, false);
-  AddString(net, "network.httpproxyserver", 706, "", EDIT_CONTROL_INPUT);
-  AddString(net, "network.httpproxyport", 730, "8080", EDIT_CONTROL_NUMBER_INPUT, false, 707);
-  AddString(net, "network.httpproxyusername", 1048, "", EDIT_CONTROL_INPUT);
-  AddString(net, "network.httpproxypassword", 733, "", EDIT_CONTROL_HIDDEN_INPUT,true,733);
-  AddInt(net, "network.bandwidth", 14041, 0, 0, 512, 100*1024, SPIN_CONTROL_INT_PLUS, MASK_KBPS, TEXT_OFF);
 
   // appearance settings
   AddGroup(7, 480);
@@ -861,6 +862,9 @@ void CGUISettings::Initialize()
   AddInt(NULL, "window.height", 0, 480, 10, 1, INT_MAX, SPIN_CONTROL_INT);
 
   AddPath(NULL,"system.playlistspath",20006,"set default",BUTTON_CONTROL_PATH_INPUT,false);
+
+  // PVR-related setting typically used by skins that are aimed at PVR and non-PVR builds
+  AddBool(NULL, "pvrmanager.enabled", 449, false);
 }
 
 CGUISettings::~CGUISettings(void)
@@ -898,21 +902,32 @@ CSettingsGroup *CGUISettings::GetGroup(int groupID)
   return NULL;
 }
 
+void CGUISettings::AddSetting(CSettingsCategory* cat, CSetting* setting)
+{
+  if (!setting)
+    return;
+
+  if (cat)
+    cat->m_settings.push_back(setting);
+  settingsMap.insert(pair<CStdString, CSetting*>(CStdString(setting->GetSetting()).ToLower(), setting));
+}
+
 void CGUISettings::AddSeparator(CSettingsCategory* cat, const char *strSetting)
 {
-  int iOrder = cat?++cat->m_entries:0;
+  int iOrder = cat ? cat->m_settings.size() : 0;
   CSettingSeparator *pSetting = new CSettingSeparator(iOrder, CStdString(strSetting).ToLower());
   if (!pSetting) return;
-  settingsMap.insert(pair<CStdString, CSetting*>(CStdString(strSetting).ToLower(), pSetting));
+  AddSetting(cat, pSetting);
 }
 
 void CGUISettings::AddBool(CSettingsCategory* cat, const char *strSetting, int iLabel, bool bData, int iControlType)
 {
-  int iOrder = cat?++cat->m_entries:0;
+  int iOrder = cat ? cat->m_settings.size() : 0;
   CSettingBool* pSetting = new CSettingBool(iOrder, CStdString(strSetting).ToLower(), iLabel, bData, iControlType);
   if (!pSetting) return ;
-  settingsMap.insert(pair<CStdString, CSetting*>(CStdString(strSetting).ToLower(), pSetting));
+  AddSetting(cat, pSetting);
 }
+
 bool CGUISettings::GetBool(const char *strSetting) const
 {
   ASSERT(settingsMap.size());
@@ -959,10 +974,10 @@ void CGUISettings::ToggleBool(const char *strSetting)
 
 void CGUISettings::AddFloat(CSettingsCategory* cat, const char *strSetting, int iLabel, float fData, float fMin, float fStep, float fMax, int iControlType)
 {
-  int iOrder = cat?++cat->m_entries:0;
+  int iOrder = cat ? cat->m_settings.size() : 0;
   CSettingFloat* pSetting = new CSettingFloat(iOrder, CStdString(strSetting).ToLower(), iLabel, fData, fMin, fStep, fMax, iControlType);
   if (!pSetting) return ;
-  settingsMap.insert(pair<CStdString, CSetting*>(CStdString(strSetting).ToLower(), pSetting));
+  AddSetting(cat, pSetting);
 }
 
 float CGUISettings::GetFloat(const char *strSetting) const
@@ -1003,39 +1018,36 @@ void CGUISettings::LoadMasterLock(TiXmlElement *pRootElement)
     LoadFromXML(pRootElement, it);
 }
 
-
 void CGUISettings::AddInt(CSettingsCategory* cat, const char *strSetting, int iLabel, int iData, int iMin, int iStep, int iMax, int iControlType, const char *strFormat)
 {
-  int iOrder = cat?++cat->m_entries:0;
+  int iOrder = cat ? cat->m_settings.size() : 0;
   CSettingInt* pSetting = new CSettingInt(iOrder, CStdString(strSetting).ToLower(), iLabel, iData, iMin, iStep, iMax, iControlType, strFormat);
   if (!pSetting) return ;
-  settingsMap.insert(pair<CStdString, CSetting*>(CStdString(strSetting).ToLower(), pSetting));
+  AddSetting(cat, pSetting);
 }
 
 void CGUISettings::AddInt(CSettingsCategory* cat, const char *strSetting, int iLabel, int iData, int iMin, int iStep, int iMax, int iControlType, int iFormat, int iLabelMin/*=-1*/)
 {
-  int iOrder = cat?++cat->m_entries:0;
+  int iOrder = cat ? cat->m_settings.size() : 0;
   CSettingInt* pSetting = new CSettingInt(iOrder, CStdString(strSetting).ToLower(), iLabel, iData, iMin, iStep, iMax, iControlType, iFormat, iLabelMin);
   if (!pSetting) return ;
-  settingsMap.insert(pair<CStdString, CSetting*>(CStdString(strSetting).ToLower(), pSetting));
+  AddSetting(cat, pSetting);
 }
 
-void CGUISettings::AddInt(CSettingsCategory* cat, const char *strSetting,
-                          int iLabel, int iData, const map<int,int>& entries,
-                          int iControlType)
+void CGUISettings::AddInt(CSettingsCategory* cat, const char *strSetting, int iLabel, int iData, const map<int,int>& entries, int iControlType)
 {
-  int iOrder = cat?++cat->m_entries:0;
+  int iOrder = cat ? cat->m_settings.size() : 0;
   CSettingInt* pSetting = new CSettingInt(iOrder, CStdString(strSetting).ToLower(), iLabel, iData, entries, iControlType);
   if (!pSetting) return ;
-  settingsMap.insert(pair<CStdString, CSetting*>(CStdString(strSetting).ToLower(), pSetting));
+  AddSetting(cat, pSetting);
 }
 
 void CGUISettings::AddHex(CSettingsCategory* cat, const char *strSetting, int iLabel, int iData, int iMin, int iStep, int iMax, int iControlType, const char *strFormat)
 {
-  int iOrder = cat?++cat->m_entries:0;
+  int iOrder = cat ? cat->m_settings.size() : 0;
   CSettingHex* pSetting = new CSettingHex(iOrder, CStdString(strSetting).ToLower(), iLabel, iData, iMin, iStep, iMax, iControlType, strFormat);
   if (!pSetting) return ;
-  settingsMap.insert(pair<CStdString, CSetting*>(CStdString(strSetting).ToLower(), pSetting));
+  AddSetting(cat, pSetting);
 }
 
 int CGUISettings::GetInt(const char *strSetting) const
@@ -1068,26 +1080,26 @@ void CGUISettings::SetInt(const char *strSetting, int iSetting)
 
 void CGUISettings::AddString(CSettingsCategory* cat, const char *strSetting, int iLabel, const char *strData, int iControlType, bool bAllowEmpty, int iHeadingString)
 {
-  int iOrder = cat?++cat->m_entries:0;
+  int iOrder = cat ? cat->m_settings.size() : 0;
   CSettingString* pSetting = new CSettingString(iOrder, CStdString(strSetting).ToLower(), iLabel, strData, iControlType, bAllowEmpty, iHeadingString);
   if (!pSetting) return ;
-  settingsMap.insert(pair<CStdString, CSetting*>(CStdString(strSetting).ToLower(), pSetting));
+  AddSetting(cat, pSetting);
 }
 
 void CGUISettings::AddPath(CSettingsCategory* cat, const char *strSetting, int iLabel, const char *strData, int iControlType, bool bAllowEmpty, int iHeadingString)
 {
-  int iOrder = cat?++cat->m_entries:0;
+  int iOrder = cat ? cat->m_settings.size() : 0;
   CSettingPath* pSetting = new CSettingPath(iOrder, CStdString(strSetting).ToLower(), iLabel, strData, iControlType, bAllowEmpty, iHeadingString);
   if (!pSetting) return ;
-  settingsMap.insert(pair<CStdString, CSetting*>(CStdString(strSetting).ToLower(), pSetting));
+  AddSetting(cat, pSetting);
 }
 
 void CGUISettings::AddDefaultAddon(CSettingsCategory* cat, const char *strSetting, int iLabel, const char *strData, const TYPE type)
 {
-  int iOrder = cat?++cat->m_entries:0;
+  int iOrder = cat ? cat->m_settings.size() : 0;
   CSettingAddon* pSetting = new CSettingAddon(iOrder, CStdString(strSetting).ToLower(), iLabel, strData, type);
   if (!pSetting) return ;
-  settingsMap.insert(pair<CStdString, CSetting*>(CStdString(strSetting).ToLower(), pSetting));
+  AddSetting(cat, pSetting);
 }
 
 const CStdString &CGUISettings::GetString(const char *strSetting, bool bPrompt /* = true */) const
@@ -1149,14 +1161,18 @@ CSetting *CGUISettings::GetSetting(const char *strSetting)
 }
 
 // get all the settings beginning with the term "strGroup"
-void CGUISettings::GetSettingsGroup(const char *strGroup, vecSettings &settings)
+void CGUISettings::GetSettingsGroup(CSettingsCategory* cat, vecSettings &settings)
 {
+  if (!cat || cat->m_settings.size() <= 0)
+    return;
+
   vecSettings unorderedSettings;
-  for (mapIter it = settingsMap.begin(); it != settingsMap.end(); it++)
+  for (unsigned int index = 0; index < cat->m_settings.size(); index++)
   {
-    if ((*it).first.Left(strlen(strGroup)).Equals(strGroup) && (*it).second->GetOrder() > 0 && !(*it).second->IsAdvanced())
-      unorderedSettings.push_back((*it).second);
+    if (!cat->m_settings.at(index)->IsAdvanced())
+      unorderedSettings.push_back(cat->m_settings.at(index));
   }
+
   // now order them...
   sort(unorderedSettings.begin(), unorderedSettings.end(), sortsettings());
 
@@ -1258,12 +1274,6 @@ void CGUISettings::LoadFromXML(TiXmlElement *pRootElement, mapIter &it, bool adv
         CStdString strValue = pGrandChild->FirstChild() ? pGrandChild->FirstChild()->Value() : "";
         if (strValue != "-")
         { // update our item
-          if ((*it).second->GetType() == SETTINGS_TYPE_PATH)
-          { // check our path
-            int pathVersion = 0;
-            pGrandChild->Attribute("pathversion", &pathVersion);
-            strValue = CSpecialProtocol::ReplaceOldPath(strValue, pathVersion);
-          }
           (*it).second->FromString(strValue);
           if (advanced)
             (*it).second->SetAdvanced();
@@ -1297,7 +1307,7 @@ void CGUISettings::SaveXML(TiXmlNode *pRootNode)
       { // successfully added (or found) our group
         TiXmlElement newElement(strSplit[1]);
         if ((*it).second->GetType() == SETTINGS_TYPE_PATH)
-          newElement.SetAttribute("pathversion", CSpecialProtocol::path_version);
+          newElement.SetAttribute("pathversion", XMLUtils::path_version);
         TiXmlNode *pNewNode = pChild->InsertEndChild(newElement);
         if (pNewNode)
         {
index 5501064..fb2308f 100644 (file)
@@ -394,13 +394,12 @@ public:
   {
     m_strCategory = strCategory;
     m_labelID = labelID;
-    m_entries = 0;
   }
   ~CSettingsCategory() {};
 
   CStdString m_strCategory;
   int m_labelID;
-  int m_entries;
+  std::vector<CSetting*> m_settings;
 };
 
 typedef std::vector<CSettingsCategory *> vecSettingsCategory;
@@ -450,6 +449,7 @@ public:
   CSettingsCategory* AddCategory(int groupID, const char *strCategory, int labelID);
   CSettingsGroup *GetGroup(int windowID);
 
+  void AddSetting(CSettingsCategory* cat, CSetting* setting);
   void AddBool(CSettingsCategory* cat, const char *strSetting, int iLabel, bool bSetting, int iControlType = CHECKMARK_CONTROL);
   bool GetBool(const char *strSetting) const;
   void SetBool(const char *strSetting, bool bSetting);
@@ -480,7 +480,7 @@ public:
 
   CSetting *GetSetting(const char *strSetting);
 
-  void GetSettingsGroup(const char *strGroup, vecSettings &settings);
+  void GetSettingsGroup(CSettingsCategory* cat, vecSettings &settings);
   void LoadXML(TiXmlElement *pRootElement, bool hideSettings = false);
   void SaveXML(TiXmlNode *pRootNode);
   void LoadMasterLock(TiXmlElement *pRootElement);
index c6492f2..48f213c 100644 (file)
@@ -346,7 +346,7 @@ void CGUIWindowSettingsCategory::CreateSettings()
   if (!group)
     return;
   vecSettings settings;
-  g_guiSettings.GetSettingsGroup(m_vecSections[m_iSection]->m_strCategory, settings);
+  g_guiSettings.GetSettingsGroup(m_vecSections[m_iSection], settings);
   int iControlID = CONTROL_START_CONTROL;
   for (unsigned int i = 0; i < settings.size(); i++)
   {
@@ -1574,15 +1574,7 @@ void CGUIWindowSettingsCategory::OnSettingChanged(CBaseSettingControl *pSettingC
     /* okey we really don't need to restarat, only deinit samba, but that could be damn hard if something is playing*/
     //TODO - General way of handling setting changes that require restart
 
-    CGUIDialogOK *dlg = (CGUIDialogOK *)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
-    if (!dlg) return ;
-    dlg->SetHeading( g_localizeStrings.Get(14038) );
-    dlg->SetLine( 0, g_localizeStrings.Get(14039) );
-    dlg->SetLine( 1, g_localizeStrings.Get(14040));
-    dlg->SetLine( 2, "");
-    dlg->DoModal();
-
-    if (dlg->IsConfirmed())
+    if (CGUIDialogYesNo::ShowAndGetInput(14038, 14039, 14040, -1, -1))
     {
       g_settings.Save();
       g_application.getApplicationMessenger().RestartApp();
@@ -2491,7 +2483,7 @@ void CGUIWindowSettingsCategory::FillInSkinColors(CSetting *pSetting)
   URIUtils::AddFileToFolder(g_SkinInfo->Path(),"colors",strPath);
 
   CFileItemList items;
-  CDirectory::GetDirectory(PTH_IC(strPath), items, ".xml");
+  CDirectory::GetDirectory(CSpecialProtocol::TranslatePathConvertCase(strPath), items, ".xml");
   // Search for Themes in the Current skin!
   for (int i = 0; i < items.Size(); ++i)
   {
index 599b61b..3557853 100644 (file)
@@ -280,10 +280,7 @@ bool CSettings::GetSource(const CStdString &category, const TiXmlNode *source, C
   {
     if (pPathName->FirstChild())
     {
-      int pathVersion = 0;
-      pPathName->Attribute("pathversion", &pathVersion);
       CStdString strPath = pPathName->FirstChild()->Value();
-      strPath = CSpecialProtocol::ReplaceOldPath(strPath, pathVersion);
       // make sure there are no virtualpaths or stack paths defined in xboxmediacenter.xml
       //CLog::Log(LOGDEBUG,"    Found path: %s", strPath.c_str());
       if (!URIUtils::IsStack(strPath))
index 64ba1c5..08a9372 100644 (file)
@@ -51,7 +51,6 @@
 #include "Application.h"
 #include "IoSupport.h"
 #include "cdioSupport.h"
-#include "storage/MediaManager.h"
 
 
 using namespace XFILE;
@@ -194,10 +193,6 @@ VOID CDetectDVDMedia::UpdateDvdrom()
           if ( m_DriveState != DRIVE_CLOSED_MEDIA_PRESENT)
           {
             m_DriveState = DRIVE_CLOSED_MEDIA_PRESENT;
-            // drive has been closed and is ready
-            OutputDebugString("Drive closed media present, remounting...\n");
-            CIoSupport::Dismount("Cdrom0");
-            CIoSupport::RemapDriveLetter('D', "Cdrom0");
             // Detect ISO9660(mode1/mode2) or CDDA filesystem
             DetectMediaType();
             CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_SOURCES);
@@ -529,27 +524,4 @@ const CStdString &CDetectDVDMedia::GetDVDPath()
 {
   return m_diskPath;
 }
-
-CDetectDisc::CDetectDisc(const CStdString &strPath, const bool bautorun)
-  : m_strPath(strPath), m_bautorun(bautorun)
-{
-}
-
-bool CDetectDisc::DoWork()
-{
-  CMediaSource share;
-  share.strPath = m_strPath;
-  share.strStatus = g_mediaManager.GetDiskLabel(share.strPath);
-  share.strDiskUniqueId = g_mediaManager.GetDiskUniqueId(share.strPath);
-  if(g_mediaManager.IsAudio(share.strPath))
-    share.strStatus = "Audio-CD";
-  else if(share.strStatus == "")
-    share.strStatus = g_localizeStrings.Get(446);
-  share.strName = share.strPath;
-  share.m_ignore = true;
-  share.m_iDriveType = CMediaSource::SOURCE_TYPE_DVD;
-  g_mediaManager.AddAutoSource(share, m_bautorun);
-  return true;
-}
-
 #endif
index c3b444b..250991d 100644 (file)
@@ -37,7 +37,6 @@
 
 #include "threads/Thread.h"
 #include "utils/StdString.h"
-#include "utils/Job.h"
 
 namespace MEDIA_DETECT
 {
@@ -93,16 +92,4 @@ private:
   CLibcdio* m_cdio;
 };
 }
-
-class CDetectDisc : public CJob
-{
-public:
-  CDetectDisc(const CStdString &strPath, const bool bautorun);
-  bool DoWork();
-
-private:
-  CStdString  m_strPath;
-  bool        m_bautorun;
-};
-
 #endif
index a1eeace..67847af 100644 (file)
 #include "XHandle.h"
 #endif
 
-#define NT_STATUS_OBJECT_NAME_NOT_FOUND long(0xC0000000 | 0x0034)
-#define NT_STATUS_VOLUME_DISMOUNTED     long(0xC0000000 | 0x026E)
-
-typedef struct
-{
-  char cDriveLetter;
-  char szDevice[MAX_PATH];
-  int iPartition;
-}
-stDriveMapping;
-
-#if defined(WIN32)
-stDriveMapping driveMapping[] =
-  {
-    {'P', "", 0},
-    {'Q', "", 0},
-    {'T', "", 0},
-    {'Z', "", 0},
-    {'U', "", 0}
-  };
-
-#else
-stDriveMapping driveMapping[] =
-  {
-    {'P', "", 0},
-    {'Q', "", 0},
-    {'T', "", 0},
-    {'Z', "", 0},
-    {'C', "", 0},
-    {'E', "", 0},
-    {'U', "", 0}
-  };
-#endif
-
-#define NUM_OF_DRIVES ( sizeof( driveMapping) / sizeof( driveMapping[0] ) )
-
 
 PVOID CIoSupport::m_rawXferBuffer;
-PARTITION_TABLE CIoSupport::m_partitionTable;
-bool CIoSupport::m_fPartitionTableIsValid;
-
-
-// cDriveLetter e.g. 'D'
-// szDevice e.g. "Cdrom0" or "Harddisk0\Partition6"
-HRESULT CIoSupport::MapDriveLetter(char cDriveLetter, const char* szDevice)
-{
-
-#ifdef _WIN32
-  // still legacy support (only used in DetectDVDType.cpp)
-  if((strnicmp(szDevice, "Harddisk0",9)==0) || (strnicmp(szDevice, "Cdrom",5)==0))
-    return S_OK;
-#endif
-  CStdString device(szDevice);
-  device.TrimRight("/\\");
-  char upperLetter = toupper(cDriveLetter);
-  for (unsigned int i=0; i < NUM_OF_DRIVES; i++)
-    if (driveMapping[i].cDriveLetter == upperLetter)
-    {
-      strcpy(driveMapping[i].szDevice, device.c_str());
-      CLog::Log(LOGNOTICE, "Mapping drive %c to %s", cDriveLetter, device.c_str());
-      return S_OK;
-    }
-  return E_FAIL;
-}
-
-// cDriveLetter e.g. 'D'
-HRESULT CIoSupport::UnmapDriveLetter(char cDriveLetter)
-{
-  return S_OK;
-}
-
-HRESULT CIoSupport::RemapDriveLetter(char cDriveLetter, const char* szDevice)
-{
-  UnmapDriveLetter(cDriveLetter);
-
-  return MapDriveLetter(cDriveLetter, szDevice);
-}
-// to be used with CdRom devices.
-HRESULT CIoSupport::Dismount(const char* szDevice)
-{
-  return S_OK;
-}
-
-void CIoSupport::GetPartition(char cDriveLetter, char* szPartition)
-{
-  char upperLetter = toupper(cDriveLetter);
-  if (upperLetter >= 'F' && upperLetter <= 'O')
-  {
-    sprintf(szPartition, "Harddisk0\\Partition%u", upperLetter - 'A' + 1);
-    return;
-  }
-  for (unsigned int i=0; i < NUM_OF_DRIVES; i++)
-    if (driveMapping[i].cDriveLetter == upperLetter)
-    {
-      strcpy(szPartition, driveMapping[i].szDevice);
-      return;
-    }
-  *szPartition = 0;
-}
-
-const char* CIoSupport::GetPartition(char cDriveLetter)
-{
-  char upperLetter = toupper(cDriveLetter);
-  for (unsigned int i=0; i < NUM_OF_DRIVES; i++)
-    if (driveMapping[i].cDriveLetter == upperLetter)
-      return driveMapping[i].szDevice;
-  return NULL;
-}
-
-void CIoSupport::GetDrive(const char* szPartition, char* cDriveLetter)
-{
-  int part_str_len = strlen(szPartition);
-  int part_num;
-
-  if (part_str_len < 19)
-  {
-    *cDriveLetter = 0;
-    return;
-  }
-
-  part_num = atoi(szPartition + 19);
-
-  if (part_num >= 6)
-  {
-    *cDriveLetter = part_num + 'A' - 1;
-    return;
-  }
-  for (unsigned int i=0; i < NUM_OF_DRIVES; i++)
-    if (strnicmp(driveMapping[i].szDevice, szPartition, strlen(driveMapping[i].szDevice)) == 0)
-    {
-      *cDriveLetter = driveMapping[i].cDriveLetter;
-      return;
-    }
-  *cDriveLetter = 0;
-}
 
 HRESULT CIoSupport::EjectTray( const bool bEject, const char cDriveLetter )
 {
@@ -263,11 +130,6 @@ HRESULT CIoSupport::ToggleTray()
     return EjectTray();
 }
 
-HRESULT CIoSupport::Shutdown()
-{
-  return S_OK;
-}
-
 HANDLE CIoSupport::OpenCDROM()
 {
   HANDLE hDevice = 0;
@@ -482,19 +344,12 @@ VOID CIoSupport::CloseCDROM(HANDLE hDevice)
   CloseHandle(hDevice);
 }
 
-// returns true if this is a debug machine
-BOOL CIoSupport::IsDebug()
-{
-  return FALSE;
-}
-
-
 VOID CIoSupport::GetXbePath(char* szDest)
 {
 
 #if WIN32
   wchar_t szAppPathW[MAX_PATH] = L"";
-  ::GetModuleFileNameW(0, szAppPathW, sizeof(szAppPathW) - 1);
+  ::GetModuleFileNameW(0, szAppPathW, sizeof(szAppPathW)/sizeof(szAppPathW[0]) - 1);
   CStdStringW strPathW = szAppPathW;
   CStdString strPath;
   g_charsetConverter.wToUTF8(strPathW,strPath);
@@ -521,56 +376,3 @@ VOID CIoSupport::GetXbePath(char* szDest)
   strcpy(szDest, buf);
 #endif
 }
-
-bool CIoSupport::DriveExists(char cDriveLetter)
-{
-  cDriveLetter = toupper(cDriveLetter);
-#if defined(WIN32)
-  if (cDriveLetter < 'A' || cDriveLetter > 'Z')
-    return false;
-
-  DWORD drivelist;
-  DWORD bitposition = cDriveLetter - 'A';
-
-  drivelist = GetLogicalDrives();
-
-  if (!drivelist)
-    return false;
-
-  return (drivelist >> bitposition) & 1;
-#else
-  return false;
-#endif
-}
-
-bool CIoSupport::PartitionExists(int nPartition)
-{
-  return false;
-}
-
-LARGE_INTEGER CIoSupport::GetDriveSize()
-{
-  LARGE_INTEGER drive_size;
-  drive_size.QuadPart = 0;
-  return drive_size;
-}
-
-bool CIoSupport::ReadPartitionTable()
-{
-  return false;
-}
-
-bool CIoSupport::HasPartitionTable()
-{
-  return m_fPartitionTableIsValid;
-}
-
-void CIoSupport::MapExtendedPartitions()
-{
-
-}
-
-unsigned int CIoSupport::ReadPartitionTable(PARTITION_TABLE *p_table)
-{
-  return (unsigned int) -1;
-}
index 8b02130..c4f76ae 100644 (file)
 #define MODE2_DATA_SIZE    2324 // And has 2324 usable bytes
 #define RAW_SECTOR_SIZE    2352 // Raw sector size
 
-// Xbox extended partition numbers, 6-7.  Note that up to 15 can normally be used, but we reserve 8->15 for memcards.
-#define EXTEND_PARTITION_BEGIN  6
-#define EXTEND_PARTITION_END    7
-#define EXTEND_DRIVE_BEGIN     'F'
-#define EXTEND_DRIVE_END       'G'
-
-// This flag (part of PARTITION_ENTRY.pe_flags) tells you whether/not a
-// partition is being used (whether/not drive G is active, for example)
-#define PE_PARTFLAGS_IN_USE          0x80000000
-
-#define IOCTL_CMD_LBA48_ACCESS        0xcafebabe
-#define IOCTL_SUBCMD_GET_INFO         0
-
-#define LBA48_GET_INFO_MAGIC1_IDX       0
-#define LBA48_GET_INFO_MAGIC1_VAL       0xcafebabe
-#define LBA48_GET_INFO_MAGIC2_IDX       1
-#define LBA48_GET_INFO_MAGIC2_VAL       0xbabeface
-#define LBA48_GET_INFO_PATCHCODE_VERSION_IDX 2
-#define LBA48_GET_INFO_LOWCODE_BASE_IDX      3
-#define LBA48_GET_INFO_HIGHCODE_BASE_IDX     4
-#define LBA48_GET_INFO_PATCHSEG_SIZE_IDX     5
-#define LBA48_GET_INFO_PART_TABLE_OFS_IDX    6
-
-#define MAX_PARTITIONS                       14
-
-typedef struct _PARTITION_ENTRY
-{
-  char pe_name[16];
-  unsigned long pe_flags; // bitmask
-  unsigned long pe_lba_start;
-  unsigned long pe_lba_size;
-  unsigned long pe_reserved;
-} PARTITION_ENTRY;
-
-typedef struct _PARTITION_TABLE
-{
-  char pt_magic[16];
-  unsigned char pt_reserved[32];
-  PARTITION_ENTRY pt_entries[MAX_PARTITIONS];
-} PARTITION_TABLE;
-
 class CIoSupport
 {
 public:
   static VOID GetXbePath(char* szDest);
 
-  static HRESULT MapDriveLetter  (char cDriveLetter, const char* szDevice);
-  static HRESULT UnmapDriveLetter(char cDriveLetter);
-  static HRESULT RemapDriveLetter(char cDriveLetter, const char* szDevice);
-
-  static HRESULT Dismount(const char* szDevice);
-
-  static bool DriveExists(char cDrive);
-  static bool PartitionExists(int nPartition);
-
-  static void GetPartition(char cDriveLetter, char* szPartition);
-  static const char* GetPartition(char cDriveLetter);
-  static void GetDrive(const char* szPartition, char* cDriveLetter);
-
-  static bool ReadPartitionTable();
-  static bool HasPartitionTable();
-  static void MapExtendedPartitions();
-
-  static LARGE_INTEGER GetDriveSize();
-
   static DWORD   GetTrayState();
   static HRESULT EjectTray( const bool bEject=true, const char cDriveLetter='\0' );
   static HRESULT CloseTray();
@@ -127,13 +67,8 @@ public:
   static INT ReadSectorCDDA(HANDLE hDevice, DWORD dwSector, LPSTR lpczBuffer);
   static VOID CloseCDROM(HANDLE hDevice);
 
-  static BOOL IsDebug();
-  static HRESULT Shutdown();
 private:
-  static unsigned int ReadPartitionTable(PARTITION_TABLE *p_table);
   static PVOID m_rawXferBuffer;
-  static PARTITION_TABLE m_partitionTable;
-  static bool m_fPartitionTableIsValid;
 };
 
 #endif // !defined(AFX_IOSUPPORT_H__F084A488_BD6E_49D5_8CD3_0BE62149DB40__INCLUDED_)
index ced4ad0..e9cae25 100644 (file)
@@ -50,7 +50,7 @@
 
 #include "FileItem.h"
 #include "filesystem/File.h"
-#include "filesystem/FactoryDirectory.h"
+#include "filesystem/DirectoryFactory.h"
 #include "filesystem/Directory.h"
 #include "utils/Crc32.h"
 
index 2e5a2bc..a46e07c 100644 (file)
 #include "WIN32Util.h"
 #include "guilib/LocalizeStrings.h"
 #include "filesystem/SpecialProtocol.h"
+#include "storage/MediaManager.h"
+#include "utils/JobManager.h"
 
 bool CWin32StorageProvider::event = false;
 
+void CWin32StorageProvider::Initialize()
+{
+  // check for a DVD drive
+  VECSOURCES vShare;
+  CWIN32Util::GetDrivesByType(vShare, DVD_DRIVES);
+  if(!vShare.empty())
+    g_mediaManager.SetHasOpticalDrive(true);
+
+  // Can be removed once the StorageHandler supports optical media
+  VECSOURCES::const_iterator it;
+  for(it=vShare.begin();it!=vShare.end();++it)
+    if(g_mediaManager.GetDriveStatus(it->strPath) == DRIVE_CLOSED_MEDIA_PRESENT)
+      CJobManager::GetInstance().AddJob(new CDetectDisc(it->strPath, false), NULL);
+  // remove end
+}
+
 void CWin32StorageProvider::GetLocalDrives(VECSOURCES &localDrives)
 {
   CMediaSource share;
-  share.strPath = _P("special://home");
+  share.strPath = CSpecialProtocol::TranslatePath("special://home");
   share.strName = g_localizeStrings.Get(21440);
   share.m_ignore = true;
   share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
@@ -62,3 +80,25 @@ bool CWin32StorageProvider::PumpDriveChangeEvents(IStorageEventsCallback *callba
   event = false;
   return b;
 }
+
+CDetectDisc::CDetectDisc(const CStdString &strPath, const bool bautorun)
+  : m_strPath(strPath), m_bautorun(bautorun)
+{
+}
+
+bool CDetectDisc::DoWork()
+{
+  CMediaSource share;
+  share.strPath = m_strPath;
+  share.strStatus = g_mediaManager.GetDiskLabel(share.strPath);
+  share.strDiskUniqueId = g_mediaManager.GetDiskUniqueId(share.strPath);
+  if(g_mediaManager.IsAudio(share.strPath))
+    share.strStatus = "Audio-CD";
+  else if(share.strStatus == "")
+    share.strStatus = g_localizeStrings.Get(446);
+  share.strName = share.strPath;
+  share.m_ignore = true;
+  share.m_iDriveType = CMediaSource::SOURCE_TYPE_DVD;
+  g_mediaManager.AddAutoSource(share, m_bautorun);
+  return true;
+}
index be4f2f2..088a060 100644 (file)
  *
  */
 #include "storage/IStorageProvider.h"
+#include "utils/Job.h"
 
 class CWin32StorageProvider : public IStorageProvider
 {
 public:
   virtual ~CWin32StorageProvider() { }
 
-  virtual void Initialize() { }
+  virtual void Initialize();
   virtual void Stop() { }
 
   virtual void GetLocalDrives(VECSOURCES &localDrives);
@@ -41,3 +42,15 @@ public:
   static void SetEvent() { event = true; }
   static bool event;
 };
+
+class CDetectDisc : public CJob
+{
+public:
+  CDetectDisc(const CStdString &strPath, const bool bautorun);
+  bool DoWork();
+
+private:
+  CStdString  m_strPath;
+  bool        m_bautorun;
+};
+
index b10ebae..8d5542a 100644 (file)
 #include "PlatformInclude.h"
 #endif
 
-// ARM does not support certain features... disable them here!
-#ifdef _ARMEL
-#undef HAS_VISUALISATION
-#undef HAS_FILESYSTEM_HTSP
-#endif
-
 // EGL detected. Dont use GLX!
 #ifdef HAVE_LIBEGL
 #undef HAS_GLX
index f06e6d9..77446a0 100644 (file)
 #include "threads/Helpers.h"
 
 #include <pthread.h>
-#include <sys/time.h>
-#include <assert.h>
+
+#ifdef TARGET_DARWIN
+  #include <sys/time.h> //for gettimeofday
+#else
+  #include <time.h> //for clock_gettime
+#endif
 
 namespace XbmcThreads
 {
@@ -59,18 +63,21 @@ namespace XbmcThreads
 
     inline bool wait(CCriticalSection& lock, unsigned long milliseconds) 
     { 
-      struct timeval tv;
       struct timespec ts;
 
-      gettimeofday(&tv,NULL);
-
-      milliseconds += tv.tv_usec / 1000; // move the usecs onto milliseconds
+#ifdef TARGET_DARWIN
+      struct timeval tv;
+      gettimeofday(&tv, NULL);
+      ts.tv_nsec = tv.tv_usec * 1000;
+      ts.tv_sec  = tv.tv_sec;
+#else
+      clock_gettime(CLOCK_REALTIME, &ts);
+#endif
 
-      time_t tsecs = (time_t)(milliseconds/1000); // temporary used for assert
-      assert(tsecs >= (time_t)0);
+      ts.tv_nsec += milliseconds % 1000 * 1000000;
+      ts.tv_sec  += milliseconds / 1000 + ts.tv_nsec / 1000000000;
+      ts.tv_nsec %= 1000000000;
 
-      ts.tv_sec = tv.tv_sec + tsecs;
-      ts.tv_nsec = (long)((milliseconds % (unsigned long)1000) * (unsigned long)1000000);
       return (pthread_cond_timedwait(&cond,&lock.get_underlying().mutex,&ts) == 0);
     }
 
index 0f61171..09c9619 100644 (file)
@@ -93,7 +93,7 @@ void CAlarmClock::Stop(const CStdString& strName, bool bSilent /* false */)
   SAlarmClockEvent& event = iter->second;
 
   CStdString strAlarmClock;
-  if (event.m_strCommand.Equals("xbmc.shutdown") || event.m_strCommand.Equals("xbmc.shutdown()"))
+  if (event.m_strCommand.Equals("xbmc.powerdown") || event.m_strCommand.Equals("xbmc.powerdown()"))
     strAlarmClock = g_localizeStrings.Get(20144);
   else
     strAlarmClock = g_localizeStrings.Get(13208);
diff --git a/xbmc/utils/Base64.cpp b/xbmc/utils/Base64.cpp
new file mode 100644 (file)
index 0000000..42c615c
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "Base64.h"
+
+#define PADDING '='
+
+using namespace std;
+
+const std::string Base64::m_characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                         "abcdefghijklmnopqrstuvwxyz"
+                                         "0123456789+/";
+
+void Base64::Encode(const char* input, unsigned int length, std::string &output)
+{
+  if (input == NULL || length == 0)
+    return;
+
+  long l;
+  output.clear();
+
+  for (unsigned int i = 0; i < length; i += 3)
+  {
+    l  = ((((unsigned long) input[i]) << 16) & 0xFFFFFF) |
+         ((((i + 1) < length) ? (((unsigned long) input[i + 1]) << 8) : 0) & 0xFFFF) |
+         ((((i + 2) < length) ? (((unsigned long) input[i + 2]) << 0) : 0) & 0x00FF);
+
+    output.push_back(m_characters[(l >> 18) & 0x3F]);
+    output.push_back(m_characters[(l >> 12) & 0x3F]);
+
+    if (i + 1 < length)
+      output.push_back(m_characters[(l >> 6) & 0x3F]);
+    if (i + 2 < length)
+      output.push_back(m_characters[(l >> 0) & 0x3F]);
+  }
+
+  int left = 3 - (length % 3);
+
+  if (length % 3)
+  {
+    for (int i = 0; i < left; i++)
+      output.push_back(PADDING);
+  }
+}
+
+std::string Base64::Encode(const char* input, unsigned int length)
+{
+  std::string output;
+  Encode(input, length, output);
+
+  return output;
+}
+
+void Base64::Encode(const std::string &input, std::string &output)
+{
+  Encode(input.c_str(), input.size(), output);
+}
+
+std::string Base64::Encode(const std::string &input)
+{
+  std::string output;
+  Encode(input, output);
+
+  return output;
+}
+
+void Base64::Decode(const char* input, unsigned int length, std::string &output)
+{
+  if (input == NULL || length == 0)
+    return;
+
+  long l;
+  output.clear();
+
+  for (unsigned int index = 0; index < length; index++)
+  {
+    if (input[index] == '=')
+    {
+      length = index;
+      break;
+    }
+  }
+
+  for (unsigned int i = 0; i < length; i += 4)
+  {
+    l = ((((unsigned long) m_characters.find(input[i])) & 0x3F) << 18);
+    l |= (((i + 1) < length) ? ((((unsigned long) m_characters.find(input[i + 1])) & 0x3F) << 12) : 0);
+    l |= (((i + 2) < length) ? ((((unsigned long) m_characters.find(input[i + 2])) & 0x3F) <<  6) : 0);
+    l |= (((i + 3) < length) ? ((((unsigned long) m_characters.find(input[i + 3])) & 0x3F) <<  0) : 0);
+
+    output.push_back((char)((l >> 16) & 0xFF));
+    if (i + 2 < length)
+      output.push_back((char)((l >> 8) & 0xFF));
+    if (i + 3 < length)
+      output.push_back((char)((l >> 0) & 0xFF));
+  }
+}
+
+std::string Base64::Decode(const char* input, unsigned int length)
+{
+  std::string output;
+  Decode(input, length, output);
+
+  return output;
+}
+
+void Base64::Decode(const std::string &input, std::string &output)
+{
+  size_t length = input.find_first_of(PADDING);
+  if (length == string::npos)
+    length = input.size();
+
+  Decode(input.c_str(), length, output);
+}
+
+std::string Base64::Decode(const std::string &input)
+{
+  std::string output;
+  Decode(input, output);
+
+  return output;
+}
diff --git a/xbmc/utils/Base64.h b/xbmc/utils/Base64.h
new file mode 100644 (file)
index 0000000..32d760f
--- /dev/null
@@ -0,0 +1,39 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <string>
+
+class Base64
+{
+public:
+  static void Encode(const char* input, unsigned int length, std::string &output);
+  static std::string Encode(const char* input, unsigned int length);
+  static void Encode(const std::string &input, std::string &output);
+  static std::string Encode(const std::string &input);
+  static void Decode(const char* input, unsigned int length, std::string &output);
+  static std::string Decode(const char* input, unsigned int length);
+  static void Decode(const std::string &input, std::string &output);
+  static std::string Decode(const std::string &input);
+
+private:
+  static const std::string m_characters;
+};
index 4101090..56dd751 100644 (file)
@@ -24,7 +24,7 @@
 #include "log.h"
 
 #include "filesystem/File.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 #include "threads/SingleLock.h"
 
 using namespace std;
@@ -124,7 +124,7 @@ void CDownloadQueue::Process()
 {
   CLog::Log(LOGNOTICE, "DownloadQueue ready.");
 
-  CFileCurl http;
+  CCurlFile http;
   bool bSuccess;
 
   while ( !m_bStop )
index 8e9f292..e9f96ee 100644 (file)
@@ -87,10 +87,16 @@ static __inline__ uint64_t Endian_Swap64(uint64_t x) {
 #define Endian_SwapLE16(X) (X)
 #define Endian_SwapLE32(X) (X)
 #define Endian_SwapLE64(X) (X)
+#define Endian_SwapBE16(X) Endian_Swap16(X)
+#define Endian_SwapBE32(X) Endian_Swap32(X)
+#define Endian_SwapBE64(X) Endian_Swap64(X)
 #else
 #define Endian_SwapLE16(X) Endian_Swap16(X)
 #define Endian_SwapLE32(X) Endian_Swap32(X)
 #define Endian_SwapLE64(X) Endian_Swap64(X)
+#define Endian_SwapBE16(X) (X)
+#define Endian_SwapBE32(X) (X)
+#define Endian_SwapBE64(X) (X)
 #endif
 
 /* Ends C function definitions when using C++ */
index 578aee9..8457f6d 100644 (file)
@@ -23,7 +23,7 @@
 #include "tinyXML/tinyxml.h"
 #include "URIUtils.h"
 #include "pictures/Picture.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 #include "StringUtils.h"
 #include "filesystem/File.h"
 
@@ -146,7 +146,7 @@ bool CFanart::DownloadThumb(unsigned int index, const CStdString &strDestination
     else
       thumbURL = URIUtils::AddFileToFolder(m_url, m_fanart[index].strPreview);
 
-    XFILE::CFileCurl http;
+    XFILE::CCurlFile http;
     if (http.Download(thumbURL, strDestination))
       return true;
   }
index c8ff417..af2990f 100644 (file)
@@ -23,7 +23,7 @@
 #include "filesystem/File.h"
 #include "filesystem/Directory.h"
 #include "filesystem/ZipManager.h"
-#include "filesystem/FactoryFileDirectory.h"
+#include "filesystem/FileDirectoryFactory.h"
 #include "filesystem/MultiPathDirectory.h"
 #include "filesystem/SpecialProtocol.h"
 #include "log.h"
@@ -95,7 +95,7 @@ bool CFileOperationJob::DoProcessFolder(FileAction action, const CStdString& str
 {
   // check whether this folder is a filedirectory - if so, we don't process it's contents
   CFileItem item(strPath, false);
-  IFileDirectory *file = CFactoryFileDirectory::Create(strPath, &item);
+  IFileDirectory *file = CFileDirectoryFactory::Create(strPath, &item);
   if (file)
   {
     delete file;
index ff9db1a..3f89726 100644 (file)
@@ -121,3 +121,27 @@ void LogGraphicsInfo()
 #endif /* !HAS_GL */
 }
 
+int glFormatElementByteCount(GLenum format)
+{
+  switch (format)
+  {
+#ifndef HAS_GLES
+  case GL_BGRA:
+#endif
+  case GL_RGBA:
+    return 4;
+#ifndef HAS_GLES
+  case GL_BGR:
+#endif
+  case GL_RGB:
+    return 3;
+  case GL_LUMINANCE_ALPHA:
+    return 2;
+  case GL_LUMINANCE:
+  case GL_ALPHA:
+    return 1;
+  default:
+    CLog::Log(LOGERROR, "glFormatElementByteCount - Unknown format %u", format);
+    return 1;
+  }
+}
index 9f7df3d..883ac4a 100644 (file)
@@ -41,3 +41,4 @@ void _VerifyGLState(const char* szfile, const char* szfunction, int lineno);
 
 void LogGraphicsInfo();
 
+int glFormatElementByteCount(GLenum format);
diff --git a/xbmc/utils/HttpResponse.cpp b/xbmc/utils/HttpResponse.cpp
new file mode 100644 (file)
index 0000000..4900a10
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+#include <stdio.h>
+
+#include "HttpResponse.h"
+
+#define SPACE     " "
+#define SEPARATOR ": "
+#define LINEBREAK "\r\n"
+
+#define HEADER_CONTENT_LENGTH "Content-Length"
+
+std::map<HTTP::StatusCode, std::string> CHttpResponse::m_statusCodeText = CHttpResponse::createStatusCodes();
+
+CHttpResponse::CHttpResponse(HTTP::Method method, HTTP::StatusCode status, HTTP::Version version /* = HTTPVersion1_1 */)
+{
+  m_method = method;
+  m_status = status;
+  m_version = version;
+
+  m_content = NULL;
+  m_contentLength = 0;
+}
+
+void CHttpResponse::AddHeader(const std::string &field, const std::string &value)
+{
+  if (field.empty())
+    return;
+
+  m_headers.push_back(std::pair<std::string, std::string>(field, value));
+}
+
+void CHttpResponse::SetContent(const char* data, unsigned int length)
+{
+  m_content = data;
+
+  if (m_content == NULL)
+    m_contentLength = 0;
+  else
+    m_contentLength = length;
+}
+
+unsigned int CHttpResponse::Create(char *&response)
+{
+  m_buffer.clear();
+
+  m_buffer.append("HTTP/");
+  switch (m_version)
+  {
+    case HTTP::Version1_0:
+      m_buffer.append("1.0");
+      break;
+
+    case HTTP::Version1_1:
+      m_buffer.append("1.1");
+      break;
+
+    default:
+      return 0;
+  }
+
+  char statusBuffer[4];
+  sprintf(statusBuffer, "%d", (int)m_status);
+  m_buffer.append(SPACE);
+  m_buffer.append(statusBuffer);
+
+  m_buffer.append(SPACE);
+  m_buffer.append(m_statusCodeText.find(m_status)->second);
+  m_buffer.append(LINEBREAK);
+
+  bool hasContentLengthHeader = false;
+  for (unsigned int index = 0; index < m_headers.size(); index++)
+  {
+    m_buffer.append(m_headers[index].first);
+    m_buffer.append(SEPARATOR);
+    m_buffer.append(m_headers[index].second);
+    m_buffer.append(LINEBREAK);
+
+    if (m_headers[index].first.compare(HEADER_CONTENT_LENGTH) == 0)
+      hasContentLengthHeader = true;
+  }
+
+  if (!hasContentLengthHeader && m_content != NULL && m_contentLength > 0)
+  {
+    m_buffer.append(HEADER_CONTENT_LENGTH);
+    m_buffer.append(SEPARATOR);
+    char lengthBuffer[11];
+    sprintf(lengthBuffer, "%d", m_contentLength);
+    m_buffer.append(lengthBuffer);
+    m_buffer.append(LINEBREAK);
+  }
+
+  m_buffer.append(LINEBREAK);
+  if (m_content != NULL && m_contentLength > 0)
+    m_buffer.append(m_content, m_contentLength);
+
+  response = (char *)m_buffer.c_str();
+  return m_buffer.size();
+}
+
+std::map<HTTP::StatusCode, std::string> CHttpResponse::createStatusCodes()
+{
+  std::map<HTTP::StatusCode, std::string> map;
+  map[HTTP::Continue]                      = "Continue";
+  map[HTTP::SwitchingProtocols]            = "Switching Protocols";
+  map[HTTP::Processing]                    = "Processing";
+  map[HTTP::ConnectionTimedOut]            = "Connection timed out";
+  map[HTTP::OK]                            = "OK";
+  map[HTTP::Created]                       = "Created";
+  map[HTTP::Accepted]                      = "Accepted";
+  map[HTTP::NonAuthoritativeInformation]   = "Non-Authoritative Information";
+  map[HTTP::NoContent]                     = "No Content";
+  map[HTTP::ResetContent]                  = "Reset Content";
+  map[HTTP::PartialContent]                = "Partial Content";
+  map[HTTP::MultiStatus]                   = "Multi-Status";
+  map[HTTP::MultipleChoices]               = "Multiple Choices";
+  map[HTTP::MovedPermanently]              = "Moved Permanently";
+  map[HTTP::Found]                         = "Found";
+  map[HTTP::SeeOther]                      = "See Other";
+  map[HTTP::NotModified]                   = "Not Modified";
+  map[HTTP::UseProxy]                      = "Use Proxy";
+  //map[HTTP::SwitchProxy]                 = "Switch Proxy";
+  map[HTTP::TemporaryRedirect]             = "Temporary Redirect";
+  map[HTTP::BadRequest]                    = "Bad Request";
+  map[HTTP::Unauthorized]                  = "Unauthorized";
+  map[HTTP::PaymentRequired]               = "Payment Required";
+  map[HTTP::Forbidden]                     = "Forbidden";
+  map[HTTP::NotFound]                      = "Not Found";
+  map[HTTP::MethodNotAllowed]              = "Method Not Allowed";
+  map[HTTP::NotAcceptable]                 = "Not Acceptable";
+  map[HTTP::ProxyAuthenticationRequired]   = "Proxy Authentication Required";
+  map[HTTP::RequestTimeout]                = "Request Time-out";
+  map[HTTP::Conflict]                      = "Conflict";
+  map[HTTP::Gone]                          = "Gone";
+  map[HTTP::LengthRequired]                = "Length Required";
+  map[HTTP::PreconditionFailed]            = "Precondition Failed";
+  map[HTTP::RequestEntityTooLarge]         = "Request Entity Too Large";
+  map[HTTP::RequestURITooLong]             = "Request-URI Too Long";
+  map[HTTP::UnsupportedMediaType]          = "Unsupported Media Type";
+  map[HTTP::RequestedRangeNotSatisfiable]  = "Requested range not satisfiable";
+  map[HTTP::ExpectationFailed]             = "Expectation Failed";
+  map[HTTP::ImATeapot]                     = "I'm a Teapot";
+  map[HTTP::TooManyConnections]            = "There are too many connections from your internet address";
+  map[HTTP::UnprocessableEntity]           = "Unprocessable Entity";
+  map[HTTP::Locked]                        = "Locked";
+  map[HTTP::FailedDependency]              = "Failed Dependency";
+  map[HTTP::UnorderedCollection]           = "UnorderedCollection";
+  map[HTTP::UpgradeRequired]               = "Upgrade Required";
+  map[HTTP::InternalServerError]           = "Internal Server Error";
+  map[HTTP::NotImplemented]                = "Not Implemented";
+  map[HTTP::BadGateway]                    = "Bad Gateway";
+  map[HTTP::ServiceUnavailable]            = "Service Unavailable";
+  map[HTTP::GatewayTimeout]                = "Gateway Time-out";
+  map[HTTP::HTTPVersionNotSupported]       = "HTTP Version not supported";
+  map[HTTP::VariantAlsoNegotiates]         = "Variant Also Negotiates";
+  map[HTTP::InsufficientStorage]           = "Insufficient Storage";
+  map[HTTP::BandwidthLimitExceeded]        = "Bandwidth Limit Exceeded";
+  map[HTTP::NotExtended]                   = "Not Extended";
+
+  return map;
+}
diff --git a/xbmc/utils/HttpResponse.h b/xbmc/utils/HttpResponse.h
new file mode 100644 (file)
index 0000000..5b1a3aa
--- /dev/null
@@ -0,0 +1,136 @@
+#pragma once
+/*
+ *      Copyright (C) 2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <string>
+#include <vector>
+#include <map>
+
+namespace HTTP
+{
+  enum Version
+  {
+    Version1_0,
+    Version1_1
+  };
+
+  enum Method
+  {
+    Get,
+    Head,
+    POST,
+    PUT,
+    Delete,
+    Trace,
+    Connect
+  };
+
+  enum StatusCode
+  {
+    // Information 1xx
+    Continue                      = 100,
+    SwitchingProtocols            = 101,
+    Processing                    = 102,
+    ConnectionTimedOut            = 103,
+
+    // Success 2xx
+    OK                            = 200,
+    Created                       = 201,
+    Accepted                      = 202,
+    NonAuthoritativeInformation   = 203,
+    NoContent                     = 204,
+    ResetContent                  = 205,
+    PartialContent                = 206,
+    MultiStatus                   = 207,
+
+    // Redirects 3xx
+    MultipleChoices               = 300,
+    MovedPermanently              = 301,
+    Found                         = 302,
+    SeeOther                      = 303,
+    NotModified                   = 304,
+    UseProxy                      = 305,
+    //SwitchProxy                 = 306,
+    TemporaryRedirect             = 307,
+
+    // Client errors 4xx
+    BadRequest                    = 400,
+    Unauthorized                  = 401,
+    PaymentRequired               = 402,
+    Forbidden                     = 403,
+    NotFound                      = 404,
+    MethodNotAllowed              = 405,
+    NotAcceptable                 = 406,
+    ProxyAuthenticationRequired   = 407,
+    RequestTimeout                = 408,
+    Conflict                      = 409,
+    Gone                          = 410,
+    LengthRequired                = 411,
+    PreconditionFailed            = 412,
+    RequestEntityTooLarge         = 413,
+    RequestURITooLong             = 414,
+    UnsupportedMediaType          = 415,
+    RequestedRangeNotSatisfiable  = 416,
+    ExpectationFailed             = 417,
+    ImATeapot                     = 418,
+    TooManyConnections            = 421,
+    UnprocessableEntity           = 422,
+    Locked                        = 423,
+    FailedDependency              = 424,
+    UnorderedCollection           = 425,
+    UpgradeRequired               = 426,
+
+    // Server errors 5xx
+    InternalServerError           = 500,
+    NotImplemented                = 501,
+    BadGateway                    = 502,
+    ServiceUnavailable            = 503,
+    GatewayTimeout                = 504,
+    HTTPVersionNotSupported       = 505,
+    VariantAlsoNegotiates         = 506,
+    InsufficientStorage           = 507,
+    BandwidthLimitExceeded        = 509,
+    NotExtended                   = 510
+  };
+}
+
+class CHttpResponse
+{
+public:
+  CHttpResponse(HTTP::Method method, HTTP::StatusCode status, HTTP::Version version = HTTP::Version1_1);
+
+  void AddHeader(const std::string &field, const std::string &value);
+  void SetContent(const char* data, unsigned int length);
+
+  unsigned int Create(char *&response);
+
+private:
+  HTTP::Method m_method;
+  HTTP::StatusCode m_status;
+  HTTP::Version m_version;
+  std::vector< std::pair<std::string, std::string> > m_headers;
+  const char* m_content;
+  unsigned int m_contentLength;
+  std::string m_buffer;
+
+  static std::map<HTTP::StatusCode, std::string> m_statusCodeText;
+  static std::map<HTTP::StatusCode, std::string> createStatusCodes();
+};
index dd7b28d..a6ba446 100644 (file)
@@ -22,6 +22,7 @@
 #include "JobManager.h"
 #include <algorithm>
 #include "threads/SingleLock.h"
+#include "utils/log.h"
 
 using namespace std;
 
@@ -41,8 +42,8 @@ CJobWorker::CJobWorker(CJobManager *manager) : CThread("Jobworker")
 CJobWorker::~CJobWorker()
 {
   // while we should already be removed from the job manager, if an exception
-  // occurs during processing, we may skip over that step.  Thus, before we
-  // go out of scope, ensure the job manager knows we're gone.
+  // occurs during processing that we haven't caught, we may skip over that step.
+  // Thus, before we go out of scope, ensure the job manager knows we're gone.
   m_jobManager->RemoveWorker(this);
   if(!IsAutoDelete())
     StopThread();
@@ -58,8 +59,15 @@ void CJobWorker::Process()
     if (!job)
       break;
 
-    // we have a job to do
-    bool success = job->DoWork();
+    bool success = false;
+    try
+    {
+      success = job->DoWork();
+    }
+    catch (...)
+    {
+      CLog::Log(LOGERROR, "%s error processing job %s", __FUNCTION__, job->GetType());
+    }
     m_jobManager->OnJobComplete(success, job);
   }
 }
@@ -295,8 +303,15 @@ void CJobManager::OnJobComplete(bool success, CJob *job)
     // tell any listeners we're done with the job, then delete it
     CWorkItem item(*i);
     lock.Leave();
-    if (item.m_callback)
-      item.m_callback->OnJobComplete(item.m_id, success, item.m_job);
+    try
+    {
+      if (item.m_callback)
+        item.m_callback->OnJobComplete(item.m_id, success, item.m_job);
+    }
+    catch (...)
+    {
+      CLog::Log(LOGERROR, "%s error processing job %s", __FUNCTION__, item.m_job->GetType());
+    }
     lock.Enter();
     Processing::iterator j = find(m_processing.begin(), m_processing.end(), job);
     if (j != m_processing.end())
index dd0e7dd..232e75c 100644 (file)
@@ -31,23 +31,6 @@ CLCDFactory::~CLCDFactory(void)
 
 ILCD* CLCDFactory::Create()
 {
-#ifdef _XBOX
-  switch (g_guiSettings.GetInt("lcd.modchip"))
-  {
-  case MODCHIP_XENIUM:
-    return new CXeniumLCD();
-    break;
-
-  case MODCHIP_SMARTXX:
-    return new CSmartXXLCD();
-    break;
-
-  case MODCHIP_XECUTER3:
-    return new CX3LCD();
-    break;
-  }
-  return new CSmartXXLCD();
-#endif
 #ifdef _LINUX
   return new XLCDproc();
 #endif
index a420c5b..080b284 100644 (file)
@@ -3,6 +3,7 @@ SRCS=AlarmClock.cpp \
      Archive.cpp \
      AsyncFileCopy.cpp \
      AutoPtrHandle.cpp \
+                Base64.cpp \
      BitstreamStats.cpp \
      CharsetConverter.cpp \
      CPUInfo.cpp \
@@ -22,6 +23,7 @@ SRCS=AlarmClock.cpp \
      HTMLUtil.cpp \
      HttpHeader.cpp \
      HttpParser.cpp \
+                HttpResponse.cpp \
      InfoLoader.cpp \
      JobManager.cpp \
      JSONVariantParser.cpp \
@@ -32,6 +34,7 @@ SRCS=AlarmClock.cpp \
      LCDFactory.cpp \
      log.cpp \
      md5.cpp \
+     Mime.cpp \
      PCMAmplifier.cpp \
      PCMRemap.cpp \
      PerformanceSample.cpp \
diff --git a/xbmc/utils/Mime.cpp b/xbmc/utils/Mime.cpp
new file mode 100644 (file)
index 0000000..c0b8cf2
--- /dev/null
@@ -0,0 +1,534 @@
+/*
+ *      Copyright (C) 2012 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <algorithm>
+
+#include "Mime.h"
+#include "FileItem.h"
+#include "StdString.h"
+#include "URIUtils.h"
+#include "music/tags/MusicInfoTag.h"
+#include "video/VideoInfoTag.h"
+
+using namespace std;
+
+map<string, string> fillMimeTypes()
+{
+  map<string, string> mimeTypes;
+
+  mimeTypes.insert(pair<string, string>("3dm",       "x-world/x-3dmf"));
+  mimeTypes.insert(pair<string, string>("3dmf",      "x-world/x-3dmf"));
+  mimeTypes.insert(pair<string, string>("a",         "application/octet-stream"));
+  mimeTypes.insert(pair<string, string>("aab",       "application/x-authorware-bin"));
+  mimeTypes.insert(pair<string, string>("aam",       "application/x-authorware-map"));
+  mimeTypes.insert(pair<string, string>("aas",       "application/x-authorware-seg"));
+  mimeTypes.insert(pair<string, string>("abc",       "text/vnd.abc"));
+  mimeTypes.insert(pair<string, string>("acgi",      "text/html"));
+  mimeTypes.insert(pair<string, string>("afl",       "video/animaflex"));
+  mimeTypes.insert(pair<string, string>("ai",        "application/postscript"));
+  mimeTypes.insert(pair<string, string>("aif",       "audio/aiff"));
+  mimeTypes.insert(pair<string, string>("aifc",      "audio/x-aiff"));
+  mimeTypes.insert(pair<string, string>("aiff",      "audio/aiff"));
+  mimeTypes.insert(pair<string, string>("aim",       "application/x-aim"));
+  mimeTypes.insert(pair<string, string>("aip",       "text/x-audiosoft-intra"));
+  mimeTypes.insert(pair<string, string>("ani",       "application/x-navi-animation"));
+  mimeTypes.insert(pair<string, string>("aos",       "application/x-nokia-9000-communicator-add-on-software"));
+  mimeTypes.insert(pair<string, string>("aps",       "application/mime"));
+  mimeTypes.insert(pair<string, string>("arc",       "application/octet-stream"));
+  mimeTypes.insert(pair<string, string>("arj",       "application/arj"));
+  mimeTypes.insert(pair<string, string>("art",       "image/x-jg"));
+  mimeTypes.insert(pair<string, string>("asf",       "video/x-ms-asf"));
+  mimeTypes.insert(pair<string, string>("asm",       "text/x-asm"));
+  mimeTypes.insert(pair<string, string>("asp",       "text/asp"));
+  mimeTypes.insert(pair<string, string>("asx",       "video/x-ms-asf"));
+  mimeTypes.insert(pair<string, string>("au",        "audio/basic"));
+  mimeTypes.insert(pair<string, string>("avi",       "video/x-msvideo"));
+  mimeTypes.insert(pair<string, string>("avs",       "video/avs-video"));
+  mimeTypes.insert(pair<string, string>("bcpio",     "application/x-bcpio"));
+  mimeTypes.insert(pair<string, string>("bin",       "application/octet-stream"));
+  mimeTypes.insert(pair<string, string>("bm",        "image/bmp"));
+  mimeTypes.insert(pair<string, string>("bmp",       "image/bmp"));
+  mimeTypes.insert(pair<string, string>("boo",       "application/book"));
+  mimeTypes.insert(pair<string, string>("book",      "application/book"));
+  mimeTypes.insert(pair<string, string>("boz",       "application/x-bzip2"));
+  mimeTypes.insert(pair<string, string>("bsh",       "application/x-bsh"));
+  mimeTypes.insert(pair<string, string>("bz",        "application/x-bzip"));
+  mimeTypes.insert(pair<string, string>("bz2",       "application/x-bzip2"));
+  mimeTypes.insert(pair<string, string>("c",         "text/plain"));
+  mimeTypes.insert(pair<string, string>("c++",       "text/plain"));
+  mimeTypes.insert(pair<string, string>("cat",       "application/vnd.ms-pki.seccat"));
+  mimeTypes.insert(pair<string, string>("cc",        "text/plain"));
+  mimeTypes.insert(pair<string, string>("ccad",      "application/clariscad"));
+  mimeTypes.insert(pair<string, string>("cco",       "application/x-cocoa"));
+  mimeTypes.insert(pair<string, string>("cdf",       "application/cdf"));
+  mimeTypes.insert(pair<string, string>("cer",       "application/pkix-cert"));
+  mimeTypes.insert(pair<string, string>("cer",       "application/x-x509-ca-cert"));
+  mimeTypes.insert(pair<string, string>("cha",       "application/x-chat"));
+  mimeTypes.insert(pair<string, string>("chat",      "application/x-chat"));
+  mimeTypes.insert(pair<string, string>("class",     "application/java"));
+  mimeTypes.insert(pair<string, string>("com",       "application/octet-stream"));
+  mimeTypes.insert(pair<string, string>("conf",      "text/plain"));
+  mimeTypes.insert(pair<string, string>("cpio",      "application/x-cpio"));
+  mimeTypes.insert(pair<string, string>("cpp",       "text/x-c"));
+  mimeTypes.insert(pair<string, string>("cpt",       "application/x-cpt"));
+  mimeTypes.insert(pair<string, string>("crl",       "application/pkcs-crl"));
+  mimeTypes.insert(pair<string, string>("crt",       "application/pkix-cert"));
+  mimeTypes.insert(pair<string, string>("csh",       "application/x-csh"));
+  mimeTypes.insert(pair<string, string>("css",       "text/css"));
+  mimeTypes.insert(pair<string, string>("cxx",       "text/plain"));
+  mimeTypes.insert(pair<string, string>("dcr",       "application/x-director"));
+  mimeTypes.insert(pair<string, string>("deepv",     "application/x-deepv"));
+  mimeTypes.insert(pair<string, string>("def",       "text/plain"));
+  mimeTypes.insert(pair<string, string>("der",       "application/x-x509-ca-cert"));
+  mimeTypes.insert(pair<string, string>("dif",       "video/x-dv"));
+  mimeTypes.insert(pair<string, string>("dir",       "application/x-director"));
+  mimeTypes.insert(pair<string, string>("dl",        "video/dl"));
+  mimeTypes.insert(pair<string, string>("doc",       "application/msword"));
+  mimeTypes.insert(pair<string, string>("docx",      "application/vnd.openxmlformats-officedocument.wordprocessingml.document"));
+  mimeTypes.insert(pair<string, string>("dot",       "application/msword"));
+  mimeTypes.insert(pair<string, string>("dp",        "application/commonground"));
+  mimeTypes.insert(pair<string, string>("drw",       "application/drafting"));
+  mimeTypes.insert(pair<string, string>("dump",      "application/octet-stream"));
+  mimeTypes.insert(pair<string, string>("dv",        "video/x-dv"));
+  mimeTypes.insert(pair<string, string>("dvi",       "application/x-dvi"));
+  mimeTypes.insert(pair<string, string>("dwf",       "model/vnd.dwf"));
+  mimeTypes.insert(pair<string, string>("dwg",       "image/vnd.dwg"));
+  mimeTypes.insert(pair<string, string>("dxf",       "image/vnd.dwg"));
+  mimeTypes.insert(pair<string, string>("dxr",       "application/x-director"));
+  mimeTypes.insert(pair<string, string>("el",        "text/x-script.elisp"));
+  mimeTypes.insert(pair<string, string>("elc",       "application/x-elc"));
+  mimeTypes.insert(pair<string, string>("env",       "application/x-envoy"));
+  mimeTypes.insert(pair<string, string>("eps",       "application/postscript"));
+  mimeTypes.insert(pair<string, string>("es",        "application/x-esrehber"));
+  mimeTypes.insert(pair<string, string>("etx",       "text/x-setext"));
+  mimeTypes.insert(pair<string, string>("evy",       "application/envoy"));
+  mimeTypes.insert(pair<string, string>("exe",       "application/octet-stream"));
+  mimeTypes.insert(pair<string, string>("f",         "text/x-fortran"));
+  mimeTypes.insert(pair<string, string>("f77",       "text/x-fortran"));
+  mimeTypes.insert(pair<string, string>("f90",       "text/x-fortran"));
+  mimeTypes.insert(pair<string, string>("fdf",       "application/vnd.fdf"));
+  mimeTypes.insert(pair<string, string>("fif",       "image/fif"));
+  mimeTypes.insert(pair<string, string>("flac",      "audio/flac"));
+  mimeTypes.insert(pair<string, string>("fli",       "video/fli"));
+  mimeTypes.insert(pair<string, string>("flo",       "image/florian"));
+  mimeTypes.insert(pair<string, string>("flv",       "video/x-flv"));
+  mimeTypes.insert(pair<string, string>("flx",       "text/vnd.fmi.flexstor"));
+  mimeTypes.insert(pair<string, string>("fmf",       "video/x-atomic3d-feature"));
+  mimeTypes.insert(pair<string, string>("for",       "text/plain"));
+  mimeTypes.insert(pair<string, string>("for",       "text/x-fortran"));
+  mimeTypes.insert(pair<string, string>("fpx",       "image/vnd.fpx"));
+  mimeTypes.insert(pair<string, string>("frl",       "application/freeloader"));
+  mimeTypes.insert(pair<string, string>("funk",      "audio/make"));
+  mimeTypes.insert(pair<string, string>("g",         "text/plain"));
+  mimeTypes.insert(pair<string, string>("g3",        "image/g3fax"));
+  mimeTypes.insert(pair<string, string>("gif",       "image/gif"));
+  mimeTypes.insert(pair<string, string>("gl",        "video/x-gl"));
+  mimeTypes.insert(pair<string, string>("gsd",       "audio/x-gsm"));
+  mimeTypes.insert(pair<string, string>("gsm",       "audio/x-gsm"));
+  mimeTypes.insert(pair<string, string>("gsp",       "application/x-gsp"));
+  mimeTypes.insert(pair<string, string>("gss",       "application/x-gss"));
+  mimeTypes.insert(pair<string, string>("gtar",      "application/x-gtar"));
+  mimeTypes.insert(pair<string, string>("gz",        "application/x-compressed"));
+  mimeTypes.insert(pair<string, string>("gzip",      "application/x-gzip"));
+  mimeTypes.insert(pair<string, string>("h",         "text/plain"));
+  mimeTypes.insert(pair<string, string>("hdf",       "application/x-hdf"));
+  mimeTypes.insert(pair<string, string>("help",      "application/x-helpfile"));
+  mimeTypes.insert(pair<string, string>("hgl",       "application/vnd.hp-hpgl"));
+  mimeTypes.insert(pair<string, string>("hh",        "text/plain"));
+  mimeTypes.insert(pair<string, string>("hlb",       "text/x-script"));
+  mimeTypes.insert(pair<string, string>("hlp",       "application/hlp"));
+  mimeTypes.insert(pair<string, string>("hpg",       "application/vnd.hp-hpgl"));
+  mimeTypes.insert(pair<string, string>("hpgl",      "application/vnd.hp-hpgl"));
+  mimeTypes.insert(pair<string, string>("hqx",       "application/binhex"));
+  mimeTypes.insert(pair<string, string>("hta",       "application/hta"));
+  mimeTypes.insert(pair<string, string>("htc",       "text/x-component"));
+  mimeTypes.insert(pair<string, string>("htm",       "text/html"));
+  mimeTypes.insert(pair<string, string>("html",      "text/html"));
+  mimeTypes.insert(pair<string, string>("htmls",     "text/html"));
+  mimeTypes.insert(pair<string, string>("htt",       "text/webviewhtml"));
+  mimeTypes.insert(pair<string, string>("htx",       "text/html"));
+  mimeTypes.insert(pair<string, string>("ice",       "x-conference/x-cooltalk"));
+  mimeTypes.insert(pair<string, string>("ico",       "image/x-icon"));
+  mimeTypes.insert(pair<string, string>("idc",       "text/plain"));
+  mimeTypes.insert(pair<string, string>("ief",       "image/ief"));
+  mimeTypes.insert(pair<string, string>("iefs",      "image/ief"));
+  mimeTypes.insert(pair<string, string>("iges",      "application/iges"));
+  mimeTypes.insert(pair<string, string>("igs",       "application/iges"));
+  mimeTypes.insert(pair<string, string>("igs",       "model/iges"));
+  mimeTypes.insert(pair<string, string>("ima",       "application/x-ima"));
+  mimeTypes.insert(pair<string, string>("imap",      "application/x-httpd-imap"));
+  mimeTypes.insert(pair<string, string>("inf",       "application/inf"));
+  mimeTypes.insert(pair<string, string>("ins",       "application/x-internett-signup"));
+  mimeTypes.insert(pair<string, string>("ip",        "application/x-ip2"));
+  mimeTypes.insert(pair<string, string>("isu",       "video/x-isvideo"));
+  mimeTypes.insert(pair<string, string>("it",        "audio/it"));
+  mimeTypes.insert(pair<string, string>("iv",        "application/x-inventor"));
+  mimeTypes.insert(pair<string, string>("ivr",       "i-world/i-vrml"));
+  mimeTypes.insert(pair<string, string>("ivy",       "application/x-livescreen"));
+  mimeTypes.insert(pair<string, string>("jam",       "audio/x-jam"));
+  mimeTypes.insert(pair<string, string>("jav",       "text/x-java-source"));
+  mimeTypes.insert(pair<string, string>("java",      "text/x-java-source"));
+  mimeTypes.insert(pair<string, string>("jcm",       "application/x-java-commerce"));
+  mimeTypes.insert(pair<string, string>("jfif",      "image/jpeg"));
+  mimeTypes.insert(pair<string, string>("jfif-tbnl", "image/jpeg"));
+  mimeTypes.insert(pair<string, string>("jpe",       "image/jpeg"));
+  mimeTypes.insert(pair<string, string>("jpeg",      "image/jpeg"));
+  mimeTypes.insert(pair<string, string>("jpg",       "image/jpeg"));
+  mimeTypes.insert(pair<string, string>("jps",       "image/x-jps"));
+  mimeTypes.insert(pair<string, string>("js",        "application/x-javascript"));
+  mimeTypes.insert(pair<string, string>("jut",       "image/jutvision"));
+  mimeTypes.insert(pair<string, string>("kar",       "music/x-karaoke"));
+  mimeTypes.insert(pair<string, string>("ksh",       "application/x-ksh"));
+  mimeTypes.insert(pair<string, string>("ksh",       "text/x-script.ksh"));
+  mimeTypes.insert(pair<string, string>("la",        "audio/nspaudio"));
+  mimeTypes.insert(pair<string, string>("lam",       "audio/x-liveaudio"));
+  mimeTypes.insert(pair<string, string>("latex",     "application/x-latex"));
+  mimeTypes.insert(pair<string, string>("lha",       "application/lha"));
+  mimeTypes.insert(pair<string, string>("lhx",       "application/octet-stream"));
+  mimeTypes.insert(pair<string, string>("list",      "text/plain"));
+  mimeTypes.insert(pair<string, string>("lma",       "audio/nspaudio"));
+  mimeTypes.insert(pair<string, string>("log",       "text/plain"));
+  mimeTypes.insert(pair<string, string>("lsp",       "application/x-lisp"));
+  mimeTypes.insert(pair<string, string>("lst",       "text/plain"));
+  mimeTypes.insert(pair<string, string>("lsx",       "text/x-la-asf"));
+  mimeTypes.insert(pair<string, string>("ltx",       "application/x-latex"));
+  mimeTypes.insert(pair<string, string>("lzh",       "application/x-lzh"));
+  mimeTypes.insert(pair<string, string>("lzx",       "application/lzx"));
+  mimeTypes.insert(pair<string, string>("m",         "text/x-m"));
+  mimeTypes.insert(pair<string, string>("m1v",       "video/mpeg"));
+  mimeTypes.insert(pair<string, string>("m2a",       "audio/mpeg"));
+  mimeTypes.insert(pair<string, string>("m2v",       "video/mpeg"));
+  mimeTypes.insert(pair<string, string>("m3u",       "audio/x-mpequrl"));
+  mimeTypes.insert(pair<string, string>("man",       "application/x-troff-man"));
+  mimeTypes.insert(pair<string, string>("map",       "application/x-navimap"));
+  mimeTypes.insert(pair<string, string>("mar",       "text/plain"));
+  mimeTypes.insert(pair<string, string>("mbd",       "application/mbedlet"));
+  mimeTypes.insert(pair<string, string>("mc$",       "application/x-magic-cap-package-1.0"));
+  mimeTypes.insert(pair<string, string>("mcd",       "application/x-mathcad"));
+  mimeTypes.insert(pair<string, string>("mcf",       "text/mcf"));
+  mimeTypes.insert(pair<string, string>("mcp",       "application/netmc"));
+  mimeTypes.insert(pair<string, string>("me",        "application/x-troff-me"));
+  mimeTypes.insert(pair<string, string>("mht",       "message/rfc822"));
+  mimeTypes.insert(pair<string, string>("mhtml",     "message/rfc822"));
+  mimeTypes.insert(pair<string, string>("mid",       "audio/midi"));
+  mimeTypes.insert(pair<string, string>("midi",      "audio/midi"));
+  mimeTypes.insert(pair<string, string>("mif",       "application/x-mif"));
+  mimeTypes.insert(pair<string, string>("mime",      "message/rfc822"));
+  mimeTypes.insert(pair<string, string>("mjf",       "audio/x-vnd.audioexplosion.mjuicemediafile"));
+  mimeTypes.insert(pair<string, string>("mjpg",      "video/x-motion-jpeg"));
+  mimeTypes.insert(pair<string, string>("mka",       "audio/x-matroska"));
+  mimeTypes.insert(pair<string, string>("mkv",       "video/x-matroska"));
+  mimeTypes.insert(pair<string, string>("mm",        "application/x-meme"));
+  mimeTypes.insert(pair<string, string>("mme",       "application/base64"));
+  mimeTypes.insert(pair<string, string>("mod",       "audio/mod"));
+  mimeTypes.insert(pair<string, string>("moov",      "video/quicktime"));
+  mimeTypes.insert(pair<string, string>("mov",       "video/quicktime"));
+  mimeTypes.insert(pair<string, string>("movie",     "video/x-sgi-movie"));
+  mimeTypes.insert(pair<string, string>("mp2",       "audio/mpeg"));
+  mimeTypes.insert(pair<string, string>("mp3",       "audio/mpeg3"));
+  mimeTypes.insert(pair<string, string>("mp4",       "video/mp4"));
+  mimeTypes.insert(pair<string, string>("mpa",       "audio/mpeg"));
+  mimeTypes.insert(pair<string, string>("mpc",       "application/x-project"));
+  mimeTypes.insert(pair<string, string>("mpe",       "video/mpeg"));
+  mimeTypes.insert(pair<string, string>("mpeg",      "video/mpeg"));
+  mimeTypes.insert(pair<string, string>("mpg",       "video/mpeg"));
+  mimeTypes.insert(pair<string, string>("mpga",      "audio/mpeg"));
+  mimeTypes.insert(pair<string, string>("mpp",       "application/vnd.ms-project"));
+  mimeTypes.insert(pair<string, string>("mpt",       "application/x-project"));
+  mimeTypes.insert(pair<string, string>("mpv",       "application/x-project"));
+  mimeTypes.insert(pair<string, string>("mpx",       "application/x-project"));
+  mimeTypes.insert(pair<string, string>("mrc",       "application/marc"));
+  mimeTypes.insert(pair<string, string>("ms",        "application/x-troff-ms"));
+  mimeTypes.insert(pair<string, string>("mv",        "video/x-sgi-movie"));
+  mimeTypes.insert(pair<string, string>("my",        "audio/make"));
+  mimeTypes.insert(pair<string, string>("mzz",       "application/x-vnd.audioexplosion.mzz"));
+  mimeTypes.insert(pair<string, string>("nap",       "image/naplps"));
+  mimeTypes.insert(pair<string, string>("naplps",    "image/naplps"));
+  mimeTypes.insert(pair<string, string>("nc",        "application/x-netcdf"));
+  mimeTypes.insert(pair<string, string>("ncm",       "application/vnd.nokia.configuration-message"));
+  mimeTypes.insert(pair<string, string>("nfo",       "text/xml"));
+  mimeTypes.insert(pair<string, string>("nif",       "image/x-niff"));
+  mimeTypes.insert(pair<string, string>("niff",      "image/x-niff"));
+  mimeTypes.insert(pair<string, string>("nix",       "application/x-mix-transfer"));
+  mimeTypes.insert(pair<string, string>("nsc",       "application/x-conference"));
+  mimeTypes.insert(pair<string, string>("nvd",       "application/x-navidoc"));
+  mimeTypes.insert(pair<string, string>("o",         "application/octet-stream"));
+  mimeTypes.insert(pair<string, string>("oda",       "application/oda"));
+  mimeTypes.insert(pair<string, string>("ogg",       "audio/ogg"));
+  mimeTypes.insert(pair<string, string>("omc",       "application/x-omc"));
+  mimeTypes.insert(pair<string, string>("omcd",      "application/x-omcdatamaker"));
+  mimeTypes.insert(pair<string, string>("omcr",      "application/x-omcregerator"));
+  mimeTypes.insert(pair<string, string>("p",         "text/x-pascal"));
+  mimeTypes.insert(pair<string, string>("p10",       "application/pkcs10"));
+  mimeTypes.insert(pair<string, string>("p12",       "application/pkcs-12"));
+  mimeTypes.insert(pair<string, string>("p7a",       "application/x-pkcs7-signature"));
+  mimeTypes.insert(pair<string, string>("p7c",       "application/pkcs7-mime"));
+  mimeTypes.insert(pair<string, string>("p7m",       "application/pkcs7-mime"));
+  mimeTypes.insert(pair<string, string>("p7r",       "application/x-pkcs7-certreqresp"));
+  mimeTypes.insert(pair<string, string>("p7s",       "application/pkcs7-signature"));
+  mimeTypes.insert(pair<string, string>("part",      "application/pro_eng"));
+  mimeTypes.insert(pair<string, string>("pas",       "text/pascal"));
+  mimeTypes.insert(pair<string, string>("pbm",       "image/x-portable-bitmap"));
+  mimeTypes.insert(pair<string, string>("pcl",       "application/vnd.hp-pcl"));
+  mimeTypes.insert(pair<string, string>("pct",       "image/x-pict"));
+  mimeTypes.insert(pair<string, string>("pcx",       "image/x-pcx"));
+  mimeTypes.insert(pair<string, string>("pdb",       "chemical/x-pdb"));
+  mimeTypes.insert(pair<string, string>("pdf",       "application/pdf"));
+  mimeTypes.insert(pair<string, string>("pfunk",     "audio/make.my.funk"));
+  mimeTypes.insert(pair<string, string>("pgm",       "image/x-portable-greymap"));
+  mimeTypes.insert(pair<string, string>("pic",       "image/pict"));
+  mimeTypes.insert(pair<string, string>("pict",      "image/pict"));
+  mimeTypes.insert(pair<string, string>("pkg",       "application/x-newton-compatible-pkg"));
+  mimeTypes.insert(pair<string, string>("pko",       "application/vnd.ms-pki.pko"));
+  mimeTypes.insert(pair<string, string>("pl",        "text/x-script.perl"));
+  mimeTypes.insert(pair<string, string>("plx",       "application/x-pixclscript"));
+  mimeTypes.insert(pair<string, string>("pm",        "text/x-script.perl-module"));
+  mimeTypes.insert(pair<string, string>("pm4",       "application/x-pagemaker"));
+  mimeTypes.insert(pair<string, string>("pm5",       "application/x-pagemaker"));
+  mimeTypes.insert(pair<string, string>("png",       "image/png"));
+  mimeTypes.insert(pair<string, string>("pnm",       "application/x-portable-anymap"));
+  mimeTypes.insert(pair<string, string>("pot",       "application/vnd.ms-powerpoint"));
+  mimeTypes.insert(pair<string, string>("pov",       "model/x-pov"));
+  mimeTypes.insert(pair<string, string>("ppa",       "application/vnd.ms-powerpoint"));
+  mimeTypes.insert(pair<string, string>("ppm",       "image/x-portable-pixmap"));
+  mimeTypes.insert(pair<string, string>("pps",       "application/mspowerpoint"));
+  mimeTypes.insert(pair<string, string>("ppt",       "application/mspowerpoint"));
+  mimeTypes.insert(pair<string, string>("ppz",       "application/mspowerpoint"));
+  mimeTypes.insert(pair<string, string>("pre",       "application/x-freelance"));
+  mimeTypes.insert(pair<string, string>("prt",       "application/pro_eng"));
+  mimeTypes.insert(pair<string, string>("ps",        "application/postscript"));
+  mimeTypes.insert(pair<string, string>("psd",       "application/octet-stream"));
+  mimeTypes.insert(pair<string, string>("pvu",       "paleovu/x-pv"));
+  mimeTypes.insert(pair<string, string>("pwz",       "application/vnd.ms-powerpoint"));
+  mimeTypes.insert(pair<string, string>("py",        "text/x-script.phyton"));
+  mimeTypes.insert(pair<string, string>("pyc",       "applicaiton/x-bytecode.python"));
+  mimeTypes.insert(pair<string, string>("qcp",       "audio/vnd.qcelp"));
+  mimeTypes.insert(pair<string, string>("qd3",       "x-world/x-3dmf"));
+  mimeTypes.insert(pair<string, string>("qd3d",      "x-world/x-3dmf"));
+  mimeTypes.insert(pair<string, string>("qif",       "image/x-quicktime"));
+  mimeTypes.insert(pair<string, string>("qt",        "video/quicktime"));
+  mimeTypes.insert(pair<string, string>("qtc",       "video/x-qtc"));
+  mimeTypes.insert(pair<string, string>("qti",       "image/x-quicktime"));
+  mimeTypes.insert(pair<string, string>("qtif",      "image/x-quicktime"));
+  mimeTypes.insert(pair<string, string>("ra",        "audio/x-realaudio"));
+  mimeTypes.insert(pair<string, string>("ram",       "audio/x-pn-realaudio"));
+  mimeTypes.insert(pair<string, string>("ras",       "image/cmu-raster"));
+  mimeTypes.insert(pair<string, string>("rast",      "image/cmu-raster"));
+  mimeTypes.insert(pair<string, string>("rexx",      "text/x-script.rexx"));
+  mimeTypes.insert(pair<string, string>("rf",        "image/vnd.rn-realflash"));
+  mimeTypes.insert(pair<string, string>("rgb",       "image/x-rgb"));
+  mimeTypes.insert(pair<string, string>("rm",        "audio/x-pn-realaudio"));
+  mimeTypes.insert(pair<string, string>("rmi",       "audio/mid"));
+  mimeTypes.insert(pair<string, string>("rmm",       "audio/x-pn-realaudio"));
+  mimeTypes.insert(pair<string, string>("rmp",       "audio/x-pn-realaudio"));
+  mimeTypes.insert(pair<string, string>("rng",       "application/ringing-tones"));
+  mimeTypes.insert(pair<string, string>("rnx",       "application/vnd.rn-realplayer"));
+  mimeTypes.insert(pair<string, string>("roff",      "application/x-troff"));
+  mimeTypes.insert(pair<string, string>("rp",        "image/vnd.rn-realpix"));
+  mimeTypes.insert(pair<string, string>("rpm",       "audio/x-pn-realaudio-plugin"));
+  mimeTypes.insert(pair<string, string>("rt",        "text/richtext"));
+  mimeTypes.insert(pair<string, string>("rtf",       "text/richtext"));
+  mimeTypes.insert(pair<string, string>("rtx",       "text/richtext"));
+  mimeTypes.insert(pair<string, string>("rv",        "video/vnd.rn-realvideo"));
+  mimeTypes.insert(pair<string, string>("s",         "text/x-asm"));
+  mimeTypes.insert(pair<string, string>("s3m",       "audio/s3m"));
+  mimeTypes.insert(pair<string, string>("saveme",    "application/octet-stream"));
+  mimeTypes.insert(pair<string, string>("sbk",       "application/x-tbook"));
+  mimeTypes.insert(pair<string, string>("scm",       "video/x-scm"));
+  mimeTypes.insert(pair<string, string>("sdml",      "text/plain"));
+  mimeTypes.insert(pair<string, string>("sdp",       "application/sdp"));
+  mimeTypes.insert(pair<string, string>("sdr",       "application/sounder"));
+  mimeTypes.insert(pair<string, string>("sea",       "application/sea"));
+  mimeTypes.insert(pair<string, string>("set",       "application/set"));
+  mimeTypes.insert(pair<string, string>("sgm",       "text/sgml"));
+  mimeTypes.insert(pair<string, string>("sgml",      "text/sgml"));
+  mimeTypes.insert(pair<string, string>("sh",        "text/x-script.sh"));
+  mimeTypes.insert(pair<string, string>("shar",      "application/x-bsh"));
+  mimeTypes.insert(pair<string, string>("shtml",     "text/html"));
+  mimeTypes.insert(pair<string, string>("shtml",     "text/x-server-parsed-html"));
+  mimeTypes.insert(pair<string, string>("sid",       "audio/x-psid"));
+  mimeTypes.insert(pair<string, string>("sit",       "application/x-sit"));
+  mimeTypes.insert(pair<string, string>("sit",       "application/x-stuffit"));
+  mimeTypes.insert(pair<string, string>("skd",       "application/x-koan"));
+  mimeTypes.insert(pair<string, string>("skm",       "application/x-koan"));
+  mimeTypes.insert(pair<string, string>("skp",       "application/x-koan"));
+  mimeTypes.insert(pair<string, string>("skt",       "application/x-koan"));
+  mimeTypes.insert(pair<string, string>("sl",        "application/x-seelogo"));
+  mimeTypes.insert(pair<string, string>("smi",       "application/smil"));
+  mimeTypes.insert(pair<string, string>("smil",      "application/smil"));
+  mimeTypes.insert(pair<string, string>("snd",       "audio/basic"));
+  mimeTypes.insert(pair<string, string>("sol",       "application/solids"));
+  mimeTypes.insert(pair<string, string>("spc",       "text/x-speech"));
+  mimeTypes.insert(pair<string, string>("spl",       "application/futuresplash"));
+  mimeTypes.insert(pair<string, string>("spr",       "application/x-sprite"));
+  mimeTypes.insert(pair<string, string>("sprite",    "application/x-sprite"));
+  mimeTypes.insert(pair<string, string>("src",       "application/x-wais-source"));
+  mimeTypes.insert(pair<string, string>("ssi",       "text/x-server-parsed-html"));
+  mimeTypes.insert(pair<string, string>("ssm",       "application/streamingmedia"));
+  mimeTypes.insert(pair<string, string>("sst",       "application/vnd.ms-pki.certstore"));
+  mimeTypes.insert(pair<string, string>("step",      "application/step"));
+  mimeTypes.insert(pair<string, string>("stl",       "application/sla"));
+  mimeTypes.insert(pair<string, string>("stp",       "application/step"));
+  mimeTypes.insert(pair<string, string>("sv4cpio",   "application/x-sv4cpio"));
+  mimeTypes.insert(pair<string, string>("sv4crc",    "application/x-sv4crc"));
+  mimeTypes.insert(pair<string, string>("svf",       "image/vnd.dwg"));
+  mimeTypes.insert(pair<string, string>("svr",       "application/x-world"));
+  mimeTypes.insert(pair<string, string>("swf",       "application/x-shockwave-flash"));
+  mimeTypes.insert(pair<string, string>("t",         "application/x-troff"));
+  mimeTypes.insert(pair<string, string>("talk",      "text/x-speech"));
+  mimeTypes.insert(pair<string, string>("tar",       "application/x-tar"));
+  mimeTypes.insert(pair<string, string>("tbk",       "application/toolbook"));
+  mimeTypes.insert(pair<string, string>("tcl",       "text/x-script.tcl"));
+  mimeTypes.insert(pair<string, string>("tcsh",      "text/x-script.tcsh"));
+  mimeTypes.insert(pair<string, string>("tex",       "application/x-tex"));
+  mimeTypes.insert(pair<string, string>("texi",      "application/x-texinfo"));
+  mimeTypes.insert(pair<string, string>("texinfo",   "application/x-texinfo"));
+  mimeTypes.insert(pair<string, string>("text",      "text/plain"));
+  mimeTypes.insert(pair<string, string>("tgz",       "application/x-compressed"));
+  mimeTypes.insert(pair<string, string>("tif",       "image/tiff"));
+  mimeTypes.insert(pair<string, string>("tr",        "application/x-troff"));
+  mimeTypes.insert(pair<string, string>("ts",        "video/mp2t"));
+  mimeTypes.insert(pair<string, string>("tsi",       "audio/tsp-audio"));
+  mimeTypes.insert(pair<string, string>("tsp",       "audio/tsplayer"));
+  mimeTypes.insert(pair<string, string>("tsv",       "text/tab-separated-values"));
+  mimeTypes.insert(pair<string, string>("turbot",    "image/florian"));
+  mimeTypes.insert(pair<string, string>("txt",       "text/plain"));
+  mimeTypes.insert(pair<string, string>("uil",       "text/x-uil"));
+  mimeTypes.insert(pair<string, string>("uni",       "text/uri-list"));
+  mimeTypes.insert(pair<string, string>("unis",      "text/uri-list"));
+  mimeTypes.insert(pair<string, string>("unv",       "application/i-deas"));
+  mimeTypes.insert(pair<string, string>("uri",       "text/uri-list"));
+  mimeTypes.insert(pair<string, string>("uris",      "text/uri-list"));
+  mimeTypes.insert(pair<string, string>("ustar",     "application/x-ustar"));
+  mimeTypes.insert(pair<string, string>("uu",        "text/x-uuencode"));
+  mimeTypes.insert(pair<string, string>("uue",       "text/x-uuencode"));
+  mimeTypes.insert(pair<string, string>("vcd",       "application/x-cdlink"));
+  mimeTypes.insert(pair<string, string>("vcs",       "text/x-vcalendar"));
+  mimeTypes.insert(pair<string, string>("vda",       "application/vda"));
+  mimeTypes.insert(pair<string, string>("vdo",       "video/vdo"));
+  mimeTypes.insert(pair<string, string>("vew",       "application/groupwise"));
+  mimeTypes.insert(pair<string, string>("viv",       "video/vivo"));
+  mimeTypes.insert(pair<string, string>("vivo",      "video/vivo"));
+  mimeTypes.insert(pair<string, string>("vmd",       "application/vocaltec-media-desc"));
+  mimeTypes.insert(pair<string, string>("vmf",       "application/vocaltec-media-file"));
+  mimeTypes.insert(pair<string, string>("voc",       "audio/voc"));
+  mimeTypes.insert(pair<string, string>("vos",       "video/vosaic"));
+  mimeTypes.insert(pair<string, string>("vox",       "audio/voxware"));
+  mimeTypes.insert(pair<string, string>("vqe",       "audio/x-twinvq-plugin"));
+  mimeTypes.insert(pair<string, string>("vqf",       "audio/x-twinvq"));
+  mimeTypes.insert(pair<string, string>("vql",       "audio/x-twinvq-plugin"));
+  mimeTypes.insert(pair<string, string>("vrml",      "application/x-vrml"));
+  mimeTypes.insert(pair<string, string>("vrt",       "x-world/x-vrt"));
+  mimeTypes.insert(pair<string, string>("vsd",       "application/x-visio"));
+  mimeTypes.insert(pair<string, string>("vst",       "application/x-visio"));
+  mimeTypes.insert(pair<string, string>("vsw",       "application/x-visio"));
+  mimeTypes.insert(pair<string, string>("w60",       "application/wordperfect6.0"));
+  mimeTypes.insert(pair<string, string>("w61",       "application/wordperfect6.1"));
+  mimeTypes.insert(pair<string, string>("w6w",       "application/msword"));
+  mimeTypes.insert(pair<string, string>("wav",       "audio/wav"));
+  mimeTypes.insert(pair<string, string>("wb1",       "application/x-qpro"));
+  mimeTypes.insert(pair<string, string>("wbmp",      "image/vnd.wap.wbmp"));
+  mimeTypes.insert(pair<string, string>("web",       "application/vnd.xara"));
+  mimeTypes.insert(pair<string, string>("wiz",       "application/msword"));
+  mimeTypes.insert(pair<string, string>("wk1",       "application/x-123"));
+  mimeTypes.insert(pair<string, string>("wma",       "audio/x-ms-wma"));
+  mimeTypes.insert(pair<string, string>("wmf",       "windows/metafile"));
+  mimeTypes.insert(pair<string, string>("wml",       "text/vnd.wap.wml"));
+  mimeTypes.insert(pair<string, string>("wmlc",      "application/vnd.wap.wmlc"));
+  mimeTypes.insert(pair<string, string>("wmls",      "text/vnd.wap.wmlscript"));
+  mimeTypes.insert(pair<string, string>("wmlsc",     "application/vnd.wap.wmlscriptc"));
+  mimeTypes.insert(pair<string, string>("wmv",       "video/x-ms-wmv"));
+  mimeTypes.insert(pair<string, string>("word",      "application/msword"));
+  mimeTypes.insert(pair<string, string>("wp",        "application/wordperfect"));
+  mimeTypes.insert(pair<string, string>("wp5",       "application/wordperfect"));
+  mimeTypes.insert(pair<string, string>("wp6",       "application/wordperfect"));
+  mimeTypes.insert(pair<string, string>("wpd",       "application/wordperfect"));
+  mimeTypes.insert(pair<string, string>("wq1",       "application/x-lotus"));
+  mimeTypes.insert(pair<string, string>("wri",       "application/mswrite"));
+  mimeTypes.insert(pair<string, string>("wrl",       "model/vrml"));
+  mimeTypes.insert(pair<string, string>("wrz",       "model/vrml"));
+  mimeTypes.insert(pair<string, string>("wsc",       "text/scriplet"));
+  mimeTypes.insert(pair<string, string>("wsrc",      "application/x-wais-source"));
+  mimeTypes.insert(pair<string, string>("wtk",       "application/x-wintalk"));
+  mimeTypes.insert(pair<string, string>("xbm",       "image/xbm"));
+  mimeTypes.insert(pair<string, string>("xdr",       "video/x-amt-demorun"));
+  mimeTypes.insert(pair<string, string>("xgz",       "xgl/drawing"));
+  mimeTypes.insert(pair<string, string>("xif",       "image/vnd.xiff"));
+  mimeTypes.insert(pair<string, string>("xl",        "application/excel"));
+  mimeTypes.insert(pair<string, string>("xla",       "application/excel"));
+  mimeTypes.insert(pair<string, string>("xlb",       "application/excel"));
+  mimeTypes.insert(pair<string, string>("xlc",       "application/excel"));
+  mimeTypes.insert(pair<string, string>("xld",       "application/excel"));
+  mimeTypes.insert(pair<string, string>("xlk",       "application/excel"));
+  mimeTypes.insert(pair<string, string>("xll",       "application/excel"));
+  mimeTypes.insert(pair<string, string>("xlm",       "application/excel"));
+  mimeTypes.insert(pair<string, string>("xls",       "application/excel"));
+  mimeTypes.insert(pair<string, string>("xlsx",      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
+  mimeTypes.insert(pair<string, string>("xlt",       "application/excel"));
+  mimeTypes.insert(pair<string, string>("xlv",       "application/excel"));
+  mimeTypes.insert(pair<string, string>("xlw",       "application/excel"));
+  mimeTypes.insert(pair<string, string>("xm",        "audio/xm"));
+  mimeTypes.insert(pair<string, string>("xml",       "text/xml"));
+  mimeTypes.insert(pair<string, string>("xmz",       "xgl/movie"));
+  mimeTypes.insert(pair<string, string>("xpix",      "application/x-vnd.ls-xpix"));
+  mimeTypes.insert(pair<string, string>("xpm",       "image/xpm"));
+  mimeTypes.insert(pair<string, string>("x-png",     "image/png"));
+  mimeTypes.insert(pair<string, string>("xsr",       "video/x-amt-showrun"));
+  mimeTypes.insert(pair<string, string>("xwd",       "image/x-xwd"));
+  mimeTypes.insert(pair<string, string>("xyz",       "chemical/x-pdb"));
+  mimeTypes.insert(pair<string, string>("z",         "application/x-compressed"));
+  mimeTypes.insert(pair<string, string>("zip",       "application/zip"));
+  mimeTypes.insert(pair<string, string>("zoo",       "application/octet-stream"));
+  mimeTypes.insert(pair<string, string>("zsh",       "text/x-script.zsh"));
+
+  return mimeTypes;
+}
+
+map<string, string> CMime::m_mimetypes = fillMimeTypes();
+
+string CMime::GetMimeType(const string &extension)
+{
+  if (extension.empty())
+    return "";
+
+  string ext = extension;
+  size_t posNotPoint = ext.find_first_not_of('.');
+  if (posNotPoint != string::npos && posNotPoint > 0)
+    ext = extension.substr(posNotPoint);
+  transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
+
+  map<string, string>::const_iterator it = m_mimetypes.find(ext);
+  if (it != m_mimetypes.end())
+    return it->second;
+
+  return "";
+}
+
+string CMime::GetMimeType(const CFileItem &item)
+{
+  CStdString path = item.GetPath();
+  if (item.HasVideoInfoTag() && !item.GetVideoInfoTag()->GetPath().IsEmpty())
+    path = item.GetVideoInfoTag()->GetPath();
+  else if (item.HasMusicInfoTag() && !item.GetMusicInfoTag()->GetURL().IsEmpty())
+    path = item.GetMusicInfoTag()->GetURL();
+
+  return GetMimeType(URIUtils::GetExtension(path));
+}
diff --git a/xbmc/utils/Mime.h b/xbmc/utils/Mime.h
new file mode 100644 (file)
index 0000000..3b51402
--- /dev/null
@@ -0,0 +1,36 @@
+#pragma once
+/*
+ *      Copyright (C) 2012 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <string>
+#include <map>
+
+class CFileItem;
+
+class CMime
+{
+public:
+  static std::string GetMimeType(const std::string &extension);
+  static std::string GetMimeType(const CFileItem &item);
+
+private:
+  static std::map<std::string, std::string> m_mimetypes;
+};
index 9cc3a04..718fb42 100644 (file)
@@ -107,10 +107,21 @@ bool CRecentlyAddedJob::UpdateVideo()
       CStdString   EpisodeNo;
       CStdString   value;
       CStdString   strRating;
+      CStdString   strSeason;
       EpisodeNo.Format("s%02de%02d", EpisodeSeason, EpisodeNumber);
       value.Format("%i", i + 1);
       strRating.Format("%.1f", item->GetVideoInfoTag()->m_fRating);
-      
+
+      if (EpisodeSeason == 0)
+        strSeason = g_localizeStrings.Get(20381);
+      else
+        strSeason.Format(g_localizeStrings.Get(20358), EpisodeSeason);
+
+      CFileItem season(strSeason);
+      season.GetVideoInfoTag()->m_strPath = item->GetVideoInfoTag()->m_strShowPath;
+
+      CFileItem show(item->GetVideoInfoTag()->m_strShowPath, true);
+
       home->SetProperty("LatestEpisode." + value + ".ShowTitle"     , item->GetVideoInfoTag()->m_strShowTitle);
       home->SetProperty("LatestEpisode." + value + ".EpisodeTitle"  , item->GetVideoInfoTag()->m_strTitle);
       home->SetProperty("LatestEpisode." + value + ".Rating"        , strRating);      
@@ -124,6 +135,8 @@ bool CRecentlyAddedJob::UpdateVideo()
         m_thumbLoader.LoadItem(item.get());
 
       home->SetProperty("LatestEpisode." + value + ".Thumb"         , item->GetThumbnailImage());
+      home->SetProperty("LatestEpisode." + value + ".ShowThumb"     , show.GetCachedVideoThumb());
+      home->SetProperty("LatestEpisode." + value + ".SeasonThumb"   , season.GetCachedSeasonThumb());
       home->SetProperty("LatestEpisode." + value + ".Fanart"        , item->GetCachedFanart());
     }
   } 
@@ -140,6 +153,8 @@ bool CRecentlyAddedJob::UpdateVideo()
     home->SetProperty("LatestEpisode." + value + ".EpisodeNumber" , "");
     home->SetProperty("LatestEpisode." + value + ".Path"          , "");
     home->SetProperty("LatestEpisode." + value + ".Thumb"         , "");
+    home->SetProperty("LatestEpisode." + value + ".ShowThumb"     , "");
+    home->SetProperty("LatestEpisode." + value + ".SeasonThumb"   , "");
     home->SetProperty("LatestEpisode." + value + ".Fanart"        , "");
   }  
 
index 18fcdb4..808a8fb 100644 (file)
@@ -26,7 +26,7 @@
 #include "CharsetConverter.h"
 #include "URL.h"
 #include "filesystem/File.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 #ifdef __APPLE__
 #include "CocoaInterface.h"
 #endif
@@ -126,7 +126,7 @@ void CRssReader::Process()
     m_strFeed[iFeed] = "";
     m_strColors[iFeed] = "";
 
-    CFileCurl http;
+    CCurlFile http;
     http.SetUserAgent(g_settings.m_userAgent);
     http.SetTimeout(2);
     CStdString strXML;
index 04e09b6..e722ea5 100644 (file)
@@ -25,8 +25,8 @@
 #include "HTMLUtil.h"
 #include "CharsetConverter.h"
 #include "URL.h"
-#include "filesystem/FileCurl.h"
-#include "filesystem/FileZip.h"
+#include "filesystem/CurlFile.h"
+#include "filesystem/ZipFile.h"
 #include "pictures/Picture.h"
 #include "URIUtils.h"
 
@@ -175,7 +175,7 @@ const CScraperUrl::SUrlEntry CScraperUrl::GetSeasonThumb(int season) const
   return result;
 }
 
-bool CScraperUrl::Get(const SUrlEntry& scrURL, std::string& strHTML, XFILE::CFileCurl& http, const CStdString& cacheContext)
+bool CScraperUrl::Get(const SUrlEntry& scrURL, std::string& strHTML, XFILE::CCurlFile& http, const CStdString& cacheContext)
 {
   CURL url(scrURL.m_url);
   http.SetReferer(scrURL.m_spoof);
@@ -222,7 +222,7 @@ bool CScraperUrl::Get(const SUrlEntry& scrURL, std::string& strHTML, XFILE::CFil
 
   if (scrURL.m_url.Find(".zip") > -1 )
   {
-    XFILE::CFileZip file;
+    XFILE::CZipFile file;
     CStdString strBuffer;
     int iSize = file.UnpackFromMemory(strBuffer,strHTML,scrURL.m_isgz);
     if (iSize)
@@ -265,7 +265,7 @@ bool CScraperUrl::DownloadThumbnail(const CStdString &thumb, const CScraperUrl::
     return false;
   }
 
-  XFILE::CFileCurl http;
+  XFILE::CCurlFile http;
   http.SetReferer(entry.m_spoof);
   CStdString thumbData;
   if (http.Get(entry.m_url, thumbData))
index abe34e9..82db709 100644 (file)
@@ -26,7 +26,7 @@
 #include "StdString.h"
 
 class TiXmlElement;
-namespace XFILE { class CFileCurl; }
+namespace XFILE { class CCurlFile; }
 
 class CScraperUrl
 {
@@ -73,7 +73,7 @@ public:
    */
   void GetThumbURLs(std::vector<CStdString> &thumbs, int season = -1) const;
   void Clear();
-  static bool Get(const SUrlEntry&, std::string&, XFILE::CFileCurl& http,
+  static bool Get(const SUrlEntry&, std::string&, XFILE::CCurlFile& http,
                  const CStdString& cacheContext);
   static bool DownloadThumbnail(const CStdString &thumb, const SUrlEntry& entry);
 
index f4aacd1..286aa0d 100644 (file)
@@ -28,7 +28,7 @@
 #include <sys/utsname.h>
 #endif
 #include "GUIInfoManager.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 #include "network/Network.h"
 #include "Application.h"
 #include "windowing/WindowingFactory.h"
@@ -81,7 +81,7 @@ CStdString CSysInfoJob::GetCPUFreqInfo()
 CSysData::INTERNET_STATE CSysInfoJob::GetInternetState()
 {
   // Internet connection state!
-  XFILE::CFileCurl http;
+  XFILE::CCurlFile http;
   if (http.IsInternet())
     return CSysData::CONNECTED;
   if (http.IsInternet(false))
index c15b634..91e7dbe 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "TuxBoxUtil.h"
 #include "URIUtils.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 #include "dialogs/GUIDialogContextMenu.h"
 #include "Application.h"
 #include "GUIInfoManager.h"
@@ -439,7 +439,7 @@ bool CTuxBoxUtil::ZapToUrl(CURL url, CStdString strOptions, int ipoint)
   }
 
   //Send ZAP Command
-  CFileCurl http;
+  CCurlFile http;
   if(http.Open(strZapUrl+strPostUrl))
   {
     //DEBUG LOG
@@ -611,7 +611,7 @@ bool CTuxBoxUtil::GetZapUrl(const CStdString& strPath, CFileItem &items )
 bool CTuxBoxUtil::InitZapstream(const CStdString& strPath)
 {
   CURL url(strPath);
-  CFileCurl http;
+  CCurlFile http;
   int iTryConnect = 0;
   int iTimeout = 2;
 
@@ -655,7 +655,7 @@ bool CTuxBoxUtil::InitZapstream(const CStdString& strPath)
 bool CTuxBoxUtil::SetAudioChannel( const CStdString& strPath, const AUDIOCHANNEL& sAC )
 {
   CURL url(strPath);
-  CFileCurl http;
+  CCurlFile http;
   int iTryConnect = 0;
   int iTimeout = 2;
 
@@ -723,7 +723,7 @@ bool CTuxBoxUtil::GetHttpXML(CURL url,CStdString strRequestType)
   url.SetFileName("");
 
   //Open
-  CFileCurl http;
+  CCurlFile http;
   http.SetTimeout(20);
   if(http.Open(url))
   {
index b32ab10..a3a4023 100644 (file)
@@ -361,7 +361,12 @@ CStdString URIUtils::SubstitutePath(const CStdString& strPath)
       i != g_advancedSettings.m_pathSubstitutions.end(); i++)
   {
     if (strncmp(strPath.c_str(), i->first.c_str(), i->first.size()) == 0)
-      return URIUtils::AddFileToFolder(i->second, strPath.Mid(i->first.size()));
+    {
+      if (strPath.size() > i->first.size())
+        return URIUtils::AddFileToFolder(i->second, strPath.Mid(i->first.size()));
+      else
+        return i->second;
+    }
   }
   return strPath;
 }
@@ -498,7 +503,7 @@ bool URIUtils::IsHD(const CStdString& strFileName)
   if (IsInArchive(strFileName))
     return IsHD(url.GetHostName());
 
-  return url.IsLocal();
+  return url.GetProtocol().IsEmpty() || url.GetProtocol() == "file";
 }
 
 bool URIUtils::IsDVD(const CStdString& strFile)
index 77d9359..6a896a3 100644 (file)
@@ -61,7 +61,7 @@ FIXME'S
 */
 
 #define WEATHER_BASE_PATH "special://temp/weather/"
-#define WEATHER_ICON_PATH "special://temp/weather/128x128/"
+#define WEATHER_ICON_PATH "special://temp/weather/"
 #define WEATHER_SOURCE_FILE "special://xbmc/media/weather.zip"
 
 bool CWeatherJob::m_imagesOkay = false;
index d55f402..c4085b2 100644 (file)
@@ -21,7 +21,6 @@
 
 #include "XMLUtils.h"
 #include "URL.h"
-#include "filesystem/SpecialProtocol.h"
 #include "StringUtils.h"
 #ifdef _WIN32
 #include "PlatformDefs.h" //for strcasecmp
@@ -196,8 +195,6 @@ bool XMLUtils::GetPath(const TiXmlNode* pRootNode, const char* strTag, CStdStrin
   const TiXmlElement* pElement = pRootNode->FirstChildElement(strTag);
   if (!pElement) return false;
 
-  int pathVersion = 0;
-  pElement->Attribute("pathversion", &pathVersion);
   const char* encoded = pElement->Attribute("urlencoded");
   const TiXmlNode* pNode = pElement->FirstChild();
   if (pNode != NULL)
@@ -205,7 +202,6 @@ bool XMLUtils::GetPath(const TiXmlNode* pRootNode, const char* strTag, CStdStrin
     strStringValue = pNode->Value();
     if (encoded && strcasecmp(encoded,"yes") == 0)
       CURL::Decode(strStringValue);
-    strStringValue = CSpecialProtocol::ReplaceOldPath(strStringValue, pathVersion);
     return true;
   }
   strStringValue.Empty();
@@ -267,7 +263,7 @@ void XMLUtils::SetHex(TiXmlNode* pRootNode, const char *strTag, uint32_t value)
 void XMLUtils::SetPath(TiXmlNode* pRootNode, const char *strTag, const CStdString& strValue)
 {
   TiXmlElement newElement(strTag);
-  newElement.SetAttribute("pathversion", CSpecialProtocol::path_version);
+  newElement.SetAttribute("pathversion", path_version);
   TiXmlNode *pNewNode = pRootNode->InsertEndChild(newElement);
   if (pNewNode)
   {
index 8aa9266..fe02b99 100644 (file)
@@ -66,5 +66,7 @@ public:
   static void SetHex(TiXmlNode* pRootNode, const char *strTag, uint32_t value);
   static void SetPath(TiXmlNode* pRootNode, const char *strTag, const CStdString& strValue);
   static void SetLong(TiXmlNode* pRootNode, const char *strTag, long iValue);
+
+  static const int path_version = 1;
 };
 
index 0e810a7..3d77c68 100644 (file)
@@ -527,3 +527,8 @@ copy_last_3_and_return:
 
 #endif    /* __ARM_ARCH__ < 7 */
 #endif
+
+#if defined(__linux__) && defined(__ELF__)
+/* we don't need an executable stack */
+.section .note.GNU-stack,"",%progbits
+#endif
index 63a94b5..09ed034 100644 (file)
@@ -442,14 +442,14 @@ VECSOURCES& CGUIViewStateWindowVideoNav::GetSources()
       share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
       m_sources.push_back(share);
     }
-    { // Playlists share
-      CMediaSource share;
-      share.strName=g_localizeStrings.Get(136); // Playlists
-      share.strPath = "special://videoplaylists/";
-      share.m_strThumbnailImage = CUtil::GetDefaultFolderThumb("DefaultVideoPlaylists.png");
-      share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
-      m_sources.push_back(share);
-    }
+  }
+  { // Playlists share
+    CMediaSource share;
+    share.strName=g_localizeStrings.Get(136); // Playlists
+    share.strPath = "special://videoplaylists/";
+    share.m_strThumbnailImage = CUtil::GetDefaultFolderThumb("DefaultVideoPlaylists.png");
+    share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
+    m_sources.push_back(share);
   }
   return CGUIViewStateWindowVideo::GetSources();
 }
index 4d6f381..8ed269c 100644 (file)
@@ -413,7 +413,7 @@ CTeletextDecoder::CTeletextDecoder()
 {
   memset(&m_RenderInfo, 0, sizeof(TextRenderInfo_t));
 
-  m_teletextFont                 = _P(TeletextFont);
+  m_teletextFont                 = CSpecialProtocol::TranslatePath(TeletextFont);
   m_TextureBuffer                = NULL;
   m_txtCache                     = NULL;
   m_Manager                      = NULL;
index 451ad91..a9827c0 100644 (file)
@@ -51,6 +51,8 @@
 #include "interfaces/AnnouncementManager.h"
 #include "dbwrappers/dataset.h"
 #include "ThumbnailCache.h"
+#include "utils/LabelFormatter.h"
+#include "XBDateTime.h"
 
 using namespace std;
 using namespace dbiplus;
@@ -156,11 +158,11 @@ bool CVideoDatabase::CreateTables()
     m_pDS->exec("CREATE TABLE actors ( idActor integer primary key, strActor text, strThumb text )\n");
 
     CLog::Log(LOGINFO, "create path table");
-    m_pDS->exec("CREATE TABLE path ( idPath integer primary key, strPath text, strContent text, strScraper text, strHash text, scanRecursive integer, useFolderNames bool, strSettings text, noUpdate bool, exclude bool)");
+    m_pDS->exec("CREATE TABLE path ( idPath integer primary key, strPath text, strContent text, strScraper text, strHash text, scanRecursive integer, useFolderNames bool, strSettings text, noUpdate bool, exclude bool, dateAdded text)");
     m_pDS->exec("CREATE UNIQUE INDEX ix_path ON path ( strPath(255) )");
 
     CLog::Log(LOGINFO, "create files table");
-    m_pDS->exec("CREATE TABLE files ( idFile integer primary key, idPath integer, strFilename text, playCount integer, lastPlayed text)");
+    m_pDS->exec("CREATE TABLE files ( idFile integer primary key, idPath integer, strFilename text, playCount integer, lastPlayed text, dateAdded text)");
     m_pDS->exec("CREATE UNIQUE INDEX ix_files ON files ( idPath, strFilename(255) )");
 
     CLog::Log(LOGINFO, "create tvshow table");
@@ -326,7 +328,7 @@ void CVideoDatabase::CreateViews()
   CLog::Log(LOGINFO, "create episodeview");
   m_pDS->exec("DROP VIEW IF EXISTS episodeview");
   CStdString episodeview = PrepareSQL("create view episodeview as select episode.*,files.strFileName as strFileName,"
-                                      "path.strPath as strPath,files.playCount as playCount,files.lastPlayed as lastPlayed,tvshow.c%02d as strTitle,tvshow.c%02d as strStudio,tvshow.idShow as idShow,"
+                                      "path.strPath as strPath,files.playCount as playCount,files.lastPlayed as lastPlayed,files.dateAdded as dateAdded,tvshow.c%02d as strTitle,tvshow.c%02d as strStudio,tvshow.idShow as idShow,"
                                       "tvshow.c%02d as premiered, tvshow.c%02d as mpaa, tvshow.c%02d as strShowPath from episode "
                                       "join files on files.idFile=episode.idFile "
                                       "join tvshowlinkepisode on episode.idEpisode=tvshowlinkepisode.idEpisode "
@@ -339,6 +341,7 @@ void CVideoDatabase::CreateViews()
   CStdString tvshowview = PrepareSQL("CREATE VIEW tvshowview AS SELECT "
                                      "tvshow.*,"
                                      "path.strPath AS strPath,"
+                                     "path.dateAdded AS dateAdded,"
                                      "  NULLIF(COUNT(episode.c12), 0) AS totalCount,"
                                      "  COUNT(files.playCount) AS watchedcount,"
                                      "  NULLIF(COUNT(DISTINCT(episode.c12)), 0) AS totalSeasons "
@@ -358,12 +361,12 @@ void CVideoDatabase::CreateViews()
 
   CLog::Log(LOGINFO, "create musicvideoview");
   m_pDS->exec("DROP VIEW IF EXISTS musicvideoview");
-  m_pDS->exec("create view musicvideoview as select musicvideo.*,files.strFileName as strFileName,path.strPath as strPath,files.playCount as playCount,files.lastPlayed as lastPlayed "
+  m_pDS->exec("create view musicvideoview as select musicvideo.*,files.strFileName as strFileName,path.strPath as strPath,files.playCount as playCount,files.lastPlayed as lastPlayed,files.dateAdded as dateAdded "
               "from musicvideo join files on files.idFile=musicvideo.idFile join path on path.idPath=files.idPath");
 
   CLog::Log(LOGINFO, "create movieview");
   m_pDS->exec("DROP VIEW IF EXISTS movieview");
-  m_pDS->exec("create view movieview as select movie.*,files.strFileName as strFileName,path.strPath as strPath,files.playCount as playCount,files.lastPlayed as lastPlayed "
+  m_pDS->exec("create view movieview as select movie.*,files.strFileName as strFileName,path.strPath as strPath,files.playCount as playCount,files.lastPlayed as lastPlayed,files.dateAdded as dateAdded "
               "from movie join files on files.idFile=movie.idFile join path on path.idPath=files.idPath");
 }
 
@@ -531,7 +534,7 @@ bool CVideoDatabase::GetSubPaths(const CStdString &basepath, vector<int>& subpat
   return false;
 }
 
-int CVideoDatabase::AddPath(const CStdString& strPath)
+int CVideoDatabase::AddPath(const CStdString& strPath, const CStdString &strDateAdded /*= "" */)
 {
   CStdString strSQL;
   try
@@ -549,7 +552,11 @@ int CVideoDatabase::AddPath(const CStdString& strPath)
 
     URIUtils::AddSlashAtEnd(strPath1);
 
-    strSQL=PrepareSQL("insert into path (idPath, strPath, strContent, strScraper) values (NULL,'%s','','')", strPath1.c_str());
+    // only set dateadded if we got one
+    if (!strDateAdded.empty())
+      strSQL=PrepareSQL("insert into path (idPath, strPath, strContent, strScraper, dateAdded) values (NULL,'%s','','', '%s')", strPath1.c_str(), strDateAdded.c_str());
+    else
+      strSQL=PrepareSQL("insert into path (idPath, strPath, strContent, strScraper) values (NULL,'%s','','')", strPath1.c_str());
     m_pDS->exec(strSQL.c_str());
     idPath = (int)m_pDS->lastinsertid();
     return idPath;
@@ -610,7 +617,8 @@ int CVideoDatabase::AddFile(const CStdString& strFileNameAndPath)
       return idFile;
     }
     m_pDS->close();
-    strSQL=PrepareSQL("insert into files (idFile,idPath,strFileName) values(NULL, %i, '%s')", idPath,strFileName.c_str());
+
+    strSQL=PrepareSQL("insert into files (idFile, idPath, strFileName) values(NULL, %i, '%s')", idPath, strFileName.c_str());
     m_pDS->exec(strSQL.c_str());
     idFile = (int)m_pDS->lastinsertid();
     return idFile;
@@ -629,6 +637,35 @@ int CVideoDatabase::AddFile(const CFileItem& item)
   return AddFile(item.GetPath());
 }
 
+void CVideoDatabase::UpdateFileDateAdded(int idFile, const CStdString& strFileNameAndPath)
+{
+  if (idFile < 0 || strFileNameAndPath.empty())
+    return;
+    
+  CStdString strSQL = "";
+  try
+  {
+    if (NULL == m_pDB.get()) return;
+    if (NULL == m_pDS.get()) return;
+
+    CDateTime dateAdded;
+    // Let's try to get the modification datetime
+    struct __stat64 buffer;
+    if (CFile::Stat(strFileNameAndPath, &buffer) == 0)
+      dateAdded = *localtime((const time_t*)&buffer.st_mtime);
+
+    if (!dateAdded.IsValid())
+      dateAdded = CDateTime::GetCurrentDateTime();
+
+    strSQL = PrepareSQL("update files set dateAdded='%s' where idFile=%d", dateAdded.GetAsDBDateTime().c_str(), idFile);
+    m_pDS->exec(strSQL.c_str());
+  }
+  catch (...)
+  {
+    CLog::Log(LOGERROR, "%s unable to update dateadded for file (%s)", __FUNCTION__, strSQL.c_str());
+  }
+}
+
 bool CVideoDatabase::SetPathHash(const CStdString &path, const CStdString &hash)
 {
   try
@@ -972,6 +1009,7 @@ int CVideoDatabase::AddMovie(const CStdString& strFilenameAndPath)
       int idFile = AddFile(strFilenameAndPath);
       if (idFile < 0)
         return -1;
+      UpdateFileDateAdded(idFile, strFilenameAndPath);
       CStdString strSQL=PrepareSQL("insert into movie (idMovie, idFile) values (NULL, %i)", idFile);
       m_pDS->exec(strSQL.c_str());
       idMovie = (int)m_pDS->lastinsertid();
@@ -1003,7 +1041,16 @@ int CVideoDatabase::AddTvShow(const CStdString& strPath)
     m_pDS->exec(strSQL.c_str());
     int idTvShow = (int)m_pDS->lastinsertid();
 
-    int idPath = AddPath(strPath);
+    // Get the creation datetime of the tvshow directory
+    CDateTime dateAdded;
+    struct __stat64 buffer;
+    if (XFILE::CFile::Stat(strPath, &buffer) == 0)
+      dateAdded = *localtime((const time_t*)&buffer.st_ctime);
+
+    if (!dateAdded.IsValid())
+      dateAdded = CDateTime::GetCurrentDateTime();
+
+    int idPath = AddPath(strPath, dateAdded.GetAsDBDateTime());
     strSQL=PrepareSQL("insert into tvshowlinkpath values (%i,%i)",idTvShow,idPath);
     m_pDS->exec(strSQL.c_str());
 
@@ -1029,6 +1076,7 @@ int CVideoDatabase::AddEpisode(int idShow, const CStdString& strFilenameAndPath)
     int idFile = AddFile(strFilenameAndPath);
     if (idFile < 0)
       return -1;
+    UpdateFileDateAdded(idFile, strFilenameAndPath);
 
     CStdString strSQL=PrepareSQL("insert into episode (idEpisode, idFile) values (NULL, %i)", idFile);
     m_pDS->exec(strSQL.c_str());
@@ -1061,6 +1109,7 @@ int CVideoDatabase::AddMusicVideo(const CStdString& strFilenameAndPath)
       int idFile = AddFile(strFilenameAndPath);
       if (idFile < 0)
         return -1;
+      UpdateFileDateAdded(idFile, strFilenameAndPath);
       CStdString strSQL=PrepareSQL("insert into musicvideo (idMVideo, idFile) values (NULL, %i)", idFile);
       m_pDS->exec(strSQL.c_str());
       idMVideo = (int)m_pDS->lastinsertid();
@@ -2851,6 +2900,7 @@ CVideoInfoTag CVideoDatabase::GetDetailsForTvShow(auto_ptr<Dataset> &pDS, bool n
   GetDetailsFromDB(pDS, VIDEODB_ID_TV_MIN, VIDEODB_ID_TV_MAX, DbTvShowOffsets, details, 1);
   details.m_iDbId = idTvShow;
   details.m_strPath = pDS->fv(VIDEODB_DETAILS_TVSHOW_PATH).get_asString();
+  details.m_dateAdded.SetFromDBDateTime(pDS->fv(VIDEODB_DETAILS_TVSHOW_DATEADDED).get_asString());
   details.m_iEpisode = m_pDS->fv(VIDEODB_DETAILS_TVSHOW_NUM_EPISODES).get_asInt();
   details.m_playCount = m_pDS->fv(VIDEODB_DETAILS_TVSHOW_NUM_WATCHED).get_asInt();
   details.m_strShowPath = details.m_strPath;
@@ -2979,6 +3029,7 @@ void CVideoDatabase::GetCommonDetails(auto_ptr<Dataset> &pDS, CVideoInfoTag &det
   ConstructPath(details.m_strFileNameAndPath,details.m_strPath,strFileName);
   details.m_playCount = pDS->fv(VIDEODB_DETAILS_PLAYCOUNT).get_asInt();
   details.m_lastPlayed = pDS->fv(VIDEODB_DETAILS_LASTPLAYED).get_asString();
+  details.m_dateAdded.SetFromDBDateTime(pDS->fv(VIDEODB_DETAILS_DATEADDED).get_asString());
 }
 
 /// \brief GetVideoSettings() obtains any saved video settings for the current file.
@@ -3482,6 +3533,11 @@ bool CVideoDatabase::UpdateOldVersion(int iVersion)
       UpdateBasePathID("musicvideo", "idMVideo", VIDEODB_ID_MUSICVIDEO_BASEPATH, VIDEODB_ID_MUSICVIDEO_PARENTPATHID);
       UpdateBasePathID("episode", "idEpisode", VIDEODB_ID_EPISODE_BASEPATH, VIDEODB_ID_EPISODE_PARENTPATHID);
     }
+    if (iVersion < 61)
+    {
+      m_pDS->exec("ALTER TABLE path ADD dateAdded text");
+      m_pDS->exec("ALTER TABLE files ADD dateAdded text");
+    }
 
     // always recreate the view after any table change
     CreateViews();
@@ -5074,6 +5130,7 @@ bool CVideoDatabase::GetEpisodesByWhere(const CStdString& strBaseDir, const CStd
 
     // get data from returned rows
     items.Reserve(iRowsFound);
+    CLabelFormatter formatter("%H. %T", "");
     while (!m_pDS->eof())
     {
       int idEpisode = m_pDS->fv("idEpisode").get_asInt();
@@ -5085,6 +5142,7 @@ bool CVideoDatabase::GetEpisodesByWhere(const CStdString& strBaseDir, const CStd
           g_passwordManager.IsDatabasePathUnlocked(movie.m_strPath, g_settings.m_videoSources))
       {
         CFileItemPtr pItem(new CFileItem(movie));
+        formatter.FormatLabel(pItem.get());
         CStdString path;
         if (appendFullShowPath)
           path.Format("%s%ld/%ld/%ld",strBaseDir.c_str(), idShow, movie.m_iSeason,idEpisode);
@@ -5138,19 +5196,19 @@ bool CVideoDatabase::GetMusicVideosNav(const CStdString& strBaseDir, CFileItemLi
 
 bool CVideoDatabase::GetRecentlyAddedMoviesNav(const CStdString& strBaseDir, CFileItemList& items, unsigned int limit)
 {
-  CStdString order = PrepareSQL("order by idMovie desc limit %u", limit ? limit : g_advancedSettings.m_iVideoLibraryRecentlyAddedItems);
+  CStdString order = PrepareSQL("order by dateAdded desc, idMovie desc limit %u", limit ? limit : g_advancedSettings.m_iVideoLibraryRecentlyAddedItems);
   return GetMoviesByWhere(strBaseDir, "", order, items);
 }
 
 bool CVideoDatabase::GetRecentlyAddedEpisodesNav(const CStdString& strBaseDir, CFileItemList& items, unsigned int limit)
 {
-  CStdString where = PrepareSQL("order by idEpisode desc limit %u", limit ? limit : g_advancedSettings.m_iVideoLibraryRecentlyAddedItems);
+  CStdString where = PrepareSQL("order by dateAdded desc, idEpisode desc limit %u", limit ? limit : g_advancedSettings.m_iVideoLibraryRecentlyAddedItems);
   return GetEpisodesByWhere(strBaseDir, where, items, false);
 }
 
 bool CVideoDatabase::GetRecentlyAddedMusicVideosNav(const CStdString& strBaseDir, CFileItemList& items, unsigned int limit)
 {
-  CStdString where = PrepareSQL("order by idMVideo desc limit %u", limit ? limit : g_advancedSettings.m_iVideoLibraryRecentlyAddedItems);
+  CStdString where = PrepareSQL("order by dateAdded desc, idMVideo desc limit %u", limit ? limit : g_advancedSettings.m_iVideoLibraryRecentlyAddedItems);
   return GetMusicVideosByWhere(strBaseDir, where, items);
 }
 
@@ -5463,13 +5521,16 @@ CStdString CVideoDatabase::GetContentForPath(const CStdString& strPath)
   ScraperPtr scraper = GetScraperForPath(strPath, settings, foundDirectly);
   if (scraper)
   {
-    if (scraper->Content() == CONTENT_TVSHOWS && !foundDirectly)
-    { // check for episodes or seasons (ASSUMPTION: no episodes == seasons (i.e. assume show/season/episodes structure)
+    if (scraper->Content() == CONTENT_TVSHOWS)
+    { // check for episodes or seasons.  Assumptions are:
+      // 1. if episodes are in the path then we're in episodes.
+      // 2. if no episodes are found, and content was set directly on this path, then we're in shows.
+      // 3. if no episodes are found, and content was not set directly on this path, we're in seasons (assumes tvshows/seasons/episodes)
       CStdString sql = PrepareSQL("select count(1) from episodeview where strPath = '%s' limit 1", strPath.c_str());
       m_pDS->query( sql.c_str() );
       if (m_pDS->num_rows() && m_pDS->fv(0).get_asInt() > 0)
         return "episodes";
-      return "seasons";
+      return foundDirectly ? "tvshows" : "seasons";
     }
     return TranslateContent(scraper->Content());
   }
@@ -7549,7 +7610,7 @@ void CVideoDatabase::ImportFromXML(const CStdString &path)
         scanner.AddVideo(&item, CONTENT_MOVIES, useFolders);
         SetPlayCount(item, info.m_playCount, info.m_lastPlayed);
         CStdString strFileName(info.m_strTitle);
-        if (GetExportVersion() >= 1 && info.m_iYear > 0)
+        if (iVersion >= 1 && info.m_iYear > 0)
           strFileName.AppendFormat("_%i", info.m_iYear);
         CStdString file(GetSafeFile(moviesDir, strFileName));
         CFile::Cache(file + ".tbn", item.GetCachedVideoThumb());
@@ -7566,7 +7627,7 @@ void CVideoDatabase::ImportFromXML(const CStdString &path)
         scanner.AddVideo(&item, CONTENT_MUSICVIDEOS, useFolders);
         SetPlayCount(item, info.m_playCount, info.m_lastPlayed);
         CStdString strFileName(info.m_strArtist + "." + info.m_strTitle);
-        if (GetExportVersion() >= 1 && info.m_iYear > 0)
+        if (iVersion >= 1 && info.m_iYear > 0)
           strFileName.AppendFormat("_%i", info.m_iYear);
         CStdString file(GetSafeFile(musicvideosDir, strFileName));
         CFile::Cache(file + ".tbn", item.GetCachedVideoThumb());
index 367d882..1ac32a2 100644 (file)
@@ -65,17 +65,19 @@ namespace VIDEO
 #define VIDEODB_DETAILS_PATH                   VIDEODB_MAX_COLUMNS + 3
 #define VIDEODB_DETAILS_PLAYCOUNT              VIDEODB_MAX_COLUMNS + 4
 #define VIDEODB_DETAILS_LASTPLAYED             VIDEODB_MAX_COLUMNS + 5
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_NAME    VIDEODB_MAX_COLUMNS + 6
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_STUDIO  VIDEODB_MAX_COLUMNS + 7
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_ID      VIDEODB_MAX_COLUMNS + 8
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_AIRED   VIDEODB_MAX_COLUMNS + 9
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_MPAA    VIDEODB_MAX_COLUMNS + 10
-#define VIDEODB_DETAILS_EPISODE_TVSHOW_PATH    VIDEODB_MAX_COLUMNS + 11
+#define VIDEODB_DETAILS_DATEADDED              VIDEODB_MAX_COLUMNS + 6
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_NAME    VIDEODB_MAX_COLUMNS + 7
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_STUDIO  VIDEODB_MAX_COLUMNS + 8
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_ID      VIDEODB_MAX_COLUMNS + 9
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_AIRED   VIDEODB_MAX_COLUMNS + 10
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_MPAA    VIDEODB_MAX_COLUMNS + 11
+#define VIDEODB_DETAILS_EPISODE_TVSHOW_PATH    VIDEODB_MAX_COLUMNS + 12
                                                
 #define VIDEODB_DETAILS_TVSHOW_PATH            VIDEODB_MAX_COLUMNS + 1
-#define VIDEODB_DETAILS_TVSHOW_NUM_EPISODES    VIDEODB_MAX_COLUMNS + 2
-#define VIDEODB_DETAILS_TVSHOW_NUM_WATCHED     VIDEODB_MAX_COLUMNS + 3
-#define VIDEODB_DETAILS_TVSHOW_NUM_SEASONS     VIDEODB_MAX_COLUMNS + 4
+#define VIDEODB_DETAILS_TVSHOW_DATEADDED               VIDEODB_MAX_COLUMNS + 2
+#define VIDEODB_DETAILS_TVSHOW_NUM_EPISODES    VIDEODB_MAX_COLUMNS + 3
+#define VIDEODB_DETAILS_TVSHOW_NUM_WATCHED     VIDEODB_MAX_COLUMNS + 4
+#define VIDEODB_DETAILS_TVSHOW_NUM_SEASONS     VIDEODB_MAX_COLUMNS + 5
 
 
 #define VIDEODB_TYPE_STRING 1
@@ -567,9 +569,17 @@ public:
   /*! \brief Add a path to the database, if necessary
    If the path is already in the database, we simply return its id.
    \param strPath the path to add
+   \param strDateAdded datetime when the path was added to the filesystem/database
    \return id of the file, -1 if it could not be added.
    */
-  int AddPath(const CStdString& strPath);
+  int AddPath(const CStdString& strPath, const CStdString &strDateAdded = "");
+  
+  /*! \brief Updates the dateAdded field in the files table for the file
+   with the given idFile and the given path based on the files modification date
+   \param idFile id of the file in the files table
+   \param strFileNameAndPath path to the file
+   */
+  void UpdateFileDateAdded(int idFile, const CStdString& strFileNameAndPath);
 
   void ExportToXML(const CStdString &path, bool singleFiles = false, bool images=false, bool actorThumbs=false, bool overwrite=false);
   bool ExportSkipEntry(const CStdString &nfoFile);
@@ -722,7 +732,7 @@ private:
    */
   bool LookupByFolders(const CStdString &path, bool shows = false);
 
-  virtual int GetMinVersion() const { return 60; };
+  virtual int GetMinVersion() const { return 61; };
   virtual int GetExportVersion() const { return 1; };
   const char *GetBaseDBName() const { return "MyVideos"; };
 
index b91477d..b9ce9fd 100644 (file)
@@ -26,7 +26,7 @@
 #include "addons/Scraper.h"
 #include "Episode.h"
 #include "XBDateTime.h"
-#include "filesystem/FileCurl.h"
+#include "filesystem/CurlFile.h"
 
 // forward declarations
 class TiXmlDocument;
@@ -67,7 +67,7 @@ protected:
                       GET_EPISODE_LIST = 3,
                       GET_EPISODE_DETAILS = 4 };
 
-  XFILE::CFileCurl m_http;
+  XFILE::CCurlFile m_http;
   CStdString        m_strMovie;
   MOVIELIST         m_movieList;
   CVideoInfoTag     m_movieDetails;
index 3ab7753..ba194bf 100644 (file)
@@ -1165,7 +1165,12 @@ namespace VIDEO
     if (bApplyToDir)
       ApplyThumbToFolder(parentDir, cachedThumb);
 
-    ANNOUNCEMENT::CAnnouncementManager::Announce(ANNOUNCEMENT::VideoLibrary, "xbmc", "OnUpdate", CFileItemPtr(new CFileItem(*pItem)));
+    CFileItemPtr itemCopy = CFileItemPtr(new CFileItem(*pItem));
+    // Hack to make sure CVideoInfoTag::m_strShowTitle is set for tvshows
+    // to make sure CAnnouncementManager provides the correct type for the item
+    if (content == CONTENT_TVSHOWS && !isEpisode && itemCopy->HasVideoInfoTag())
+      itemCopy->GetVideoInfoTag()->m_strShowTitle = itemCopy->GetVideoInfoTag()->m_strTitle;
+    ANNOUNCEMENT::CAnnouncementManager::Announce(ANNOUNCEMENT::VideoLibrary, "xbmc", "OnUpdate", itemCopy);
   }
 
   void CVideoInfoScanner::DownloadImage(const CStdString &url, const CStdString &destination, bool asThumb /*= true */, CGUIDialogProgress *progress /*= NULL */)
index 216d4fb..b33fbf1 100644 (file)
@@ -89,6 +89,7 @@ void CVideoInfoTag::Reset()
   m_resumePoint.type = CBookmark::RESUME;
   m_iIdShow = -1;
   m_strShowPath.clear();
+  m_dateAdded.Reset();
 }
 
 bool CVideoInfoTag::Save(TiXmlNode *node, const CStdString &tag, bool savePathInfo)
@@ -247,6 +248,8 @@ bool CVideoInfoTag::Save(TiXmlNode *node, const CStdString &tag, bool savePathIn
   XMLUtils::SetFloat(&resume, "total", (float)m_resumePoint.totalTimeInSeconds);
   movie->InsertEndChild(resume);
 
+  XMLUtils::SetString(movie, "dateadded", m_dateAdded.GetAsDBDateTime());
+
   return true;
 }
 
@@ -332,6 +335,7 @@ void CVideoInfoTag::Archive(CArchive& ar)
     ar << m_resumePoint.totalTimeInSeconds;
     ar << m_iIdShow;
     ar << m_strShowPath;
+    ar << m_dateAdded.GetAsDBDateTime();
   }
   else
   {
@@ -421,6 +425,10 @@ void CVideoInfoTag::Archive(CArchive& ar)
     ar >> m_resumePoint.totalTimeInSeconds;
     ar >> m_iIdShow;
     ar >> m_strShowPath;
+
+    CStdString dateAdded;
+    ar >> dateAdded;
+    m_dateAdded.SetFromDBDateTime(dateAdded);
   }
 }
 
@@ -488,6 +496,7 @@ void CVideoInfoTag::Serialize(CVariant& value)
   value["resume"] = resume;
   value["tvshowid"] = m_iIdShow;
   value["tvshowpath"] = m_strShowPath;
+  value["dateadded"] = m_dateAdded.IsValid() ? m_dateAdded.GetAsDBDateTime() : "";
 }
 
 const CStdString CVideoInfoTag::GetCast(bool bIncludeRole /*= false*/) const
@@ -726,6 +735,11 @@ void CVideoInfoTag::ParseNative(const TiXmlElement* movie, bool prioritise)
     XMLUtils::GetDouble(resume, "position", m_resumePoint.timeInSeconds);
     XMLUtils::GetDouble(resume, "total", m_resumePoint.totalTimeInSeconds);
   }
+
+  // dateAdded
+  CStdString dateAdded;
+  XMLUtils::GetString(movie, "dateadded", dateAdded);
+  m_dateAdded.SetFromDBDateTime(dateAdded);
 }
 
 bool CVideoInfoTag::HasStreamDetails() const
index 3ee238b..981461b 100644 (file)
@@ -22,6 +22,7 @@
 
 
 #include <vector>
+#include "XBDateTime.h"
 #include "utils/ScraperUrl.h"
 #include "utils/Fanart.h"
 #include "utils/StreamDetails.h"
@@ -127,6 +128,7 @@ public:
   CFanart m_fanart;
   CStreamDetails m_streamDetails;
   CBookmark m_resumePoint;
+  CDateTime m_dateAdded;
 
 private:
   /* \brief Parse our native XML format for video info.
index ea72ee8..bec6e14 100644 (file)
@@ -651,6 +651,9 @@ void CVideoReferenceClock::RunGLX()
         return;
       }
 
+      //sleep here so we don't busy spin when this constantly happens, for example when the display went to sleep
+      Sleep(1000);
+
       CLog::Log(LOGDEBUG, "CVideoReferenceClock: Attaching glX context");
       if (!m_bIsATI)
         ReturnV = glXMakeCurrent(m_Dpy, m_Window, m_Context);
index 47f2343..5fd99c3 100644 (file)
@@ -117,11 +117,16 @@ void CGUIDialogTeletext::OnInitWindow()
   m_bClose            = false;
   m_windowLoaded      = true;
 
-  RESOLUTION res = g_graphicsContext.GetVideoResolution();
-  m_vertCoords.SetRect((float)g_settings.m_ResInfo[res].Overscan.left,
-                       (float)g_settings.m_ResInfo[res].Overscan.top,
-                       (float)g_settings.m_ResInfo[res].Overscan.right,
-                       (float)g_settings.m_ResInfo[res].Overscan.bottom);
+  g_graphicsContext.SetScalingResolution(m_coordsRes, m_needsScaling);
+  float left = g_graphicsContext.ScaleFinalXCoord(0, 0);
+  float right = g_graphicsContext.ScaleFinalXCoord(m_coordsRes.iWidth, 0);
+  float top = g_graphicsContext.ScaleFinalYCoord(0, 0);
+  float bottom = g_graphicsContext.ScaleFinalYCoord(0, m_coordsRes.iHeight);
+
+  m_vertCoords.SetRect(left,
+                       top,
+                       right,
+                       bottom);
 
   if (!m_TextDecoder.InitDecoder())
   {
index 9412ba7..bfeabd5 100644 (file)
@@ -142,7 +142,8 @@ void CGUIDialogVideoBookmarks::Update()
 
   // open the d/b and retrieve the bookmarks for the current movie
   CStdString path = g_application.CurrentFile();
-  if (g_application.CurrentFileItem().HasProperty("original_listitem_url"))
+  if (g_application.CurrentFileItem().HasProperty("original_listitem_url") && 
+     !URIUtils::IsVideoDb(g_application.CurrentFileItem().GetProperty("original_listitem_url").asString()))
     path = g_application.CurrentFileItem().GetProperty("original_listitem_url").asString();
   CVideoDatabase videoDatabase;
   videoDatabase.Open();
@@ -220,7 +221,8 @@ void CGUIDialogVideoBookmarks::ClearBookmarks()
   CVideoDatabase videoDatabase;
   videoDatabase.Open();
   CStdString path = g_application.CurrentFile();
-  if (g_application.CurrentFileItem().HasProperty("original_listitem_url"))
+  if (g_application.CurrentFileItem().HasProperty("original_listitem_url") && 
+     !URIUtils::IsVideoDb(g_application.CurrentFileItem().GetProperty("original_listitem_url").asString()))
     path = g_application.CurrentFileItem().GetProperty("original_listitem_url").asString();
   videoDatabase.ClearBookMarksOfFile(path, CBookmark::STANDARD);
   videoDatabase.ClearBookMarksOfFile(path, CBookmark::RESUME);
@@ -282,7 +284,8 @@ void CGUIDialogVideoBookmarks::AddBookmark(CVideoInfoTag* tag)
   else
   {
     CStdString path = g_application.CurrentFile();
-    if (g_application.CurrentFileItem().HasProperty("original_listitem_url"))
+    if (g_application.CurrentFileItem().HasProperty("original_listitem_url") && 
+       !URIUtils::IsVideoDb(g_application.CurrentFileItem().GetProperty("original_listitem_url").asString()))
       path = g_application.CurrentFileItem().GetProperty("original_listitem_url").asString();
     videoDatabase.AddBookMarkToFile(path, bookmark, CBookmark::STANDARD);
   }
index 4d77a03..c1f86b9 100644 (file)
@@ -55,6 +55,7 @@
 #include "windowing/WindowingFactory.h"
 
 #include <stdio.h>
+#include <algorithm>
 #ifdef __APPLE__
 #include "linux/LinuxResourceCounter.h"
 #endif
@@ -601,6 +602,27 @@ bool CGUIWindowFullScreen::OnAction(const CAction &action)
 
       break;
     }
+  case ACTION_VOLAMP_UP:
+  case ACTION_VOLAMP_DOWN:
+    {
+      float sliderMax = VOLUME_DRC_MAXIMUM / 100.0f;
+      float sliderMin = VOLUME_DRC_MINIMUM / 100.0f;
+
+      if (action.GetID() == ACTION_VOLAMP_UP)
+        g_settings.m_currentVideoSettings.m_VolumeAmplification += 1.0f;
+      else
+        g_settings.m_currentVideoSettings.m_VolumeAmplification -= 1.0f;
+
+      g_settings.m_currentVideoSettings.m_VolumeAmplification =
+        std::max(std::min(g_settings.m_currentVideoSettings.m_VolumeAmplification, sliderMax), sliderMin);
+
+      if (g_application.m_pPlayer)
+        g_application.m_pPlayer->SetDynamicRangeCompression((long)(g_settings.m_currentVideoSettings.m_VolumeAmplification * 100));
+
+      ShowSlider(action.GetID(), 660, g_settings.m_currentVideoSettings.m_VolumeAmplification, sliderMin, 1.0f, sliderMax);
+
+      break;
+    }
   default:
       break;
   }
@@ -1103,6 +1125,8 @@ void CGUIWindowFullScreen::OnSliderChange(void *data, CGUISliderControl *slider)
     strValue.Format("%1.2f",slider->GetFloatValue());
     slider->SetTextValue(strValue);
   }
+  else if (m_sliderAction == ACTION_VOLAMP_UP || m_sliderAction == ACTION_VOLAMP_DOWN)
+    slider->SetTextValue(CGUIDialogAudioSubtitleSettings::FormatDecibel(slider->GetFloatValue(), 1.0f));
   else
     slider->SetTextValue(CGUIDialogAudioSubtitleSettings::FormatDelay(slider->GetFloatValue(), 0.025f));
 
index 109d859..07c0702 100644 (file)
@@ -1153,9 +1153,7 @@ bool CGUIWindowVideoBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
   {
   case CONTEXT_BUTTON_SET_CONTENT:
     {
-      SScanSettings settings;
-      ADDON::ScraperPtr info = m_database.GetScraperForPath(item->HasVideoInfoTag() ? item->GetVideoInfoTag()->m_strPath : item->GetPath(), settings);
-      OnAssignContent(item->GetPath(),0, info, settings);
+      OnAssignContent(item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strPath.IsEmpty() ? item->GetVideoInfoTag()->m_strPath : item->GetPath());
       return true;
     }
   case CONTEXT_BUTTON_PLAY_PART:
@@ -1468,6 +1466,7 @@ void CGUIWindowVideoBase::OnDeleteItem(int iItem)
 
   OnDeleteItem(m_vecItems->Get(iItem));
 
+  m_vecItems->RemoveDiscCache(GetID());
   Update(m_vecItems->GetPath());
   m_viewControl.SetSelectedItem(iItem);
 }
@@ -1929,7 +1928,7 @@ int CGUIWindowVideoBase::GetScraperForItem(CFileItem *item, ADDON::ScraperPtr &i
   }
 
   bool foundDirectly = false;
-  info = m_database.GetScraperForPath(item->HasVideoInfoTag() ? item->GetVideoInfoTag()->m_strPath : item->GetPath(), settings, foundDirectly);
+  info = m_database.GetScraperForPath(item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strPath.IsEmpty() ? item->GetVideoInfoTag()->m_strPath : item->GetPath(), settings, foundDirectly);
   return foundDirectly ? 1 : 0;
 }
 
@@ -1989,16 +1988,15 @@ bool CGUIWindowVideoBase::OnUnAssignContent(const CStdString &path, int label1,
   return false;
 }
 
-void CGUIWindowVideoBase::OnAssignContent(const CStdString &path, int iFound, ADDON::ScraperPtr& info, SScanSettings& settings)
+void CGUIWindowVideoBase::OnAssignContent(const CStdString &path)
 {
   bool bScan=false;
   CVideoDatabase db;
   db.Open();
-  if (iFound == 0)
-  {
-    info = db.GetScraperForPath(path, settings);
-  }
-  
+
+  SScanSettings settings;
+  ADDON::ScraperPtr info = db.GetScraperForPath(path, settings);
+
   ADDON::ScraperPtr info2(info);
   
   if (CGUIDialogContentSettings::Show(info, settings, bScan))
@@ -2012,14 +2010,14 @@ void CGUIWindowVideoBase::OnAssignContent(const CStdString &path, int iFound, AD
       if (OnUnAssignContent(path,20442,20443,20444))
         bScan = true;
     }
-    
-    db.SetScraperForPath(path,info,settings);
-    
-    if (bScan)
-    {
-      CGUIDialogVideoScan* pDialog = (CGUIDialogVideoScan*)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
-      if (pDialog)
-        pDialog->StartScanning(path, true);
-    }
+  }
+
+  db.SetScraperForPath(path,info,settings);
+
+  if (bScan)
+  {
+    CGUIDialogVideoScan* pDialog = (CGUIDialogVideoScan*)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_SCAN);
+    if (pDialog)
+      pDialog->StartScanning(path, true);
   }
 }
index d9168fd..01cda2c 100644 (file)
@@ -60,7 +60,12 @@ public:
    */
   static void AppendAndClearSearchItems(CFileItemList &searchItems, const CStdString &prependLabel, CFileItemList &results);
 
-  static void OnAssignContent(const CStdString &path, int iFound, ADDON::ScraperPtr& scraper, VIDEO::SScanSettings& settings);
+  /*! \brief Prompt the user for assigning content to a path.
+   Based on changes, we then call OnUnassignContent, update or refresh scraper information in the database
+   and optionally start a scan
+   \param path the path to assign content for
+   */
+  static void OnAssignContent(const CStdString &path);
 
   /*! \brief checks the database for a resume position and puts together a string
    \param item selected item
index 05b3dd2..fb3afbf 100644 (file)
@@ -1,24 +1,25 @@
 ARCH=@ARCH@
 CXXFLAGS=-fPIC
-OBJS=opengl_spectrum.o
 
-SLIB=@abs_top_srcdir@/addons/visualization.glspectrum/opengl_spectrum.vis
+SLIB = @abs_top_srcdir@/addons/visualization.glspectrum/opengl_spectrum.vis
+OBJS = opengl_spectrum.o
 
 ifeq (@USE_OPENGLES@,1)
-  OBJS+=../EGLHelpers/Shader.o ../EGLHelpers/GUIShader.o ../../guilib/MatrixGLES.o
-  DEFINES+=-DHAS_GLES=2
+  DEFINES += -DHAS_GLES=2
+  OBJS += @abs_top_srcdir@/xbmc/visualizations/EGLHelpers/GUIShader.o
+  OBJS += @abs_top_srcdir@/xbmc/visualizations/EGLHelpers/Shader.o
   ifeq ($(findstring osx,$(ARCH)), osx)
-    LDFLAGS+=-framework OpenGLES
+    LDFLAGS += -framework OpenGLES
   else
-    LDFLAGS+=-lGLESv2
+    LDFLAGS += -lGLESv2
   endif
 else
-  DEFINES+=-DHAS_SDL
-  DEFINES+=-DHAS_SDL_OPENGL
+  DEFINES += -DHAS_SDL
+  DEFINES += -DHAS_SDL_OPENGL
   ifeq ($(findstring osx,$(ARCH)), osx)
-    LDFLAGS+=-framework OpenGL
+    LDFLAGS += -framework OpenGL
   else
-    LDFLAGS+=-lGL
+    LDFLAGS += -lGL
   endif
 endif
 
index 9865ad5..584eddd 100644 (file)
@@ -1,24 +1,26 @@
 ARCH=@ARCH@
 CXXFLAGS=-fPIC
-OBJS=Main.o
 
-SLIB=@abs_top_srcdir@/addons/visualization.waveform/Waveform.vis
+SLIB = @abs_top_srcdir@/addons/visualization.waveform/Waveform.vis
 
 ifeq (@USE_OPENGLES@,1)
-  OBJS=Main_gles.o ../EGLHelpers/Shader.o ../EGLHelpers/GUIShader.o ../../guilib/MatrixGLES.o
-  DEFINES+=-DHAS_GLES=2
+  DEFINES += -DHAS_GLES=2
+  OBJS  = Main_gles.o
+  OBJS += @abs_top_srcdir@/xbmc/visualizations/EGLHelpers/GUIShader.o
+  OBJS += @abs_top_srcdir@/xbmc/visualizations/EGLHelpers/Shader.o
   ifeq ($(findstring osx,$(ARCH)), osx)
-    LDFLAGS+=-framework OpenGLES
+    LDFLAGS += -framework OpenGLES
   else
-    LDFLAGS+=-lGLESv2
+    LDFLAGS += -lGLESv2
   endif
 else
-  DEFINES+=-DHAS_SDL
-  DEFINES+=-DHAS_SDL_OPENGL
+  OBJS  = Main.o
+  DEFINES += -DHAS_SDL
+  DEFINES += -DHAS_SDL_OPENGL
   ifeq ($(findstring osx,$(ARCH)), osx)
-    LDFLAGS+=-framework OpenGL
+    LDFLAGS += -framework OpenGL
   else
-    LDFLAGS+=-lGL -lGLU
+    LDFLAGS += -lGL -lGLU
   endif
 endif
 
diff --git a/xbmc/win32/WINFileSMB.cpp b/xbmc/win32/WINFileSMB.cpp
deleted file mode 100644 (file)
index 9c59c5d..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-
-/*
- * XBMC Media Center
- * Copyright (c) 2002 Frodo
- * Portions Copyright (c) by the authors of ffmpeg and xvid
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-#include "WINFileSMB.h"
-#include "URL.h"
-#include "settings/GUISettings.h"
-
-#include <sys/stat.h>
-#include <io.h>
-#include "utils/log.h"
-#include "utils/CharsetConverter.h"
-#include "utils/URIUtils.h"
-#include "WINSMBDirectory.h"
-
-using namespace XFILE;
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-//*********************************************************************************************
-CWINFileSMB::CWINFileSMB()
-    : m_hFile(INVALID_HANDLE_VALUE)
-{}
-
-//*********************************************************************************************
-CWINFileSMB::~CWINFileSMB()
-{
-  if (m_hFile != INVALID_HANDLE_VALUE) Close();
-}
-//*********************************************************************************************
-CStdString CWINFileSMB::GetLocal(const CURL &url)
-{
-  CStdString path( url.GetFileName() );
-
-  if( url.GetProtocol().Equals("smb", false) )
-  {
-    CStdString host( url.GetHostName() );
-
-    if(host.size() > 0)
-    {
-      path = "//" + host + "/" + path;
-    }
-  }
-
-  path.Replace('/', '\\');
-
-  return path;
-}
-
-//*********************************************************************************************
-bool CWINFileSMB::Open(const CURL& url)
-{
-  CStdString strFile = GetLocal(url);
-
-  CStdStringW strWFile;
-  g_charsetConverter.utf8ToW(strFile, strWFile, false);
-  m_hFile.attach(CreateFileW(strWFile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL));
-
-  if (!m_hFile.isValid())
-  {
-    if(GetLastError() == ERROR_FILE_NOT_FOUND)
-      return false;
-
-    XFILE::CWINSMBDirectory smb;
-    smb.ConnectToShare(url);
-    m_hFile.attach(CreateFileW(strWFile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL));
-    if (!m_hFile.isValid())
-    {
-      CLog::Log(LOGERROR,"CWINFileSMB: Unable to open file '%s' Error '%d%",strWFile.c_str(), GetLastError());
-      return false;
-    }
-  }
-
-  m_i64FilePos = 0;
-  Seek(0, SEEK_SET);
-
-  return true;
-}
-
-bool CWINFileSMB::Exists(const CURL& url)
-{
-  struct __stat64 buffer;
-  if(url.GetFileName() == url.GetShareName())
-    return false;
-  CStdString strFile = GetLocal(url);
-  URIUtils::RemoveSlashAtEnd(strFile);
-  CStdStringW strWFile;
-  g_charsetConverter.utf8ToW(strFile, strWFile, false);
-  if(_wstat64(strWFile.c_str(), &buffer) == 0)
-    return true;
-
-  if(errno == ENOENT)
-    return false;
-
-  XFILE::CWINSMBDirectory smb;
-  if(smb.ConnectToShare(url) == false)
-    return false;
-
-  return (_wstat64(strWFile.c_str(), &buffer) == 0);
-}
-
-int CWINFileSMB::Stat(struct __stat64* buffer)
-{
-  int fd;
-  HANDLE hFileDup;
-  if (0 == DuplicateHandle(GetCurrentProcess(), (HANDLE)m_hFile, GetCurrentProcess(), &hFileDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
-  {
-    CLog::Log(LOGERROR, __FUNCTION__" - DuplicateHandle()");
-    return -1;
-  }
-
-  fd = _open_osfhandle((intptr_t)((HANDLE)hFileDup), 0);
-  if (fd == -1)
-  {
-    CLog::Log(LOGERROR, "CWINFileSMB Stat: fd == -1");
-    return -1;
-  }
-
-  int result = _fstat64(fd, buffer);
-  _close(fd);
-  return result;
-}
-
-int CWINFileSMB::Stat(const CURL& url, struct __stat64* buffer)
-{
-  CStdString strFile = GetLocal(url);
-  /* _wstat64 calls FindFirstFileEx. According to MSDN, the path should not end in a trailing backslash.
-    Remove it before calling _wstat64 */
-  if (strFile.length() > 3 && URIUtils::HasSlashAtEnd(strFile))
-    URIUtils::RemoveSlashAtEnd(strFile);
-  CStdStringW strWFile;
-  g_charsetConverter.utf8ToW(strFile, strWFile, false);
-  if(_wstat64(strWFile.c_str(), buffer) == 0)
-    return 0;
-
-  if(errno == ENOENT)
-    return -1;
-
-  XFILE::CWINSMBDirectory smb;
-  if(smb.ConnectToShare(url) == false)
-    return -1;
-
-  return _wstat64(strWFile.c_str(), buffer);
-}
-
-
-//*********************************************************************************************
-bool CWINFileSMB::OpenForWrite(const CURL& url, bool bOverWrite)
-{
-  CStdString strPath = GetLocal(url);
-
-  CStdStringW strWPath;
-  g_charsetConverter.utf8ToW(strPath, strWPath, false);
-  m_hFile.attach(CreateFileW(strWPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
-
-  if (!m_hFile.isValid())
-  {
-    if(GetLastError() == ERROR_FILE_NOT_FOUND)
-      return false;
-
-    XFILE::CWINSMBDirectory smb;
-    smb.ConnectToShare(url);
-    m_hFile.attach(CreateFileW(strWPath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
-    if (!m_hFile.isValid())
-    {
-      CLog::Log(LOGERROR,"CWINFileSMB: Unable to open file for writing '%s' Error '%d%",strWPath.c_str(), GetLastError());
-      return false;
-    }
-  }
-
-  m_i64FilePos = 0;
-  Seek(0, SEEK_SET);
-
-  return true;
-}
-
-//*********************************************************************************************
-unsigned int CWINFileSMB::Read(void *lpBuf, int64_t uiBufSize)
-{
-  if (!m_hFile.isValid()) return 0;
-  DWORD nBytesRead;
-  if ( ReadFile((HANDLE)m_hFile, lpBuf, (DWORD)uiBufSize, &nBytesRead, NULL) )
-  {
-    m_i64FilePos += nBytesRead;
-    return nBytesRead;
-  }
-  return 0;
-}
-
-//*********************************************************************************************
-int CWINFileSMB::Write(const void *lpBuf, int64_t uiBufSize)
-{
-  if (!m_hFile.isValid())
-    return 0;
-  
-  DWORD nBytesWriten;
-  if ( WriteFile((HANDLE)m_hFile, (void*) lpBuf, (DWORD)uiBufSize, &nBytesWriten, NULL) )
-    return nBytesWriten;
-  
-  return 0;
-}
-
-//*********************************************************************************************
-void CWINFileSMB::Close()
-{
-  m_hFile.reset();
-}
-
-//*********************************************************************************************
-int64_t CWINFileSMB::Seek(int64_t iFilePosition, int iWhence)
-{
-  LARGE_INTEGER lPos, lNewPos;
-  lPos.QuadPart = iFilePosition;
-  int bSuccess;
-
-  int64_t length = GetLength();
-
-  switch (iWhence)
-  {
-  case SEEK_SET:
-    if (iFilePosition <= length || length == 0)
-      bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_BEGIN);
-    else
-      bSuccess = false;
-    break;
-
-  case SEEK_CUR:
-    if ((GetPosition()+iFilePosition) <= length || length == 0)
-      bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_CURRENT);
-    else
-      bSuccess = false;
-    break;
-
-  case SEEK_END:
-    bSuccess = SetFilePointerEx((HANDLE)m_hFile, lPos, &lNewPos, FILE_END);
-    break;
-
-  default:
-    return -1;
-  }
-  if (bSuccess)
-  {
-    m_i64FilePos = lNewPos.QuadPart;
-    return m_i64FilePos;
-  }
-  else
-    return -1;
-}
-
-//*********************************************************************************************
-int64_t CWINFileSMB::GetLength()
-{
-  LARGE_INTEGER i64Size;
-  GetFileSizeEx((HANDLE)m_hFile, &i64Size);
-  return i64Size.QuadPart;
-}
-
-//*********************************************************************************************
-int64_t CWINFileSMB::GetPosition()
-{
-  return m_i64FilePos;
-}
-
-bool CWINFileSMB::Delete(const CURL& url)
-{
-  CStdString strFile=GetLocal(url);
-
-  CStdStringW strWFile;
-  g_charsetConverter.utf8ToW(strFile, strWFile, false);
-  return ::DeleteFileW(strWFile.c_str()) ? true : false;
-}
-
-bool CWINFileSMB::Rename(const CURL& url, const CURL& urlnew)
-{
-  CStdString strFile=GetLocal(url);
-  CStdString strNewFile=GetLocal(urlnew);
-
-  CStdStringW strWFile;
-  CStdStringW strWNewFile;
-  g_charsetConverter.utf8ToW(strFile, strWFile, false);
-  g_charsetConverter.utf8ToW(strNewFile, strWNewFile, false);
-  return ::MoveFileW(strWFile.c_str(), strWNewFile.c_str()) ? true : false;
-}
-
-bool CWINFileSMB::SetHidden(const CURL &url, bool hidden)
-{
-  CStdStringW path;
-  g_charsetConverter.utf8ToW(GetLocal(url), path, false);
-  DWORD attributes = hidden ? FILE_ATTRIBUTE_HIDDEN : FILE_ATTRIBUTE_NORMAL;
-  if (SetFileAttributesW(path.c_str(), attributes))
-    return true;
-  return false;
-}
-
-void CWINFileSMB::Flush()
-{
-  ::FlushFileBuffers(m_hFile);
-}
-
-int CWINFileSMB::IoControl(EIoControl request, void* param)
-{ 
-  return -1;
-}
diff --git a/xbmc/win32/WINFileSMB.h b/xbmc/win32/WINFileSMB.h
deleted file mode 100644 (file)
index 3f89fb3..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * XBMC Media Center
- * Copyright (c) 2002 Frodo
- * Portions Copyright (c) by the authors of ffmpeg and xvid
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-// WINFileSMB.h: interface for the CWINFileSMB class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include "filesystem/IFile.h"
-#include "utils/AutoPtrHandle.h"
-
-namespace XFILE
-{
-class CWINFileSMB : public IFile
-{
-public:
-  CWINFileSMB();
-  virtual ~CWINFileSMB();
-  virtual int64_t GetPosition();
-  virtual int64_t GetLength();
-  virtual bool Open(const CURL& url);
-  virtual bool Exists(const CURL& url);
-  virtual int Stat(const CURL& url, struct __stat64* buffer);
-  virtual int Stat(struct __stat64* buffer);
-  virtual unsigned int Read(void* lpBuf, int64_t uiBufSize);
-  virtual int Write(const void* lpBuf, int64_t uiBufSize);
-  virtual int64_t Seek(int64_t iFilePosition, int iWhence = SEEK_SET);
-  virtual void Close();
-  virtual void Flush();
-
-  virtual bool OpenForWrite(const CURL& url, bool bOverWrite = false);
-
-  virtual bool Delete(const CURL& url);
-  virtual bool Rename(const CURL& url, const CURL& urlnew);
-  virtual bool SetHidden(const CURL& url, bool hidden);
-
-  virtual int IoControl(EIoControl request, void* param);
-protected:
-  CStdString GetLocal(const CURL &url); /* crate a properly format path from an url */
-  AUTOPTR::CAutoPtrHandle m_hFile;
-  int64_t m_i64FilePos;
-};
-
-}
diff --git a/xbmc/win32/WINSMBDirectory.cpp b/xbmc/win32/WINSMBDirectory.cpp
deleted file mode 100644 (file)
index 5e2c2de..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-
-#include "WINSMBDirectory.h"
-#include "URL.h"
-#include "utils/URIUtils.h"
-#include "settings/GUISettings.h"
-#include "FileItem.h"
-#include "WIN32Util.h"
-#include "utils/AutoPtrHandle.h"
-#include "utils/log.h"
-#include "utils/CharsetConverter.h"
-#include "PasswordManager.h"
-#include "Util.h"
-
-#ifndef INVALID_FILE_ATTRIBUTES
-#define INVALID_FILE_ATTRIBUTES ((DWORD) -1)
-#endif
-
-
-using namespace AUTOPTR;
-using namespace XFILE;
-
-CWINSMBDirectory::CWINSMBDirectory(void)
-{
-  m_bHost=false;
-}
-
-CWINSMBDirectory::~CWINSMBDirectory(void)
-{
-}
-
-CStdString CWINSMBDirectory::GetLocal(const CStdString& strPath)
-{
-  CURL url(strPath);
-  CStdString path( url.GetFileName() );
-  if( url.GetProtocol().Equals("smb", false) )
-  {
-    CStdString host( url.GetHostName() );
-
-    if(host.size() > 0)
-    {
-      path = "//" + host + "/" + path;
-    }
-  }
-  path.Replace('/', '\\');
-  return path;
-}
-
-bool CWINSMBDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &items)
-{
-  WIN32_FIND_DATAW wfd;
-
-  CStdString strPath=strPath1;
-
-  CURL url(strPath);
-
-  if(url.GetShareName().empty())
-  {
-    LPNETRESOURCEW lpnr = NULL;
-    bool ret;
-    if(!url.GetHostName().empty())
-    {
-      lpnr = (LPNETRESOURCEW) GlobalAlloc(GPTR, 16384);
-      if(lpnr == NULL)
-        return false;
-
-      ConnectToShare(url);
-      CStdString strHost = "\\\\" + url.GetHostName();
-      CStdStringW strHostW;
-      g_charsetConverter.utf8ToW(strHost,strHostW);
-      lpnr->lpRemoteName = (LPWSTR)strHostW.c_str();
-      m_bHost = true;
-      ret = EnumerateFunc(lpnr, items);
-      GlobalFree((HGLOBAL) lpnr);
-      m_bHost = false;
-    }
-    else
-      ret = EnumerateFunc(lpnr, items);  
-    return ret; 
-  }
-
-  memset(&wfd, 0, sizeof(wfd));
-  //rebuild the URL
-  CStdString strUNCShare = "\\\\" + url.GetHostName() + "\\" + url.GetFileName();
-  strUNCShare.Replace("/", "\\");
-  if(!URIUtils::HasSlashAtEnd(strUNCShare))
-    strUNCShare.append("\\");
-
-  CStdStringW strSearchMask;
-  g_charsetConverter.utf8ToW(strUNCShare, strSearchMask, false); 
-  strSearchMask += "*";
-
-  FILETIME localTime;
-  CAutoPtrFind hFind ( FindFirstFileW(strSearchMask.c_str(), &wfd));
-  
-  // on error, check if path exists at all, this will return true if empty folder
-  if (!hFind.isValid()) 
-  {
-    DWORD ret = GetLastError();
-    if(ret == ERROR_INVALID_PASSWORD || ret == ERROR_LOGON_FAILURE || ret == ERROR_ACCESS_DENIED || ret == ERROR_INVALID_HANDLE)
-    {
-      if(ConnectToShare(url) == false)
-        return false;
-      hFind.attach(FindFirstFileW(strSearchMask.c_str(), &wfd));
-    }
-    else
-      return Exists(strPath1);
-  }
-
-  if (hFind.isValid())
-  {
-    do
-    {
-      if (wfd.cFileName[0] != 0)
-      {
-        CStdString strLabel;
-        g_charsetConverter.wToUTF8(wfd.cFileName,strLabel);
-        if ( (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
-        {
-          if (strLabel != "." && strLabel != "..")
-          {
-            CFileItemPtr pItem(new CFileItem(strLabel));
-            CStdString path = URIUtils::AddFileToFolder(strPath, strLabel);
-            URIUtils::AddSlashAtEnd(path);
-            pItem->SetPath(path);
-            pItem->m_bIsFolder = true;
-            FileTimeToLocalFileTime(&wfd.ftLastWriteTime, &localTime);
-            pItem->m_dateTime=localTime;
-
-            if (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
-              pItem->SetProperty("file:hidden", true);
-
-            items.Add(pItem);
-          }
-        }
-        else
-        {
-          CFileItemPtr pItem(new CFileItem(strLabel));
-          pItem->SetPath(URIUtils::AddFileToFolder(strPath, strLabel));
-          pItem->m_bIsFolder = false;
-          pItem->m_dwSize = CUtil::ToInt64(wfd.nFileSizeHigh, wfd.nFileSizeLow);
-          FileTimeToLocalFileTime(&wfd.ftLastWriteTime, &localTime);
-          pItem->m_dateTime=localTime;
-
-          if (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
-            pItem->SetProperty("file:hidden", true);
-          items.Add(pItem);
-        }
-      }
-    }
-    while (FindNextFileW((HANDLE)hFind, &wfd));
-  }
-  return true;
-}
-
-bool CWINSMBDirectory::Create(const char* strPath)
-{
-  CStdString strPath1 = GetLocal(strPath);
-  CStdStringW strWPath1;
-  g_charsetConverter.utf8ToW(strPath1, strWPath1, false);
-  if(::CreateDirectoryW(strWPath1, NULL))
-    return true;
-  else if(GetLastError() == ERROR_ALREADY_EXISTS)
-    return true;
-
-  return false;
-}
-
-bool CWINSMBDirectory::Remove(const char* strPath)
-{
-  CStdStringW strWPath;
-  CStdString strPath1 = GetLocal(strPath);
-  g_charsetConverter.utf8ToW(strPath1, strWPath, false);
-  return ::RemoveDirectoryW(strWPath) ? true : false;
-}
-
-bool CWINSMBDirectory::Exists(const char* strPath)
-{
-  CStdString strReplaced=GetLocal(strPath);
-  CStdStringW strWReplaced;
-  g_charsetConverter.utf8ToW(strReplaced, strWReplaced, false);
-  // this will fail on shares, needs a subdirectory inside a share
-  DWORD attributes = GetFileAttributesW(strWReplaced);
-  if(attributes == INVALID_FILE_ATTRIBUTES)
-    return false;
-  if (FILE_ATTRIBUTE_DIRECTORY & attributes) 
-    return true;
-  return false;
-}
-
-bool CWINSMBDirectory::EnumerateFunc(LPNETRESOURCEW lpnr, CFileItemList &items)
-{
-  DWORD dwResult, dwResultEnum;
-  HANDLE hEnum;
-  DWORD cbBuffer = 16384;     // 16K is a good size
-  LPNETRESOURCEW lpnrLocal;   // pointer to enumerated structures
-  DWORD cEntries = -1;        // enumerate all possible entries
-  //
-  // Call the WNetOpenEnum function to begin the enumeration.
-  //
-  dwResult = WNetOpenEnumW( RESOURCE_GLOBALNET,  // all network resources
-                            RESOURCETYPE_DISK,   // all disk resources
-                            0,                   // enumerate all resources
-                            lpnr,                // NULL first time the function is called
-                            &hEnum);             // handle to the resource
-
-  if (dwResult != NO_ERROR) 
-  {
-    CLog::Log(LOGERROR,"WnetOpenEnum failed with error %d", dwResult);
-    if(dwResult == ERROR_EXTENDED_ERROR)
-    {
-      DWORD dwWNetResult, dwLastError;   
-      CHAR szDescription[256]; 
-      CHAR szProvider[256]; 
-      dwWNetResult = WNetGetLastError(&dwLastError, // error code
-                            (LPSTR) szDescription,  // buffer for error description 
-                            sizeof(szDescription),  // size of error buffer
-                            (LPSTR) szProvider,     // buffer for provider name 
-                            sizeof(szProvider));    // size of name buffer
-      if(dwWNetResult == NO_ERROR) 
-        CLog::Log(LOGERROR,"%s failed with code %ld; %s", szProvider, dwLastError, szDescription);
-    }
-    return false;
-  }
-  //
-  // Call the GlobalAlloc function to allocate resources.
-  //
-  lpnrLocal = (LPNETRESOURCEW) GlobalAlloc(GPTR, cbBuffer);
-  if (lpnrLocal == NULL) 
-  {
-    CLog::Log(LOGERROR,"Can't allocate buffer %d", cbBuffer);
-    return false;
-  }
-
-  do 
-  {
-    //
-    // Initialize the buffer.
-    //
-    ZeroMemory(lpnrLocal, cbBuffer);
-    //
-    // Call the WNetEnumResource function to continue
-    //  the enumeration.
-    //
-    dwResultEnum = WNetEnumResourceW( hEnum,          // resource handle
-                                      &cEntries,      // defined locally as -1
-                                      lpnrLocal,      // LPNETRESOURCE
-                                      &cbBuffer);     // buffer size
-    //
-    // If the call succeeds, loop through the structures.
-    //
-    if (dwResultEnum == NO_ERROR) 
-    {
-      for (DWORD i = 0; i < cEntries; i++) 
-      {
-        DWORD dwDisplayType = lpnrLocal[i].dwDisplayType;
-        DWORD dwType = lpnrLocal[i].dwType;
-
-        if((((dwDisplayType == RESOURCEDISPLAYTYPE_SERVER) && (m_bHost == false)) || 
-           ((dwDisplayType == RESOURCEDISPLAYTYPE_SHARE) && m_bHost)) &&
-           (dwType != RESOURCETYPE_PRINT))
-        {
-          CStdString strurl = "smb:";
-          CStdStringW strRemoteNameW = lpnrLocal[i].lpRemoteName;
-          CStdString  strName,strRemoteName;
-
-          g_charsetConverter.wToUTF8(strRemoteNameW,strRemoteName);
-          CLog::Log(LOGDEBUG,"Found Server/Share: %s", strRemoteName.c_str());
-
-          strurl.append(strRemoteName);
-          strurl.Replace("\\","/");
-          CURL rooturl(strurl);
-          rooturl.SetFileName("");
-
-          if(!rooturl.GetShareName().empty())
-            strName = rooturl.GetShareName();
-          else
-            strName = rooturl.GetHostName();
-
-          strName.Replace("\\","");
-
-          URIUtils::AddSlashAtEnd(strurl);
-          CFileItemPtr pItem(new CFileItem(strName));
-          pItem->SetPath(strurl);
-          pItem->m_bIsFolder = true;
-          items.Add(pItem);
-        }
-
-        // If the NETRESOURCE structure represents a container resource, 
-        //  call the EnumerateFunc function recursively.
-        if (RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage & RESOURCEUSAGE_CONTAINER))
-          EnumerateFunc(&lpnrLocal[i], items);
-      }
-    }
-    // Process errors.
-    //
-    else if (dwResultEnum != ERROR_NO_MORE_ITEMS) 
-    {
-      CLog::Log(LOGERROR,"WNetEnumResource failed with error %d", dwResultEnum);
-      break;
-    }
-  }
-  //
-  // End do.
-  //
-  while (dwResultEnum != ERROR_NO_MORE_ITEMS);
-  //
-  // Call the GlobalFree function to free the memory.
-  //
-  GlobalFree((HGLOBAL) lpnrLocal);
-  //
-  // Call WNetCloseEnum to end the enumeration.
-  //
-  dwResult = WNetCloseEnum(hEnum);
-
-  if (dwResult != NO_ERROR) 
-  {
-      //
-      // Process errors.
-      //
-      CLog::Log(LOGERROR,"WNetCloseEnum failed with error %d", dwResult);
-      return false;
-  }
-
-  return true;
-}
-
-bool CWINSMBDirectory::ConnectToShare(const CURL& url)
-{
-  NETRESOURCE nr;
-  CURL urlIn(url);
-  DWORD dwRet=-1;
-  CStdString strUNC("\\\\"+url.GetHostName());
-  if(!url.GetShareName().empty())
-    strUNC.append("\\"+url.GetShareName());
-
-  CStdString strPath;
-  memset(&nr,0,sizeof(nr));
-  nr.dwType = RESOURCETYPE_ANY;
-  nr.lpRemoteName = (char*)strUNC.c_str();
-
-  // in general we shouldn't need the password manager as we won't disconnect from shares yet
-  CPasswordManager::GetInstance().AuthenticateURL(urlIn);
-
-  CStdString strAuth = URLEncode(urlIn);
-
-  while(dwRet != NO_ERROR)
-  {
-    strPath = URLEncode(urlIn);
-    LPCTSTR pUser = urlIn.GetUserNameA().empty() ? NULL : (LPCTSTR)urlIn.GetUserNameA().c_str();
-    LPCTSTR pPass = urlIn.GetPassWord().empty() ? NULL : (LPCTSTR)urlIn.GetPassWord().c_str();
-    dwRet = WNetAddConnection2(&nr, pPass, pUser, CONNECT_TEMPORARY);
-#ifdef _DEBUG
-    CLog::Log(LOGDEBUG,"Trying to connect to %s with username(%s) and password(%s)", strUNC.c_str(), urlIn.GetUserNameA().c_str(), urlIn.GetPassWord().c_str());
-#else
-    CLog::Log(LOGDEBUG,"Trying to connect to %s with username(%s) and password(%s)", strUNC.c_str(), urlIn.GetUserNameA().c_str(), "XXXX");
-#endif
-    if(dwRet == ERROR_ACCESS_DENIED || dwRet == ERROR_INVALID_PASSWORD || dwRet == ERROR_LOGON_FAILURE)
-    {
-      CLog::Log(LOGERROR,"Couldn't connect to %s, access denied", strUNC.c_str());
-      if (m_allowPrompting)
-        RequireAuthentication(urlIn.Get());
-      break;
-    }
-    else if(dwRet == ERROR_SESSION_CREDENTIAL_CONFLICT)
-    {
-      DWORD dwRet2=-1;
-      CStdString strRN = nr.lpRemoteName;
-      do
-      {
-        dwRet2 = WNetCancelConnection2((LPCSTR)strRN.c_str(), 0, false);
-        strRN.erase(strRN.find_last_of("\\"),CStdString::npos);
-      } 
-      while(dwRet2 == ERROR_NOT_CONNECTED && !strRN.Equals("\\\\"));
-    }
-    else if(dwRet != NO_ERROR)
-    {
-      break;
-    }
-  }
-
-  if(dwRet != NO_ERROR)
-  {
-    CLog::Log(LOGERROR,"Couldn't connect to %s, error code %d", strUNC.c_str(), dwRet);
-    return false;
-  }
-  return true;
-}
-
-CStdString CWINSMBDirectory::URLEncode(const CURL &url)
-{
-  /* due to smb wanting encoded urls we have to build it manually */
-
-  CStdString flat = "smb://";
-
-  /* samba messes up of password is set but no username is set. don't know why yet */
-  /* probably the url parser that goes crazy */
-  if(url.GetUserName().length() > 0 /* || url.GetPassWord().length() > 0 */)
-  {
-    flat += url.GetUserName();
-    flat += ":";
-    flat += url.GetPassWord();
-    flat += "@";
-  }
-  flat += url.GetHostName();
-
-  /* okey sadly since a slash is an invalid name we have to tokenize */
-  std::vector<CStdString> parts;
-  std::vector<CStdString>::iterator it;
-  CUtil::Tokenize(url.GetFileName(), parts, "/");
-  for( it = parts.begin(); it != parts.end(); it++ )
-  {
-    flat += "/";
-    flat += (*it);
-  }
-
-  /* okey options should go here, thou current samba doesn't support any */
-
-  return flat;
-}
diff --git a/xbmc/win32/WINSMBDirectory.h b/xbmc/win32/WINSMBDirectory.h
deleted file mode 100644 (file)
index f7811be..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#pragma once
-/*
- *      Copyright (C) 2005-2008 Team XBMC
- *      http://www.xbmc.org
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-
-#include "filesystem/IDirectory.h"
-#include "URL.h"
-
-namespace XFILE
-{
-
-class CWINSMBDirectory : public IDirectory
-{
-public:
-  CWINSMBDirectory(void);
-  virtual ~CWINSMBDirectory(void);
-  virtual bool GetDirectory(const CStdString& strPath, CFileItemList &items);
-  virtual DIR_CACHE_TYPE GetCacheType(const CStdString &strPath) const { return DIR_CACHE_ONCE; };
-  virtual bool Create(const char* strPath);
-  virtual bool Exists(const char* strPath);
-  virtual bool Remove(const char* strPath);
-
-  bool ConnectToShare(const CURL& url);
-private:
-  bool m_bHost;
-  bool EnumerateFunc(LPNETRESOURCEW lpnr, CFileItemList &items);
-  CStdString GetLocal(const CStdString& strPath);
-  CStdString URLEncode(const CURL &url);
-};
-}
index ed82b46..8ab1928 100644 (file)
@@ -128,6 +128,7 @@ typedef struct XBMC_JoyButtonEvent {
        unsigned char which;    /* The joystick device index */
        unsigned char button;   /* The joystick button index */
        unsigned char state;    /* XBMC_PRESSED or XBMC_RELEASED */
+  uint32_t      holdTime; /*holdTime of the pressed button*/
 } XBMC_JoyButtonEvent;
 
 /* The "window resized" event
index 4add43b..4796905 100644 (file)
@@ -1,5 +1,5 @@
 /*
-*      Copyright (C) 2010 Team XBMC
+*      Copyright (C) 2012 Team XBMC
 *      http://www.xbmc.org
 *
 *  This Program is free software; you can redistribute it and/or modify
@@ -33,8 +33,10 @@ public:
   static void DeInit();
   static void MessagePush(XBMC_Event *newEvent);
   static bool MessagePump();
+  static int  GetQueueSize();
 
 protected:
 };
 
 #endif // WINDOW_EVENTS_IOS_H
+
index b016aa7..38126b4 100644 (file)
@@ -1,5 +1,5 @@
 /*
-*      Copyright (C) 2010 Team XBMC
+*      Copyright (C) 2012 Team XBMC
 *      http://www.xbmc.org
 *
 *  This Program is free software; you can redistribute it and/or modify
@@ -70,14 +70,16 @@ bool CWinEventsIOS::MessagePump()
     if (pumpEvent.type == XBMC_USEREVENT)
     {
       // On ATV2, we push in events as a XBMC_USEREVENT,
-      // the user.code will be the keyID to translate using joystick.AppleRemote.xml
+      // the jbutton.which will be the keyID to translate using joystick.AppleRemote.xml
+      // jbutton.holdTime is the time the button is hold in ms (for repeated keypresses)
       std::string joystickName = "AppleRemote";
       bool isAxis = false;
-      float fAmount = 0.0;
-      unsigned short wKeyID = pumpEvent.user.code;
+      float fAmount = 1.0;
+      unsigned char wKeyID = pumpEvent.jbutton.which;
+      unsigned int holdTime = pumpEvent.jbutton.holdTime;
 
       CLog::Log(LOGDEBUG,"CWinEventsIOS: Button press keyID = %i", wKeyID);
-      ret |= g_application.ProcessJoystickEvent(joystickName, wKeyID, isAxis, fAmount);
+      ret |= g_application.ProcessJoystickEvent(joystickName, wKeyID, isAxis, fAmount, holdTime);
     }
     else
       ret |= g_application.OnEvent(pumpEvent);
@@ -85,3 +87,9 @@ bool CWinEventsIOS::MessagePump()
 
   return ret;
 }
+
+int CWinEventsIOS::GetQueueSize()
+{
+  CSingleLock lock(g_inputCond);
+  return events.size();
+}
index ece372e..1efd651 100644 (file)
@@ -27,6 +27,9 @@
 #include "Application.h"
 #include "input/XBMC_vkeys.h"
 #include "input/MouseStat.h"
+#if defined(HAS_SDL_JOYSTICK)
+#include "input/SDLJoystick.h"
+#endif
 #include "storage/MediaManager.h"
 #include "windowing/WindowingFactory.h"
 #include <dbt.h>
@@ -39,7 +42,6 @@
 #include "settings/Settings.h"
 #include "settings/AdvancedSettings.h"
 #include "peripherals/Peripherals.h"
-#include "storage/DetectDVDType.h"
 #include "utils/JobManager.h"
 
 #ifdef _WIN32
@@ -384,6 +386,8 @@ LRESULT CALLBACK CWinEventsWin32::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
     case WM_CLOSE:
     case WM_QUIT:
     case WM_DESTROY:
+      if (hDeviceNotify)
+        UnregisterDeviceNotification(hDeviceNotify);
       newEvent.type = XBMC_QUIT;
       m_pEventFunc(newEvent);
       break;
@@ -679,14 +683,20 @@ LRESULT CALLBACK CWinEventsWin32::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
       break;
     case WM_DEVICECHANGE:
       {
-        PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE) lParam;
-        switch (wParam)
+        switch(wParam)
         {
-          case DBT_DEVICEARRIVAL:
-          case DBT_DEVICEREMOVECOMPLETE:
           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);
+#if defined(HAS_SDL_JOYSTICK)
+              g_Joystick.Reinitialize();
+#endif
+            }
         }
         break;
       }
index e0f65cb..7cdf87b 100644 (file)
@@ -53,7 +53,7 @@
 #include "utils/URIUtils.h"
 #include "guilib/LocalizeStrings.h"
 #include "utils/TimeUtils.h"
-#include "filesystem/FactoryFileDirectory.h"
+#include "filesystem/FileDirectoryFactory.h"
 #include "utils/log.h"
 #include "utils/FileUtils.h"
 #include "guilib/GUIEditControl.h"
@@ -656,7 +656,7 @@ bool CGUIMediaWindow::GetDirectory(const CStdString &strDirectory, CFileItemList
       m_history.RemoveParentPath();
   }
 
-  if (m_guiState.get() && !m_guiState->HideParentDirItems() && items.GetPath() != m_startDirectory)
+  if (m_guiState.get() && !m_guiState->HideParentDirItems() && !items.GetPath().IsEmpty())
   {
     CFileItemPtr pItem(new CFileItem(".."));
     pItem->SetPath(strParentPath);
@@ -878,7 +878,7 @@ bool CGUIMediaWindow::OnClick(int iItem)
   if (!pItem->m_bIsFolder && pItem->IsFileFolder())
   {
     XFILE::IFileDirectory *pFileDirectory = NULL;
-    pFileDirectory = XFILE::CFactoryFileDirectory::Create(pItem->GetPath(), pItem.get(), "");
+    pFileDirectory = XFILE::CFileDirectoryFactory::Create(pItem->GetPath(), pItem.get(), "");
     if(pFileDirectory)
       pItem->m_bIsFolder = true;
     else if(pItem->m_bIsFolder)
index 72fb75f..019991f 100644 (file)
@@ -56,7 +56,7 @@ void CGUIWindowHome::OnInitWindow()
   CGUIWindow::OnInitWindow();
 }
 
-void CGUIWindowHome::Announce(EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
+void CGUIWindowHome::Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data)
 {
   int ra_flag = 0;
 
index 4215404..50a695d 100644 (file)
@@ -34,7 +34,7 @@ public:
   CGUIWindowHome(void);
   virtual ~CGUIWindowHome(void);
   virtual void OnInitWindow();
-  virtual void Announce(ANNOUNCEMENT::EAnnouncementFlag flag, const char *sender, const char *message, const CVariant &data);
+  virtual void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data);
 
   virtual bool OnMessage(CGUIMessage& message);