diff options
Diffstat (limited to 'Src/Plugins/General/gen_ff/wa2wndembed.cpp')
-rw-r--r-- | Src/Plugins/General/gen_ff/wa2wndembed.cpp | 946 |
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; + } +} + |