aboutsummaryrefslogtreecommitdiff
path: root/Src/Winamp/Browser.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/Winamp/Browser.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Winamp/Browser.cpp')
-rw-r--r--Src/Winamp/Browser.cpp368
1 files changed, 368 insertions, 0 deletions
diff --git a/Src/Winamp/Browser.cpp b/Src/Winamp/Browser.cpp
new file mode 100644
index 00000000..5808bae1
--- /dev/null
+++ b/Src/Winamp/Browser.cpp
@@ -0,0 +1,368 @@
+#include "Main.h"
+#include "Browser.h"
+#include "menuv5.h"
+#include "ExternalCOM.h"
+#include "wa_dlg.h"
+#include "resource.h"
+#include "../nu/ns_wc.h"
+
+Browser *browser = 0;
+static WNDPROC oldBrowserProc = 0;
+static DWORD browserThreadId=0;
+static HANDLE killBrowserEvent=0;
+static HANDLE browserThreadHandle=0;
+static BOOL fUnicode = FALSE;
+static LRESULT WINAPI BrowserSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_PAINT:
+ {
+ HDC out = GetDC(hwnd);
+ RECT r;
+ GetClientRect(hwnd, &r);
+ r.left = 11;
+ r.top = 20;
+ r.right -= 8;
+ r.bottom -= 14;
+
+ HBRUSH b = CreateSolidBrush(WADlg_getColor(WADLG_WNDBG));
+ FillRect(out, &r, b);
+ DeleteObject(b);
+ ValidateRect(hwnd, &r);
+ }
+ break;
+
+ case WM_USER + 0x100:
+ if (wParam == 1 && lParam)
+ {
+ config_si_wx = ((POINT *)lParam)->x;
+ config_si_wy = ((POINT *)lParam)->y;
+ }
+ break;
+
+ case WM_USER + 0x101:
+ if (wParam == 1 && lParam)
+ {
+ config_si_width = ((POINT *)lParam)->x;
+ config_si_height = ((POINT *)lParam)->y;
+ }
+ break;
+
+ case WM_USER + 0x102:
+ {
+ if (wParam == 1)
+ {
+ if (!config_minimized)
+ ShowWindow(browser->m_hwnd, SW_SHOW);
+ config_si_open = 1;
+ const char *url = PlayList_getbrowser(PlayList_getPosition());
+ if (url && *url)
+ browser->NavigateToName(url);
+ }
+ else
+ {
+ ShowWindow(browser->m_hwnd, SW_HIDE);
+ config_si_open = 0;
+ }
+ browser->SetMenuCheckMark();
+ }
+ break;
+
+ case WM_USER + 101:
+ {
+ ShowWindow(hwnd, SW_HIDE);
+ ShowWindow(browser->m_hwnd, SW_HIDE);
+ config_si_open = 0;
+ browser->SetMenuCheckMark();
+ return 0;
+ }
+ break;
+
+ case WM_DESTROY:
+ browser->m_hwnd = 0;
+ SetEvent(killBrowserEvent);
+ return 0;
+ }
+
+ if (oldBrowserProc) return (fUnicode) ? CallWindowProcW(oldBrowserProc, hwnd, msg, wParam, lParam) : CallWindowProcA(oldBrowserProc, hwnd, msg, wParam, lParam);
+ else return (fUnicode) ? DefWindowProcW(hwnd, msg, wParam, lParam) : DefWindowProcA(hwnd, msg, wParam, lParam);
+}
+// {25CE50EF-3EE2-4356-A638-6E495C44BFB8}
+static const GUID StationInfoGUID =
+{ 0x25ce50ef, 0x3ee2, 0x4356, { 0xa6, 0x38, 0x6e, 0x49, 0x5c, 0x44, 0xbf, 0xb8 } };
+
+Browser::Browser()
+: minimised(false), threadId(0), state(0)
+{
+}
+
+Browser::~Browser()
+{
+}
+
+HWND Browser::CreateHWND()
+{
+ if (!m_hwnd)
+ {
+ threadId = GetCurrentThreadId();
+
+ state.flags = EMBED_FLAGS_NOWINDOWMENU;
+ state.me = 0;
+ state.r.left = config_si_wx;
+ state.r.right = config_si_wx + config_si_width;
+ state.r.top = config_si_wy;
+ state.r.bottom = config_si_wy + config_si_height;
+
+ state.flags |= EMBED_FLAGS_GUID;
+ void *blah = state.extra_data+4;
+ memcpy(blah, &StationInfoGUID, sizeof(GUID));
+
+ HWND owner = (HWND)SendMessage(hMainWindow, WM_WA_IPC, (WPARAM)&state, IPC_GET_EMBEDIF);
+
+ m_hwnd = owner;
+ setLocation(11, 20, config_si_width - 19, config_si_height - 34);
+ fUnicode = IsWindowUnicode(owner);
+ oldBrowserProc = (WNDPROC) ((fUnicode) ? SetWindowLongPtrW(owner, GWLP_WNDPROC, (LONG_PTR)BrowserSubclassProc) :
+ SetWindowLongPtrA(owner, GWLP_WNDPROC, (LONG_PTR)BrowserSubclassProc));
+ wchar_t langBuf[1024];
+ SetWindowTextW(owner, getStringW(IDS_STATIONINFOCAPTION, langBuf, 1024));
+ }
+ EnableMenuItem(main_menu, WINAMP_BROWSER_ID, MF_BYCOMMAND | MF_ENABLED);
+
+ if (config_si_autoshow || (config_si_open/* && !visible*/))
+ {
+ if(g_showcode!=SW_SHOWMINIMIZED && !config_minimized)
+ ShowWindow(m_hwnd, SW_SHOW);
+ else
+ browser->minimised = 1;
+ config_si_open = 1;
+ browser->SetMenuCheckMark();
+ }
+
+ return m_hwnd;
+}
+
+// ---------------------------------------------------------------
+void Browser::NavigateToName(LPCTSTR pszUrl)
+{
+ if (!config_si_open)
+ return ;
+ if (!m_pweb) return ;
+ DWORD dwChars = lstrlen (pszUrl) + 1;
+ LPWSTR pwszUrl = (LPWSTR)LocalAlloc (LPTR, dwChars * sizeof (WCHAR));
+ long moptions = navNoReadFromCache | navNoWriteToCache | navNoHistory;
+ VARIANT options;
+ memset( (void*)&options, 0, sizeof(VARIANT));
+ V_VT(&options) = VT_I4;
+ V_I4(&options) = moptions;
+ if (pwszUrl)
+ {
+ MultiByteToWideCharSZ(CP_ACP, 0, pszUrl, -1, pwszUrl, dwChars);
+ m_pweb->Navigate (pwszUrl, &options , 0, 0, 0);
+ LocalFree (pwszUrl);
+ }
+}
+
+#define VIDEO_GENFF_SIZEREQUEST (WM_USER+2048)
+void Browser::Resized(unsigned long width, unsigned long height)
+{
+ if (!config_si_autosize)
+ return ;
+ setLocation(11, 20, width, height);
+ config_si_width = width + 19;
+ config_si_height = height + 34;
+ if (GetParent(m_hwnd))
+ SendMessage(GetParent(m_hwnd), VIDEO_GENFF_SIZEREQUEST, width, height);
+ else
+ SetWindowPos(m_hwnd, 0, 0, 0, width + 19, height + 34, SWP_NOMOVE | SWP_ASYNCWINDOWPOS);
+
+ InvalidateRect(m_hwnd, NULL, TRUE);
+}
+
+HRESULT Browser::GetExternal(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch)
+{
+ *ppDispatch = (IDispatch *) & externalCOM;
+ return S_OK;
+}
+
+void Browser::ToggleVisible(int showing)
+{
+ if ((!config_si_open && !showing) || (showing && minimised))
+ {
+ if(minimised) minimised = 0;
+ CreateHWND();
+ if (m_hwnd)
+ PostMessage(m_hwnd, WM_USER + 0x102, 1, 0);
+ }
+ else if(!showing)
+ {
+ if(minimised) minimised = 0;
+ if (m_hwnd)
+ PostMessage(m_hwnd, WM_USER + 0x102, 0, 0);
+ }
+}
+
+void Browser::OnNavigateComplete()
+{
+ setVisible(TRUE);
+ RECT r;
+ GetClientRect(m_hwnd, &r);
+ setLocation(11, 20, r.right - 19, r.bottom - 34);
+}
+
+void Browser::SetMenuCheckMark()
+{
+ MENUITEMINFO i = {sizeof(i), MIIM_STATE , MFT_STRING, config_si_open ? MFS_CHECKED : MFS_UNCHECKED, WINAMP_BROWSER_ID};
+ SetMenuItemInfo(main_menu, WINAMP_BROWSER_ID, FALSE, &i);
+}
+
+/* ---- APCs ---- */
+VOID CALLBACK ToggleVisibleAPC(ULONG_PTR param)
+{
+ browser->ToggleVisible(param);
+}
+
+VOID CALLBACK SetVisibleAPC(ULONG_PTR param)
+{
+ BOOL visible = (BOOL)param;
+ browser->setVisible(visible);
+}
+
+VOID CALLBACK NavigateAPC(ULONG_PTR param)
+{
+ char *url = (char *)param;
+ browser->NavigateToName(url);
+ free(url);
+}
+
+VOID CALLBACK CreateHWNDAPC(ULONG_PTR param)
+{
+ browser->CreateHWND();
+}
+
+HANDLE browserEvent=0;
+/* ---- ---- */
+static DWORD CALLBACK BrowserThread(LPVOID param)
+{
+ if (!browser)
+ browser = new Browser;
+ killBrowserEvent = CreateEvent(0, TRUE, FALSE, 0);
+ SetEvent(browserEvent);
+
+ while (1)
+ {
+ DWORD dwStatus = MsgWaitForMultipleObjectsEx(1, &killBrowserEvent,
+ INFINITE, QS_ALLINPUT,
+ MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
+ if (dwStatus == WAIT_OBJECT_0)
+ {
+ browser->remove();
+ browser->close();
+ browser->Release();
+ CloseHandle(killBrowserEvent);
+ return 0;
+ }
+ else if (dwStatus == WAIT_OBJECT_0 + 1)
+ {
+ MSG msg;
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (msg.message == WM_QUIT)
+ {
+ browser->remove();
+ browser->close();
+ browser->Release();
+ CloseHandle(killBrowserEvent);
+ return 0;
+ }
+ if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN ||
+ msg.message == WM_KEYUP || msg.message == WM_SYSKEYUP)
+ {
+ if (!browser->translateKey(&msg))
+ {
+ PostMessage(hMainWindow, msg.message, msg.wParam, msg.lParam);
+ }
+ }
+ else
+ {
+ if (!browser->translateKey(&msg))
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static void CreateBrowser()
+{
+ if (!browser)
+ {
+ browserEvent = CreateEvent(0, TRUE, FALSE, 0);
+ browserThreadHandle = CreateThread(0, 0, BrowserThread, 0, 0, &browserThreadId);
+ WaitForSingleObject(browserEvent, INFINITE);
+ }
+}
+
+static void CallAPC(PAPCFUNC func, ULONG_PTR param)
+{
+ if (browserThreadHandle)
+ {
+ DWORD curThreadId = GetCurrentThreadId();
+ if (curThreadId == browserThreadId)
+ func(param);
+ else
+ {
+ QueueUserAPC(func, browserThreadHandle, param);
+ }
+ }
+}
+
+void Browser_toggleVisible(int showing)
+{
+ CreateBrowser();
+ CallAPC(ToggleVisibleAPC, showing);
+}
+
+void CloseBrowser()
+{
+ if (!browser || !browser->m_hwnd)
+ return ;
+ if (config_si_autohide)
+ PostMessage(browser->m_hwnd, WM_USER + 0x102, 0, 0);
+ else
+ CallAPC(SetVisibleAPC, FALSE);
+}
+
+void LaunchBrowser(const char *url)
+{
+ OpenBrowser();
+ CallAPC(NavigateAPC, (ULONG_PTR)_strdup(url));
+}
+
+void OpenBrowser()
+{
+ CreateBrowser();
+ CallAPC(CreateHWNDAPC, 0);
+}
+
+void Browser_init()
+{
+ MENUITEMINFO i = {sizeof(i), MIIM_ID | MIIM_STATE | MIIM_TYPE, MFT_STRING, MFS_UNCHECKED, WINAMP_BROWSER_ID};
+ i.dwTypeData = getString(IDS_STATIONINFO_MENU,NULL,0);;
+ InsertMenuItem(main_menu, 10 + g_mm_optionsbase_adj, TRUE, &i);
+ g_mm_optionsbase_adj++;
+}
+
+void Browser_kill()
+{
+ if (browserThreadHandle)
+ {
+ SetEvent(killBrowserEvent); // just in case, so we don't hang here
+ WaitForSingleObject(browserThreadHandle, INFINITE);
+ CloseHandle(browserThreadHandle);
+ browserThreadHandle=0;
+ }
+} \ No newline at end of file