aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_swf/main.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Input/in_swf/main.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Plugins/Input/in_swf/main.cpp')
-rw-r--r--Src/Plugins/Input/in_swf/main.cpp447
1 files changed, 447 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_swf/main.cpp b/Src/Plugins/Input/in_swf/main.cpp
new file mode 100644
index 00000000..8da97055
--- /dev/null
+++ b/Src/Plugins/Input/in_swf/main.cpp
@@ -0,0 +1,447 @@
+#include "main.h"
+#include "api.h"
+#include "../Winamp/wa_ipc.h"
+#include "../Winamp/strutil.h"
+#include <shlwapi.h>
+#include "FLVExternalInterface.h"
+#include <api/service/waServiceFactory.h>
+#include <strsafe.h>
+#include "resource.h"
+
+#define SWF_PLUGIN_VERSION L"1.15"
+
+FLVExternalInterface flashExternalInterface;
+IVideoOutput *videoOutput=0;
+int playPosition=0;
+int playLength=-1000;
+api_application *WASABI_API_APP = 0;
+api_language *WASABI_API_LNG = 0;
+HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
+wchar_t pluginName[256] = {0}, status[256] = {0};
+Nullsoft::Utility::LockGuard statusGuard;
+
+template <class api_T>
+static void ServiceBuild(api_T *&api_t, GUID factoryGUID_t)
+{
+ if (plugin.service)
+ {
+ waServiceFactory *factory = plugin.service->service_getServiceByGuid(factoryGUID_t);
+ if (factory)
+ api_t = reinterpret_cast<api_T *>( factory->getInterface() );
+ }
+}
+
+template <class api_T>
+static void ServiceRelease(api_T *api_t, GUID factoryGUID_t)
+{
+ if (plugin.service)
+ {
+ waServiceFactory *factory = plugin.service->service_getServiceByGuid(factoryGUID_t);
+ if (factory)
+ factory->releaseInterface(api_t);
+ }
+ api_t = NULL;
+}
+
+void SetFileExtensions(void)
+{
+ static char fileExtensionsString[1200] = {0}; // "SWF\0Shockwave Flash Files\0"
+ char* end = 0;
+ StringCchCopyExA(fileExtensionsString, 1200, "SWF", &end, 0, 0);
+ StringCchCopyExA(end+1, 1200, WASABI_API_LNGSTRING(IDS_SWF_FILES), 0, 0, 0);
+ plugin.FileExtensions = fileExtensionsString;
+}
+
+int Init()
+{
+ if (!IsWindow(plugin.hMainWindow))
+ return IN_INIT_FAILURE;
+
+ ServiceBuild(WASABI_API_APP, applicationApiServiceGuid);
+ ServiceBuild(WASABI_API_LNG, languageApiGUID);
+
+ WASABI_API_START_LANG(plugin.hDllInstance,InSwfLangGUID);
+ StringCchPrintfW(pluginName,256,WASABI_API_LNGSTRINGW(IDS_NULLSOFT_SWF),SWF_PLUGIN_VERSION);
+ plugin.description = (char*)pluginName;
+ SetFileExtensions();
+
+ return IN_INIT_SUCCESS;
+}
+
+void Quit()
+{
+ ServiceRelease(WASABI_API_APP, applicationApiServiceGuid);
+ ServiceRelease(WASABI_API_LNG, languageApiGUID);
+}
+
+void GetFileInfo(const in_char *file, in_char *title, int *length_in_ms)
+{
+ if (length_in_ms)
+ {
+ if (file && *file)
+ *length_in_ms=-1000;
+ else
+ *length_in_ms = playLength;
+ }
+
+ if (title)
+ {
+ if (file && *file)
+ *title=0;
+ else
+ {
+ Nullsoft::Utility::AutoLock autolock(statusGuard);
+ if (status[0])
+ StringCchPrintf(title, GETFILEINFO_TITLE_LENGTH, L"[%s]", status);
+ else
+ *title=0;
+ }
+ }
+}
+
+int InfoBox(const in_char *file, HWND hwndParent)
+{
+ return INFOBOX_UNCHANGED;
+}
+
+int IsOurFile(const in_char *fn)
+{
+ if (!_wcsnicmp(fn, L"rtmp://", 7))
+ return 1;
+ return 0;
+}
+
+static bool isFLV = false;
+static int PlaySWF(BSTR filename)
+{
+#ifdef WIN64
+ if (!activeContainer || (unsigned long long)activeContainer < 65536)
+ {
+ isFLV = false;
+ return 1;
+ }
+#else
+ if (!activeContainer || (unsigned long)activeContainer < 65536)
+ {
+ isFLV = false;
+ return 1;
+}
+#endif
+
+ isFLV = false;
+ activeContainer->externalInterface = &flashExternalInterface;
+ activeContainer->flash->DisableLocalSecurity();
+ activeContainer->flash->put_BackgroundColor(0);
+ activeContainer->flash->put_EmbedMovie(FALSE);
+ activeContainer->flash->put_Scale(L"showAll");
+ activeContainer->flash->put_AllowScriptAccess(L"always");
+
+ HRESULT hr = activeContainer->flash->LoadMovie(0, filename);
+
+ activeContainer->setVisible(TRUE);
+
+ plugin.is_seekable = 0; // not seekable to start, we'll find out after opening if it's really seekable or not
+ return 0;
+}
+
+static int PlayFLV(const wchar_t *filename)
+{
+#ifdef WIN64
+ if (!activeContainer || (unsigned long long)activeContainer < 65536)
+ {
+ isFLV = false;
+ return 1;
+}
+# else
+ if (!activeContainer || (unsigned long)activeContainer < 65536)
+ {
+ isFLV = false;
+ return 1;
+ }
+#endif //
+
+// if (!activeContainer || (unsigned long)activeContainer < 65536)
+// {
+// isFLV = false;
+// return 1;
+// }
+
+ isFLV = true;
+ activeContainer->externalInterface = &flashExternalInterface;
+ activeContainer->flash->DisableLocalSecurity();
+ activeContainer->flash->put_BackgroundColor(0);
+ activeContainer->flash->put_EmbedMovie(FALSE);
+ activeContainer->flash->put_Scale(L"showAll");
+ activeContainer->flash->put_AllowScriptAccess(L"always");
+
+ static wchar_t pluginPath[MAX_PATH] = {0}, swfPath[MAX_PATH+7] = {0};
+ if (!pluginPath[0] && !swfPath[0])
+ {
+ lstrcpynW(pluginPath, (wchar_t*)SendMessage(plugin.hMainWindow, WM_WA_IPC, 0, IPC_GETPLUGINDIRECTORYW), MAX_PATH);
+ PathAppend(pluginPath, L"winampFLV.swf");
+ for (wchar_t *itr = pluginPath; *itr; itr++)
+ {
+ if (*itr == '\\')
+ *itr = '/';
+ }
+ StringCchPrintf(swfPath, MAX_PATH+7, L"file://%s", pluginPath);
+ }
+
+ HRESULT hr = activeContainer->flash->LoadMovie(0, swfPath);
+
+ activeContainer->setVisible(TRUE);
+
+ // TODO: make filename XML-safe
+ wchar_t funcCall[1024] = {0};
+ StringCchPrintf(funcCall, 1024, L"<invoke name=\"PlayFLV\" returntype=\"xml\"><arguments><string>%s</string></arguments></invoke>", filename);
+ BSTR bstr_ret = 0;
+ activeContainer->flash->CallFunction(funcCall, &bstr_ret);
+ SetVolume(volume);
+ SetPan(pan);
+
+ plugin.is_seekable = 1; // not seekable to start, we'll find out after opening if it's really seekable or not
+ return 0;
+}
+
+int Play(const in_char *filename)
+{
+ status[0]=0;
+ playPosition=0;
+ playLength=-1000;
+
+ if (!filename || !*filename)
+ return 1;
+
+ if (!videoOutput)
+ videoOutput = (IVideoOutput *)SendMessage(plugin.hMainWindow,WM_WA_IPC,0,IPC_GET_IVIDEOOUTPUT);
+
+ if (!videoOutput)
+ return 1;
+
+ HWND videoWnd = (HWND)videoOutput->extended(VIDUSER_GET_VIDEOHWND, 0, 0); // ask for the video hwnd
+
+ wchar_t *mangledFilename = 0;
+ if (PathIsURL(filename))
+ mangledFilename = const_cast<wchar_t *>(filename);
+ else
+ {
+ mangledFilename = (wchar_t *)malloc((MAX_PATH + 7)*sizeof(wchar_t));
+ StringCchPrintf(mangledFilename, MAX_PATH+7, L"file://%s", filename);
+ }
+ videoOutput->open(0, 0, 0, 1.0, 'ENON');
+ activeContainer = new SWFContainer(videoWnd);
+ if (!activeContainer->flash)
+ {
+ delete activeContainer;
+ activeContainer=0;
+ if (mangledFilename != filename)
+ free(mangledFilename);
+ return 1; // failed
+ }
+
+ oldVidProc = (WNDPROC)(LONG_PTR)SetWindowLongPtr(videoWnd, GWLP_WNDPROC, (LONG)(LONG_PTR)WndProc);
+
+ wchar_t ext[16]=L"";
+ extension_exW(filename, ext, 16);
+ if (!_wcsicmp(ext, L"swf"))
+ {
+ if (PlaySWF(mangledFilename))
+ {
+ return 1; // failed
+ }
+ }
+ else
+ {
+ if (PlayFLV(mangledFilename))
+ {
+ return 1; // failed
+ }
+ }
+
+ HRESULT hr = activeContainer->flash->Play();
+
+ if (mangledFilename != filename)
+ free(mangledFilename);
+
+ return 0;
+}
+
+int localPause=0;
+void Pause()
+{
+ localPause=1;
+
+ if (isFLV)
+ {
+ BSTR bstr_ret;
+ activeContainer->flash->CallFunction(L"<invoke name=\"Pause\" returntype=\"xml\"><arguments></arguments></invoke>", &bstr_ret);
+ }
+}
+
+void UnPause()
+{
+ localPause=0;
+ if (isFLV)
+ {
+ BSTR bstr_ret;
+ activeContainer->flash->CallFunction(L"<invoke name=\"Resume\" returntype=\"xml\"><arguments></arguments></invoke>", &bstr_ret);
+ }
+}
+
+int IsPaused()
+{
+ return localPause;
+}
+
+void Stop()
+{
+ videoOutput->close();
+ HWND videoWnd = (HWND)videoOutput->extended(VIDUSER_GET_VIDEOHWND, 0, 0); // ask for the video hwnd
+ SetWindowLongPtr(videoWnd, GWLP_WNDPROC, (LONG)(LONG_PTR)oldVidProc);
+ activeContainer->close();
+ activeContainer->Release();
+ activeContainer=0;
+}
+
+int GetLength()
+{
+ return playLength;
+}
+
+int GetOutputTime()
+{
+ return playPosition;
+}
+
+void SetOutputTime(int time_in_ms)
+{
+ if (activeContainer)
+ {
+ if (isFLV)
+ {
+ double seconds = time_in_ms;
+ seconds/=1000.0;
+
+ wchar_t funcCall[1024] = {0};
+ StringCchPrintf(funcCall, 1024, L"<invoke name=\"Seek\" returntype=\"xml\"><arguments><number>%.3f</number></arguments></invoke>", seconds);
+ BSTR bstr_ret;
+ activeContainer->flash->CallFunction(funcCall, &bstr_ret);
+ }
+ else
+ {
+ // TODO: maybe change the frame?
+ }
+ }
+}
+
+int pan = 0, volume = 255;
+void SetVolume(int _volume)
+{
+ volume = _volume;
+ if (activeContainer)
+ {
+ if (isFLV)
+ {
+ int newVolume = (volume * 100) / 255;
+
+ wchar_t funcCall[1024] = {0};
+ StringCchPrintf(funcCall, 1024, L"<invoke name=\"SetVolume\" returntype=\"xml\"><arguments><number>%u</number></arguments></invoke>", newVolume);
+ BSTR bstr_ret;
+ activeContainer->flash->CallFunction(funcCall, &bstr_ret);
+ }
+ }
+}
+
+void SetPan(int _pan)
+{
+ pan = _pan;
+ if (activeContainer)
+ {
+ if (isFLV)
+ {
+ int left = 100;
+ int right = 100;
+ if (pan < 0)
+ left += (pan * 100)/127;
+ if (pan>0)
+ right-=(pan*100)/127;
+
+ wchar_t funcCall[1024] = {0};
+ StringCchPrintf(funcCall, 1024, L"<invoke name=\"SetPan\" returntype=\"xml\"><arguments><number>%u</number><number>%u</number></arguments></invoke>", left, right);
+ BSTR bstr_ret = 0;
+ activeContainer->flash->CallFunction(funcCall, &bstr_ret);
+ }
+ }
+}
+
+void EQSet(int on, char data[10], int preamp)
+{}
+
+int DoAboutMessageBox(HWND parent, wchar_t* title, wchar_t* message)
+{
+ MSGBOXPARAMS msgbx = {sizeof(MSGBOXPARAMS),0};
+ msgbx.lpszText = message;
+ msgbx.lpszCaption = title;
+ msgbx.lpszIcon = MAKEINTRESOURCE(102);
+ msgbx.hInstance = GetModuleHandle(0);
+ msgbx.dwStyle = MB_USERICON;
+ msgbx.hwndOwner = parent;
+ return MessageBoxIndirect(&msgbx);
+}
+
+void About(HWND hwndParent);
+In_Module plugin =
+{
+ IN_VER_RET,
+ "nullsoft(in_swf.dll)",
+ 0,
+ 0,
+ 0 /*"SWF\0Shockwave Flash Files\0"*/,
+ 1,
+ 1,
+ About,
+ About,
+ Init,
+ Quit,
+ GetFileInfo,
+ InfoBox,
+ IsOurFile,
+ Play,
+ Pause,
+ UnPause,
+ IsPaused,
+ Stop,
+ GetLength,
+ GetOutputTime,
+ SetOutputTime,
+ SetVolume,
+ SetPan,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ EQSet,
+ 0,
+ 0
+};
+
+void About(HWND hwndParent)
+{
+ wchar_t message[1024] = {0}, text[1024] = {0};
+ WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_SWF_OLD,text,1024);
+ StringCchPrintf(message, 1024, WASABI_API_LNGSTRINGW(IDS_ABOUT_TEXT),
+ plugin.description, TEXT(__DATE__));
+ DoAboutMessageBox(hwndParent,text,message);
+}
+
+extern "C" __declspec(dllexport) In_Module * winampGetInModule2()
+{
+ return &plugin;
+} \ No newline at end of file