BuildTools
Qt
Src
Agave
Components
Elevator
Mastering
Plugins
DSP
Encoder
General
gen_crasher
gen_ff
bitmaps
AlbumArt.cpp
AlbumArt.h
MediaDownloader.cpp
README.txt
WinampConfigScriptObject.cpp
WinampConfigScriptObject.h
api__gen_ff.h
embedwndguid.cpp
embedwndguid.h
ff_ipc.cpp
ff_ipc.h
fsmonitor.cpp
fsmonitor.h
gen.h
gen_ff.rc
gen_ff.rc2
gen_ff.sln
gen_ff.vcxproj
gen_ff.vcxproj.filters
gen_ff_ipc.h
main.cpp
main.h
menuactions.cpp
menuactions.h
minibrowserCOM.cpp
minibrowserCOM.h
precomp__gen_ff.cpp
precomp__gen_ff.h
prefs.cpp
prefs.h
prefs_about.cpp
prefs_alpha.cpp
prefs_colorthemes.cpp
prefs_font.cpp
prefs_general.cpp
resource.h
servicelink.cpp
skininfo.cpp
skininfo.h
wa2buckitems.cpp
wa2buckitems.h
wa2cfgitems.cpp
wa2cfgitems.h
wa2core.cpp
wa2core.h
wa2coreactions.cpp
wa2coreactions.h
wa2frontend.cpp
wa2frontend.h
wa2groupdefs.cpp
wa2groupdefs.h
wa2playlist.cpp
wa2playlist.h
wa2pldirobj.cpp
wa2pldirobj.h
wa2pledit.cpp
wa2pledit.h
wa2songticker.cpp
wa2songticker.h
wa2wndembed.cpp
wa2wndembed.h
wasabi.dsp
wasabi.vcproj
wasabicfg.h
gen_hotkeys
gen_ml
gen_tray
Input
Library
Output
Portable
SDK
Visualization
ReplayGainAnalysis
WAT
Wasabi
Wasabi2
Winamp
aacPlus
aacdec
aacdec-mft
adpcm
alac
albumart
apev2
auth
bmp
burnlib
codesign
config
devices
external_dependencies
f263
filereader
freetypewac
gif
gracenote
h264
h264dec
id3v2
ie_plugin
installer
jpeg
libvp6
libvpShared
mp3-mpg123
mp4v
mpeg4dec
nde
nprt_plugin
ns-eel
ns-eel2
nsavi
nsmkv
nsutil
nsv
nsvdec_vp3
nsvdec_vp5
nsvdec_vp6
nswasabi
nu
omBrowser
pcm
pfc
playlist
plist
png
replicant
resources
tagz
tataki
theora
timer
vlb
vp32
vp6
vp8x
wbm
winampAll
winampa
xml
xspf
vcpkg-ports
.gitignore
LICENSE.md
README.md
automate-git.py
cef_x86.bat
install-packages.cmd
vcpkg_version_finder.py
winampAll_2019.sln
947 lines
29 KiB
C++
947 lines
29 KiB
C++
#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;
|
|
}
|
|
}
|
|
|