video.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. #include <windowsx.h>
  2. #include "main.h"
  3. #include <ddraw.h>
  4. #include <multimon.h>
  5. #include "api.h"
  6. #include "vid_overlay.h"
  7. #include "vid_ddraw.h"
  8. #include "vid_subs.h"
  9. #include "vid_none.h"
  10. #include "VideoOutput.h"
  11. #include "Browser.h"
  12. #include "video.h"
  13. #include "../nu/AutoWide.h"
  14. #include "WinampAttributes.h"
  15. #include "resource.h"
  16. #define WM_VIDEO_UPDATE_STATUS_TEXT WM_USER+0x874
  17. #define WM_VIDEO_OPEN WM_USER+0x875
  18. #define WM_VIDEO_CLOSE WM_USER+0x876
  19. #define WM_VIDEO_RESIZE WM_USER+0x877
  20. #define WM_VIDEO_CREATE WM_USER+0x900
  21. #define VIDEO_GENFF_SIZEREQUEST (WM_USER+2048)
  22. #undef GetSystemMetrics
  23. #define INIT_DIRECTDRAW_STRUCT(x) (ZeroMemory(&x, sizeof(x)), x.dwSize=sizeof(x))
  24. VideoOutput *m_videooutput = NULL;
  25. static int VW_OnLButtonUp(HWND hwnd, int x, int y, UINT flags);
  26. static int VW_OnRButtonUp(HWND hwnd, int x, int y, UINT flags);
  27. static int VW_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags);
  28. static int VW_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags);
  29. static int VW_OnLButtonDblClk(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags);
  30. static BOOL VW_OnNCActivate(HWND hwnd, BOOL fActive, HWND hwndActDeact, BOOL fMinimized);
  31. extern "C" int g_video_numaudiotracks;
  32. extern "C" int is_fullscreen_video = 0;
  33. extern "C" int no_notify_play;
  34. extern "C" int last_no_notify_play;
  35. #undef GetSystemMetrics
  36. bool sizeOnOpen = false;
  37. int widthOnOpen, heightOnOpen;
  38. #define VideoClassicWidth() 19
  39. #define VideoClassicHeight() 58
  40. static void VideoClose();
  41. /* Resizes the windows (parent and children) based on what the size of the video should be */
  42. static void SetVideoSize(int width, int height)
  43. {
  44. if (m_videooutput && m_videooutput->is_fullscreen()) // fullscreen
  45. {
  46. m_videooutput->SetVideoPosition(0, 0, config_video_width, config_video_height);
  47. }
  48. else // not fullscreen
  49. {
  50. // send out ideal video size message (in case anyone wants it)
  51. PostMessageW(hMainWindow, WM_WA_IPC, (((width) & 0xFFFF) << 16) | ((height) & 0xFFFF), IPC_SETIDEALVIDEOSIZE);
  52. if (GetParent(hVideoWindow)) // if gen_ff owns the window, then signal it about the video size
  53. PostMessageW(GetParent(hVideoWindow), VIDEO_GENFF_SIZEREQUEST, width, height);
  54. else // classic skin
  55. SetWindowPos(hVideoWindow, 0, 0, 0, width + VideoClassicWidth(), height + VideoClassicHeight(), SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  56. }
  57. }
  58. /* Resizes the windows (parent and children) based on what the size of the parent should be */
  59. void SetExteriorSize(int width, int height)
  60. {
  61. // calculate interior size
  62. width -= VideoClassicWidth();
  63. height -= VideoClassicHeight();
  64. // pass our calculated value onto the size routine
  65. SetVideoSize(width, height);
  66. }
  67. /* lays out children (video and ad) based on a given parent window size */
  68. static void LayoutChildren(int width, int height)
  69. {
  70. if (m_videooutput && m_videooutput->is_fullscreen()) // fullscreen
  71. {
  72. m_videooutput->SetVideoPosition(0, 0, config_video_width, config_video_height);
  73. }
  74. else // not fullscreen
  75. {
  76. // calculate interior size
  77. width -= VideoClassicWidth();
  78. height -= VideoClassicHeight();
  79. // size the video
  80. if (m_videooutput)
  81. {
  82. m_videooutput->SetVideoPosition(11, 20, width, height);
  83. InvalidateRect(m_videooutput->getHwnd(), 0, TRUE); // force repaint of video
  84. }
  85. InvalidateRect(hVideoWindow, 0, TRUE); // force repaint of parent window
  86. }
  87. }
  88. /* Resizes the windows (parent and children) based on what the size of the parent should be
  89. Sets the position of the parent window */
  90. static void SetExteriorSizeAndPosition(int x, int y, int width, int height)
  91. {
  92. config_video_wx = x;
  93. config_video_wy = y;
  94. SetExteriorSize(width, height);
  95. }
  96. void updateTrackSubmenu()
  97. {
  98. HMENU menu = GetSubMenu(GetSubMenu(top_menu, 3), 13);
  99. HMENU audiomenu = GetSubMenu(menu, 6);
  100. HMENU videomenu = GetSubMenu(menu, 7);
  101. static int audioadded = 0;
  102. static int videoadded = 0;
  103. static int first = 1;
  104. if (first)
  105. {
  106. RemoveMenu(audiomenu, ID_VID_AUDIO0, MF_BYCOMMAND);
  107. RemoveMenu(videomenu, ID_VID_VIDEO0, MF_BYCOMMAND);
  108. first = 1;
  109. }
  110. if (audioadded)
  111. {
  112. for (int i = 0;i < 16;i++)
  113. {
  114. RemoveMenu(audiomenu, ID_VID_AUDIO0 + i, MF_BYCOMMAND);
  115. }
  116. audioadded = 0;
  117. }
  118. if (videoadded)
  119. {
  120. for (int i = 0;i < 16;i++)
  121. {
  122. RemoveMenu(videomenu, ID_VID_VIDEO0 + i, MF_BYCOMMAND);
  123. }
  124. videoadded = 0;
  125. }
  126. VideoOutput *out = (VideoOutput *)video_getIVideoOutput();
  127. if (!out || !out->getTrackSelector())
  128. {
  129. EnableMenuItem(menu, 8, MF_GRAYED | MF_BYPOSITION);
  130. EnableMenuItem(menu, 9, MF_GRAYED | MF_BYPOSITION);
  131. return ;
  132. }
  133. ITrackSelector *sel = out->getTrackSelector();
  134. int numaudiotracks = sel->getNumAudioTracks();
  135. if (numaudiotracks < 2)
  136. {
  137. EnableMenuItem(menu, 8, MF_GRAYED | MF_BYPOSITION);
  138. }
  139. else
  140. {
  141. audioadded = 1;
  142. int curtrack = sel->getCurAudioTrack();
  143. for (int i = 0;i < numaudiotracks;i++)
  144. {
  145. char t[256] = {0};
  146. sel->enumAudioTrackName(i, t, 255);
  147. InsertMenuA(audiomenu, i, MF_BYPOSITION, ID_VID_AUDIO0 + i, t);
  148. CheckMenuItem(audiomenu, ID_VID_AUDIO0 + i, ((i == curtrack) ? MF_CHECKED : MF_UNCHECKED) | MF_BYCOMMAND);
  149. }
  150. EnableMenuItem(menu, 8, MF_ENABLED | MF_BYPOSITION);
  151. }
  152. int numvideotracks = sel->getNumVideoTracks();
  153. if (numvideotracks < 2)
  154. {
  155. EnableMenuItem(menu, 9, MF_GRAYED | MF_BYPOSITION);
  156. }
  157. else
  158. {
  159. videoadded = 1;
  160. int curtrack = sel->getCurVideoTrack();
  161. for (int i = 0;i < numvideotracks;i++)
  162. {
  163. char t[256] = {0};
  164. sel->enumVideoTrackName(i, t, 255);
  165. InsertMenuA(videomenu, i, MF_BYPOSITION, ID_VID_VIDEO0 + i, t);
  166. CheckMenuItem(videomenu, ID_VID_VIDEO0 + i, ((i == curtrack) ? MF_CHECKED : MF_UNCHECKED) | MF_BYCOMMAND);
  167. }
  168. EnableMenuItem(menu, 9, MF_ENABLED | MF_BYPOSITION);
  169. }
  170. }
  171. int ShowVideoWindow(int init_state)
  172. {
  173. sizeOnOpen = false;
  174. if (config_video_open // if we're already open
  175. || !hVideoWindow // or we havn't made the video window yet
  176. || !g_has_video_plugin // or we're configured to not have video
  177. || !Ipc_WindowToggle(IPC_CB_WND_VIDEO, 1)) // or some plugin doesn't want us to open the video window
  178. return 0; // then bail out
  179. CheckMenuItem(main_menu, WINAMP_OPTIONS_VIDEO, MF_CHECKED);
  180. if(!init_state && !config_minimized) ShowWindow(hVideoWindow, SW_SHOWNA);
  181. //ad->show(true);
  182. config_video_open = 1;
  183. set_aot(1);
  184. return 1;
  185. }
  186. void HideVideoWindow(int autoStop)
  187. {
  188. sizeOnOpen = false;
  189. if (!config_video_open // if we're not even open
  190. || !hVideoWindow // or we havn't made the video window yet
  191. // || !g_has_video_plugin // or we're configured to not have video
  192. || !Ipc_WindowToggle(IPC_CB_WND_VIDEO, !config_video_open)) // or some plugin doesn't want us to close the video window
  193. return ; // then bail out
  194. if (GetForegroundWindow() == hVideoWindow || IsChild(hVideoWindow, GetForegroundWindow()))
  195. {
  196. SendMessageW(hMainWindow, WM_COMMAND, WINAMP_NEXT_WINDOW, 0);
  197. }
  198. CheckMenuItem(main_menu, WINAMP_OPTIONS_VIDEO, MF_UNCHECKED);
  199. ShowWindow(hVideoWindow, SW_HIDE);
  200. config_video_open = 0;
  201. if (autoStop && config_video_stopclose && !(GetAsyncKeyState(VK_SHIFT)&0x8000) && video_isVideoPlaying())
  202. {
  203. PostMessageW(hMainWindow, WM_COMMAND, WINAMP_BUTTON4, 0);
  204. }
  205. }
  206. HMENU BuildPopupMenu();
  207. void Vid_Cmd(windowCommand *wc)
  208. {
  209. switch (wc->cmd)
  210. {
  211. case VIDCMD_FULLSCREEN:
  212. videoGoFullscreen();
  213. break;
  214. case VIDCMD_1X:
  215. SendMessageW(videoGetHwnd(), WM_COMMAND, ID_VIDEOWND_ZOOM100, 0);
  216. break;
  217. case VIDCMD_2X:
  218. SendMessageW(videoGetHwnd(), WM_COMMAND, ID_VIDEOWND_ZOOM200, 0);
  219. break;
  220. case VIDCMD_LIB:
  221. SendMessageW(videoGetHwnd(), WM_COMMAND, WINAMP_VIDEO_TVBUTTON, 0);
  222. break;
  223. case VIDPOPUP_MISC:
  224. DoTrackPopup(BuildPopupMenu(), wc->align, wc->x, wc->y, videoGetHwnd());
  225. break;
  226. case VIDCMD_EXIT_FS:
  227. videoForceFullscreenOff();
  228. break;
  229. }
  230. }
  231. static int VW_OnRButtonUp(HWND hwnd, int x, int y, UINT flags)
  232. {
  233. POINT p;
  234. extern HMENU top_menu;
  235. GetCursorPos(&p);
  236. DoTrackPopup(main_menu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, p.x, p.y, hMainWindow);
  237. return 1;
  238. }
  239. static int VW_OnLButtonUp(HWND hwnd, int x, int y, UINT flags)
  240. {
  241. ReleaseCapture();
  242. videoui_handlemouseevent(x, y, -1, flags);
  243. return 1;
  244. }
  245. static int VW_OnLButtonDown( HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags )
  246. {
  247. SetCapture( hwnd );
  248. videoui_handlemouseevent( x, y, 1, keyFlags );
  249. SetFocus( hwnd );
  250. return 1;
  251. }
  252. static int VW_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
  253. {
  254. videoui_handlemouseevent(x, y, 0, keyFlags);
  255. return 1;
  256. }
  257. static BOOL VW_OnNCActivate( HWND hwnd, BOOL fActive, HWND hwndActDeact, BOOL fMinimized )
  258. {
  259. if ( !m_videooutput || ( m_videooutput && !m_videooutput->is_fullscreen() ) )
  260. {
  261. if ( fActive == FALSE )
  262. draw_vw_tbar( config_hilite ? 0 : 1 );
  263. else
  264. draw_vw_tbar( 1 );
  265. }
  266. return TRUE;
  267. }
  268. static int VW_OnLButtonDblClk(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
  269. {
  270. return 1;
  271. }
  272. /*Turns off and on the screensaver*/
  273. VOID CALLBACK ResetScreenSaver(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
  274. {
  275. // benski> this seems less hackish. only win2k and up
  276. if (config_video_noss && video_isVideoPlaying())
  277. SetThreadExecutionState(ES_DISPLAY_REQUIRED);
  278. // TODO: maybe we should do the same thing with ES_SYSTEM_REQUIRED to keep the system from snoozing
  279. // benski> old code was here
  280. /*
  281. BOOL b;
  282. if (config_video_noss && video_isVideoPlaying() && SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &b, 0) && b)
  283. {
  284. SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, 0, 0); // turn off
  285. SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, 0, 0); // turn back on
  286. // this is just a hack
  287. // basically by toggling off and on we reset the timeout count
  288. }
  289. */
  290. }
  291. static void VideoOpen(HWND hwnd, int width, int height)
  292. {
  293. sizeOnOpen=false;
  294. // check if we appear to be doing a resume from a tag edit
  295. // and if so then we need to ignore the show window option
  296. if (config_video_autoopen &&
  297. ((no_notify_play != last_no_notify_play && !last_no_notify_play) || (no_notify_play == last_no_notify_play)))
  298. ShowVideoWindow(0);
  299. last_no_notify_play = no_notify_play;
  300. HWND skinVidWindow = GetParent(hwnd) ? GetParent(hwnd) : hwnd;
  301. if (m_videooutput->is_fullscreen() || config_video_auto_fs) // go fullscreen
  302. {
  303. videoGoFullscreen();
  304. InvalidateRect(m_videooutput->getHwnd(), 0, TRUE);
  305. }
  306. else // not fullscreen
  307. {
  308. if (config_video_updsize)
  309. {
  310. widthOnOpen = width;
  311. heightOnOpen = height;
  312. sizeOnOpen = true;
  313. SetVideoSize(width, height);
  314. }
  315. LayoutChildren(config_video_width, config_video_height);
  316. if (!IsIconic(skinVidWindow))
  317. BringWindowToTop(skinVidWindow);
  318. InvalidateRect(hwnd, 0, TRUE);
  319. }
  320. }
  321. LRESULT CALLBACK video_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  322. {
  323. if (uMsg == g_scrollMsg) { wParam <<= 16; uMsg = WM_MOUSEWHEEL; }
  324. if (uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONUP || uMsg == WM_MOUSEMOVE)
  325. if (!m_videooutput || !m_videooutput->is_fullscreen())
  326. {
  327. switch (uMsg)
  328. {
  329. HANDLE_MSG(hwnd, WM_LBUTTONUP, VW_OnLButtonUp);
  330. HANDLE_MSG(hwnd, WM_LBUTTONDOWN, VW_OnLButtonDown);
  331. HANDLE_MSG(hwnd, WM_MOUSEMOVE, VW_OnMouseMove);
  332. HANDLE_MSG(hwnd, WM_RBUTTONUP, VW_OnRButtonUp);
  333. }
  334. }
  335. switch (uMsg)
  336. {
  337. case WM_USER + 1:
  338. if (m_videooutput)
  339. SendMessageW(m_videooutput->getHwnd(), uMsg, wParam, lParam);
  340. break;
  341. case WM_USER + 2:
  342. if (sizeOnOpen)
  343. {
  344. // sizeOnOpen=false;
  345. PostMessageW(hwnd, WM_VIDEO_RESIZE, widthOnOpen, heightOnOpen);
  346. }
  347. if (m_videooutput)
  348. SendMessageW(m_videooutput->getHwnd(), uMsg, wParam, lParam);
  349. break;
  350. case WM_USER + 0x100:
  351. if (wParam == 1 && lParam)
  352. {
  353. config_video_wx = ((POINT *)lParam)->x;
  354. config_video_wy = ((POINT *)lParam)->y;
  355. if ((!!config_snap) ^ (!!(GetKeyState(VK_SHIFT) & 0x8000)))
  356. {
  357. RECT outrc;
  358. EstVidWindowRect(&outrc);
  359. SnapWindowToAllWindows(&outrc, hVideoWindow);
  360. SetVidWindowRect(&outrc);
  361. }
  362. SetWindowPos(hVideoWindow, 0, config_video_wx, config_video_wy, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  363. }
  364. return 0;
  365. case WM_TIMER:
  366. switch (wParam)
  367. {
  368. case 12345: // signal from elsewhere
  369. if (m_videooutput)
  370. SendMessageW(m_videooutput->getHwnd(), WM_TIMER, 0, 0);
  371. break;
  372. }
  373. return 0;
  374. case WM_WINDOWPOSCHANGING:
  375. case WM_WINDOWPOSCHANGED: // we trap both windowposchanging and windowposchanged incase someone uses SetWindowPos(..., SWP_NOSENDCHANGING)
  376. {
  377. LPWINDOWPOS windowPos = (LPWINDOWPOS) lParam;
  378. if (windowPos->flags & SWP_NOSIZE)
  379. {
  380. break;
  381. }
  382. if (uMsg == WM_WINDOWPOSCHANGED)
  383. {
  384. config_video_width = windowPos->cx;
  385. config_video_height = windowPos->cy;
  386. LayoutChildren(config_video_width, config_video_height);
  387. // update the position of the tooltips on window resize
  388. set_vid_wnd_tooltip();
  389. }
  390. }
  391. break;
  392. case WM_NOTIFY:
  393. {
  394. LPTOOLTIPTEXT tt = (LPTOOLTIPTEXT)lParam;
  395. if(tt->hdr.hwndFrom = hVideoTooltipWindow)
  396. {
  397. switch (tt->hdr.code)
  398. {
  399. case TTN_SHOW:
  400. SetWindowPos(tt->hdr.hwndFrom,HWND_TOPMOST,0,0,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE);
  401. break;
  402. }
  403. }
  404. }
  405. break;
  406. case WM_GETMINMAXINFO:
  407. {
  408. MINMAXINFO *p = (MINMAXINFO *)lParam;
  409. p->ptMaxTrackSize.x = 16384;
  410. p->ptMaxTrackSize.y = 16384;
  411. }
  412. return 0;
  413. case WM_VIDEO_RESIZE:
  414. //ReplyMessage(0); // if IVideoOutput::open() was called on a different thread, this will unblock it.
  415. {
  416. int width = wParam;
  417. int height = lParam;
  418. // idealWidth = wParam;
  419. SetVideoSize(width, height);
  420. LayoutChildren(config_video_width, config_video_height);
  421. }
  422. return 0;
  423. case WM_DESTROY:
  424. if (NULL != WASABI_API_APP) WASABI_API_APP->app_unregisterGlobalWindow(hwnd);
  425. if (vw_init)
  426. draw_vw_kill();
  427. break;
  428. case WM_DISPLAYCHANGE:
  429. InvalidateRect(hwnd, NULL, TRUE);
  430. break;
  431. case WM_VIDEO_OPEN:
  432. VideoOpen(hwnd, wParam, lParam);
  433. // set_aot(1);
  434. return 0;
  435. break;
  436. case WM_VIDEO_CREATE:
  437. m_videooutput->mainthread_Create();
  438. break;
  439. case WM_VIDEO_CLOSE:
  440. VideoClose();
  441. InvalidateRect(hwnd, NULL, TRUE); //repaint
  442. return 0;
  443. case WM_VIDEO_UPDATE_STATUS_TEXT:
  444. if (m_videooutput && !m_videooutput->is_fullscreen())
  445. draw_vw_info((wchar_t*)wParam, 1);
  446. videoTextFeed->UpdateText((const wchar_t*)wParam, 1024);
  447. return 0;
  448. case WM_MOUSEWHEEL:
  449. return SendMessageW(hMainWindow, uMsg, wParam, lParam);
  450. HANDLE_MSG(hwnd, WM_QUERYNEWPALETTE, Main_OnQueryNewPalette);
  451. HANDLE_MSG(hwnd, WM_PALETTECHANGED, Main_OnPaletteChanged);
  452. HANDLE_MSG(hwnd, WM_NCACTIVATE, VW_OnNCActivate);
  453. HANDLE_MSG(hwnd, WM_LBUTTONDBLCLK, VW_OnLButtonDblClk);
  454. case WM_CONTEXTMENU:
  455. {
  456. if (lParam == MAKELONG(-1, -1))
  457. {
  458. extern HMENU top_menu;
  459. RECT r;
  460. GetWindowRect(videoGetHwnd(), &r);
  461. DoTrackPopup(BuildPopupMenu(), TPM_LEFTALIGN | TPM_RIGHTBUTTON, r.left, r.top, videoGetHwnd());
  462. }
  463. }
  464. return 0;
  465. case WM_KEYDOWN: case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP:
  466. if ((GetAsyncKeyState(VK_CONTROL)&0x8000) && wParam == VK_F4)
  467. {
  468. if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)
  469. SendMessageW(hMainWindow, WM_COMMAND, WINAMP_OPTIONS_VIDEO, 0);
  470. }
  471. /* else if(uMsg==WM_SYSKEYDOWN && (LPARAM&(1<<29)) && wParam == VK_RETURN)
  472. {
  473. if (m_videooutput)
  474. {
  475. if(!m_videooutput->is_fullscreen()) m_videooutput->fullscreen();
  476. else m_videooutput->remove_fullscreen();
  477. }
  478. }*/
  479. else
  480. {
  481. if (SendMessageW(m_videooutput->getHwnd(), uMsg, wParam, lParam)) return 0;
  482. if (wParam != VK_RETURN && m_videooutput->is_fullscreen() && ((GetAsyncKeyState(VK_CONTROL) | GetAsyncKeyState(VK_MENU))&0x8000)) return 0;
  483. {
  484. MSG winmsg;
  485. winmsg.message = uMsg;
  486. winmsg.hwnd = hMainWindow;
  487. winmsg.wParam = wParam;
  488. winmsg.lParam = lParam;
  489. if (WASABI_API_APP->app_translateAccelerators(&winmsg)) return 0;
  490. //if (transAccel(hwnd,uMsg,wParam,lParam)) return 0;
  491. //transAccelStruct tas = {hwnd, uMsg, wParam, lParam};
  492. //if (SendMessageW(hMainWindow, WM_WA_IPC, (WPARAM)&tas, IPC_TRANSLATEACCELERATOR)) return 0;
  493. }
  494. }
  495. break;
  496. case WM_DROPFILES:
  497. return SendMessageW(hMainWindow, uMsg, wParam, lParam);
  498. case WM_SHOWWINDOW:
  499. if (wParam == TRUE) // showing
  500. {
  501. if (sizeOnOpen)
  502. {
  503. //sizeOnOpen=false;
  504. PostMessageW(hwnd, WM_VIDEO_RESIZE, widthOnOpen, heightOnOpen);
  505. }
  506. if (!IsIconic(hwnd))
  507. BringWindowToTop(hwnd);
  508. LayoutChildren(config_video_width, config_video_height);
  509. }
  510. RefreshIconicThumbnail();
  511. /*
  512. {
  513. // if extra_data[EMBED_STATE_EXTRA_REPARENTING] is set, we are being reparented by the freeform lib, so we should
  514. // just ignore this message because our visibility will not change once the freeform
  515. // takeover/restoration is complete
  516. embedWindowState *ws = (embedWindowState *)GetWindowLongW(hwnd, GWL_USERDATA);
  517. if (ws != NULL && ws->extra_data[EMBED_STATE_EXTRA_REPARENTING])
  518. {
  519. }
  520. }
  521. */
  522. break;
  523. case WM_CLOSE:
  524. if (!m_videooutput || !m_videooutput->is_fullscreen())
  525. WASABI_API_APP->main_shutdown();
  526. else
  527. m_videooutput->remove_fullscreen();
  528. return 0;
  529. case WM_PAINT:
  530. if (!m_videooutput || !m_videooutput->is_fullscreen())
  531. {
  532. draw_paint_vw(hwnd);
  533. return 0;
  534. }
  535. break;
  536. case WM_CREATE:
  537. hVideoWindow = hwnd;
  538. SetTimer(hwnd, 32, 15000, ResetScreenSaver);
  539. SetWindowLongPtrW(hwnd, GWLP_USERDATA, (config_keeponscreen&2) ? 0x49474541 : 0);
  540. SetWindowLongW(hwnd, GWL_STYLE, GetWindowLongW(hwnd, GWL_STYLE)&~(WS_CAPTION));
  541. SetWindowPos(hVideoWindow, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
  542. //ad->CreateHWND(hwnd);
  543. m_videooutput = new VideoOutput(hwnd);
  544. if (!config_minimized)
  545. ShowWindow(m_videooutput->getHwnd(), SW_SHOWNA);
  546. SetExteriorSizeAndPosition(config_video_wx, config_video_wy, config_video_width, config_video_height);
  547. LayoutChildren(config_video_width, config_video_height);
  548. if (NULL != WASABI_API_APP) WASABI_API_APP->app_registerGlobalWindow(hwnd);
  549. return 0;
  550. case WM_COMMAND:
  551. return SendMessageW(hMainWindow, uMsg, wParam, lParam);
  552. case WM_MOVE:
  553. if (m_videooutput)
  554. SendMessageW(m_videooutput->getHwnd(), WM_MOVE, 0, 0);
  555. return 0;
  556. case WM_SETCURSOR:
  557. if (config_usecursors && !disable_skin_cursors)
  558. {
  559. #define inreg(x,y,x2,y2) \
  560. ((mouse_x <= ( x2 ) && mouse_x >= ( x ) && \
  561. mouse_y <= ( y2 ) && mouse_y >= ( y )))
  562. if (((HWND)wParam == hVideoWindow || IsChild(hVideoWindow, (HWND)wParam)) && HIWORD(lParam) == WM_MOUSEMOVE)
  563. {
  564. int mouse_x, mouse_y;
  565. POINT p;
  566. static RECT b[] =
  567. {
  568. { -(275 - 264), 3, -(275 - 272), 12}, //close
  569. {0, 0, -1, 13}, // titelbar
  570. { -20, -20, -1, -1},
  571. };
  572. int iconoffs[] = {15 + 1, 15 + 2, 15 + 4, 15 + 5};
  573. int b_len = 3;
  574. int x;
  575. GetCursorPos(&p);
  576. ScreenToClient(hVideoWindow, &p);
  577. mouse_x = p.x;
  578. mouse_y = p.y;
  579. for (x = 0; x < b_len; x ++)
  580. {
  581. int l, r, t, bo;
  582. l = b[x].left;r = b[x].right;t = b[x].top;bo = b[x].bottom;
  583. if (l < 0) l += config_video_width;
  584. if (r < 0) r += config_video_width;
  585. if (t < 0) t += config_video_height;
  586. if (bo < 0) bo += config_video_height;
  587. if (inreg(l, t, r, bo)) break;
  588. }
  589. if (Skin_Cursors[iconoffs[x]]) SetCursor(Skin_Cursors[iconoffs[x]]);
  590. else SetCursor(LoadCursorW(NULL, IDC_ARROW));
  591. }
  592. return TRUE;
  593. }
  594. else SetCursor(LoadCursorW(NULL, IDC_ARROW));
  595. return TRUE;
  596. case WM_SYSCOMMAND:
  597. // eat screen saver message when fullscreen
  598. if (((wParam & 0xfff0) == SC_SCREENSAVE || (wParam & 0xfff0) == SC_MONITORPOWER) && config_video_noss &&
  599. video_isVideoPlaying())
  600. {
  601. return -1;
  602. }
  603. break;
  604. }
  605. if (FALSE != IsDirectMouseWheelMessage(uMsg))
  606. {
  607. SendMessageW(hwnd, WM_MOUSEWHEEL, wParam, lParam);
  608. return TRUE;
  609. }
  610. return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  611. }
  612. static void VideoClose()
  613. {
  614. sizeOnOpen=false;
  615. if (!g_has_video_plugin)
  616. return ;
  617. if (m_videooutput && m_videooutput->is_fullscreen() && config_video_remove_fs_on_stop)
  618. videoForceFullscreenOff();
  619. if ((!m_videooutput && (bool)config_video_autoclose)
  620. || (m_videooutput && !m_videooutput->is_fullscreen() && (bool)config_video_autoclose))
  621. HideVideoWindow(false);
  622. }
  623. extern "C"
  624. {
  625. void videoAdSizeChanged()
  626. {
  627. LayoutChildren(config_video_width, config_video_height);
  628. }
  629. void *video_getIVideoOutput()
  630. {
  631. return (void *)m_videooutput;
  632. }
  633. int video_isVideoPlaying()
  634. {
  635. if (!m_videooutput) return 0;
  636. return m_videooutput->isVideoPlaying();
  637. }
  638. void videoGoFullscreen()
  639. {
  640. if (m_videooutput)
  641. {
  642. m_videooutput->fullscreen();
  643. }
  644. }
  645. int videoIsFullscreen()
  646. {
  647. if (m_videooutput) return !!m_videooutput->is_fullscreen();
  648. return 0;
  649. }
  650. void videoReinit()
  651. {
  652. if (m_videooutput)
  653. PostMessageW(m_videooutput->getHwnd(), WM_USER + 0x1, 0, 0);
  654. }
  655. void videoForceFullscreenOff()
  656. {
  657. if (m_videooutput)
  658. {
  659. m_videooutput->remove_fullscreen();
  660. LayoutChildren(config_video_width, config_video_height);
  661. }
  662. }
  663. void videoToggleFullscreen()
  664. {
  665. if (m_videooutput)
  666. {
  667. if (!m_videooutput->is_fullscreen())
  668. videoGoFullscreen();
  669. else
  670. videoForceFullscreenOff();
  671. }
  672. }
  673. void videoSetFlip(int on)
  674. {
  675. if (m_videooutput)
  676. {
  677. m_videooutput->extended(VIDUSER_SET_VFLIP, on, 0);
  678. }
  679. // for consistency we need to update the state on the prefs page
  680. if(prefs_last_page == 24 && IsWindow(prefs_hwnd))
  681. {
  682. SendMessageW(prefs_hwnd, WM_USER + 33, IDC_PREFS_VIDEO_FLIPRGB, on);
  683. }
  684. CheckMenuItem(GetSubMenu(GetSubMenu(top_menu, 3), 13), ID_VIDEOWND_VERTICALLYFLIP, (on ? MF_CHECKED: MF_UNCHECKED));
  685. }
  686. DWORD videoGetWidthHeightDWORD()
  687. {
  688. if (!m_videooutput) return 0;
  689. return m_videooutput->GetWidthHeightDWORD();
  690. }
  691. HWND videoGetHwnd()
  692. {
  693. if (m_videooutput) return m_videooutput->getHwnd();
  694. return NULL;
  695. }
  696. int video_getNumAudioTracks()
  697. {
  698. VideoOutput *vid = (VideoOutput *)video_getIVideoOutput();
  699. if (!vid) return 1;
  700. ITrackSelector *sel = vid->getTrackSelector();
  701. if (!sel) return 1;
  702. return sel->getNumAudioTracks();
  703. }
  704. int video_getNumVideoTracks()
  705. {
  706. VideoOutput *vid = (VideoOutput *)video_getIVideoOutput();
  707. if (!vid) return 1;
  708. ITrackSelector *sel = vid->getTrackSelector();
  709. if (!sel) return 1;
  710. return sel->getNumVideoTracks();
  711. }
  712. int video_getCurAudioTrack()
  713. {
  714. VideoOutput *vid = (VideoOutput *)video_getIVideoOutput();
  715. if (!vid) return 0;
  716. ITrackSelector *sel = vid->getTrackSelector();
  717. if (!sel) return 0;
  718. return sel->getCurAudioTrack();
  719. }
  720. int video_getCurVideoTrack()
  721. {
  722. VideoOutput *vid = (VideoOutput *)video_getIVideoOutput();
  723. if (!vid) return 0;
  724. ITrackSelector *sel = vid->getTrackSelector();
  725. if (!sel) return 0;
  726. return sel->getCurVideoTrack();
  727. }
  728. int video_setCurAudioTrack(int track)
  729. {
  730. VideoOutput *vid = (VideoOutput *)video_getIVideoOutput();
  731. if (!vid) return 0;
  732. ITrackSelector *sel = vid->getTrackSelector();
  733. if (!sel) return 0;
  734. sel->setAudioTrack(track);
  735. return sel->getCurAudioTrack();
  736. }
  737. int video_setCurVideoTrack(int track)
  738. {
  739. VideoOutput *vid = (VideoOutput *)video_getIVideoOutput();
  740. if (!vid) return 0;
  741. ITrackSelector *sel = vid->getTrackSelector();
  742. if (!sel) return 0;
  743. sel->setVideoTrack(track);
  744. return sel->getCurVideoTrack();
  745. }
  746. HWND video_Create()
  747. {
  748. return CreateWindowExW(WS_EX_ACCEPTFILES, L"Winamp Video", getStringW(IDS_VIDEOCAPTION, NULL, 0), (WS_OVERLAPPED | WS_CLIPCHILDREN)&(~WS_CAPTION),
  749. config_video_wx, config_video_wy, config_video_width, config_video_height,
  750. hMainWindow, NULL, GetModuleHandle(NULL), NULL);
  751. }
  752. }