ml_playlists.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. //#define PLUGIN_NAME "Nullsoft Playlists"
  2. #define PLUGIN_VERSION L"1.78"
  3. #include "main.h"
  4. #include "../../General/gen_ml/ml_ipc_0313.h"
  5. #include "api__ml_playlists.h"
  6. #include "replicant/nu/AutoChar.h"
  7. #include "PlaylistsCOM.h"
  8. #include "api/service/waservicefactory.h"
  9. #include "PlaylistsCB.h"
  10. #include "playlist/plstring.h"
  11. #define PLAYLIST_IMAGE_INDEX 201
  12. #define PLAYLIST_CLOUD_IMAGE_INDEX 202
  13. PlaylistsCOM playlistsCOM;
  14. HMENU wa_playlists_cmdmenu = NULL;
  15. HMENU wa_play_menu = NULL;
  16. INT_PTR playlistsTreeId = 0, playlistsCloudTreeId = 3002;
  17. HNAVITEM playlistItem = 0;
  18. wchar_t g_path[ MAX_PATH ] = { 0 };
  19. HMENU g_context_menus = 0, g_context_menus2 = 0, g_context_menus3 = 0;
  20. int Init();
  21. void Quit();
  22. int( *warand )( void ) = 0;
  23. INT_PTR sendToIgnoreID = 0;
  24. int IPC_LIBRARY_PLAYLISTS_REFRESH = -1, IPC_CLOUD_ENABLED = -1;
  25. extern "C" winampMediaLibraryPlugin plugin =
  26. {
  27. MLHDR_VER,
  28. "nullsoft(ml_playlists.dll)",
  29. Init,
  30. Quit,
  31. pluginMessageProc,
  32. 0,
  33. 0,
  34. 0,
  35. };
  36. HCURSOR hDragNDropCursor;
  37. C_Config *g_config = 0;
  38. int imgPL = 0, imgCloudPL = 0;
  39. api_playlistmanager *AGAVE_API_PLAYLISTMANAGER = 0;
  40. api_application *WASABI_API_APP = 0;
  41. api_playlists *AGAVE_API_PLAYLISTS = 0;
  42. api_downloadManager *WAC_API_DOWNLOADMANAGER = 0;
  43. api_syscb *WASABI_API_SYSCB = 0;
  44. api_explorerfindfile *WASABI_API_EXPLORERFINDFILE = 0;
  45. PlaylistsCB playlistsCB;
  46. // wasabi based services for localisation support
  47. api_language *WASABI_API_LNG = 0;
  48. HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
  49. template <class api_t>
  50. api_t *GetService( GUID serviceGUID )
  51. {
  52. waServiceFactory *sf = plugin.service->service_getServiceByGuid( serviceGUID );
  53. if ( sf )
  54. return (api_t *)sf->getInterface();
  55. else
  56. return 0;
  57. }
  58. inline void ReleaseService( GUID serviceGUID, void *service )
  59. {
  60. waServiceFactory *sf = plugin.service->service_getServiceByGuid( serviceGUID );
  61. if ( sf )
  62. sf->releaseInterface( service );
  63. }
  64. wchar_t prefsname[ 64 ] = { 0 };
  65. extern WORD waMenuID;
  66. int Init()
  67. {
  68. waMenuID = (WORD)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_REGISTER_LOWORD_COMMAND );
  69. AGAVE_API_PLAYLISTMANAGER = GetService<api_playlistmanager>( api_playlistmanagerGUID );
  70. if ( !AGAVE_API_PLAYLISTMANAGER ) // no sense in continuing
  71. return ML_INIT_FAILURE;
  72. AGAVE_API_PLAYLISTS = GetService<api_playlists>( api_playlistsGUID );
  73. if ( !AGAVE_API_PLAYLISTS ) // no sense in continuing
  74. return ML_INIT_FAILURE;
  75. WAC_API_DOWNLOADMANAGER = GetService<api_downloadManager>( DownloadManagerGUID );
  76. WASABI_API_APP = GetService<api_application>( applicationApiServiceGuid );
  77. WASABI_API_SYSCB = GetService<api_syscb>( syscbApiServiceGuid );
  78. WASABI_API_SYSCB->syscb_registerCallback( &playlistsCB );
  79. WASABI_API_EXPLORERFINDFILE = GetService<api_explorerfindfile>( ExplorerFindFileApiGUID );
  80. // Hook(plugin.hwndWinampParent);
  81. warand = ( int( * )( void ) )SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_RANDFUNC );
  82. // need to get WASABI_API_APP first
  83. plstring_init();
  84. // loader so that we can get the localisation service api for use
  85. WASABI_API_LNG = GetService<api_language>( languageApiGUID );
  86. // need to have this initialised before we try to do anything with localisation features
  87. WASABI_API_START_LANG( plugin.hDllInstance, MlPlaylistsLangGUID );
  88. static wchar_t szDescription[ 256 ];
  89. swprintf( szDescription, ARRAYSIZE( szDescription ), WASABI_API_LNGSTRINGW( IDS_NULLSOFT_PLAYLISTS ), PLUGIN_VERSION );
  90. plugin.description = (char *)szDescription;
  91. mediaLibrary.library = plugin.hwndLibraryParent;
  92. mediaLibrary.winamp = plugin.hwndWinampParent;
  93. mediaLibrary.instance = plugin.hDllInstance;
  94. mediaLibrary.GetWinampIni(); // to prevent a SendMessage hang later
  95. mediaLibrary.AddDispatch( L"Playlists", &playlistsCOM );
  96. wchar_t inifile[ MAX_PATH ] = { 0 };
  97. mediaLibrary.BuildPath( L"Plugins", inifile, MAX_PATH );
  98. CreateDirectoryW( inifile, NULL );
  99. mediaLibrary.BuildPath( L"Plugins\\gen_ml.ini", inifile, MAX_PATH );
  100. g_config = new C_Config( inifile );
  101. enqueuedef = g_config->ReadInt( L"enqueuedef", 0 );
  102. // if m3udir has been changed (not the same as inidir) then
  103. // we attempt to use the same folder for our playlist files
  104. const wchar_t *m3udir = (wchar_t *)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETM3UDIRECTORYW );
  105. const wchar_t *inidir = mediaLibrary.GetIniDirectoryW();
  106. if ( !lstrcmpiW( m3udir, inidir ) )
  107. mediaLibrary.BuildPath( L"Plugins\\ml\\playlists", g_path, MAX_PATH );
  108. else
  109. lstrcpynW( g_path, m3udir, MAX_PATH );
  110. CreateDirectoryW( g_path, NULL );
  111. g_context_menus = WASABI_API_LOADMENU( IDR_MENU1 );
  112. g_context_menus2 = WASABI_API_LOADMENU( IDR_MENU1 ); // this and next one are used for the combined buttons
  113. g_context_menus3 = WASABI_API_LOADMENU( IDR_MENU1 ); // so we don't have to mess around the translators etc
  114. HookMediaLibrary();
  115. hDragNDropCursor = LoadCursor( GetModuleHandle( L"gen_ml.dll" ), MAKEINTRESOURCE( ML_IDC_DRAGDROP ) );
  116. HMENU wa_plcontext_menu = GetSubMenu( (HMENU)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, -1, IPC_GET_HMENU ), 2 );
  117. if ( wa_plcontext_menu )
  118. {
  119. wa_playlists_cmdmenu = GetSubMenu( wa_plcontext_menu, 4 );
  120. if ( wa_playlists_cmdmenu )
  121. {
  122. MENUITEMINFO i = { sizeof( i ), MIIM_TYPE, MFT_SEPARATOR, 0, 0 };
  123. InsertMenuItem( wa_playlists_cmdmenu, 9, TRUE, &i );
  124. MENUITEMINFO j = { sizeof( i ), MIIM_ID | MIIM_STATE | MIIM_TYPE, MFT_STRING, 0, WINAMP_MANAGEPLAYLISTS };
  125. j.dwTypeData = WASABI_API_LNGSTRINGW( IDS_MANAGE_PLAYLISTS );
  126. InsertMenuItem( wa_playlists_cmdmenu, 10, TRUE, &j );
  127. }
  128. }
  129. IPC_CLOUD_ENABLED = SendMessage( plugin.hwndWinampParent, WM_WA_IPC, ( WPARAM ) & "WinampCloudEnabled", IPC_REGISTER_WINAMP_IPCMESSAGE );
  130. IPC_LIBRARY_PLAYLISTS_REFRESH = SendMessage( plugin.hwndWinampParent, WM_WA_IPC, ( WPARAM ) & "ml_playlist_refresh", IPC_REGISTER_WINAMP_IPCMESSAGE );
  131. wa_play_menu = GetSubMenu( (HMENU)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_HMENU ), 2 );
  132. // lets extend menu that called on button press
  133. int IPC_GET_ML_HMENU = (int)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, ( WPARAM ) & "LibraryGetHmenu", IPC_REGISTER_WINAMP_IPCMESSAGE );
  134. HMENU context_menu = (HMENU)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_ML_HMENU );
  135. if ( context_menu )
  136. {
  137. HMENU btnMenu = GetSubMenu( context_menu, 0 );
  138. if ( btnMenu )
  139. {
  140. MENUITEMINFO mii = { sizeof( MENUITEMINFO ) };
  141. mii.fMask = MIIM_FTYPE;
  142. mii.fType = MFT_SEPARATOR;
  143. mii.fState = MFS_ENABLED;
  144. InsertMenuItem( btnMenu, 0, TRUE, &mii );
  145. mii.fMask = MIIM_TYPE | MIIM_ID;
  146. mii.fType = MFT_STRING;
  147. mii.dwTypeData = WASABI_API_LNGSTRINGW( IDS_MANAGE_PLAYLISTS );
  148. mii.cch = (unsigned int)lstrlen( mii.dwTypeData );
  149. mii.wID = WINAMP_MANAGEPLAYLISTS;
  150. InsertMenuItem( btnMenu, 0, TRUE, &mii );
  151. mii.dwTypeData = WASABI_API_LNGSTRINGW( IDS_NEW_PLAYLIST );
  152. mii.cch = (unsigned int)lstrlen( mii.dwTypeData );
  153. mii.wID = ID_DOSHITMENU_ADDNEWPLAYLIST;
  154. InsertMenuItem( btnMenu, 0, TRUE, &mii );
  155. }
  156. }
  157. imgPL = mediaLibrary.AddTreeImage( IDB_TREEITEM_PLAYLIST, PLAYLIST_IMAGE_INDEX, (BMPFILTERPROC)FILTER_DEFAULT1 );
  158. imgCloudPL = mediaLibrary.AddTreeImage( IDB_TREEITEM_CLOUD_PLAYLIST, PLAYLIST_CLOUD_IMAGE_INDEX, (BMPFILTERPROC)FILTER_DEFAULT1 );
  159. NAVINSERTSTRUCT nis = { 0 };
  160. nis.item.cbSize = sizeof( NAVITEM );
  161. nis.item.pszText = WASABI_API_LNGSTRINGW_BUF( IDS_PLAYLISTS, prefsname, 64 );
  162. nis.item.pszInvariant = L"Playlists";
  163. nis.item.id = playlistsTreeId = 3001; // for backwards compatability
  164. nis.item.style = NIS_HASCHILDREN;
  165. nis.item.mask = NIMF_TEXT | NIMF_TEXTINVARIANT | NIMF_ITEMID | NIMF_STYLE;
  166. playlistItem = MLNavCtrl_InsertItem( plugin.hwndLibraryParent, &nis );
  167. LoadPlaylists();
  168. Hook( plugin.hwndWinampParent );
  169. HookPlaylistEditor();
  170. return ML_INIT_SUCCESS;
  171. }
  172. void Quit()
  173. {
  174. AGAVE_API_PLAYLISTS->Flush();
  175. WASABI_API_SYSCB->syscb_deregisterCallback( &playlistsCB );
  176. ReleaseService( api_playlistmanagerGUID, AGAVE_API_PLAYLISTMANAGER );
  177. ReleaseService( api_playlistsGUID, AGAVE_API_PLAYLISTS );
  178. ReleaseService( DownloadManagerGUID, WAC_API_DOWNLOADMANAGER );
  179. ReleaseService( applicationApiServiceGuid, WASABI_API_APP );
  180. ReleaseService( syscbApiServiceGuid, WASABI_API_SYSCB );
  181. ReleaseService( ExplorerFindFileApiGUID, WASABI_API_EXPLORERFINDFILE );
  182. UnhookPlaylistEditor();
  183. UnhookMediaLibrary();
  184. delete g_config;
  185. }
  186. extern "C" __declspec( dllexport ) winampMediaLibraryPlugin * winampGetMediaLibraryPlugin()
  187. {
  188. return &plugin;
  189. }