aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/General/gen_ff/wa2wndembed.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/General/gen_ff/wa2wndembed.cpp')
-rw-r--r--Src/Plugins/General/gen_ff/wa2wndembed.cpp946
1 files changed, 946 insertions, 0 deletions
diff --git a/Src/Plugins/General/gen_ff/wa2wndembed.cpp b/Src/Plugins/General/gen_ff/wa2wndembed.cpp
new file mode 100644
index 00000000..bcd2aaac
--- /dev/null
+++ b/Src/Plugins/General/gen_ff/wa2wndembed.cpp
@@ -0,0 +1,946 @@
+#include <precomp.h>
+#include "wa2wndembed.h"
+#include "wa2frontend.h"
+#include "wa2buckitems.h"
+#include "embedwndguid.h"
+#include "main.h"
+#include <api/wnd/bucketitem.h>
+#include "resource.h"
+#include <api/wnd/wndclass/wndholder.h>
+#include <api/wndmgr/layout.h>
+#include "wa2cfgitems.h"
+#include "gen.h"
+#include "../Agave/Language/api_language.h"
+
+extern TList<HWND> forcedoffwnds;
+
+#define BUCKETITEM_WNDTYPE L"buck"
+#define WINAMP_OPTIONS_WINDOWSHADE_PL 40266
+ReentryFilterObject wndMsgFilter;
+
+int embedTable[] = {
+ IPC_GETWND_PE,
+#ifdef MINIBROWSER_SUPPORT
+ IPC_GETWND_MB,
+#endif
+
+ IPC_GETWND_VIDEO};
+
+extern int switching_skin;
+extern int going_fixedform;
+extern int going_freeform;
+extern HINSTANCE hInstance;
+//-----------------------------------------------------------------------------------------------
+void WaOsWndHost::onBeforeReparent(int host)
+{
+#if defined(_WIN64)
+ embedWindowState *ws = (embedWindowState *)GetWindowLong(getHWND(), GWLP_USERDATA);
+#else
+ embedWindowState* ws = (embedWindowState*)GetWindowLong(getHWND(), GWL_USERDATA);
+#endif
+ // 0x49474541 is related to keeping windows shown on litestep desktops
+ if (ws == NULL || (int)ws == 0x49474541)
+ {
+ HWND w = getHWND();
+ if (w == wa2.getWnd(IPC_GETWND_VIDEO))
+ {
+ // this tells the video to not trigger its callback on windowposchanged, otherwise it will generate a new IPC_ONSHOW
+ SendMessageW(w, WM_USER + 0x2, 0, 1);
+ }
+ return ;
+ }
+ ws->extra_data[EMBED_STATE_EXTRA_REPARENTING] = 1; // tell winamp to ignore show/hide events
+ if (!host)
+ {
+ ShowWindow(getHWND(), SW_HIDE);
+ if (!transfer && ((switching_skin && !Wa2WndEmbed::hadRememberedWndVisible(getHWND())) || !switching_skin))
+ {
+ PostMessage(getHWND(), WM_USER + 101, 0, 0);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------------------
+void WaOsWndHost::onAfterReparent(int host)
+{
+#if defined(_WIN64)
+ embedWindowState *ws = (embedWindowState *)GetWindowLong(getHWND(), GWLP_USERDATA);
+#else
+ embedWindowState* ws = (embedWindowState*)GetWindowLong(getHWND(), GWL_USERDATA);
+#endif
+ // 0x49474541 is related to keeping windows shown on litestep desktops
+ if (ws == NULL || (int)ws == 0x49474541)
+ {
+ HWND w = getHWND();
+ if (w == wa2.getWnd(IPC_GETWND_VIDEO))
+ {
+ // stop preventing handling of video windowposchanged
+ SendMessageW(w, WM_USER + 0x2, 0, 0);
+ }
+ return ;
+ }
+ ws->extra_data[EMBED_STATE_EXTRA_REPARENTING] = 0; // tell winamp NOT to ignore show/hide events anymore
+}
+
+//-----------------------------------------------------------------------------------------------
+int WaOsWndHost::onGetFocus()
+{
+ XuiOSWndHost::onGetFocus();
+ ifc_window *z = findWindowByInterface(windowHolderGuid);
+ if (z)
+ {
+ WindowHolder *wh = static_cast<WindowHolder*>(z->getInterface(windowHolderGuid));
+ if (wh && wh->wndholder_wantAutoFocus())
+ {
+ HWND w = getHWND();
+ if (IsWindow(w)) SetFocus(w);
+ }
+ }
+ return 1;
+}
+
+//-----------------------------------------------------------------------------------------------
+int WaOsWndHost::wantFocus()
+{
+ ifc_window *w = findWindowByInterface(windowHolderGuid);
+ if (w)
+ {
+ WindowHolder *wh = static_cast<WindowHolder*>(w->getInterface(windowHolderGuid));
+ if (wh)
+ {
+ return wh->wndholder_wantAutoFocus();
+ }
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------------------------
+int WaOsWndHost::onMouseWheelUp(int click, int lines)
+{
+ return 1;
+}
+
+//-----------------------------------------------------------------------------------------------
+int WaOsWndHost::onMouseWheelDown(int click, int lines)
+{
+ return 1;
+}
+
+//-----------------------------------------------------------------------------------------------
+void VideoLayoutMonitor::hook_onResize(int x, int y, int w, int h)
+{
+ SendMessageW(wa2.getWnd(IPC_GETWND_VIDEO), WM_TIMER, 12345, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+void VideoLayoutMonitor::hook_onMove()
+{
+ SendMessageW(wa2.getWnd(IPC_GETWND_VIDEO), WM_TIMER, 12345, 0);
+}
+
+//-----------------------------------------------------------------------------------------------
+Wa2WndEmbed::Wa2WndEmbed()
+{
+ WASABI_API_SYSCB->syscb_registerCallback(static_cast<WndCallbackI*>(this));
+}
+
+//-----------------------------------------------------------------------------------------------
+Wa2WndEmbed::~Wa2WndEmbed()
+{
+ WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<WndCallbackI*>(this));
+ wa2wndstatus.deleteAll();
+}
+
+extern int we_have_ml;
+
+//-----------------------------------------------------------------------------------------------
+int Wa2WndEmbed::testGuid(GUID g)
+{
+ if (embedWndGuidMgr.testGuid(g)) return 1;
+
+ /* if (embedWndGuids.Data2 == g.Data2 && // embed wnd check :)
+ embedWndGuids.Data3 == g.Data3 &&
+ !memcmp(embedWndGuids.Data4,g.Data4,8)) return 1;*/
+
+ return (g == pleditWndGuid || g == videoWndGuid
+#ifdef MINIBROWSER_SUPPORT
+ || g == minibrowserWndGuid
+#endif
+ || (we_have_ml && g == library_guid)
+ );
+}
+
+int make_sure_library_is_here_at_startup = 0;
+extern int m_loading_at_startup;
+
+//-----------------------------------------------------------------------------------------------
+ifc_window *Wa2WndEmbed::createWindowByGuid(GUID g, ifc_window *parent)
+{
+ if (m_loading_at_startup)
+ if (g == library_guid)
+ make_sure_library_is_here_at_startup = 1;
+ WaOsWndHost *oldhost = NULL;
+ if (embedWndGuidMgr.testGuid(g) && !embedWndGuidMgr.getEmbedWindowState(g))
+ return NULL;
+ // first check if this window is already open in a host, and if so, remove it from the wndholder
+ foreach(wndhosts)
+ if (wndhosts.getfor()->g == g)
+ {
+ WaOsWndHost *host = wndhosts.getfor()->host;
+ oldhost = host;
+ host->setTransfering(1);
+ host->oswndhost_unhost();
+ Layout *l = static_cast<Layout *>(host->getDesktopParent());
+ if (l)
+ {
+ Container *c = l->getParentContainer();
+ if (c)
+ {
+ if (!WCSCASEEQLSAFE(c->getId(), L"main"))
+ {
+ c->close(); // deferred if needed
+ }
+ else
+ {
+ softclose:
+ ifc_window *wnd = host->findWindowByInterface(windowHolderGuid);
+ if (wnd != NULL)
+ {
+ WindowHolder *wh = static_cast<WindowHolder *>(wnd->getInterface(windowHolderGuid));
+ if (wh != NULL)
+ {
+ wh->onRemoveWindow(1);
+ }
+ }
+ }
+ }
+ else goto softclose;
+ }
+ }
+ endfor;
+ // now host the wnd in a new host
+ WaOsWndHost *host = new WaOsWndHost();
+ viewer_addViewItem(host);
+ EmbedEntry *ee = new EmbedEntry();
+ wndhosts.addItem(ee);
+ ee->g = g;
+ ee->host = host;
+ ee->monitor = NULL;
+ ee->dep = host->getDependencyPtr();
+ ee->cmds = NULL;
+ if (g == pleditWndGuid)
+ {
+ RECT r = {10, 20, 5, 38};
+ host->oswndhost_setRegionOffsets(&r);
+ host->oswndhost_host(wa2.getWnd(IPC_GETWND_PE));
+ ee->whichwnd = IPC_GETWND_PE;
+ host->setName((L"Playlist Editor")/*(WASABI_API_LNGSTRINGW(IDS_PLAYLIST_EDITOR)*/);
+ GuiObject *go = parent->getGuiObject();
+ PlaylistAppCmds *plEditAppCmds = new PlaylistAppCmds();
+ ee->cmds = plEditAppCmds;
+ go->guiobject_addAppCmds(plEditAppCmds);
+ plWnd = parent; //parent->getDesktopParent();
+ //ShowWindow(host->getHWND(), SW_NORMAL);
+ }
+ else if (g == videoWndGuid)
+ {
+ RECT r = {11, 20, 8, 38};
+ host->oswndhost_setRegionOffsets(&r);
+#ifdef VIDDEBUG
+ DebugString("Video : Window service creates the host\n");
+#endif
+ HWND vid = wa2.getWnd(IPC_GETWND_VIDEO);
+ host->oswndhost_host(vid);
+ ((WaOsWndHost *)host)->setNoTransparency();
+ ee->whichwnd = IPC_GETWND_VIDEO;
+ host->setName(WASABI_API_LNGSTRINGW(IDS_VIDEO));
+ ifc_window *lw = parent->getDesktopParent();
+ if (lw)
+ {
+ GuiObject *o = lw->getGuiObject();
+ if (o)
+ {
+ ee->monitor = new VideoLayoutMonitor(o->guiobject_getScriptObject());
+ }
+ }
+ SetTimer(vid, 12345, 250, NULL);
+ GuiObject *go = parent->getGuiObject();
+ VideoAppCmds *videoAppCmds = new VideoAppCmds();
+ ee->cmds = videoAppCmds;
+ go->guiobject_addAppCmds(videoAppCmds);
+ vidWnd = parent; //parent->getDesktopParent();
+ //ShowWindow(host->getHWND(), SW_NORMAL);
+#ifdef MINIBROWSER_SUPPORT
+
+ }
+ else if (g == minibrowserWndGuid)
+ {
+ RECT r = {10, 20, 5, 38};
+ host->oswndhost_setRegionOffsets(&r);
+ host->oswndhost_host(wa2.getWnd(IPC_GETWND_MB));
+ ee->whichwnd = IPC_GETWND_MB;
+ host->setName("Minibrowser");
+ GuiObject *go = parent->getGuiObject();
+ mbWnd = parent; //parent->getDesktopParent();
+ MinibrowserAppCmds *mbAppCmds = new MinibrowserAppCmds();
+ ee->cmds = mbAppCmds;
+ go->guiobject_addAppCmds(mbAppCmds);
+ //ShowWindow(host->getHWND(), SW_NORMAL);
+#endif
+
+ }
+ else if (embedWndGuidMgr.testGuid(g)) /*(embedWndGuids.Data2 == g.Data2 &&
+ embedWndGuids.Data3 == g.Data3 &&
+ !memcmp(embedWndGuids.Data4,g.Data4,8))*/
+ {
+ embedWindowState *ws = embedWndGuidMgr.getEmbedWindowState(g);
+ ASSERT(ws != NULL);
+
+ if (0 == (WS_BORDER & GetWindowLongPtrW(ws->me, GWL_STYLE)))
+ {
+ RECT r = {11, 20, 8, 14};
+ host->oswndhost_setRegionOffsets(&r);
+ }
+ else
+ host->oswndhost_setRegionOffsets(NULL);
+
+ ws->extra_data[EMBED_STATE_EXTRA_HOSTCOUNT]++;
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t)parent; //parent->getDesktopParent();
+ ee->whichwnd = (intptr_t)ws;
+ if (ws->flags & EMBED_FLAGS_NOTRANSPARENCY) host->setNoTransparency();
+ host->oswndhost_host(ws->me);
+ wchar_t buf[512] = {0};
+ GetWindowTextW(ws->me, buf, 512);
+ host->setName(buf);
+ }
+ else
+ {
+ wndhosts.removeItem(ee);
+ delete host;
+ delete ee;
+ return NULL;
+ }
+ wa2.setOnTop(cfg_options_alwaysontop.getValueAsInt());
+ return host;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Wa2WndEmbed::testType(const wchar_t *windowtype)
+{
+ return !_wcsicmp(windowtype, BUCKETITEM_WNDTYPE) || !_wcsicmp(windowtype, L"plsc");
+}
+
+//-----------------------------------------------------------------------------------------------
+ifc_window *Wa2WndEmbed::createWindowOfType(const wchar_t *windowtype, ifc_window *parent, int n)
+{
+ if (!_wcsicmp(windowtype, BUCKETITEM_WNDTYPE))
+ {
+ switch (n)
+ {
+ case 0:
+ {
+ PlBucketItem *bi = new PlBucketItem();
+ bi->setBitmaps(L"winamp.thinger.pledit", NULL, L"winamp.thinger.pledit.hilited", L"winamp.thinger.pledit.selected");
+ bucketitems.addItem(bi);
+ return bi;
+ }
+ case 1:
+ {
+ MlBucketItem *bi = new MlBucketItem();
+ bi->setBitmaps(L"winamp.thinger.library", NULL, L"winamp.thinger.library.hilited", L"winamp.thinger.library.selected");
+ bucketitems.addItem(bi);
+ return bi;
+ }
+ case 2:
+ {
+ VidBucketItem *bi = new VidBucketItem();
+ bi->setBitmaps(L"winamp.thinger.video", NULL, L"winamp.thinger.video.hilited", L"winamp.thinger.video.selected");
+ bucketitems.addItem(bi);
+ return bi;
+ }
+ case 3:
+ {
+ VisBucketItem *bi = new VisBucketItem();
+ bi->setBitmaps(L"winamp.thinger.vis", NULL, L"winamp.thinger.vis.hilited", L"winamp.thinger.vis.selected");
+ bucketitems.addItem(bi);
+ return bi;
+ }
+ // cases must be contiguous, enumerator stops at first NULL
+#ifdef MINIBROWSER_SUPPORT
+ case 4:
+ {
+ MbBucketItem *bi = new MbBucketItem();
+ bi->setBitmaps(hInstance, IDB_MB_TAB_NORMAL, NULL, IDB_MB_TAB_HILITED, IDB_MB_TAB_SELECTED);
+ bucketitems.addItem(bi);
+ return bi;
+ }
+#endif
+ // n is enumertor, not whichwnd
+ // 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)
+ /* default:
+ if (n > 1024)
+ {
+ EmbedBucketItem *bi = new EmbedBucketItem();
+ bi->setBitmaps(hInstance, IDB_PLEDIT_TAB_NORMAL, NULL, IDB_PLEDIT_TAB_HILITED, IDB_PLEDIT_TAB_SELECTED);
+ bucketitems.addItem(bi);
+ return bi;
+ }
+ break;*/
+ }
+ }
+ else if (!_wcsicmp(windowtype, L"plsc"))
+ {
+ switch (n)
+ {
+ case 0:
+ pldirs.addItem(new PlDirObject);
+ return pldirs.getLast();
+ }
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Wa2WndEmbed::destroyWindow(ifc_window *w)
+{
+ foreach(bucketitems)
+ Wa2BucketItem *i = bucketitems.getfor();
+ ifc_window *rw = i;
+ if (rw == w)
+ {
+ delete i;
+ return 1;
+ }
+ endfor;
+ foreach(wndhosts)
+ EmbedEntry *ee = wndhosts.getfor();
+ WaOsWndHost *x = ee->host;
+ if (WASABI_API_WND->rootwndIsValid(x))
+ {
+ ifc_window *rw = x;
+ if (rw == w)
+ {
+ ReentryFilter f(&wndMsgFilter, ee->whichwnd);
+ if (!f.mustLeave())
+ {
+ // this would hide the winamp window, which is probably not what we want to do (it should remain visible if it
+ // was visible, no?
+
+ // well, no, because we don't only run this in skin unloading, but also when a window gets destroyed (this is the wndcreation
+ // service being called to free what it created) -- this won't happen for mmd3/pledit because mmd3 has a static window for
+ // 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
+ // if you load another skin (ie: NonStep), and you close the pledit, it immediately reappears with the wa2 look since oswndhost_unhost
+ // reset the flags, region and parent to what they were before the window was embedded
+
+ // i think that what we need is to save which windows were visible (and their location) before switching to freeform
+ // and to restore them when we go back to wa2 mode. this will also be more consistant with the freeform behavior of
+ // remembering visible status and coordinates on a per skin basis (since otherwise freeform dockings get screwed)
+ // it also makes sense when we consider that we are going to need to remove all windowshade modes from the embedded
+ // windows when going freeform.
+
+ // see new functions: rememberVisibleWindows() and restoreVisibleWindows()
+
+ // in any case, we need to hide the window here, at least temporarily in the case of skin unloading
+ {
+ if (ee->whichwnd > 1024)
+ {
+ embedWindowState *ws = NULL;
+ //embedWindowState *ws = (embedWindowState *)ee->whichwnd;
+ HWND hHost, hContent;
+ hHost = (NULL != x) ? x->getHWND() : NULL;
+ hContent = (NULL != hHost) ? (HWND)SendMessageW(plugin.hwndParent, WM_WA_IPC, (WPARAM)hHost, IPC_FF_GETCONTENTWND) : NULL;
+
+ if (NULL != hContent)
+ {
+ ws = (embedWindowState *)GetWindowLongPtrW(hContent, GWLP_USERDATA);
+ }
+ else
+ {
+ embedWndGuidMgr.retireEmbedWindowState((embedWindowState *)ee->whichwnd);
+ }
+
+ if (NULL != ws &&
+ !(wa2.isValidEmbedWndState(ws) && --ws->hostcount != 0))
+ {
+ if (0 != (EMBED_FLAGS_FFCALLBACK & ws->flags) &&
+ NULL != ws->callback)
+ {
+ ws->callback(ws, FFC_DESTROYEMBED, (LPARAM)w);
+ }
+
+ x->oswndhost_unhost();
+ if (wa2.isValidEmbedWndState(ws))
+ ws->wasabi_window = NULL;
+
+ if (!x->isTransfering() && wa2.isValidEmbedWndState(ws))
+ {
+ if (IsWindow(x->getHWND()))
+ {
+ SendMessageW(ws->me, WM_USER + 101, 0, 0);
+ }
+ embedWndGuidMgr.retireEmbedWindowState(ws);
+ }
+
+ }
+ }
+ else
+ {
+ if (ee->whichwnd == IPC_GETWND_VIDEO) KillTimer(wa2.getWnd(ee->whichwnd), 12345);
+ x->oswndhost_unhost();
+ if (!x->isTransfering())
+ wa2.setWindowVisible(ee->whichwnd, 0);
+#ifdef VIDDEBUG
+ if (ee->whichwnd == IPC_GETWND_VIDEO) DebugString("Video : Window service asks WA2 to close the window\n");
+#endif
+
+ }
+ }
+ }
+ wndhosts.removeItem(ee);
+
+ embedWindowState *ws = NULL;
+ HWND thiswnd = NULL;
+ if (ee->whichwnd > 1024)
+ {
+ if (IsWindow(x->getHWND()))
+ thiswnd = x->getHWND();
+ //ws=(embedWindowState *)ee->whichwnd;
+ //thiswnd=ws->me;
+ }
+ else thiswnd = wa2.getWnd(ee->whichwnd);
+ //moved to xuioswndhost
+ //SetWindowLong(thiswnd,GWL_STYLE,GetWindowLong(thiswnd,GWL_STYLE)&~(WS_CHILDWINDOW));
+ switch (ee->whichwnd)
+ {
+ case IPC_GETWND_PE: plWnd = NULL; break;
+#ifdef MINIBROWSER_SUPPORT
+ case IPC_GETWND_MB: mbWnd = NULL; break;
+#endif
+ case IPC_GETWND_VIDEO:
+#ifdef VIDDEBUG
+ DebugString("Video : Window service destroys host\n");
+#endif
+ vidWnd = NULL;
+ break;
+ default:
+ if (ee->whichwnd > 1024 && ws && thiswnd != NULL)
+ {
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = 0;
+ }
+ break;
+ }
+ if (ee->cmds)
+ {
+ GuiObject *o = w->getParent()->getGuiObject();
+ o->guiobject_removeAppCmds(ee->cmds);
+ }
+ x->oswndhost_unhost(); // ignored if already done by reentryfiltered code
+ delete ee->monitor;
+ delete ee->cmds;
+ delete x;
+
+
+ if (ee->whichwnd > 1024 && ws)
+ {
+ if (forcedoffwnds.haveItem(ws->me))
+ {
+ RECT r;
+ GetWindowRect(ws->me, &r);
+ SetWindowPos(ws->me, NULL, r.left + 20000, r.top + 20000, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOZORDER);
+ forcedoffwnds.delItem(ws->me);
+ }
+ }
+ delete ee;
+ SetFocus(wa2.getMainWindow());
+
+ return 1;
+ }
+ endfor;
+ foreach (pldirs)
+ PlDirObject *pldir = pldirs.getfor();
+ if (pldir == w)
+ {
+ delete pldir;
+ return 1;
+ }
+ endfor;
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------------------------
+int Wa2WndEmbed::viewer_onEvent(ifc_window *item, int event, intptr_t param, void *ptr, size_t ptrlen)
+{
+ if (event == ifc_window::Event_SETVISIBLE)
+ {
+ /* if (!param) {
+ // the wnd may be going away, but then again, it might just be hidden to show an alternate layout of the same
+ // container, so before continuing, we need to check if it's actually going away. There is of course an exception
+ // in that if the window is hosted by a wndholder with autoclose="1", we should mirror the hiding state regardless
+ // of the container state
+
+ api_window *whr = item->getParent();
+ int except = 0;
+ if (whr) {
+ GuiObject *go = whr->getGuiObject();
+ if (go) {
+ const char *par = go->guiobject_getXmlParam("autoclose");
+ if (!par || (par && ATOI(par) == 1)) except = 1;
+ }
+ }
+ if (!except) {
+ api_window *lr = item->getDesktopParent();
+ if (lr) {
+ Layout *l = static_cast<Layout *>(lr->getInterface(layoutGuid));
+ if (l) {
+ Container *c = l->getParentContainer();
+ if (c) {
+ if (c->isVisible()) return 1;
+ }
+ }
+ }
+ }
+ }*/
+ foreach(wndhosts)
+ EmbedEntry *ee = wndhosts.getfor();
+ XuiOSWndHost *x = ee->host;
+ ifc_window *rw = x;
+ if (rw == item)
+ {
+ {
+ ReentryFilter f(&wndMsgFilter, ee->whichwnd);
+ if (f.mustLeave()) continue;
+ }
+ if (ee->whichwnd > 1024)
+ {
+ embedWindowState *ws = (embedWindowState *)ee->whichwnd;
+ if (!param && wa2.isValidEmbedWndState(ws))
+ {
+ if (IsWindow(ws->me))
+ SendMessageW(ws->me, WM_USER + 101, 0, 0);
+ ifc_window *rwh = x->findWindowByInterface(windowHolderGuid);
+ if (rwh != NULL)
+ {
+ WindowHolder *wh = static_cast<WindowHolder *>(rwh->getInterface(windowHolderGuid));
+ if (wh != NULL)
+ {
+ wh->onRemoveWindow(1);
+ }
+ }
+ if (wa2.isValidEmbedWndState(ws)) ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL;
+ }
+ else if (wa2.isValidEmbedWndState(ws))
+ {
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = (intptr_t)item->getParent();
+ ShowWindow(ws->me, SW_NORMAL);
+ }
+ }
+ else
+ {
+ ReentryFilter f(&wndMsgFilter, ee->whichwnd);
+#ifdef VIDDEBUG
+ if (ee->whichwnd == IPC_GETWND_VIDEO && param != wa2.isWindowVisible(ee->whichwnd)) DebugString("Video : Detected that the host is %s, syncing\n", param ? "shown" : "hidden");
+#endif
+ wa2.setWindowVisible(ee->whichwnd, param);
+ }
+ }
+ endfor;
+ }
+ return 1;
+}
+
+int Wa2WndEmbed::onShowWindow(Container *c, GUID guid, const wchar_t *groupid)
+{
+ foreach(wndhosts)
+ EmbedEntry *ee = wndhosts.getfor();
+ if (ee->g == guid)
+ {
+ ReentryFilter f(&wndMsgFilter, ee->whichwnd);
+ if (f.mustLeave()) return 1;
+ if (guid == videoWndGuid) wa2.setWindowVisible(IPC_GETWND_VIDEO, 1);
+#ifdef MINIBROWSER_SUPPORT
+ else if (guid == minibrowserWndGuid) wa2.setWindowVisible(IPC_GETWND_MB, 1);
+#endif
+ else if (guid == pleditWndGuid) wa2.setWindowVisible(IPC_GETWND_PE, 1);
+ }
+ endfor;
+ return 1;
+}
+
+int Wa2WndEmbed::onHideWindow(Container *c, GUID guid, const wchar_t *groupid)
+{
+ /* if (guid == INVALID_GUID) return 1;
+ embedWindowState *ws = embedWndGuidMgr.getEmbedWindowState(guid);
+ if (ws != NULL && wa2.isValidEmbedWndState(ws)) {
+ if (IsWindow(ws->me))
+ SendMessageW(ws->me,WM_USER+101,0,0);
+ api_window *x = (api_window*)ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND];
+ if (x && WASABI_API_WND->rootwndIsValid(x)) {
+ api_window *rwh = x->findWindowByInterface(windowHolderGuid);
+ if (rwh != NULL) {
+ WindowHolder *wh = static_cast<WindowHolder *>(rwh->getInterface(windowHolderGuid));
+ if (wh != NULL) {
+ wh->onRemoveWindow(1);
+ }
+ }
+ }
+ ws->extra_data[EMBED_STATE_EXTRA_FFROOTWND] = NULL;
+ }
+ */
+ foreach(wndhosts)
+ EmbedEntry *ee = wndhosts.getfor();
+ if (ee->g == guid)
+ {
+ ReentryFilter f(&wndMsgFilter, ee->whichwnd);
+ if (f.mustLeave()) return 1;
+ if (ee->host->isTransfering()) return 1;
+ ifc_window *dp = ee->host->getDesktopParent();
+ if (dp)
+ {
+ Layout *l = static_cast<Layout*>(dp->getInterface(layoutGuid));
+ if (l)
+ {
+ if (l->getParentContainer() != c) return 1;
+ }
+ }
+ if (guid == videoWndGuid) wa2.setWindowVisible(IPC_GETWND_VIDEO, 0);
+#ifdef MINIBROWSER_SUPPORT
+ else if (guid == minibrowserWndGuid) wa2.setWindowVisible(IPC_GETWND_MB, 0);
+#endif
+ else if (guid == pleditWndGuid) wa2.setWindowVisible(IPC_GETWND_PE, 0);
+ }
+ endfor;
+
+ return 1;
+}
+
+extern wchar_t *INI_FILE;
+
+int Wa2WndEmbed::embedRememberProc(embedWindowState *p, embedEnumStruct *parms)
+{
+ WndStatus *ws = new WndStatus;
+ ws->wndcode = -1; // if you insert a wnd that is not in embedTable, put -1 as wndcode
+ ws->wnd = p->me;
+ ws->visible = IsWindowVisible(p->me);
+ GetWindowRect(p->me, &ws->position);
+ // ws->position=p->r;
+ wa2wndstatus.addItem(ws);
+
+ // only store the ml window position if not loading on startup
+ if(going_freeform && !m_loading_at_startup)
+ {
+ HWND mlwnd = wa2.getMediaLibrary();
+ if(GetWindow(p->me, GW_CHILD) == mlwnd)
+ {
+ WritePrivateProfileStringW(L"gen_ff", L"classicmlwidth", StringPrintfW(L"%d", ws->position.right - ws->position.left), INI_FILE);
+ WritePrivateProfileStringW(L"gen_ff", L"classicmlheight", StringPrintfW(L"%d", ws->position.bottom - ws->position.top), INI_FILE);
+ }
+ }
+ return 0;
+}
+
+extern int m_loading_at_startup;
+
+//-----------------------------------------------------------------------------------------------
+// todo: remember and restore windowshade modes
+void Wa2WndEmbed::rememberVisibleWindows()
+{
+ wa2wndstatus.deleteAll();
+ for (int i = 0;i < sizeof(embedTable) / sizeof(embedTable[0]);i++)
+ {
+ HWND w = wa2.getWnd(embedTable[i]);
+ WndStatus *ws = new WndStatus;
+ ws->wndcode = embedTable[i]; // if you insert a wnd that is not in embedTable, put -1 as wndcode
+ ws->wnd = w;
+ ws->visible = wa2.isWindowVisible(embedTable[i]);
+ GetWindowRect(w, &ws->position);
+ if (going_freeform)
+ {
+ if (embedTable[i] == IPC_GETWND_PE)
+ {
+ int peheight = ws->position.bottom - ws->position.top;
+ int pewidth = ws->position.right - ws->position.left;
+ if (!m_loading_at_startup)
+ {
+ WritePrivateProfileStringW(L"gen_ff", L"classicplwidth", StringPrintfW(L"%d", pewidth), INI_FILE);
+ WritePrivateProfileStringW(L"gen_ff", L"classicplheight", StringPrintfW(L"%d", peheight), INI_FILE);
+ }
+ int classicpews = wa2.isWindowShade(IPC_GETWND_PE);
+ if (!m_loading_at_startup || GetPrivateProfileIntW(L"gen_ff", L"classicplws", -1, INI_FILE) == -1)
+ WritePrivateProfileStringW(L"gen_ff", L"classicplws", classicpews ? L"1" : L"0", INI_FILE);
+ if (classicpews)
+ SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_WINDOWSHADE_PL, 0);
+ GetWindowRect(w, &ws->position);
+ }
+ }
+ wa2wndstatus.addItem(ws);
+ }
+ embedEnumStruct cs = { embedRememberProc, 0};
+ SendMessageW(wa2.getMainWindow(), WM_WA_IPC, (WPARAM)&cs, IPC_EMBED_ENUM);
+}
+
+int Wa2WndEmbed::hadRememberedWndVisible(HWND w)
+{
+ int n = wa2wndstatus.getNumItems();
+ for (int i = 0;i < n;i++)
+ {
+ WndStatus *ws = wa2wndstatus.enumItem(i);
+ if (ws->wnd == w && ws->visible)
+ return 1;
+ }
+ return 0;
+}
+
+void Wa2WndEmbed::restoreVisibleWindows()
+{
+ int n = wa2wndstatus.getNumItems();
+ HWND mlwnd = wa2.getMediaLibrary();
+ for (int i = 0;i < n;i++)
+ {
+ WndStatus *ws = wa2wndstatus.enumItem(i);
+ if (going_fixedform && !m_loading_at_startup)
+ {
+ if (embedTable[i] == IPC_GETWND_PE)
+ {
+ int classicpews = GetPrivateProfileIntW(L"gen_ff", L"classicplws", 0, INI_FILE);
+ if (classicpews)
+ {
+ SendMessageW(wa2.getMainWindow(), WM_COMMAND, WINAMP_OPTIONS_WINDOWSHADE_PL, 0);
+ }
+ int classicwidth = GetPrivateProfileIntW(L"gen_ff", L"classicplwidth", 275, INI_FILE);
+ int classicheight = GetPrivateProfileIntW(L"gen_ff", L"classicplheight", 145, INI_FILE);
+ wa2.setPlEditWidthHeight(classicwidth, classicheight);
+ }
+
+ if(GetWindow(ws->wnd, GW_CHILD) == mlwnd)
+ {
+ // only restore the ml window size if we were able to read in saved values
+ int mlwidth = GetPrivateProfileIntW(L"gen_ff", L"classicmlwidth", -1, INI_FILE);
+ int mlheight = GetPrivateProfileIntW(L"gen_ff", L"classicmlheight", -1, INI_FILE);
+ if(mlwidth != -1 && mlheight != -1)
+ SetWindowPos(ws->wnd, 0, 0, 0, mlwidth, mlheight, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
+ }
+ }
+ // FG> as of oct19, this function only restores state for windows that WERE visible
+ // because there is no reason to hide one, since this function is designed to bring
+ // back those windows that were here in one mode, but aren't so anymore in another
+ if (ws->visible)
+ {
+ if (ws->wndcode != -1)
+ {
+ wa2.setWindowVisible(ws->wndcode, ws->visible);
+ }
+ else
+ {
+ ShowWindow(ws->wnd, ws->visible ? SW_SHOWNA : SW_HIDE);
+ }
+ }
+ }
+}
+
+PtrList<WndStatus> Wa2WndEmbed::wa2wndstatus;
+
+//-----------------------------------------------------------------------------------------------
+PlaylistAppCmds::PlaylistAppCmds()
+: addCmd(L"Add", PL_ADD, AppCmds::SIDE_LEFT, 0),
+ remCmd(L"Rem", PL_REM, AppCmds::SIDE_LEFT, 0),
+ selCmd(L"Sel", PL_SEL, AppCmds::SIDE_LEFT, 0),
+ miscCmd(L"Misc", PL_MISC, AppCmds::SIDE_LEFT, 0),
+ listCmd(L"List", PL_LIST, AppCmds::SIDE_RIGHT, 0)
+{
+ appcmds_addCmd(&addCmd);
+ appcmds_addCmd(&remCmd);
+ appcmds_addCmd(&selCmd);
+ appcmds_addCmd(&miscCmd);
+ appcmds_addCmd(&listCmd);
+}
+
+void PlaylistAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
+{
+ switch (id)
+ {
+ case PL_ADD:
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_ADD, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ case PL_REM:
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_REM, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ case PL_SEL:
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_SEL, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ case PL_MISC:
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_MISC, buttonRect->left, buttonRect->top, TPM_BOTTOMALIGN | TPM_LEFTALIGN);
+ break;
+ case PL_LIST:
+ wa2.sendPlCmd(Winamp2FrontEnd::WA2_PLEDITPOPUP_LIST, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
+ break;
+ }
+}
+
+
+#ifdef MINIBROWSER_SUPPORT
+//-----------------------------------------------------------------------------------------------
+MinibrowserAppCmds::MinibrowserAppCmds()
+{
+ appcmds_addCmd(new CmdRec("Back", MB_BACK, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec("Forward", MB_FORWARD, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec("Stop", MB_STOP, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec("Reload", MB_RELOAD, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec("Misc", MB_MISC, AppCmds::SIDE_RIGHT, 1));
+}
+
+void MinibrowserAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
+{
+ switch (id)
+ {
+ case MB_BACK:
+ wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_BACK);
+ break;
+ case MB_FORWARD:
+ wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_FORWARD);
+ break;
+ case MB_STOP:
+ wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_STOP);
+ break;
+ case MB_RELOAD:
+ wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBCMD_RELOAD);
+ break;
+ case MB_MISC:
+ wa2.sendMbCmd(Winamp2FrontEnd::WA2_MBPOPUP_MISC, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
+ break;
+ }
+}
+#endif
+
+//-----------------------------------------------------------------------------------------------
+VideoAppCmds::VideoAppCmds()
+{
+ appcmds_addCmd(new CmdRec(L"Fullscreen", VID_FULLSCREEN, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec(L"1x", VID_1X, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec(L"2x", VID_2X, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec(L"TV", VID_LIB, AppCmds::SIDE_LEFT, 1));
+ appcmds_addCmd(new CmdRec(L"Misc", VID_MISC, AppCmds::SIDE_RIGHT, 1));
+}
+
+void VideoAppCmds::appcmds_onCommand(int id, const RECT *buttonRect, int which_button)
+{
+ switch (id)
+ {
+ case VID_FULLSCREEN:
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_FULLSCREEN);
+ break;
+ case VID_1X:
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_1X);
+ break;
+ case VID_2X:
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_2X);
+ break;
+ case VID_LIB:
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDCMD_LIB);
+ break;
+ case VID_MISC:
+ wa2.sendVidCmd(Winamp2FrontEnd::WA2_VIDPOPUP_MISC, buttonRect->right, buttonRect->top, TPM_BOTTOMALIGN | TPM_RIGHTALIGN);
+ break;
+ }
+}
+