diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Winamp/Browser.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Winamp/Browser.cpp')
-rw-r--r-- | Src/Winamp/Browser.cpp | 368 |
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 |