123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- #include "api__ml_history.h"
- #include "main.h"
- #include "..\..\General\gen_ml/config.h"
- #include "HistoryAPIFactory.h"
- #include "JSAPI2_Creator.h"
- #include "..\..\General\gen_ml/ml_ipc_0313.h"
- #include "../nu/AutoCharFn.h"
- #include <strsafe.h>
- #define LOCAL_WRITE_VER L"2.03"
- // wasabi based services for localisation support
- api_language *WASABI_API_LNG = 0;
- api_explorerfindfile *WASABI_API_EXPLORERFINDFILE = 0;
- JSAPI2::api_security *AGAVE_API_JSAPI2_SECURITY = 0;
- api_application *WASABI_API_APP=0;
- HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
- static HistoryAPIFactory historyAPIFactory;
- static JSAPI2Factory jsapi2Factory;
- static int Init();
- static void Quit();
- static INT_PTR MessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3);
- prefsDlgRecW preferences = {0};
- wchar_t g_tableDir[MAX_PATH] = {0};
- extern "C" winampMediaLibraryPlugin plugin =
- {
- MLHDR_VER,
- "nullsoft(ml_history.dll)",
- Init,
- Quit,
- MessageProc,
- 0,
- 0,
- 0,
- };
- // Delay load library control << begin >>
- #include <delayimp.h>
- #pragma comment(lib, "delayimp")
- bool nde_error = false;
- FARPROC WINAPI FailHook(unsigned dliNotify, PDelayLoadInfo pdli)
- {
- nde_error = true;
- return 0;
- }
- /*
- extern "C"
- {
- PfnDliHook __pfnDliFailureHook2 = FailHook;
- }
- */
- // Delay load library control << end >>
- int Init()
- {
- InitializeCriticalSection(&g_db_cs);
- g_db = NULL;
- g_table = NULL;
-
- mediaLibrary.library = plugin.hwndLibraryParent;
- mediaLibrary.winamp = plugin.hwndWinampParent;
- mediaLibrary.instance = plugin.hDllInstance;
- wchar_t configName[ MAX_PATH ] = { 0 };
- const wchar_t *dir = mediaLibrary.GetIniDirectoryW();
- if ( (INT_PTR)( dir ) < 65536 )
- return ML_INIT_FAILURE;
- PathCombineW( g_tableDir, dir, L"Plugins" );
- PathCombineW( configName, g_tableDir, L"gen_ml.ini" );
- g_config = new C_Config( configName );
- CreateDirectoryW( g_tableDir, NULL );
- PathCombineW( g_tableDir, g_tableDir, L"ml" );
- CreateDirectoryW( g_tableDir, NULL );
- // loader so that we can get the localisation service api for use
- waServiceFactory *sf = plugin.service->service_getServiceByGuid( languageApiGUID );
- if ( sf )
- WASABI_API_LNG = reinterpret_cast<api_language *>( sf->getInterface() );
- sf = plugin.service->service_getServiceByGuid( JSAPI2::api_securityGUID );
- if ( sf )
- AGAVE_API_JSAPI2_SECURITY = reinterpret_cast<JSAPI2::api_security *>( sf->getInterface() );
-
- sf = plugin.service->service_getServiceByGuid( applicationApiServiceGuid );
- if ( sf )
- WASABI_API_APP = reinterpret_cast<api_application *>( sf->getInterface() );
- sf = plugin.service->service_getServiceByGuid( ExplorerFindFileApiGUID );
- if ( sf )
- WASABI_API_EXPLORERFINDFILE = reinterpret_cast<api_explorerfindfile *>( sf->getInterface() );
- plugin.service->service_register( &historyAPIFactory );
- plugin.service->service_register( &jsapi2Factory );
- // need to have this initialised before we try to do anything with localisation features
- WASABI_API_START_LANG( plugin.hDllInstance, MlHistoryLangGUID );
- g_context_menus2 = WASABI_API_LOADMENUW(IDR_CONTEXTMENUS);
- static wchar_t szDescription[256];
- StringCchPrintfW( szDescription, ARRAYSIZE( szDescription ), WASABI_API_LNGSTRINGW( IDS_NULLSOFT_HISTORY ), LOCAL_WRITE_VER );
- plugin.description = (char*)szDescription;
- static wchar_t preferencesName[64] = {0};
- preferences.hInst = WASABI_API_LNG_HINST;
- preferences.dlgID = IDD_PREFS;
- preferences.proc = (void *)PrefsProc;
- preferences.name = WASABI_API_LNGSTRINGW_BUF( IDS_HISTORY, preferencesName, 64 );
- preferences.where = 6; // media library
- SENDWAIPC( plugin.hwndWinampParent, IPC_ADD_PREFS_DLGW, &preferences );
-
- if ( !history_init() )
- return ML_INIT_FAILURE;
- return ML_INIT_SUCCESS;
- }
- void Quit()
- {
- plugin.service->service_deregister(&historyAPIFactory);
- plugin.service->service_deregister(&jsapi2Factory);
- history_quit();
- delete g_config;
- DeleteCriticalSection(&g_db_cs);
- waServiceFactory *sf = plugin.service->service_getServiceByGuid(languageApiGUID);
- if (sf) sf->releaseInterface(WASABI_API_LNG);
- sf = plugin.service->service_getServiceByGuid(JSAPI2::api_securityGUID);
- if (sf) sf->releaseInterface(AGAVE_API_JSAPI2_SECURITY);
- }
- static INT_PTR History_OnContextMenu(INT_PTR param1, HWND hHost, POINTS pts)
- {
- HNAVITEM hItem = (HNAVITEM)param1;
- HNAVITEM myItem = MLNavCtrl_FindItemById(plugin.hwndLibraryParent, ml_history_tree);
- if (hItem != myItem)
- return FALSE;
- POINT pt;
- POINTSTOPOINT(pt, pts);
- if (-1 == pt.x || -1 == pt.y)
- {
- NAVITEMGETRECT itemRect;
- itemRect.fItem = FALSE;
- itemRect.hItem = hItem;
- if (MLNavItem_GetRect(plugin.hwndLibraryParent, &itemRect))
- {
- MapWindowPoints(hHost, HWND_DESKTOP, (POINT*)&itemRect.rc, 2);
- pt.x = itemRect.rc.left + 2;
- pt.y = itemRect.rc.top + 2;
- }
- }
- HMENU hMenu = WASABI_API_LOADMENUW(IDR_CONTEXTMENUS);
- HMENU subMenu = (NULL != hMenu) ? GetSubMenu(hMenu, 1) : NULL;
- if (NULL != subMenu)
- {
- INT r = Menu_TrackPopup(plugin.hwndLibraryParent, subMenu,
- TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY |
- TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON,
- pt.x, pt.y, hHost, NULL);
- switch(r)
- {
- case ID_NAVIGATION_PREFERENCES:
- SENDWAIPC(plugin.hwndWinampParent, IPC_OPENPREFSTOPAGE, &preferences);
- break;
- case ID_NAVIGATION_HELP:
- SENDWAIPC(plugin.hwndWinampParent, IPC_OPEN_URL, L"https://help.winamp.com/hc/articles/8105304048660-The-Winamp-Media-Library");
- break;
- }
- }
- if (NULL != hMenu)
- DestroyMenu(hMenu);
-
- return TRUE;
- }
- void History_StartTracking(const wchar_t *filename, bool resume)
- {
- KillTimer(plugin.hwndWinampParent, 8082);
- if (!resume)
- {
- free(history_fn);
- history_fn = 0;
- history_fn_mode = 0;
- if (wcsstr(filename, L"://") && _wcsnicmp(filename, L"cda://", 6) && _wcsnicmp(filename, L"file://", 7))
- {
- history_fn_mode = 1;
- }
- history_fn = _wcsdup(filename);
- }
-
- int timer1 = -1, timer2 = -1, timer3 = -1;
- // wait for x seconds
- if(g_config->ReadInt(L"recent_wait_secs",0))
- {
- timer1 = g_config->ReadInt(L"recent_wait_secs_lim",5)*1000;
- }
- // wait for x percent of the song (approx to a second)
- if(g_config->ReadInt(L"recent_wait_percent",0))
- {
- basicFileInfoStructW bfiW = {0};
- bfiW.filename = history_fn;
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&bfiW, IPC_GET_BASIC_FILE_INFOW);
- if(bfiW.length > 0)
- {
- bfiW.length=bfiW.length*1000;
- timer2 = (bfiW.length*g_config->ReadInt(L"recent_wait_percent_lim",50))/100;
- }
- }
- // wait for the end of the item (within the last second of the track hopefully)
- if(g_config->ReadInt(L"recent_wait_end",0))
- {
- basicFileInfoStructW bfiW = {0};
- bfiW.filename = history_fn;
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&bfiW, IPC_GET_BASIC_FILE_INFOW);
- if(bfiW.length > 0)
- {
- timer3=(bfiW.length-1)*1000;
- }
- }
- // decide on which playback option will be the prefered duration (smallest wins)
- if(timer1 != -1 && timer2 != -1)
- {
- if(timer1 > timer2)
- {
- timer = timer2;
- }
- if(timer2 > timer1)
- {
- timer = timer1;
- }
- }
- else if(timer1 == -1 && timer2 != -1)
- {
- timer = timer2;
- }
- else if(timer2 == -1 && timer1 != -1)
- {
- timer = timer1;
- }
- // only track on end of file as very last method
- if((timer <= 0) && (timer3 > 0)){ timer = timer3; }
-
- // if no match or something went wrong then try to ensure the default timer value is used
- SetTimer(plugin.hwndWinampParent, 8082, ((timer > 0)? timer : 350), NULL);
- }
- INT_PTR MessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3)
- {
- switch (message_type)
- {
- case ML_MSG_TREE_ONCREATEVIEW: // param1 = param of tree item, param2 is HWND of parent. return HWND if it is us
- return (param1 == ml_history_tree) ? (INT_PTR)onTreeViewSelectChange((HWND)param2) : 0;
-
- case ML_MSG_CONFIG:
- mediaLibrary.GoToPreferences((int)preferences._id);
- return TRUE;
- case ML_MSG_VIEW_PLAY_ENQUEUE_CHANGE:
- enqueuedef = (int)param1;
- groupBtn = (int)param2;
- PostMessage(m_curview_hwnd, WM_APP + 104, param1, param2);
- return 0;
- case ML_MSG_NAVIGATION_CONTEXTMENU:
- return History_OnContextMenu(param1, (HWND)param2, MAKEPOINTS(param3));
- case ML_MSG_PLAYING_FILE:
- if (param1)
- {
- int resume = g_config->ReadInt(L"resumeplayback",0);
- if(resume)
- {
- int is_playing = (int)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_ISPLAYING);
- //int play_pos = SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_GETOUTPUTTIME);
- if(is_playing == 1/* && !(play_pos/1000 > 0)*/) //playing, look up last play offset and send seek message
- {
- wchar_t genre[256]={0};
- extendedFileInfoStructW efis={
- (wchar_t*)param1,
- L"genre",
- genre,
- ARRAYSIZE(genre),
- };
- SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)&efis,IPC_GET_EXTENDED_FILE_INFOW);
- wchar_t ispodcast[8]={0};
- extendedFileInfoStructW efis1={
- (wchar_t*)param1,
- L"ispodcast",
- ispodcast,
- ARRAYSIZE(ispodcast),
- };
- SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)&efis1,IPC_GET_EXTENDED_FILE_INFOW_HOOKABLE);
- if (resume == 2 || (ispodcast[0] && _wtoi(ispodcast) > 0) || (genre[0] && !_wcsicmp(genre, L"podcast")))
- {
- int offset = retrieve_offset((wchar_t*)param1);
- if (offset > 0 && (offset/1000 > 0)) PostMessage(plugin.hwndWinampParent,WM_WA_IPC,offset,IPC_JUMPTOTIME);
- }
- }
- }
- History_StartTracking((const wchar_t *)param1, false);
- }
- break;
- case ML_MSG_WRITE_CONFIG:
- if(param1)
- {
- closeDb();
- openDb();
- }
- break;
- }
- return 0;
- }
- extern "C" __declspec(dllexport) winampMediaLibraryPlugin *winampGetMediaLibraryPlugin()
- {
- return &plugin;
- }
|