wa2wndembed.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. #include <precomp.h>
  2. #include "wa2wndembed.h"
  3. #include "wa2frontend.h"
  4. #include "wa2buckitems.h"
  5. #include "embedwndguid.h"
  6. #include "main.h"
  7. #include <api/wnd/bucketitem.h>
  8. #include "resource.h"
  9. #include <api/wnd/wndclass/wndholder.h>
  10. #include <api/wndmgr/layout.h>
  11. #include "wa2cfgitems.h"
  12. #include "gen.h"
  13. #include "../Agave/Language/api_language.h"
  14. extern TList<HWND> forcedoffwnds;
  15. #define BUCKETITEM_WNDTYPE L"buck"
  16. #define WINAMP_OPTIONS_WINDOWSHADE_PL 40266
  17. ReentryFilterObject wndMsgFilter;
  18. int embedTable[] = {
  19. IPC_GETWND_PE,
  20. #ifdef MINIBROWSER_SUPPORT
  21. IPC_GETWND_MB,
  22. #endif
  23. IPC_GETWND_VIDEO};
  24. extern int switching_skin;
  25. extern int going_fixedform;
  26. extern int going_freeform;
  27. extern HINSTANCE hInstance;
  28. //-----------------------------------------------------------------------------------------------
  29. void WaOsWndHost::onBeforeReparent(int host)
  30. {
  31. #if defined(_WIN64)
  32. embedWindowState *ws = (embedWindowState *)GetWindowLong(getHWND(), GWLP_USERDATA);
  33. #else
  34. embedWindowState* ws = (embedWindowState*)GetWindowLong(getHWND(), GWL_USERDATA);
  35. #endif
  36. // 0x49474541 is related to keeping windows shown on litestep desktops
  37. if (ws == NULL || (int)ws == 0x49474541)
  38. {
  39. HWND w = getHWND();
  40. if (w == wa2.getWnd(IPC_GETWND_VIDEO))
  41. {
  42. // this tells the video to not trigger its callback on windowposchanged, otherwise it will generate a new IPC_ONSHOW
  43. SendMessageW(w, WM_USER + 0x2, 0, 1);
  44. }
  45. return ;
  46. }
  47. ws->extra_data[EMBED_STATE_EXTRA_REPARENTING] = 1; // tell winamp to ignore show/hide events
  48. if (!host)
  49. {
  50. ShowWindow(getHWND(), SW_HIDE);
  51. if (!transfer && ((switching_skin && !Wa2WndEmbed::hadRememberedWndVisible(getHWND())) || !switching_skin))
  52. {
  53. PostMessage(getHWND(), WM_USER + 101, 0, 0);
  54. }
  55. }
  56. }
  57. //-----------------------------------------------------------------------------------------------
  58. void WaOsWndHost::onAfterReparent(int host)
  59. {
  60. #if defined(_WIN64)
  61. embedWindowState *ws = (embedWindowState *)GetWindowLong(getHWND(), GWLP_USERDATA);
  62. #else
  63. embedWindowState* ws = (embedWindowState*)GetWindowLong(getHWND(), GWL_USERDATA);
  64. #endif
  65. // 0x49474541 is related to keeping windows shown on litestep desktops
  66. if (ws == NULL || (int)ws == 0x49474541)
  67. {
  68. HWND w = getHWND();
  69. if (w == wa2.getWnd(IPC_GETWND_VIDEO))
  70. {
  71. // stop preventing handling of video windowposchanged
  72. SendMessageW(w, WM_USER + 0x2, 0, 0);
  73. }
  74. return ;
  75. }
  76. ws->extra_data[EMBED_STATE_EXTRA_REPARENTING] = 0; // tell winamp NOT to ignore show/hide events anymore
  77. }
  78. //-----------------------------------------------------------------------------------------------
  79. int WaOsWndHost::onGetFocus()
  80. {
  81. XuiOSWndHost::onGetFocus();
  82. ifc_window *z = findWindowByInterface(windowHolderGuid);
  83. if (z)
  84. {
  85. WindowHolder *wh = static_cast<WindowHolder*>(z->getInterface(windowHolderGuid));
  86. if (wh && wh->wndholder_wantAutoFocus())
  87. {
  88. HWND w = getHWND();
  89. if (IsWindow(w)) SetFocus(w);
  90. }
  91. }
  92. return 1;
  93. }
  94. //-----------------------------------------------------------------------------------------------
  95. int WaOsWndHost::wantFocus()
  96. {
  97. ifc_window *w = findWindowByInterface(windowHolderGuid);
  98. if (w)
  99. {
  100. WindowHolder *wh = static_cast<WindowHolder*>(w->getInterface(windowHolderGuid));
  101. if (wh)
  102. {
  103. return wh->wndholder_wantAutoFocus();
  104. }
  105. }
  106. return 0;
  107. }
  108. //-----------------------------------------------------------------------------------------------
  109. int WaOsWndHost::onMouseWheelUp(int click, int lines)
  110. {
  111. return 1;
  112. }
  113. //-----------------------------------------------------------------------------------------------
  114. int WaOsWndHost::onMouseWheelDown(int click, int lines)
  115. {
  116. return 1;
  117. }
  118. //-----------------------------------------------------------------------------------------------
  119. void VideoLayoutMonitor::hook_onResize(int x, int y, int w, int h)
  120. {
  121. SendMessageW(wa2.getWnd(IPC_GETWND_VIDEO), WM_TIMER, 12345, 0);
  122. }
  123. //-----------------------------------------------------------------------------------------------
  124. void VideoLayoutMonitor::hook_onMove()
  125. {
  126. SendMessageW(wa2.getWnd(IPC_GETWND_VIDEO), WM_TIMER, 12345, 0);
  127. }
  128. //-----------------------------------------------------------------------------------------------
  129. Wa2WndEmbed::Wa2WndEmbed()
  130. {
  131. WASABI_API_SYSCB->syscb_registerCallback(static_cast<WndCallbackI*>(this));
  132. }
  133. //-----------------------------------------------------------------------------------------------
  134. Wa2WndEmbed::~Wa2WndEmbed()
  135. {
  136. WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<WndCallbackI*>(this));
  137. wa2wndstatus.deleteAll();
  138. }
  139. extern int we_have_ml;
  140. //-----------------------------------------------------------------------------------------------
  141. int Wa2WndEmbed::testGuid(GUID g)
  142. {
  143. if (embedWndGuidMgr.testGuid(g)) return 1;
  144. /* if (embedWndGuids.Data2 == g.Data2 && // embed wnd check :)
  145. embedWndGuids.Data3 == g.Data3 &&
  146. !memcmp(embedWndGuids.Data4,g.Data4,8)) return 1;*/
  147. return (g == pleditWndGuid || g == videoWndGuid
  148. #ifdef MINIBROWSER_SUPPORT
  149. || g == minibrowserWndGuid
  150. #endif
  151. || (we_have_ml && g == library_guid)
  152. );
  153. }
  154. int make_sure_library_is_here_at_startup = 0;
  155. extern int m_loading_at_startup;
  156. //-----------------------------------------------------------------------------------------------
  157. ifc_window *Wa2WndEmbed::createWindowByGuid(GUID g, ifc_window *parent)
  158. {
  159. if (m_loading_at_startup)
  160. if (g == library_guid)
  161. make_sure_library_is_here_at_startup = 1;
  162. WaOsWndHost *oldhost = NULL;
  163. if (embedWndGuidMgr.testGuid(g) && !embedWndGuidMgr.getEmbedWindowState(g))
  164. return NULL;
  165. // first check if this window is already open in a host, and if so, remove it from the wndholder
  166. foreach(wndhosts)
  167. if (wndhosts.getfor()->g == g)
  168. {
  169. WaOsWndHost *host = wndhosts.getfor()->host;
  170. oldhost = host;
  171. host->setTransfering(1);
  172. host->oswndhost_unhost();
  173. Layout *l = static_cast<Layout *>(host->getDesktopParent());
  174. if (l)
  175. {
  176. Container *c = l->getParentContainer();
  177. if (c)
  178. {
  179. if (!WCSCASEEQLSAFE(c->getId(), L"main"))
  180. {
  181. c->close(); // deferred if needed
  182. }
  183. else
  184. {
  185. softclose:
  186. ifc_window *wnd = host->findWindowByInterface(windowHolderGuid);
  187. if (wnd != NULL)
  188. {
  189. WindowHolder *wh = static_cast<WindowHolder *>(wnd->getInterface(windowHolderGuid));
  190. if (wh != NULL)
  191. {
  192. wh->onRemoveWindow(1);
  193. }
  194. }
  195. }
  196. }
  197. else goto softclose;
  198. }
  199. }
  200. endfor;
  201. // now host the wnd in a new host
  202. WaOsWndHost *host = new WaOsWndHost();
  203. viewer_addViewItem(host);
  204. EmbedEntry *ee = new EmbedEntry();
  205. wndhosts.addItem(ee);
  206. ee->g = g;
  207. ee->host = host;
  208. ee->monitor = NULL;
  209. ee->dep = host->getDependencyPtr();
  210. ee->cmds = NULL;
  211. if (g == pleditWndGuid)
  212. {
  213. RECT r = {10, 20, 5, 38};
  214. host->oswndhost_setRegionOffsets(&r);
  215. host->oswndhost_host(wa2.getWnd(IPC_GETWND_PE));
  216. ee->whichwnd = IPC_GETWND_PE;
  217. host->setName((L"Playlist Editor")/*(WASABI_API_LNGSTRINGW(IDS_PLAYLIST_EDITOR)*/);
  218. GuiObject *go = parent->getGuiObject();
  219. PlaylistAppCmds *plEditAppCmds = new PlaylistAppCmds();
  220. ee->cmds = plEditAppCmds;
  221. go->guiobject_addAppCmds(plEditAppCmds);
  222. plWnd = parent; //parent->getDesktopParent();
  223. //ShowWindow(host->getHWND(), SW_NORMAL);
  224. }
  225. else if (g == videoWndGuid)
  226. {
  227. RECT r = {11, 20, 8, 38};
  228. host->oswndhost_setRegionOffsets(&r);
  229. #ifdef VIDDEBUG
  230. DebugString("Video : Window service creates the host\n");
  231. #endif
  232. HWND vid = wa2.getWnd(IPC_GETWND_VIDEO);
  233. host->oswndhost_host(vid);
  234. ((WaOsWndHost *)host)->setNoTransparency();
  235. ee->whichwnd = IPC_GETWND_VIDEO;
  236. host->setName(WASABI_API_LNGSTRINGW(IDS_VIDEO));
  237. ifc_window *lw = parent->getDesktopParent();
  238. if (lw)
  239. {
  240. GuiObject *o = lw->getGuiObject();
  241. if (o)
  242. {
  243. ee->monitor = new VideoLayoutMonitor(o->guiobject_getScriptObject());
  244. }
  245. }
  246. SetTimer(vid, 12345, 250, NULL);
  247. GuiObject *go = parent->getGuiObject();
  248. VideoAppCmds *videoAppCmds = new VideoAppCmds();
  249. ee->cmds = videoAppCmds;
  250. go->guiobject_addAppCmds(videoAppCmds);
  251. vidWnd = parent; //parent->getDesktopParent();
  252. //ShowWindow(host->getHWND(), SW_NORMAL);
  253. #ifdef MINIBROWSER_SUPPORT
  254. }
  255. else if (g == minibrowserWndGuid)
  256. {
  257. RECT r = {10, 20, 5, 38};
  258. host->oswndhost_setRegionOffsets(&r);
  259. host->oswndhost_host(wa2.getWnd(IPC_GETWND_MB));
  260. ee->whichwnd = IPC_GETWND_MB;
  261. host->setName("Minibrowser");
  262. GuiObject *go = parent->getGuiObject();
  263. mbWnd = parent; //parent->getDesktopParent();
  264. MinibrowserAppCmds *mbAppCmds = new MinibrowserAppCmds();
  265. ee->cmds = mbAppCmds;
  266. go->guiobject_addAppCmds(mbAppCmds);
  267. //ShowWindow(host->getHWND(), SW_NORMAL);
  268. #endif
  269. }
  270. else if (embedWndGuidMgr.testGuid(g)) /*(embedWndGuids.Data2 == g.Data2 &&
  271. embedWndGuids.Data3 == g.Data3 &&
  272. !memcmp(embedWndGuids.Data4,g.Data4,8))*/
  273. {
  274. embedWindowState *ws = embedWndGuidMgr.getEmbedWindowState(g);
  275. ASSERT(ws != NULL);
  276. if (0 == (WS_BORDER & GetWindowLongPtrW(ws->me, GWL_STYLE)))
  277. {
  278. RECT r = {11, 20, 8, 14};
  279. host->oswndhost_setRegionOffsets(&r);
  280. }
  281. else
  282. host->oswndhost_setRegionOffsets(NULL);
  283. ws->extra_data[EMBED_STATE_EXTRA_HOSTCOUNT]++;
  284. ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t)parent; //parent->getDesktopParent();
  285. ee->whichwnd = (intptr_t)ws;
  286. if (ws->flags & EMBED_FLAGS_NOTRANSPARENCY) host->setNoTransparency();
  287. host->oswndhost_host(ws->me);
  288. wchar_t buf[512] = {0};
  289. GetWindowTextW(ws->me, buf, 512);
  290. host->setName(buf);
  291. }
  292. else
  293. {
  294. wndhosts.removeItem(ee);
  295. delete host;
  296. delete ee;
  297. return NULL;
  298. }
  299. wa2.setOnTop(cfg_options_alwaysontop.getValueAsInt());
  300. return host;
  301. }
  302. //-----------------------------------------------------------------------------------------------
  303. int Wa2WndEmbed::testType(const wchar_t *windowtype)
  304. {
  305. return !_wcsicmp(windowtype, BUCKETITEM_WNDTYPE) || !_wcsicmp(windowtype, L"plsc");
  306. }
  307. //-----------------------------------------------------------------------------------------------
  308. ifc_window *Wa2WndEmbed::createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int n)
  309. {
  310. if (!_wcsicmp(windowtype, BUCKETITEM_WNDTYPE))
  311. {
  312. switch (n)
  313. {
  314. case 0:
  315. {
  316. PlBucketItem *bi = new PlBucketItem();
  317. bi->setBitmaps(L"winamp.thinger.pledit", NULL, L"winamp.thinger.pledit.hilited", L"winamp.thinger.pledit.selected");
  318. bucketitems.addItem(bi);
  319. return bi;
  320. }
  321. case 1:
  322. {
  323. MlBucketItem *bi = new MlBucketItem();
  324. bi->setBitmaps(L"winamp.thinger.library", NULL, L"winamp.thinger.library.hilited", L"winamp.thinger.library.selected");
  325. bucketitems.addItem(bi);
  326. return bi;
  327. }
  328. case 2:
  329. {
  330. VidBucketItem *bi = new VidBucketItem();
  331. bi->setBitmaps(L"winamp.thinger.video", NULL, L"winamp.thinger.video.hilited", L"winamp.thinger.video.selected");
  332. bucketitems.addItem(bi);
  333. return bi;
  334. }
  335. case 3:
  336. {
  337. VisBucketItem *bi = new VisBucketItem();
  338. bi->setBitmaps(L"winamp.thinger.vis", NULL, L"winamp.thinger.vis.hilited", L"winamp.thinger.vis.selected");
  339. bucketitems.addItem(bi);
  340. return bi;
  341. }
  342. // cases must be contiguous, enumerator stops at first NULL
  343. #ifdef MINIBROWSER_SUPPORT
  344. case 4:
  345. {
  346. MbBucketItem *bi = new MbBucketItem();
  347. bi->setBitmaps(hInstance, IDB_MB_TAB_NORMAL, NULL, IDB_MB_TAB_HILITED, IDB_MB_TAB_SELECTED);
  348. bucketitems.addItem(bi);
  349. return bi;
  350. }
  351. #endif
  352. // n is enumertor, not whichwnd
  353. // we also need some way for the embeddedwnd to expose at least one bitmap (ideally 3) so we can make a nice bucketitem here (this code uses a pledit icon)
  354. /* default:
  355. if (n > 1024)
  356. {
  357. EmbedBucketItem *bi = new EmbedBucketItem();
  358. bi->setBitmaps(hInstance, IDB_PLEDIT_TAB_NORMAL, NULL, IDB_PLEDIT_TAB_HILITED, IDB_PLEDIT_TAB_SELECTED);
  359. bucketitems.addItem(bi);
  360. return bi;
  361. }
  362. break;*/
  363. }
  364. }
  365. else if (!_wcsicmp(windowtype, L"plsc"))
  366. {
  367. switch (n)
  368. {
  369. case 0:
  370. pldirs.addItem(new PlDirObject);
  371. return pldirs.getLast();
  372. }
  373. }
  374. return NULL;
  375. }
  376. //-----------------------------------------------------------------------------------------------
  377. int Wa2WndEmbed::destroyWindow(ifc_window *w)
  378. {
  379. foreach(bucketitems)
  380. Wa2BucketItem *i = bucketitems.getfor();
  381. ifc_window *rw = i;
  382. if (rw == w)
  383. {
  384. delete i;
  385. return 1;
  386. }
  387. endfor;
  388. foreach(wndhosts)
  389. EmbedEntry *ee = wndhosts.getfor();
  390. WaOsWndHost *x = ee->host;
  391. if (WASABI_API_WND->rootwndIsValid(x))
  392. {
  393. ifc_window *rw = x;
  394. if (rw == w)
  395. {
  396. ReentryFilter f(&wndMsgFilter, ee->whichwnd);
  397. if (!f.mustLeave())
  398. {
  399. // this would hide the winamp window, which is probably not what we want to do (it should remain visible if it
  400. // was visible, no?
  401. // well, no, because we don't only run this in skin unloading, but also when a window gets destroyed (this is the wndcreation
  402. // service being called to free what it created) -- this won't happen for mmd3/pledit because mmd3 has a static window for
  403. // everything, which means that when you click close on it, it doesn't destroy it but hides it, so this code isn't called. but
  404. // if you load another skin (ie: NonStep), and you close the pledit, it immediately reappears with the wa2 look since oswndhost_unhost
  405. // reset the flags, region and parent to what they were before the window was embedded
  406. // i think that what we need is to save which windows were visible (and their location) before switching to freeform
  407. // and to restore them when we go back to wa2 mode. this will also be more consistant with the freeform behavior of
  408. // remembering visible status and coordinates on a per skin basis (since otherwise freeform dockings get screwed)
  409. // it also makes sense when we consider that we are going to need to remove all windowshade modes from the embedded
  410. // windows when going freeform.
  411. // see new functions: rememberVisibleWindows() and restoreVisibleWindows()
  412. // in any case, we need to hide the window here, at least temporarily in the case of skin unloading
  413. {
  414. if (ee->whichwnd > 1024)
  415. {
  416. embedWindowState *ws = NULL;
  417. //embedWindowState *ws = (embedWindowState *)ee->whichwnd;
  418. HWND hHost, hContent;
  419. hHost = (NULL != x) ? x->getHWND() : NULL;
  420. hContent = (NULL != hHost) ? (HWND)SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)hHost, IPC_FF_GETCONTENTWND) : NULL;
  421. if (NULL != hContent)
  422. {
  423. ws = (embedWindowState *)GetWindowLongPtrW(hContent, GWLP_USERDATA);
  424. }
  425. else
  426. {
  427. embedWndGuidMgr.retireEmbedWindowState((embedWindowState *)ee->whichwnd);
  428. }
  429. if (NULL != ws &&
  430. !(wa2.isValidEmbedWndState(ws) && --ws->hostcount != 0))
  431. {
  432. if (0 != (EMBED_FLAGS_FFCALLBACK & ws->flags) &&
  433. NULL != ws->callback)
  434. {
  435. ws->callback(ws, FFC_DESTROYEMBED, (LPARAM)w);
  436. }
  437. x->oswndhost_unhost();
  438. if (wa2.isValidEmbedWndState(ws))
  439. ws->wasabi_window = NULL;
  440. if (!x->isTransfering() && wa2.isValidEmbedWndState(ws))
  441. {
  442. if (IsWindow(x->getHWND()))
  443. {
  444. SendMessageW(ws->me, WM_USER + 101, 0, 0);
  445. }
  446. embedWndGuidMgr.retireEmbedWindowState(ws);
  447. }
  448. }
  449. }
  450. else
  451. {
  452. if (ee->whichwnd == IPC_GETWND_VIDEO) KillTimer(wa2.getWnd(ee->whichwnd), 12345);
  453. x->oswndhost_unhost();
  454. if (!x->isTransfering())
  455. wa2.setWindowVisible(ee->whichwnd, 0);
  456. #ifdef VIDDEBUG
  457. if (ee->whichwnd == IPC_GETWND_VIDEO) DebugString("Video : Window service asks WA2 to close the window\n");
  458. #endif
  459. }
  460. }
  461. }
  462. wndhosts.removeItem(ee);
  463. embedWindowState *ws = NULL;
  464. HWND thiswnd = NULL;
  465. if (ee->whichwnd > 1024)
  466. {
  467. if (IsWindow(x->getHWND()))
  468. thiswnd = x->getHWND();
  469. //ws=(embedWindowState *)ee->whichwnd;
  470. //thiswnd=ws->me;
  471. }
  472. else thiswnd = wa2.getWnd(ee->whichwnd);
  473. //moved to xuioswndhost
  474. //SetWindowLong(thiswnd,GWL_STYLE,GetWindowLong(thiswnd,GWL_STYLE)&~(WS_CHILDWINDOW));
  475. switch (ee->whichwnd)
  476. {
  477. case IPC_GETWND_PE: plWnd = NULL; break;
  478. #ifdef MINIBROWSER_SUPPORT
  479. case IPC_GETWND_MB: mbWnd = NULL; break;
  480. #endif
  481. case IPC_GETWND_VIDEO:
  482. #ifdef VIDDEBUG
  483. DebugString("Video : Window service destroys host\n");
  484. #endif
  485. vidWnd = NULL;
  486. break;
  487. default:
  488. if (ee->whichwnd > 1024 && ws && thiswnd != NULL)
  489. {
  490. ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = 0;
  491. }
  492. break;
  493. }
  494. if (ee->cmds)
  495. {
  496. GuiObject *o = w->getParent()->getGuiObject();
  497. o->guiobject_removeAppCmds(ee->cmds);
  498. }
  499. x->oswndhost_unhost(); // ignored if already done by reentryfiltered code
  500. delete ee->monitor;
  501. delete ee->cmds;
  502. delete x;
  503. if (ee->whichwnd > 1024 && ws)
  504. {
  505. if (forcedoffwnds.haveItem(ws->me))
  506. {
  507. RECT r;
  508. GetWindowRect(ws->me, &r);
  509. SetWindowPos(ws->me, NULL, r.left + 20000, r.top + 20000, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOZORDER);
  510. forcedoffwnds.delItem(ws->me);
  511. }
  512. }
  513. delete ee;
  514. SetFocus(wa2.getMainWindow());
  515. return 1;
  516. }
  517. endfor;
  518. foreach (pldirs)
  519. PlDirObject *pldir = pldirs.getfor();
  520. if (pldir == w)
  521. {
  522. delete pldir;
  523. return 1;
  524. }
  525. endfor;
  526. }
  527. return 0;
  528. }
  529. //-----------------------------------------------------------------------------------------------
  530. int Wa2WndEmbed::viewer_onEvent(ifc_window *item, int event, intptr_t param, void *ptr, size_t ptrlen)
  531. {
  532. if (event == ifc_window::Event_SETVISIBLE)
  533. {
  534. /* if (!param) {
  535. // the wnd may be going away, but then again, it might just be hidden to show an alternate layout of the same
  536. // container, so before continuing, we need to check if it's actually going away. There is of course an exception
  537. // in that if the window is hosted by a wndholder with autoclose="1", we should mirror the hiding state regardless
  538. // of the container state
  539. api_window *whr = item->getParent();
  540. int except = 0;
  541. if (whr) {
  542. GuiObject *go = whr->getGuiObject();
  543. if (go) {
  544. const char *par = go->guiobject_getXmlParam("autoclose");
  545. if (!par || (par && ATOI(par) == 1)) except = 1;
  546. }
  547. }
  548. if (!except) {
  549. api_window *lr = item->getDesktopParent();
  550. if (lr) {
  551. Layout *l = static_cast<Layout *>(lr->getInterface(layoutGuid));
  552. if (l) {
  553. Container *c = l->getParentContainer();
  554. if (c) {
  555. if (c->isVisible()) return 1;
  556. }
  557. }
  558. }
  559. }
  560. }*/
  561. foreach(wndhosts)
  562. EmbedEntry *ee = wndhosts.getfor();
  563. XuiOSWndHost *x = ee->host;
  564. ifc_window *rw = x;
  565. if (rw == item)
  566. {
  567. {
  568. ReentryFilter f(&wndMsgFilter, ee->whichwnd);
  569. if (f.mustLeave()) continue;
  570. }
  571. if (ee->whichwnd > 1024)
  572. {
  573. embedWindowState *ws = (embedWindowState *)ee->whichwnd;
  574. if (!param && wa2.isValidEmbedWndState(ws))
  575. {
  576. if (IsWindow(ws->me))
  577. SendMessageW(ws->me, WM_USER + 101, 0, 0);
  578. ifc_window *rwh = x->findWindowByInterface(windowHolderGuid);
  579. if (rwh != NULL)
  580. {
  581. WindowHolder *wh = static_cast<WindowHolder *>(rwh->getInterface(windowHolderGuid));
  582. if (wh != NULL)
  583. {
  584. wh->onRemoveWindow(1);
  585. }
  586. }
  587. if (wa2.isValidEmbedWndState(ws)) ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL;
  588. }
  589. else if (wa2.isValidEmbedWndState(ws))
  590. {
  591. ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t)item->getParent();
  592. ShowWindow(ws->me, SW_NORMAL);
  593. }
  594. }
  595. else
  596. {
  597. ReentryFilter f(&wndMsgFilter, ee->whichwnd);
  598. #ifdef VIDDEBUG
  599. if (ee->whichwnd == IPC_GETWND_VIDEO && param != wa2.isWindowVisible(ee->whichwnd)) DebugString("Video : Detected that the host is %s, syncing\n", param ? "shown" : "hidden");
  600. #endif
  601. wa2.setWindowVisible(ee->whichwnd, param);
  602. }
  603. }
  604. endfor;
  605. }
  606. return 1;
  607. }
  608. int Wa2WndEmbed::onShowWindow(Container *c, GUID guid, const wchar_t *groupid)
  609. {
  610. foreach(wndhosts)
  611. EmbedEntry *ee = wndhosts.getfor();
  612. if (ee->g == guid)
  613. {
  614. ReentryFilter f(&wndMsgFilter, ee->whichwnd);
  615. if (f.mustLeave()) return 1;
  616. if (guid == videoWndGuid) wa2.setWindowVisible(IPC_GETWND_VIDEO, 1);
  617. #ifdef MINIBROWSER_SUPPORT
  618. else if (guid == minibrowserWndGuid) wa2.setWindowVisible(IPC_GETWND_MB, 1);
  619. #endif
  620. else if (guid == pleditWndGuid) wa2.setWindowVisible(IPC_GETWND_PE, 1);
  621. }
  622. endfor;
  623. return 1;
  624. }
  625. int Wa2WndEmbed::onHideWindow(Container *c, GUID guid, const wchar_t *groupid)
  626. {
  627. /* if (guid == INVALID_GUID) return 1;
  628. embedWindowState *ws = embedWndGuidMgr.getEmbedWindowState(guid);
  629. if (ws != NULL && wa2.isValidEmbedWndState(ws)) {
  630. if (IsWindow(ws->me))
  631. SendMessageW(ws->me,WM_USER+101,0,0);
  632. api_window *x = (api_window*)ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND];
  633. if (x && WASABI_API_WND->rootwndIsValid(x)) {
  634. api_window *rwh = x->findWindowByInterface(windowHolderGuid);
  635. if (rwh != NULL) {
  636. WindowHolder *wh = static_cast<WindowHolder *>(rwh->getInterface(windowHolderGuid));
  637. if (wh != NULL) {
  638. wh->onRemoveWindow(1);
  639. }
  640. }
  641. }
  642. ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL;
  643. }
  644. */
  645. foreach(wndhosts)
  646. EmbedEntry *ee = wndhosts.getfor();
  647. if (ee->g == guid)
  648. {
  649. ReentryFilter f(&wndMsgFilter, ee->whichwnd);
  650. if (f.mustLeave()) return 1;
  651. if (ee->host->isTransfering()) return 1;
  652. ifc_window *dp = ee->host->getDesktopParent();
  653. if (dp)
  654. {
  655. Layout *l = static_cast<Layout*>(dp->getInterface(layoutGuid));
  656. if (l)
  657. {
  658. if (l->getParentContainer() != c) return 1;
  659. }
  660. }
  661. if (guid == videoWndGuid) wa2.setWindowVisible(IPC_GETWND_VIDEO, 0);
  662. #ifdef MINIBROWSER_SUPPORT
  663. else if (guid == minibrowserWndGuid) wa2.setWindowVisible(IPC_GETWND_MB, 0);
  664. #endif
  665. else if (guid == pleditWndGuid) wa2.setWindowVisible(IPC_GETWND_PE, 0);
  666. }
  667. endfor;
  668. return 1;
  669. }
  670. extern wchar_t *INI_FILE;
  671. int Wa2WndEmbed::embedRememberProc(embedWindowState *p, embedEnumStruct *parms)
  672. {
  673. WndStatus *ws = new WndStatus;
  674. ws->wndcode = -1; // if you insert a wnd that is not in embedTable, put -1 as wndcode
  675. ws->wnd = p->me;
  676. ws->visible = IsWindowVisible(p->me);
  677. GetWindowRect(p->me, &ws->position);
  678. // ws->position=p->r;
  679. wa2wndstatus.addItem(ws);
  680. // only store the ml window position if not loading on startup
  681. if(going_freeform && !m_loading_at_startup)
  682. {
  683. HWND mlwnd = wa2.getMediaLibrary();
  684. if(GetWindow(p->me, GW_CHILD) == mlwnd)
  685. {
  686. WritePrivateProfileStringW(L"gen_ff", L"classicmlwidth", StringPrintfW(L"%d", ws->position.right - ws->position.left), INI_FILE);
  687. WritePrivateProfileStringW(L"gen_ff", L"classicmlheight", StringPrintfW(L"%d", ws->position.bottom - ws->position.top), INI_FILE);
  688. }
  689. }
  690. return 0;
  691. }
  692. extern int m_loading_at_startup;
  693. //-----------------------------------------------------------------------------------------------
  694. // todo: remember and restore windowshade modes
  695. void Wa2WndEmbed::rememberVisibleWindows()
  696. {
  697. wa2wndstatus.deleteAll();
  698. for (int i = 0;i < sizeof(embedTable) / sizeof(embedTable[0]);i++)
  699. {
  700. HWND w = wa2.getWnd(embedTable[i]);
  701. WndStatus *ws = new WndStatus;
  702. ws->wndcode = embedTable[i]; // if you insert a wnd that is not in embedTable, put -1 as wndcode
  703. ws->wnd = w;
  704. ws->visible = wa2.isWindowVisible(embedTable[i]);
  705. GetWindowRect(w, &ws->position);
  706. if (going_freeform)
  707. {
  708. if (embedTable[i] == IPC_GETWND_PE)
  709. {
  710. int peheight = ws->position.bottom - ws->position.top;
  711. int pewidth = ws->position.right - ws->position.left;
  712. if (!m_loading_at_startup)
  713. {
  714. WritePrivateProfileStringW(L"gen_ff", L"classicplwidth", StringPrintfW(L"%d", pewidth), INI_FILE);
  715. WritePrivateProfileStringW(L"gen_ff", L"classicplheight", StringPrintfW(L"%d", peheight), INI_FILE);
  716. }
  717. int classicpews = wa2.isWindowShade(IPC_GETWND_PE);
  718. if (!m_loading_at_startup || GetPrivateProfileIntW(L"gen_ff", L"classicplws", -1, INI_FILE) == -1)
  719. WritePrivateProfileStringW(L"gen_ff", L"classicplws", classicpews ? L"1" : L"0", INI_FILE);
  720. if (classicpews)
  721. SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_WINDOWSHADE_PL, 0);
  722. GetWindowRect(w, &ws->position);
  723. }
  724. }
  725. wa2wndstatus.addItem(ws);
  726. }
  727. embedEnumStruct cs = { embedRememberProc, 0};
  728. SendMessageW(wa2.getMainWindow(), WM_WA_IPC, (WPARAM)&cs, IPC_EMBED_ENUM);
  729. }
  730. int Wa2WndEmbed::hadRememberedWndVisible(HWND w)
  731. {
  732. int n = wa2wndstatus.getNumItems();
  733. for (int i = 0;i < n;i++)
  734. {
  735. WndStatus *ws = wa2wndstatus.enumItem(i);
  736. if (ws->wnd == w && ws->visible)
  737. return 1;
  738. }
  739. return 0;
  740. }
  741. void Wa2WndEmbed::restoreVisibleWindows()
  742. {
  743. int n = wa2wndstatus.getNumItems();
  744. HWND mlwnd = wa2.getMediaLibrary();
  745. for (int i = 0;i < n;i++)
  746. {
  747. WndStatus *ws = wa2wndstatus.enumItem(i);
  748. if (going_fixedform && !m_loading_at_startup)
  749. {
  750. if (embedTable[i] == IPC_GETWND_PE)
  751. {
  752. int classicpews = GetPrivateProfileIntW(L"gen_ff", L"classicplws", 0, INI_FILE);
  753. if (classicpews)
  754. {
  755. SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_WINDOWSHADE_PL, 0);
  756. }
  757. int classicwidth = GetPrivateProfileIntW(L"gen_ff", L"classicplwidth", 275, INI_FILE);
  758. int classicheight = GetPrivateProfileIntW(L"gen_ff", L"classicplheight", 145, INI_FILE);
  759. wa2.setPlEditWidthHeight(classicwidth, classicheight);
  760. }
  761. if(GetWindow(ws->wnd, GW_CHILD) == mlwnd)
  762. {
  763. // only restore the ml window size if we were able to read in saved values
  764. int mlwidth = GetPrivateProfileIntW(L"gen_ff", L"classicmlwidth", -1, INI_FILE);
  765. int mlheight = GetPrivateProfileIntW(L"gen_ff", L"classicmlheight", -1, INI_FILE);
  766. if(mlwidth != -1 && mlheight != -1)
  767. SetWindowPos(ws->wnd, 0, 0, 0, mlwidth, mlheight, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
  768. }
  769. }
  770. // FG> as of oct19, this function only restores state for windows that WERE visible
  771. // because there is no reason to hide one, since this function is designed to bring
  772. // back those windows that were here in one mode, but aren't so anymore in another
  773. if (ws->visible)
  774. {
  775. if (ws->wndcode != -1)
  776. {
  777. wa2.setWindowVisible(ws->wndcode, ws->visible);
  778. }
  779. else
  780. {
  781. ShowWindow(ws->wnd, ws->visible ? SW_SHOWNA : SW_HIDE);
  782. }
  783. }
  784. }
  785. }
  786. PtrList<WndStatus> Wa2WndEmbed::wa2wndstatus;
  787. //-----------------------------------------------------------------------------------------------
  788. PlaylistAppCmds::PlaylistAppCmds()
  789. : addCmd(L"Add", PL_ADD, AppCmds::SIDE_LEFT, 0),
  790. remCmd(L"Rem", PL_REM, AppCmds::SIDE_LEFT, 0),
  791. selCmd(L"Sel", PL_SEL, AppCmds::SIDE_LEFT, 0),
  792. miscCmd(L"Misc", PL_MISC, AppCmds::SIDE_LEFT, 0),
  793. listCmd(L"List", PL_LIST, AppCmds::SIDE_RIGHT, 0)
  794. {
  795. appcmds_addCmd(&addCmd);
  796. appcmds_addCmd(&remCmd);
  797. appcmds_addCmd(&selCmd);
  798. appcmds_addCmd(&miscCmd);
  799. appcmds_addCmd(&listCmd);
  800. }
  801. void PlaylistAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
  802. {
  803. switch (id)
  804. {
  805. case PL_ADD:
  806. wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_ADD, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
  807. break;
  808. case PL_REM:
  809. wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_REM, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
  810. break;
  811. case PL_SEL:
  812. wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_SEL, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
  813. break;
  814. case PL_MISC:
  815. wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_MISC, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
  816. break;
  817. case PL_LIST:
  818. wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_LIST, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
  819. break;
  820. }
  821. }
  822. #ifdef MINIBROWSER_SUPPORT
  823. //-----------------------------------------------------------------------------------------------
  824. MinibrowserAppCmds::MinibrowserAppCmds()
  825. {
  826. appcmds_addCmd(new CmdRec("Back", MB_BACK, AppCmds::SIDE_LEFT, 1));
  827. appcmds_addCmd(new CmdRec("Forward", MB_FORWARD, AppCmds::SIDE_LEFT, 1));
  828. appcmds_addCmd(new CmdRec("Stop", MB_STOP, AppCmds::SIDE_LEFT, 1));
  829. appcmds_addCmd(new CmdRec("Reload", MB_RELOAD, AppCmds::SIDE_LEFT, 1));
  830. appcmds_addCmd(new CmdRec("Misc", MB_MISC, AppCmds::SIDE_RIGHT, 1));
  831. }
  832. void MinibrowserAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
  833. {
  834. switch (id)
  835. {
  836. case MB_BACK:
  837. wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_BACK);
  838. break;
  839. case MB_FORWARD:
  840. wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_FORWARD);
  841. break;
  842. case MB_STOP:
  843. wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_STOP);
  844. break;
  845. case MB_RELOAD:
  846. wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_RELOAD);
  847. break;
  848. case MB_MISC:
  849. wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBPOPUP_MISC, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
  850. break;
  851. }
  852. }
  853. #endif
  854. //-----------------------------------------------------------------------------------------------
  855. VideoAppCmds::VideoAppCmds()
  856. {
  857. appcmds_addCmd(new CmdRec(L"Fullscreen", VID_FULLSCREEN, AppCmds::SIDE_LEFT, 1));
  858. appcmds_addCmd(new CmdRec(L"1x", VID_1X, AppCmds::SIDE_LEFT, 1));
  859. appcmds_addCmd(new CmdRec(L"2x", VID_2X, AppCmds::SIDE_LEFT, 1));
  860. appcmds_addCmd(new CmdRec(L"TV", VID_LIB, AppCmds::SIDE_LEFT, 1));
  861. appcmds_addCmd(new CmdRec(L"Misc", VID_MISC, AppCmds::SIDE_RIGHT, 1));
  862. }
  863. void VideoAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
  864. {
  865. switch (id)
  866. {
  867. case VID_FULLSCREEN:
  868. wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_FULLSCREEN);
  869. break;
  870. case VID_1X:
  871. wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_1X);
  872. break;
  873. case VID_2X:
  874. wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_2X);
  875. break;
  876. case VID_LIB:
  877. wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_LIB);
  878. break;
  879. case VID_MISC:
  880. wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDPOPUP_MISC, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
  881. break;
  882. }
  883. }