Play.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /** (c) Nullsoft, Inc. C O N F I D E N T I A L
  2. ** Filename:
  3. ** Project:
  4. ** Description:
  5. ** Author:
  6. ** Created:
  7. **/
  8. #include "Main.h"
  9. #include "resource.h"
  10. #include "strutil.h"
  11. #include "../nu/AutoChar.h"
  12. #include "../nu/AutoCharFn.h"
  13. #include "MediaCoreCOM.h"
  14. #include "externalCOM.h"
  15. #include "JSAPI2_CallbackManager.h"
  16. static int in_play;
  17. extern int no_notify_play;
  18. void Play(const wchar_t *playstring)
  19. {
  20. int i = -31337;
  21. static int a = -2;
  22. AutoCharFn charFn(playstring);
  23. // added in 5.64 - this helps to keep the currently playing file after
  24. // a tag update to stay playing correctly when it is no longer in the
  25. // main playlist editor - this helps to keep a consistent ui experience
  26. bool restart = false;
  27. if (no_notify_play && playstring && *playstring && !PlayList_getlength())
  28. {
  29. PlayList_insert(0, playstring);
  30. restart = true;
  31. }
  32. in_play = 1;
  33. g_video_numaudiotracks = 1;
  34. g_video_curaudiotrack = 0;
  35. g_stopaftercur = 0;
  36. CheckMenuItem(main_menu, WINAMP_BUTTON4_CTRL, MF_UNCHECKED);
  37. CheckMenuItem(GetSubMenu(top_menu, 3), WINAMP_BUTTON4_CTRL, MF_UNCHECKED);
  38. g_has_deleted_current = 0;
  39. Skin_Random();
  40. Stats_OnPlay(playstring);
  41. // has cropped up in a few crash reports where app_name is null which causes the update to bork
  42. // when receiving a 'stop' command and we try to send an update via JSAPI1_CurrentTitleChanged()
  43. if (!app_name || app_name && !*app_name || (unsigned int)(ULONG_PTR)app_name < 65536)
  44. BuildAppName();
  45. set_caption(0, L"%s - %S", (config_dotasknum?FileTitleNum:FileTitle), app_name); // TODO: benski> get rid of FileTitle here
  46. eq_autoload(charFn);
  47. if (a == -2)
  48. a = PlayList_getlength();
  49. if (!*playstring || (i = in_open(playstring)))
  50. {
  51. if (*playstring && i != -31337 && --a) //-31337 == no_sound_card
  52. {
  53. PostMessageW(hMainWindow, WM_WA_MPEG_EOF, 0, 0);
  54. }
  55. else
  56. {
  57. if (i == -31337) in_mod = 0;
  58. StopPlaying(0);
  59. a = -2;
  60. }
  61. in_play = 0;
  62. return ;
  63. }
  64. else
  65. {
  66. a = -2;
  67. }
  68. SendMessageW(hMainWindow, WM_TIMER, UPDATE_DISPLAY_TIMER + 4, 0);
  69. PlayList_refreshtitle();
  70. PlayList_GetCurrentTitle(FileTitle, FILETITLE_SIZE); // TODO: benski> don't want to be using global FileTitle here
  71. // has cropped up in a few crash reports where app_name is null which causes the update to bork
  72. // when receiving a 'stop' command and we try to send an update via JSAPI1_CurrentTitleChanged()
  73. if (!app_name || app_name && !*app_name || (unsigned int)(ULONG_PTR)app_name < 65536) BuildAppName();
  74. set_caption(0, L"%s - %S", (config_dotasknum?FileTitleNum:FileTitle), app_name);
  75. if (in_mod && in_mod->is_seekable) draw_positionbar(0, 0);
  76. plEditSelect(PlayList_getPosition());
  77. SetTimer(hMainWindow, UPDATE_DISPLAY_TIMER, 100, NULL);
  78. playing = 1;
  79. draw_playicon(1);
  80. ui_songposition = 0;
  81. draw_songname(FileTitle, &ui_songposition, in_getlength());
  82. if (config_visplugin_autoexec && !vis_running())
  83. vis_start(hMainWindow, NULL);
  84. if (!dsp_isactive()) dsp_init();
  85. paused = 0;
  86. // added in 5.64
  87. if(restart) PlayList_deleteitem(0);
  88. if (!no_notify_play)
  89. {
  90. // don't tell anyone we're playing the file is there are hidden items or there's an ad curtain
  91. if (PlayList_hasanycurtain(PlayList_getPosition()) == 0 && PlayList_ishidden(PlayList_getPosition()) == 0)
  92. {
  93. SendMessageW(hMainWindow, WM_WA_IPC, (WPARAM)(char *)charFn, IPC_PLAYING_FILE);
  94. SendMessageW(hMainWindow, WM_WA_IPC, (WPARAM)playstring, IPC_PLAYING_FILEW);
  95. SendNotifyMessage(HWND_BROADCAST, songChangeBroadcastMessage, 0, 0);
  96. }
  97. }
  98. in_play = 0;
  99. PostMessageW(hMainWindow, WM_WA_IPC, IPC_CB_MISC_STATUS, IPC_CB_MISC);
  100. MediaCoreCOM *mediaCore;
  101. if (SUCCEEDED(JSAPI1_GetMediaCoreCOM(&mediaCore)))
  102. {
  103. mediaCore->OnPlay();
  104. mediaCore->Release();
  105. }
  106. JSAPI2::callbackManager.OnPlay(FileName);
  107. }
  108. void StartPlaying()
  109. {
  110. // reset this flag when we start playing otherwise
  111. // it can cause it to be incorrectly applied later
  112. plcleared = 0;
  113. if (playing) StopPlaying(0);
  114. if (in_play) return ;
  115. {
  116. // Check if we have the media library , if we do check to see if we have and ad curtain
  117. // If we do, and the current item is the first item, display it
  118. const char *adcurtain = PlayList_getcurtain(PlayList_getPosition());
  119. if (adcurtain && *adcurtain)
  120. {
  121. if (*adcurtain == 'a')
  122. {
  123. // 'a' means it's an Ad, so pop out of fullscreen.
  124. if ( videoIsFullscreen() ) videoForceFullscreenOff();
  125. adcurtain = CharNextA(adcurtain); // get past the a in ahttp://....
  126. }
  127. }
  128. }
  129. if (!no_notify_play)
  130. {
  131. PlayList_getcurrent(FileName, FileTitle, FileTitleNum);
  132. }
  133. Play(FileName);
  134. }
  135. /* -------- Stoppping -------- */
  136. // TODO: avoid passing g_quit
  137. void ClassicSkin_OnStop(int g_quit)
  138. {
  139. if (playing)
  140. {
  141. KillTimer(hMainWindow, UPDATE_DISPLAY_TIMER);
  142. }
  143. if (!g_quit)
  144. {
  145. sa_setthread(0);
  146. if (!no_notify_play)
  147. {
  148. PlayList_getcurrent_onstop(FileName, FileTitle);
  149. if (*FileTitle)
  150. {
  151. wchar_t titleStr[64] = {0};
  152. set_caption(0, getStringW(IDS_TITLE_ON_STOP,titleStr,64), (config_dotasknum?FileTitleNum:FileTitle), app_name);
  153. }
  154. else
  155. {
  156. // has cropped up in a few crash reports where app_name is null which causes the update to bork
  157. // when receiving a 'stop' command and we try to send an update via JSAPI1_CurrentTitleChanged()
  158. if (!app_name || app_name && !*app_name || (unsigned int)(ULONG_PTR)app_name < 65536) BuildAppName();
  159. set_caption(0, L"%S %S", (!app_name || app_name && !*app_name ? "Winamp" : app_name), app_version_string);
  160. }
  161. plEditSelect(PlayList_getPosition());
  162. }
  163. draw_setnoupdate(1);
  164. draw_clear();
  165. draw_monostereo(0);
  166. draw_clutterbar(0);
  167. draw_playicon(2);
  168. draw_shuffle(config_shuffle, 0);
  169. draw_eject(0);
  170. draw_eqplbut(config_eq_open, 0, config_pe_open, 0);
  171. draw_repeat(config_repeat, 0);
  172. draw_volumebar(config_volume, 0);
  173. draw_panbar(config_pan, 0);
  174. draw_buttonbar( -1);
  175. if (config_pe_height != 14)
  176. draw_pe_timedisp(NULL, 0, 0, 0, 1);
  177. draw_songname(FileTitle, &ui_songposition, PlayList_getcurrentlength());
  178. draw_setnoupdate(0);
  179. last_brate = -1;
  180. }
  181. }
  182. void StopPlaying(int g_quit)
  183. {
  184. if (in_play) return ;
  185. in_play = 1;
  186. g_has_deleted_current = 0;
  187. int last_time = 0;
  188. if (!g_fullstop) // if this wasn't an EOF situation, grab the current time so that the callback can be told the stop time.
  189. last_time = in_getouttime();
  190. if (playing)
  191. {
  192. paused = 0;
  193. playing = 0;
  194. g_video_numaudiotracks = 1;
  195. g_video_curaudiotrack = 0;
  196. in_close();
  197. }
  198. ClassicSkin_OnStop(g_quit);
  199. in_play = 0;
  200. stopPlayingInfoStruct infoStruct;
  201. infoStruct.g_fullstop = g_fullstop;
  202. infoStruct.last_time = last_time;
  203. SendMessageW(hMainWindow, WM_WA_IPC, (WPARAM)&infoStruct, IPC_STOPPLAYING);
  204. PostMessageW(hMainWindow, WM_WA_IPC, IPC_CB_MISC_STATUS, IPC_CB_MISC);
  205. MediaCoreCOM *mediaCore;
  206. if (SUCCEEDED(JSAPI1_GetMediaCoreCOM(&mediaCore)))
  207. {
  208. mediaCore->OnStop(last_time, g_fullstop);
  209. mediaCore->Release();
  210. }
  211. JSAPI2::callbackManager.OnStop(last_time, g_fullstop);
  212. }
  213. void Skin_OnPause()
  214. {
  215. wchar_t titleStr[64] = {0};
  216. set_caption(0, getStringW(IDS_TITLE_ON_PAUSE,titleStr,64), (config_dotasknum?FileTitleNum:FileTitle), app_name);
  217. draw_playicon(4);
  218. }
  219. void Skin_OnUnpause()
  220. {
  221. // has cropped up in a few crash reports where app_name is null which causes the update to bork
  222. // when receiving a 'stop' command and we try to send an update via JSAPI1_CurrentTitleChanged()
  223. if (!app_name || app_name && !*app_name || (unsigned int)(ULONG_PTR)app_name < 65536) BuildAppName();
  224. set_caption(0, L"%s - %S", (config_dotasknum?FileTitleNum:FileTitle), app_name);
  225. draw_playicon(1);
  226. }
  227. /* -------- Pausing -------- */
  228. void PausePlaying()
  229. {
  230. if (!playing || paused) return ;
  231. paused = 1;
  232. in_pause(1);
  233. Skin_OnPause();
  234. PostMessageW(hMainWindow, WM_WA_IPC, IPC_CB_MISC_STATUS, IPC_CB_MISC);
  235. PostMessageW(hMainWindow, WM_WA_IPC, IPC_CB_MISC_PAUSE, IPC_CB_MISC);
  236. MediaCoreCOM *mediaCore;
  237. if (SUCCEEDED(JSAPI1_GetMediaCoreCOM(&mediaCore)))
  238. {
  239. mediaCore->OnPause();
  240. mediaCore->Release();
  241. }
  242. JSAPI2::callbackManager.OnPause(true);
  243. }
  244. void UnPausePlaying()
  245. {
  246. if (!playing || !paused) return ;
  247. in_pause(0);
  248. paused = 0;
  249. Skin_OnUnpause();
  250. PostMessageW(hMainWindow, WM_WA_IPC, IPC_CB_MISC_STATUS, IPC_CB_MISC);
  251. PostMessageW(hMainWindow, WM_WA_IPC, IPC_CB_MISC_UNPAUSE, IPC_CB_MISC);
  252. MediaCoreCOM *mediaCore = 0;
  253. if (SUCCEEDED(JSAPI1_GetMediaCoreCOM(&mediaCore)) && mediaCore)
  254. {
  255. mediaCore->OnResume();
  256. mediaCore->Release();
  257. }
  258. JSAPI2::callbackManager.OnPause(false);
  259. }
  260. void PlayThing(const char *thing, int clearlist)
  261. {
  262. }
  263. void BeginPlayback()
  264. {
  265. PlayList_setposition(0);
  266. if (config_shuffle)
  267. PlayList_randpos( -BIGINT);
  268. PlayList_getcurrent(FileName, FileTitle, FileTitleNum);
  269. StartPlaying();
  270. }