diff options
Diffstat (limited to 'Src/Winamp/util.cpp')
-rw-r--r-- | Src/Winamp/util.cpp | 660 |
1 files changed, 660 insertions, 0 deletions
diff --git a/Src/Winamp/util.cpp b/Src/Winamp/util.cpp new file mode 100644 index 00000000..23427f56 --- /dev/null +++ b/Src/Winamp/util.cpp @@ -0,0 +1,660 @@ +/** (c) Nullsoft, Inc. C O N F I D E N T I A L + ** Filename: + ** Project: + ** Description: + ** Author: + ** Created: + **/ + +#include "main.h" +#include <windows.h> +#include "strutil.h" +#include "../nu/ns_wc.h" +#include "plush/plush.h" +#include "../nu/AutoChar.h" +#include "../nu/AutoWide.h" +#include "WinampAttributes.h" + +#undef GetSystemMetrics + +int IsUrl(const char *url) +{ + return !!strstr(url, "://"); +} + + +void link_startsubclass(HWND hwndDlg, UINT id){ +HWND ctrl = GetDlgItem(hwndDlg, id); + if(!GetPropW(ctrl, L"link_proc")) + { + SetPropW(ctrl, L"link_proc", + (HANDLE)SetWindowLongPtrW(ctrl, GWLP_WNDPROC, (LONG_PTR)link_handlecursor)); + } +} + +static HCURSOR link_hand_cursor; +LRESULT link_handlecursor(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LRESULT ret = CallWindowProcW((WNDPROC)GetPropW(hwndDlg, L"link_proc"), hwndDlg, uMsg, wParam, lParam); + // override the normal cursor behaviour so we have a hand to show it is a link + if(uMsg == WM_SETCURSOR) + { + if((HWND)wParam == hwndDlg) + { + if(!link_hand_cursor) + { + link_hand_cursor = LoadCursor(NULL, IDC_HAND); + } + SetCursor(link_hand_cursor); + return TRUE; + } + } + return ret; +} + +void link_handledraw(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == WM_DRAWITEM) + { + DRAWITEMSTRUCT *di = (DRAWITEMSTRUCT *)lParam; + if (di->CtlType == ODT_BUTTON) + { + wchar_t wt[123] = {0}; + int y; + RECT r; + HPEN hPen, hOldPen; + GetDlgItemTextW(hwndDlg, wParam, wt, sizeof(wt)/sizeof(wt[0])); + + // draw text + SetTextColor(di->hDC, (di->itemState & ODS_SELECTED) ? RGB(220, 0, 0) : RGB(0, 0, 220)); + r = di->rcItem; + // is used by the file types page to have a slimmer button so it doesn't override other + // characters which are otherwise drawn over by the size of the button needed for a link + if(GetPropW(di->hwndItem, L"slim")) + { + r.top -= 2; + } + r.left += 2; + DrawTextW(di->hDC, wt, -1, &r, DT_VCENTER | DT_SINGLELINE); + + memset(&r, 0, sizeof(r)); + DrawTextW(di->hDC, wt, -1, &r, DT_SINGLELINE | DT_CALCRECT); + + // draw underline + y = di->rcItem.bottom - ((di->rcItem.bottom - di->rcItem.top) - (r.bottom - r.top)) / 2 - 1; + hPen = CreatePen(PS_SOLID, 0, (di->itemState & ODS_SELECTED) ? RGB(220, 0, 0) : RGB(0, 0, 220)); + hOldPen = (HPEN) SelectObject(di->hDC, hPen); + MoveToEx(di->hDC, di->rcItem.left + 2, y, NULL); + LineTo(di->hDC, di->rcItem.right + 2 - ((di->rcItem.right - di->rcItem.left) - (r.right - r.left)), y); + SelectObject(di->hDC, hOldPen); + DeleteObject(hPen); + } + } +} + +///////// if you update this, be sure to update the copy of it in $/winampa/winampicon.c +// thx. +int geticonid(int x) +{ + switch (x) { + case 1: return IDI_FILEICON; + case 2: return IDI_FILEICON2; + case 3: return IDI_FILEICON3; + case 4: return IDI_FILEICON10; + case 5: return IDI_FILEICON5; + case 6: return IDI_FILEICON6; + case 7: return IDI_FILEICON7; + case 8: return IDI_FILEICON8; + case 9: return IDI_FILEICON9; + case 10: return IDI_FILEICON4; + case 11: return IDI_FILEICON11; + case 12: return ICON_TB1; + case 13: return -666; + default: return ICON_XP; + } +} +/* +void plSplineGetPoint(pl_Spline *s, float frame, float *out) +{ + int i, i_1, i0, i1, i2; + float time1, time2, time3; + float t1, t2, t3, t4, u1, u2, u3, u4, v1, v2, v3; + float a, b, c, d; + + float *keys = s->keys; + + a = (1 - s->tens) * (1 + s->cont) * (1 + s->bias); + b = (1 - s->tens) * (1 - s->cont) * (1 - s->bias); + c = (1 - s->tens) * (1 - s->cont) * (1 + s->bias); + d = (1 - s->tens) * (1 + s->cont) * (1 - s->bias); + v1 = t1 = -a / 2.0f; u1 = a; + u2 = ( -6 - 2 * a + 2 * b + c) / 2.0f; v2 = (a - b) / 2.0f; t2 = (4 + a - b - c) / 2.0f; + t3 = ( -4 + b + c - d) / 2.0f; + u3 = (6 - 2 * b - c + d) / 2.0f; + v3 = b / 2.0f; + t4 = d / 2.0f; u4 = -t4; + + i0 = (int) frame; + i_1 = i0 - 1; + while (i_1 < 0) i_1 += s->numKeys; + i1 = i0 + 1; + while (i1 >= s->numKeys) i1 -= s->numKeys; + i2 = i0 + 2; + while (i2 >= s->numKeys) i2 -= s->numKeys; + time1 = frame - (float) ((int) frame); + time2 = time1 * time1; + time3 = time2 * time1; + i0 *= s->keyWidth; + i1 *= s->keyWidth; + i2 *= s->keyWidth; + i_1 *= s->keyWidth; + for (i = 0; i < s->keyWidth; i ++) + { + a = t1 * keys[i + i_1] + t2 * keys[i + i0] + t3 * keys[i + i1] + t4 * keys[i + i2]; + b = u1 * keys[i + i_1] + u2 * keys[i + i0] + u3 * keys[i + i1] + u4 * keys[i + i2]; + c = v1 * keys[i + i_1] + v2 * keys[i + i0] + v3 * keys[i + i1]; + *out++ = a * time3 + b * time2 + c * time1 + keys[i + i0]; + } +} +*/ +//int transAccel(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +//{ +// HACCEL h; +// MSG msg; +// if (hwnd == hMainWindow) h = hAccel[0]; +// else if (hwnd == hEQWindow) h = hAccel[1]; +// else if (hwnd == hPLWindow) h = hAccel[2]; +// // else if (hwnd==hMBWindow) h=hAccel[3]; +// else if (hwnd == hVideoWindow || GetParent(hwnd) == hVideoWindow) +// { +// h = hAccel[0]; +// } +// else +// { +// return 0; +// } +// msg.hwnd = hwnd; +// msg.lParam = lParam; +// msg.message = uMsg; +// msg.wParam = wParam; +// return TranslateAccelerator(hwnd, h, &msg); +// +//} + +#include <pshpack4.h> + +typedef struct +{ + DWORD dwSize; + HANDLE hrasconn; + char szEntryName[256 + 1]; + char szDeviceType[ 16 + 1 ]; + char szDeviceName[ 128 + 1 ]; +} +RASCONN ; +#include <poppack.h> + +typedef DWORD (WINAPI *RASENUMCONNECTIONS)(RASCONN *lprasconn, + LPDWORD lpcb, + LPDWORD lpcConnections); + +static int isRASActive() +{ + int r = 0; + HINSTANCE h = LoadLibraryA("rasapi32.dll"); + RASENUMCONNECTIONS RasEnumConnections; + RASCONN v = {sizeof(RASCONN), }; + + DWORD i = sizeof(v), o = 0; + + if (!h) return 0; + RasEnumConnections = (RASENUMCONNECTIONS)GetProcAddress(h, "RasEnumConnectionsA"); + if (RasEnumConnections && !RasEnumConnections(&v, &i, &o) && o) r = 1; + FreeModule(h); + return r; +} + +int isInetAvailable(void) +{ + if (config_inet_mode == 3) + { + if (isRASActive()) config_inet_mode = 1; + else config_inet_mode = 0; + return (1 == config_inet_mode); + } + if (config_inet_mode == 0) return 1; + if (config_inet_mode == 2) return 0; + return isRASActive(); +} + +unsigned int getDay(void) +{ + unsigned int day = 0; + SYSTEMTIME tm, st = {0, }; + FILETIME ft1, ft2; + ULARGE_INTEGER l1, l2; + GetSystemTime(&tm); + st.wYear = 1978; + st.wMonth = 10; + st.wDay = 14; + SystemTimeToFileTime(&tm, &ft1); + SystemTimeToFileTime(&st, &ft2); + memcpy(&l1, &ft1, sizeof(l1)); + memcpy(&l2, &ft2, sizeof(l2)); + day = (int) ((l1.QuadPart - l2.QuadPart) / (10 * 1000 * 1000) / (60 * 60 * 24)); + return day; +} + +void recent_add(const wchar_t *loc) +{ + wchar_t ls[MAX_PATH] = {0}; + _r_sW("RecentURL1", ls, MAX_PATH); + _w_sW("RecentURL1", loc); + + if (wcscmp(ls, loc)) + { + int x = 2; + while(1) + { + char s[123] = {0}; + wchar_t temp[MAX_PATH] = {0}; + StringCchPrintfA(s, 123, "RecentURL%d", x); + + _r_sW(s, temp, MAX_PATH); + if (ls[0]) _w_sW(s, ls); + if (!_wcsicmp(temp, loc) || !temp[0]) + break; + lstrcpynW(ls, temp, MAX_PATH); + x++; + } + } +} + +#include <assert.h> +void getViewport(RECT *r, HWND wnd, int full, RECT *sr) +{ + POINT *p = NULL; + if (p || sr || wnd) + { + HMONITOR hm = NULL; + + if (sr) + hm = MonitorFromRect(sr, MONITOR_DEFAULTTONEAREST); + else if (wnd) + hm = MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST); + else if (p) + hm = MonitorFromPoint(*p, MONITOR_DEFAULTTONEAREST); + + if (hm) + { + MONITORINFOEXW mi; + memset(&mi, 0, sizeof(mi)); + mi.cbSize = sizeof(mi); + + if (GetMonitorInfoW(hm, &mi)) + { + if (!full) + *r = mi.rcWork; + else + *r = mi.rcMonitor; + + return ; + } + } + } + if (full) + { // this might be borked =) + r->top = r->left = 0; + r->right = GetSystemMetrics(SM_CXSCREEN); + r->bottom = GetSystemMetrics(SM_CYSCREEN); + } + else + { + SystemParametersInfoW(SPI_GETWORKAREA, 0, r, 0); + } +} + +BOOL windowOffScreen(HWND hwnd, POINT pt) +{ + RECT r = {0}, wnd = {0}, sr = {0}; + GetWindowRect(hwnd, &wnd); + sr.left = pt.x; + sr.top = pt.y; + sr.right = sr.left + (wnd.right - wnd.left); + sr.bottom = sr.top + (wnd.bottom - wnd.top); + getViewport(&r, hwnd, 0, &sr); + return !PtInRect(&r, pt); +} + +void readwrite_client_uid(int isWrite, wchar_t uid_str[64]) +{ + HKEY hkey; + wchar_t path[MAX_PATH] = {0}; + GetModuleFileNameW(0, path, MAX_PATH); + + if (isWrite) + { + IFileTypeRegistrar *registrar=0; + if (GetRegistrar(®istrar, true) == 0 && registrar) + { + registrar->WriteClientUIDKey(path, uid_str); + registrar->Release(); + } + return; + } + + if (!isWrite) *uid_str = 0; + if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Nullsoft\\Winamp", 0, 0, 0, KEY_READ, NULL, &hkey, NULL) == ERROR_SUCCESS) + { + DWORD s = 512, t = REG_SZ; + if (RegQueryValueExW(hkey, path, 0, &t, (LPBYTE)uid_str, &s) != ERROR_SUCCESS || t != REG_SZ) uid_str[0] = 0; + RegCloseKey(hkey); + } +} + + +BOOL read_compatmode() +{ + HKEY hkey = NULL; + wchar_t path[MAX_PATH] = {0}; + GetModuleFileNameW(0, path, MAX_PATH); + if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers", 0, 0, 0, KEY_READ, NULL, &hkey, NULL) == ERROR_SUCCESS) + { + DWORD s = 512, t = REG_SZ; + wchar_t buf[128] = {0}; + if (RegQueryValueExW(hkey, path, 0, &t, (LPBYTE)buf, &s) != ERROR_SUCCESS || t != REG_SZ) buf[0] = 0; + RegCloseKey(hkey); + + wchar_t *p = buf, *fields[] = {L"256COLOR", L"640X480", L"DISABLETHEMES", L"$", + L"DISABLEDWM", L"DISABLEUSERCALLBACKEXCEPTION", + L"HIGHDPIAWARE", L"RUNASADMIN", L"IGNOREFREELIBRARY", + L"ELEVATECREATEPROCESS", L"#", L"~", L"PLACEHOLDERFILES"}; + int fields_len[] = {8, 7, 13, 1, 10, 28, 12, 10, 17, 20, 1, 1, 16}; + while (p && *p) + { + wchar_t *pp = p; + while (pp && *pp && *pp != L' ') + { + pp = CharNextW(pp); + } + + wchar_t pp_old = (pp ? *pp : 0); + if (pp && *pp) *pp = 0; + + bool found = false; + for (int i = 0; i < sizeof(fields)/sizeof(fields[0]); i++) + { + if (!wcsncmp(fields[i], p, fields_len[i])) + found = true; + } + if (!found) + return TRUE; + + if (pp) *pp = pp_old; + if (!pp_old) break; + p = CharNextW(pp); + } + } + return FALSE; +} + +BOOL IsVista(void) +{ + static INT fVista = -1; + + if (-1 == fVista) + { + OSVERSIONINFO osver = {0}; + osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + fVista = (::GetVersionEx(&osver) && osver.dwPlatformId == VER_PLATFORM_WIN32_NT && (osver.dwMajorVersion >= 6)) ? 1 : 0; + } + + return (1 == fVista); +} + +BOOL IsVistaOrLower(void) +{ + static INT fVistaOrLower = -1; + + if (-1 == fVistaOrLower) + { + OSVERSIONINFO osver = {0}; + osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + fVistaOrLower = (::GetVersionEx(&osver) && osver.dwPlatformId == VER_PLATFORM_WIN32_NT && + (osver.dwMajorVersion <= 5 || (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0))) ? 1 : 0; + } + + return (1 == fVistaOrLower); +} + +BOOL IsWin8(void) +{ + static INT fWin8 = -1; + + if (-1 == fWin8) + { + OSVERSIONINFO osver = {0}; + osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + fWin8 = ( ::GetVersionEx(&osver) && osver.dwPlatformId == VER_PLATFORM_WIN32_NT && (osver.dwMajorVersion > 6 || (osver.dwMajorVersion == 6 && osver.dwMinorVersion >= 2))) ? 1 : 0; + } + + return (1 == fWin8); +} + +//XP Theme crap +typedef HRESULT (WINAPI * ENABLETHEMEDIALOGTEXTURE)(HWND, DWORD); + +int IsWinXPTheme(void) +{ + static int previousRet = -1; + if (previousRet == -1) + { + BOOL bEnabled(FALSE); + OSVERSIONINFO vi; + + vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (GetVersionEx(&vi) && (vi.dwMajorVersion > 5 || (vi.dwMajorVersion == 5 && vi.dwMinorVersion > 0))) + { + HINSTANCE dll = LoadLibraryW(TEXT("uxtheme.dll")); + if (dll) + { + BOOL (WINAPI *waIsAppThemed)(void); + BOOL (WINAPI *waIsThemeActive)(void); + waIsAppThemed = (BOOL (WINAPI *)())GetProcAddress(dll, "IsAppThemed"); + waIsThemeActive = (BOOL (WINAPI *)())GetProcAddress(dll, "IsThemeActive"); + + if (waIsAppThemed && waIsThemeActive && waIsAppThemed() && waIsThemeActive()) + { + HMODULE hComCtl = LoadLibraryW(TEXT("comctl32.dll")); + if (hComCtl) + { + HRESULT (CALLBACK *waDllGetVersion)(DLLVERSIONINFO*) = (HRESULT (CALLBACK *)(DLLVERSIONINFO*))GetProcAddress(hComCtl, "DllGetVersion"); + if (waDllGetVersion) + { + DLLVERSIONINFO dllVer; + dllVer.cbSize = sizeof(DLLVERSIONINFO); + if (S_OK == waDllGetVersion(&dllVer) && dllVer.dwMajorVersion >= 6) bEnabled = TRUE; + } + FreeLibrary(hComCtl); + } + } + FreeLibrary(dll); + } + } + previousRet = bEnabled; + } + return previousRet; +} + +void DoWinXPStyle(HWND tab) +{ + WAEnableThemeDialogTexture(tab, ETDT_ENABLETAB); +} + +HRESULT WAEnableThemeDialogTexture(HWND hwnd, DWORD dwFlags) +{ + static int uxThemeTried = 0; + static ENABLETHEMEDIALOGTEXTURE pfnETDT = NULL; + + if(!uxThemeTried) + { + HINSTANCE ux_hDll; + if ((ux_hDll = LoadLibraryA("uxtheme.dll")) != NULL) + pfnETDT = (ENABLETHEMEDIALOGTEXTURE)GetProcAddress(ux_hDll, "EnableThemeDialogTexture"); + + uxThemeTried = 1; + } + + return (pfnETDT) ? pfnETDT(hwnd, dwFlags) : E_NOTIMPL; +} + +typedef BOOL(WINAPI*ISCOMPOSITIONACTIVE)(VOID); + +int IsAero(void) +{ + static int uxTried = 0; + static ISCOMPOSITIONACTIVE IsAeroActive = 0; + if (!uxTried) + { + static HMODULE UXTHEME = 0; + if ((UXTHEME = LoadLibraryA("uxtheme.dll")) != NULL) + IsAeroActive = (ISCOMPOSITIONACTIVE)GetProcAddress(UXTHEME, "IsCompositionActive"); + + uxTried = 1; + } + if (IsAeroActive) + return !!IsAeroActive(); + else + return 0; +} + +/* +int IsCharSpace(char digit) +{ + WORD type=0; + GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, &digit, 1, &type); + return type&C1_SPACE; +} + +int IsCharSpaceW(wchar_t digit) +{ + WORD type=0; + GetStringTypeExW(LOCALE_USER_DEFAULT, CT_CTYPE1, &digit, 1, &type); + return type&C1_SPACE; +} +*/ +LPCWSTR BuildFullPath(LPCWSTR pszPathRoot, LPCWSTR pszPath, LPWSTR pszDest, INT cchDest) +{ + LPCWSTR pszFile; + if (!pszPath || !*pszPath) + { + pszDest[0] = 0x00; + return pszDest; + } + pszFile = PathFindFileNameW(pszPath); + if (pszFile != pszPath) + { + if (PathIsRelativeW(pszPath)) + { + wchar_t szTemp[MAX_PATH] = {0}; + PathCombineW(szTemp, pszPathRoot, pszPath); + PathCanonicalizeW(pszDest, szTemp); + } + else StringCchCopyW(pszDest, cchDest, pszPath); + } + else { + if (pszPathRoot && *pszPathRoot) PathCombineW(pszDest, pszPathRoot, pszPath); + else StringCchCopyW(pszDest, cchDest, pszPath); + } + + return pszDest; +} + +INT ComparePath(LPCWSTR pszPath1, LPCWSTR pszPath2, LPCWSTR pszPathRoot) // compares two pathes +{ + INT cr; + DWORD lcid; + LPCWSTR pszFile1, pszFile2; + + if (!pszPath1 || !pszPath2) return 0; + + lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); + + pszFile1 = PathFindFileNameW(pszPath1); + pszFile2 = PathFindFileNameW(pszPath2); + + cr = CompareStringW(lcid, NORM_IGNORECASE, pszFile1, -1, pszFile2, -1); + + if (CSTR_EQUAL == cr && (pszFile1 != pszPath1 || pszFile2 != pszPath2)) + { + wchar_t path1[MAX_PATH*2] = {0}, path2[MAX_PATH*2] = {0}; + pszPath1 = BuildFullPath(pszPathRoot, pszPath1, path1, sizeof(path1)/sizeof(wchar_t)); + pszPath2 = BuildFullPath(pszPathRoot, pszPath2, path2, sizeof(path2)/sizeof(wchar_t)); + if (!pszPath1 || !pszPath2) return 0; + cr = CompareStringW(lcid, NORM_IGNORECASE, pszPath1, -1, path2, -1); + } + return cr; +} + +BOOL DisabledWindow_OnMouseClick(HWND hwnd) +{ + DWORD windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE); + if (WS_DISABLED != ((WS_CHILD | WS_DISABLED) & windowStyle)) + return FALSE; + + HWND hActive = GetActiveWindow(); + HWND hPopup = GetWindow(hwnd, GW_ENABLEDPOPUP); + + BOOL beepOk = (hPopup == hActive || hwnd == GetWindow(hActive, GW_OWNER)); + if (!beepOk && NULL == hPopup) + { + for (HWND hWalker = hwnd; ;) + { + hWalker = GetWindow(hWalker, GW_OWNER); + if (NULL == hWalker || (0 != (WS_CHILD & GetWindowLongPtrW(hWalker, GWL_STYLE)))) + break; + if (hActive == GetWindow(hWalker, GW_ENABLEDPOPUP)) + { + beepOk = TRUE; + break; + } + } + } + + if (beepOk) + { + if (config_accessibility_modalflash.GetBool()) + { + FLASHWINFO flashInfo; + flashInfo.cbSize = sizeof(FLASHWINFO); + flashInfo.hwnd = hActive; + flashInfo.dwFlags = FLASHW_CAPTION; + flashInfo.uCount = 2; + flashInfo.dwTimeout = 100; + + FlashWindowEx(&flashInfo); + } + + if (config_accessibility_modalbeep.GetBool()) + MessageBeep(MB_OK); + } + else + { + for (HWND hWalker = hwnd; NULL == hPopup;) + { + hWalker = GetWindow(hWalker, GW_OWNER); + if (NULL == hWalker || (0 != (WS_CHILD & GetWindowLongPtrW(hWalker, GWL_STYLE)))) + break; + hPopup = GetWindow(hWalker, GW_ENABLEDPOPUP); + } + + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE); + if (NULL != hPopup && hPopup != hwnd) + { + BringWindowToTop(hPopup); + SetActiveWindow(hPopup); + } + } + + return TRUE; +}
\ No newline at end of file |