aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_wv
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/Input/in_wv')
-rw-r--r--Src/Plugins/Input/in_wv/changes.txt7
-rw-r--r--Src/Plugins/Input/in_wv/in2.h152
-rw-r--r--Src/Plugins/Input/in_wv/in_wv.cpp2062
-rw-r--r--Src/Plugins/Input/in_wv/resource.h49
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Agave/AlbumArt/svc_albumArtProvider.h73
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Agave/Config/api_config.h123
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Agave/Config/ifc_configgroup.h35
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Agave/Config/ifc_configitem.h200
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Agave/Language/api_language.h315
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Agave/Language/lang.h595
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Wasabi.cpp161
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Wasabi.h66
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Winamp/DSP.H65
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Winamp/GEN.H37
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Winamp/IN2.H138
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Winamp/api_audiostream.h65
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Winamp/api_decodefile.h99
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Winamp/api_random.h78
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Winamp/api_wa5component.h34
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Winamp/ipc_pe.h56
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Winamp/wa_dlg.h436
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Winamp/wa_hotkeys.h39
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/Winamp/wa_ipc.h2468
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/api/memmgr/api_memmgr.h78
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/api/service/api_service.h155
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/api/service/services.h68
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/api/service/waservicefactory.h97
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/bfc/dispatch.h559
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/bfc/nsguid.h37
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/bfc/platform/guid.h24
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/bfc/platform/platform.h500
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/bfc/platform/types.h78
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/bfc/platform/win32.h38
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/bfc/std_mkncc.h11
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/nu/AutoChar.h133
-rw-r--r--Src/Plugins/Input/in_wv/wasabi/nu/AutoWide.h86
-rw-r--r--Src/Plugins/Input/in_wv/wavpack.rc118
-rw-r--r--Src/Plugins/Input/in_wv/winamp.vcproj237
38 files changed, 9572 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_wv/changes.txt b/Src/Plugins/Input/in_wv/changes.txt
new file mode 100644
index 00000000..4a03afc1
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/changes.txt
@@ -0,0 +1,7 @@
+* Removed incorrect manifest file which causes issues loading the plug-in on some systems
+* Now built with VS2008 so now depends on 5.57+ due to msvcr90.dll dependency (cuts size)
+* Changed localisation system to directly use api_language
+* Added %type%, %family% (used mainly by the installer) and %gain% to complement the other replaygain options
+* Removed config dialog as not applicable now with new defaults and also if we're following Winamp's settings
+* Changed some of the stringtable resource (adds new strings, removes deprecated strings and some minor tweaks)
+* Changed some of the options for the plug-in project (including using lng_generator directly)
diff --git a/Src/Plugins/Input/in_wv/in2.h b/Src/Plugins/Input/in_wv/in2.h
new file mode 100644
index 00000000..7c712f3f
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/in2.h
@@ -0,0 +1,152 @@
+#ifndef NULLSOFT_WINAMP_IN2H
+#define NULLSOFT_WINAMP_IN2H
+// Input plugin interface
+
+#include "out.h"
+
+// If you want your input plugin to support unicode then define the following which will then
+// adjust required functions to their unicode variants. This is supported from Winamp 5.3+.
+#define IN_UNICODE 0x0F000000
+
+#ifdef UNICODE_INPUT_PLUGIN
+#define in_char wchar_t
+#define IN_VER (IN_UNICODE | 0x100)
+#else
+#define in_char char
+#define IN_VER 0x100
+#endif
+
+#define IN_MODULE_FLAG_USES_OUTPUT_PLUGIN 1
+
+// By default Winamp assumes your input plugin wants to use Winamp's EQ, and doesn't do replay gain
+// if you handle any of these yourself (EQ, Replay Gain adjustments), then set these flags accordingly
+
+// Set this if you want to implement your own EQ inplace of using Winamp's native implementation.
+#define IN_MODULE_FLAG_EQ 2
+
+// Set this if you adjusted volume for replay gain. For tracks with no replay gain metadata then you
+// should clear this flag UNLESS you handle "non_replaygain" gain adjustment yourself then keep it.
+#define IN_MODULE_FLAG_REPLAYGAIN 8
+
+// Use this if you queried for the replay gain preamp parameter and used it. This is new to 5.54 clients.
+#define IN_MODULE_FLAG_REPLAYGAIN_PREAMP 16
+typedef struct
+{
+ int version; // module type (IN_VER)
+ char *description; // description of module, with version string
+
+ HWND hMainWindow; // Winamp's main window (filled in by winamp - is a valid HWND on 5.1+ clients)
+ HINSTANCE hDllInstance; // DLL instance handle (Also filled in by winamp)
+
+ char *FileExtensions; // "mp3\0Layer 3 MPEG\0mp2\0Layer 2 MPEG\0mpg\0Layer 1 MPEG\0"
+ // May be altered from Config, so the user can select what they want
+
+ int is_seekable; // is this stream seekable?
+ int UsesOutputPlug; // does this plug-in use the output plug-ins? (musn't ever change, ever :)
+ // note that this has turned into a "flags" field see IN_MODULE_FLAG_*
+
+ void (*Config)(HWND hwndParent); // configuration dialog
+ void (*About)(HWND hwndParent); // about dialog
+
+ void (*Init)(); // called at program init
+ void (*Quit)(); // called at program quit
+
+ #define GETFILEINFO_TITLE_LENGTH 2048
+ // If file == NULL then the currently playing file is used (assumes you've cached it as required)
+ void (*GetFileInfo)(const in_char *file, in_char *title, int *length_in_ms);
+
+ #define INFOBOX_EDITED 0
+ #define INFOBOX_UNCHANGED 1
+ int (*InfoBox)(const in_char *file, HWND hwndParent);
+
+ int (*IsOurFile)(const in_char *fn); // called before extension checks, to allow detection of mms://, etc
+
+ // playback stuff
+ int (*Play)(const in_char *fn); // return zero on success, -1 on file-not-found, some other value on other (stopping winamp) error
+ void (*Pause)(); // pause stream
+ void (*UnPause)(); // unpause stream
+ int (*IsPaused)(); // ispaused? return 1 if paused, 0 if not
+ void (*Stop)(); // stop (unload) stream
+
+ // time stuff
+ int (*GetLength)(); // get length in ms
+ int (*GetOutputTime)(); // returns current output time in ms. (usually returns outMod->GetOutputTime()
+ void (*SetOutputTime)(int time_in_ms); // seeks to point in stream (in ms). Usually you signal your thread to seek, which seeks and calls outMod->Flush()..
+
+ // volume stuff
+ void (*SetVolume)(int volume); // from 0 to 255.. usually just call outMod->SetVolume
+ void (*SetPan)(int pan); // from -127 to 127.. usually just call outMod->SetPan
+
+ // in-window builtin vis stuff
+ void (*SAVSAInit)(int maxlatency_in_ms, int srate); // call once in Play(). maxlatency_in_ms should be the value returned from outMod->Open()
+ // call after opening audio device with max latency in ms and samplerate
+ void (*SAVSADeInit)(); // call in Stop()
+
+ // simple vis supplying mode
+ void (*SAAddPCMData)(void *PCMData, int nch, int bps, int timestamp); // sets the spec data directly from PCM data quick and easy way
+ // to get vis working :) needs at least 576 samples :)
+
+ // advanced vis supplying mode, only use if you're cool. Use SAAddPCMData for most stuff.
+ int (*SAGetMode)(); // gets csa (the current type (4=ws,2=osc,1=spec)) use when calling SAAdd()
+ int (*SAAdd)(void *data, int timestamp, int csa); // sets the spec data, filled in by winamp
+
+ // vis stuff (plug-in)
+ // simple vis supplying mode
+ void (*VSAAddPCMData)(void *PCMData, int nch, int bps, int timestamp); // sets the vis data directly from PCM data quick and easy way
+ // to get vis working :) needs at least 576 samples :)
+
+ // advanced vis supplying mode, only use if you're cool. Use VSAAddPCMData for most stuff.
+ int (*VSAGetMode)(int *specNch, int *waveNch); // use to figure out what to give to VSAAdd
+ int (*VSAAdd)(void *data, int timestamp); // filled in by winamp, called by plug-in
+
+ // call this in Play() to tell the vis plug-ins the current output params.
+ void (*VSASetInfo)(int srate, int nch); // <-- Correct (benski, dec 2005).. old declaration had the params backwards
+
+ // dsp plug-in processing:
+ // (filled in by winamp, calld by input plug)
+
+ // returns 1 if active (which means that the number of samples returned by dsp_dosamples could be
+ // greater than went in.. Use it to estimate if you'll have enough room in the output buffer
+ int (*dsp_isactive)();
+
+ // returns number of samples to output. This can be as much as twice numsamples.
+ // be sure to allocate enough buffer for samples, then.
+ int (*dsp_dosamples)(short int *samples, int numsamples, int bps, int nch, int srate);
+
+ // eq stuff
+ void (*EQSet)(int on, char data[10], int preamp); // 0-64 each, 31 is +0, 0 is +12, 63 is -12. Do nothing to ignore.
+
+ // info setting (filled in by winamp)
+ void (*SetInfo)(int bitrate, int srate, int stereo, int synched); // if -1, changes ignored? :)
+
+ Out_Module *outMod; // filled in by winamp, optionally used :)
+} In_Module;
+
+// These are the return values to be used with the uninstall plugin export function:
+// __declspec(dllexport) int winampUninstallPlugin(HINSTANCE hDllInst, HWND hwndDlg, int param)
+// which determines if Winamp can uninstall the plugin immediately or on winamp restart.
+// If this is not exported then Winamp will assume an uninstall with reboot is the only way.
+//
+#define IN_PLUGIN_UNINSTALL_NOW 0x1
+#define IN_PLUGIN_UNINSTALL_REBOOT 0x0
+//
+// Uninstall support was added from 5.0+ and uninstall now support from 5.5+ though note
+// that it is down to you to ensure that if uninstall now is returned that it will not
+// cause a crash i.e. don't use if you've been subclassing the main window.
+//
+// The HWND passed in the calling of winampUninstallPlugin(..) is the preference page HWND.
+//
+
+// For a input plugin to be correctly detected by Winamp you need to ensure that
+// the exported winampGetInModule2(..) is exported as an undecorated function
+// e.g.
+// #ifdef __cplusplus
+// extern "C" {
+// #endif
+// __declspec(dllexport) In_Module *winampGetInModule2(){ return &plugin; }
+// #ifdef __cplusplus
+// }
+// #endif
+//
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/in_wv.cpp b/Src/Plugins/Input/in_wv/in_wv.cpp
new file mode 100644
index 00000000..ddfef3d6
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/in_wv.cpp
@@ -0,0 +1,2062 @@
+/*
+** .WV input plug-in for WavPack
+** Copyright (c) 2000 - 2006, Conifer Software, All Rights Reserved
+*/
+#include <windows.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <mmreg.h>
+#include <msacm.h>
+#include <math.h>
+#include <sys/stat.h>
+#include <io.h>
+#include <strsafe.h>
+
+#include "in2.h"
+#include "wavpack.h"
+#include "resource.h"
+#include "wasabi/winamp/wa_ipc.h"
+#include "wasabi/wasabi.h"
+#include "wasabi/nu/autochar.h"
+#include "wasabi/nu/autowide.h"
+
+#define fileno _fileno
+
+static float calculate_gain(WavpackContext *wpc, bool allowDefault=true);
+
+#define PLUGIN_VERSION "2.8.1"
+//#define DEBUG_CONSOLE
+//#define ANSI_METADATA
+#define UNICODE_METADATA
+//#define OLD_INFO_DIALOG
+
+// post this to the main window at end of file (after playback as stopped)
+#define WM_WA_MPEG_EOF WM_USER+2
+
+#define MAX_NCH 8
+
+static struct wpcnxt {
+ WavpackContext *wpc; // WavPack context provided by library
+ float play_gain; // playback gain (for replaygain support)
+ //int soft_clipping; // soft clipping active for playback
+ int output_bits; // 16, 24, or 32 bits / sample
+ long sample_buffer[576*MAX_NCH*2]; // sample buffer
+ float error [MAX_NCH]; // error term for noise shaping
+ char lastfn[MAX_PATH]; // filename stored for comparisons only
+ wchar_t w_lastfn[MAX_PATH]; // w_filename stored for comparisons only
+ FILE *wv_id, *wvc_id; // file pointer when we use reader callbacks
+} curr, edit, info;
+
+int decode_pos_ms; // current decoding position, in milliseconds
+int paused; // are we paused?
+int seek_needed; // if != -1, it is the point that the decode thread should seek to, in ms.
+
+#define ALLOW_WVC 0x1
+#define REPLAYGAIN_TRACK 0x2
+#define REPLAYGAIN_ALBUM 0x4
+#define SOFTEN_CLIPPING 0x8
+#define PREVENT_CLIPPING 0x10
+
+#define ALWAYS_16BIT 0x20 // new flags added for version 2.5
+#define ALLOW_MULTICHANNEL 0x40
+#define REPLAYGAIN_24BIT 0x80
+
+int config_bits = ALLOW_WVC | ALLOW_MULTICHANNEL; // all configuration goes here
+
+int killDecodeThread=0; // the kill switch for the decode thread
+HANDLE thread_handle=INVALID_HANDLE_VALUE; // the handle to the decode thread
+
+DWORD WINAPI __stdcall DecodeThread(void *b); // the decode thread procedure
+
+static api_service* WASABI_API_SVC;
+static api_language* WASABI_API_LNG;
+static api_config *AGAVE_API_CONFIG;
+static api_memmgr *WASABI_API_MEMMGR;
+HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
+
+static char file_extensions[128] = {"WV\0WavPack Files (*.WV)\0"};
+
+// function definitions for the In_Module stucture
+void about (HWND hwndParent);
+void init();
+void quit();
+void getfileinfo(const char *filename, char *title, int *length_in_ms);
+int infoDlg(const char *fn, HWND hwnd);
+int isourfile(const char *fn);
+int play(const char *fn);
+void pause();
+void unpause();
+int ispaused();
+void stop();
+int getlength();
+int getoutputtime();
+void setoutputtime(int time_in_ms);
+void setvolume(int volume);
+void setpan(int pan);
+void eq_set(int on, char data [10], int preamp);
+
+In_Module mod = // the output module
+{
+ IN_VER,
+ "WavPack Decoder v"PLUGIN_VERSION,
+ 0, // hMainWindow
+ 0, // hDllInstance
+ file_extensions,
+ 1, // is_seekable
+ 1, // uses output
+ about,
+ about,
+ init,
+ quit,
+ getfileinfo,
+ infoDlg,
+ isourfile,
+ play,
+ pause,
+ unpause,
+ ispaused,
+ stop,
+ getlength,
+ getoutputtime,
+ setoutputtime,
+ setvolume,
+ setpan,
+ 0,0,0,0,0,0,0,0,0, // vis stuff
+ 0,0, // dsp
+ eq_set,
+ NULL, // setinfo
+ 0 // out_mod
+};
+
+static BOOL CALLBACK WavPackDlgProc(HWND, UINT, WPARAM, LPARAM);
+
+extern long dump_alloc (void);
+
+int DoAboutMessageBox(HWND parent, wchar_t* title, wchar_t* message)
+{
+ MSGBOXPARAMSW msgbx = {sizeof(MSGBOXPARAMSW),0};
+ msgbx.lpszText = message;
+ msgbx.lpszCaption = title;
+ msgbx.lpszIcon = MAKEINTRESOURCEW(102);
+ msgbx.hInstance = GetModuleHandle(0);
+ msgbx.dwStyle = MB_USERICON;
+ msgbx.hwndOwner = parent;
+ return MessageBoxIndirectW(&msgbx);
+}
+
+void about(HWND hwndParent)
+{
+ wchar_t about_string[512];
+#ifdef DEBUG_ALLOC
+ sprintf (about_string, "alloc_count = %d", dump_alloc ());
+#else
+ StringCchPrintfW(about_string, 512, WASABI_API_LNGSTRINGW(IDS_ABOUT_MESSAGE), PLUGIN_VERSION, "1998-2010", __DATE__);
+#endif
+ DoAboutMessageBox(hwndParent, WASABI_API_LNGSTRINGW(IDS_ABOUT), about_string);
+}
+
+void init() /* any one-time initialization goes here (configuration reading, etc) */
+{
+ if (mod.hMainWindow)
+ {
+ // load all of the required wasabi services from the winamp client
+ WASABI_API_SVC = (api_service *)SendMessage(mod.hMainWindow, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+ if (WASABI_API_SVC == (api_service *)1)
+ WASABI_API_SVC=0;
+
+ WASABI_API_SVC->service_register(&albumArtFactory);
+ }
+ ServiceBuild(AGAVE_API_CONFIG, AgaveConfigGUID);
+ ServiceBuild(WASABI_API_LNG, languageApiGUID);
+ ServiceBuild(WASABI_API_MEMMGR, memMgrApiServiceGuid);
+
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(mod.hDllInstance,InWvLangGuid);
+
+ static char szDescription[256];
+ StringCchPrintfA(szDescription,256,WASABI_API_LNGSTRING(IDS_DESCRIPTION),PLUGIN_VERSION);
+ mod.description = szDescription;
+
+ // set the file extension to the localised version
+ char tmp [64], *tmp_ptr = tmp, *fex_ptr = file_extensions;
+ WASABI_API_LNGSTRING_BUF(IDS_FILETYPE, tmp, sizeof (tmp));
+
+ *fex_ptr++ = 'W';
+ *fex_ptr++ = 'V';
+ *fex_ptr++ = 0;
+
+ while (*tmp_ptr)
+ *fex_ptr++ = *tmp_ptr++;
+
+ *fex_ptr++ = 0;
+ *fex_ptr++ = 0;
+}
+
+#ifdef DEBUG_CONSOLE
+
+HANDLE debug_console=INVALID_HANDLE_VALUE; // debug console
+
+void debug_write (char *str)
+{
+ static int cant_debug;
+
+ if (cant_debug)
+ return;
+
+ if (debug_console == INVALID_HANDLE_VALUE) {
+ AllocConsole ();
+
+#if 1
+ debug_console = GetStdHandle (STD_OUTPUT_HANDLE);
+#else
+ debug_console = CreateConsoleScreenBuffer (GENERIC_WRITE, FILE_SHARE_WRITE,
+ NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
+#endif
+
+ if (debug_console == INVALID_HANDLE_VALUE) {
+ MessageBox(NULL, "Can't get a console handle", "WavPack",MB_OK);
+ cant_debug = 1;
+ return;
+ }
+ else if (!SetConsoleActiveScreenBuffer (debug_console)) {
+ MessageBox(NULL, "Can't activate console buffer", "WavPack",MB_OK);
+ cant_debug = 1;
+ return;
+ }
+ }
+
+ WriteConsole (debug_console, str, strlen (str), NULL, NULL);
+}
+
+#endif
+
+void quit() /* one-time deinit, such as memory freeing */
+{
+#ifdef DEBUG_CONSOLE
+ if (debug_console != INVALID_HANDLE_VALUE) {
+ FreeConsole ();
+
+ if (debug_console != GetStdHandle (STD_OUTPUT_HANDLE))
+ CloseHandle (debug_console);
+
+ debug_console = INVALID_HANDLE_VALUE;
+ }
+#endif
+ ServiceRelease(AGAVE_API_CONFIG, AgaveConfigGUID);
+ ServiceRelease(WASABI_API_LNG, languageApiGUID);
+ ServiceRelease(WASABI_API_MEMMGR, memMgrApiServiceGuid);
+ WASABI_API_SVC->service_deregister(&albumArtFactory);
+}
+
+// used for detecting URL streams.. unused here. strncmp(fn,"http://",7) to detect HTTP streams, etc
+int isourfile(const char *fn)
+{
+ return 0;
+}
+
+int play(const char *fn)
+{
+ int num_chans, sample_rate;
+ char error[128];
+ int maxlatency;
+ int thread_id;
+ int open_flags;
+
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "play (%s)\n", fn);
+ debug_write (error);
+#endif
+
+ open_flags = OPEN_TAGS | OPEN_NORMALIZE;
+
+ if (config_bits & ALLOW_WVC)
+ open_flags |= OPEN_WVC;
+
+ if (!(config_bits & ALLOW_MULTICHANNEL))
+ open_flags |= OPEN_2CH_MAX;
+
+ curr.wpc = WavpackOpenFileInput(fn, error, open_flags, 0);
+
+ if (!curr.wpc) // error opening file, just return error
+ return -1;
+
+ num_chans = WavpackGetReducedChannels(curr.wpc);
+ sample_rate = WavpackGetSampleRate(curr.wpc);
+ curr.output_bits = WavpackGetBitsPerSample(curr.wpc) > 16 ? 24 : 16;
+
+ if (config_bits & ALWAYS_16BIT)
+ curr.output_bits = 16;
+ else if ((config_bits & (REPLAYGAIN_TRACK | REPLAYGAIN_ALBUM)) &&
+ (config_bits & REPLAYGAIN_24BIT))
+ curr.output_bits = 24;
+
+ if (num_chans > MAX_NCH) // don't allow too many channels!
+ {
+ WavpackCloseFile(curr.wpc);
+ return -1;
+ }
+
+ curr.play_gain = calculate_gain(curr.wpc);
+ lstrcpyn(curr.lastfn, fn, MAX_PATH);
+
+ paused = 0;
+ decode_pos_ms = 0;
+ seek_needed = -1;
+
+ maxlatency = mod.outMod->Open(sample_rate, num_chans, curr.output_bits, -1, -1);
+
+ if (maxlatency < 0) // error opening device
+ {
+ curr.wpc = WavpackCloseFile(curr.wpc);
+ return -1;
+ }
+
+ // dividing by 1000 for the first parameter of setinfo makes it
+ // display 'H'... for hundred.. i.e. 14H Kbps.
+
+ mod.SetInfo(0, (sample_rate + 500) / 1000, num_chans, 1);
+
+ // initialize vis stuff
+
+ mod.SAVSAInit(maxlatency, sample_rate);
+ mod.VSASetInfo(sample_rate, num_chans);
+
+ mod.outMod->SetVolume(-666); // set the output plug-ins default volume
+
+ killDecodeThread=0;
+
+ thread_handle = (HANDLE)CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) DecodeThread, (void *) &killDecodeThread, 0, (LPDWORD)&thread_id);
+
+ if (SetThreadPriority(thread_handle, THREAD_PRIORITY_HIGHEST) == 0) {
+ curr.wpc = WavpackCloseFile(curr.wpc);
+ return -1;
+ }
+
+ return 0;
+}
+
+void pause()
+{
+#ifdef DEBUG_CONSOLE
+ debug_write ("pause ()\n");
+#endif
+
+ paused = 1;
+ mod.outMod->Pause(1);
+}
+
+void unpause()
+{
+#ifdef DEBUG_CONSOLE
+ debug_write ("unpause ()\n");
+#endif
+
+ paused = 0;
+ mod.outMod->Pause(0);
+}
+
+int ispaused()
+{
+ return paused;
+}
+
+void stop()
+{
+#ifdef DEBUG_CONSOLE
+ debug_write ("stop ()\n");
+#endif
+
+ if (thread_handle != INVALID_HANDLE_VALUE)
+ {
+ killDecodeThread = 1;
+
+ if (WaitForSingleObject(thread_handle, INFINITE) == WAIT_TIMEOUT)
+ {
+ MessageBox(mod.hMainWindow,"error asking thread to die!\n", "error killing decode thread", 0);
+ TerminateThread(thread_handle,0);
+ }
+
+ CloseHandle(thread_handle);
+ thread_handle = INVALID_HANDLE_VALUE;
+ }
+
+ if (curr.wpc)
+ curr.wpc = WavpackCloseFile(curr.wpc);
+
+ mod.outMod->Close();
+ mod.SAVSADeInit();
+}
+
+int getlength()
+{
+ return (int)(WavpackGetNumSamples (curr.wpc) * 1000.0 / WavpackGetSampleRate (curr.wpc));
+}
+
+int getoutputtime()
+{
+ if (seek_needed == -1)
+ return decode_pos_ms + (mod.outMod->GetOutputTime () - mod.outMod->GetWrittenTime ());
+ else
+ return seek_needed;
+}
+
+void setoutputtime (int time_in_ms)
+{
+#ifdef DEBUG_CONSOLE
+ char str [40];
+ sprintf (str, "setoutputtime (%d)\n", time_in_ms);
+ debug_write (str);
+#endif
+
+ seek_needed = time_in_ms;
+}
+
+void setvolume (int volume)
+{
+ mod.outMod->SetVolume(volume);
+}
+
+void setpan (int pan)
+{
+ mod.outMod->SetPan(pan);
+}
+
+static void generate_format_string(WavpackContext *wpc, wchar_t *string, int maxlen, int wide);
+static void AnsiToUTF8(char *string, int len);
+static int UTF8ToWideChar(const char *pUTF8, wchar_t *pWide);
+static void UTF8ToAnsi(char *string, int len);
+
+int infoDlg(const char *fn, HWND hwnd)
+{
+#ifdef OLD_INFO_DIALOG
+ char string[2048];
+ wchar_t w_string[2048];
+ WavpackContext *wpc;
+ int open_flags;
+
+ open_flags = OPEN_TAGS | OPEN_NORMALIZE;
+
+ if (config_bits & ALLOW_WVC)
+ open_flags |= OPEN_WVC;
+
+ if (!(config_bits & ALLOW_MULTICHANNEL))
+ open_flags |= OPEN_2CH_MAX;
+
+ wpc = WavpackOpenFileInput(fn, string, open_flags, 0);
+
+ if (wpc)
+ {
+ int mode = WavpackGetMode(wpc);
+
+ //generate_format_string(wpc, string, sizeof (string), 1);
+ wchar_t *temp = (wchar_t *)malloc(sizeof(string) * sizeof(wchar_t));
+ generate_format_string(wpc, temp, sizeof(string), 0);
+ lstrcpyn(string, AutoChar(temp, CP_UTF8), sizeof(string));
+ free(temp);
+
+ if (WavpackGetMode(wpc) & MODE_VALID_TAG)
+ {
+ char value [128];
+
+ if (config_bits & (REPLAYGAIN_TRACK | REPLAYGAIN_ALBUM))
+ {
+ int local_clipping = 0;
+ float local_gain;
+
+ local_gain = calculate_gain(wpc);
+
+ if (local_gain != 1.0)
+ StringCchPrintf(string + strlen (string), 2048, "Gain: %+.2f dB %s\n",
+ log10 (local_gain) * 20.0, local_clipping ? "(w/soft clipping)" : "");
+ }
+
+ if (WavpackGetTagItem(wpc, "title", value, sizeof (value)))
+ {
+ if (!(mode & MODE_APETAG))
+ AnsiToUTF8(value, sizeof (value));
+
+ StringCchPrintf(string + strlen (string), 2048, "\nTitle: %s", value);
+ }
+
+ if (WavpackGetTagItem(wpc, "artist", value, sizeof (value)))
+ {
+ if (!(mode & MODE_APETAG))
+ AnsiToUTF8(value, sizeof (value));
+
+ StringCchPrintf(string + strlen (string), 2048, "\nArtist: %s", value);
+ }
+
+ if (WavpackGetTagItem (wpc, "album", value, sizeof (value)))
+ {
+ if (!(mode & MODE_APETAG))
+ AnsiToUTF8(value, sizeof (value));
+
+ StringCchPrintf (string + strlen (string), 2048, "\nAlbum: %s", value);
+ }
+
+ if (WavpackGetTagItem (wpc, "genre", value, sizeof (value)))
+ {
+ if (!(mode & MODE_APETAG))
+ AnsiToUTF8(value, sizeof (value));
+
+ StringCchPrintf(string + strlen (string), 2048, "\nGenre: %s", value);
+ }
+
+ if (WavpackGetTagItem (wpc, "comment", value, sizeof (value)))
+ {
+ if (!(mode & MODE_APETAG))
+ AnsiToUTF8(value, sizeof (value));
+
+ StringCchPrintf(string + strlen (string), 2048, "\nComment: %s", value);
+ }
+
+ if (WavpackGetTagItem(wpc, "year", value, sizeof (value)))
+ StringCchPrintf(string + strlen (string), 2048, "\nYear: %s", value);
+
+ if (WavpackGetTagItem(wpc, "track", value, sizeof (value)))
+ StringCchPrintf(string + strlen (string), 2048, "\nTrack: %s", value);
+
+ StringCchCat(string, 2048, "\n");
+ }
+
+ UTF8ToWideChar(string, w_string);
+ MessageBoxW(hwnd, w_string, L"WavPack File Info Box", MB_OK);
+ wpc = WavpackCloseFile(wpc);
+ }
+ else
+ MessageBox(hwnd, string, "WavPack Decoder", MB_OK);
+
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+void getfileinfo(const char *filename, char *title, int *length_in_ms)
+{
+ if (!filename || !*filename) // currently playing file
+ {
+
+ if (length_in_ms)
+ *length_in_ms = getlength ();
+
+ if (title)
+ {
+ if (WavpackGetTagItem(curr.wpc, "title", NULL, 0))
+ {
+ char art [128], ttl [128];
+
+ WavpackGetTagItem(curr.wpc, "title", ttl, sizeof (ttl));
+
+ if (WavpackGetMode(curr.wpc) & MODE_APETAG)
+ UTF8ToAnsi(ttl, sizeof (ttl));
+
+ if (WavpackGetTagItem(curr.wpc, "artist", art, sizeof (art)))
+ {
+ if (WavpackGetMode(curr.wpc) & MODE_APETAG)
+ UTF8ToAnsi(art, sizeof (art));
+
+ StringCchPrintf(title, GETFILEINFO_TITLE_LENGTH, "%s - %s", art, ttl);
+ }
+ else
+ lstrcpyn(title, ttl, GETFILEINFO_TITLE_LENGTH);
+ }
+ else
+ {
+ char *p = curr.lastfn + strlen (curr.lastfn);
+
+ while (*p != '\\' && p >= curr.lastfn)
+ p--;
+
+ lstrcpyn(title, ++p, GETFILEINFO_TITLE_LENGTH);
+ }
+ }
+ }
+ else // some other file
+ {
+ WavpackContext *wpc;
+ char error [128];
+ int open_flags;
+
+ if (length_in_ms)
+ *length_in_ms = -1000;
+
+ if (title)
+ *title = 0;
+
+ open_flags = OPEN_TAGS | OPEN_NORMALIZE;
+
+ if (config_bits & ALLOW_WVC)
+ open_flags |= OPEN_WVC;
+
+ if (!(config_bits & ALLOW_MULTICHANNEL))
+ open_flags |= OPEN_2CH_MAX;
+
+ wpc = WavpackOpenFileInput(filename, error, open_flags, 0);
+
+ if (wpc)
+ {
+ if (length_in_ms)
+ *length_in_ms = (int)(WavpackGetNumSamples(wpc) * 1000.0 / WavpackGetSampleRate(wpc));
+
+ if (title && WavpackGetTagItem(wpc, "title", NULL, 0))
+ {
+ char art [128], ttl [128];
+
+ WavpackGetTagItem(wpc, "title", ttl, sizeof (ttl));
+
+ if (WavpackGetMode(wpc) & MODE_APETAG)
+ UTF8ToAnsi(ttl, sizeof (ttl));
+
+ if (WavpackGetTagItem(wpc, "artist", art, sizeof (art)))
+ {
+ if (WavpackGetMode(wpc) & MODE_APETAG)
+ UTF8ToAnsi(art, sizeof (art));
+
+ StringCchPrintf(title, GETFILEINFO_TITLE_LENGTH, "%s - %s", art, ttl);
+ }
+ else
+ lstrcpyn(title, ttl, GETFILEINFO_TITLE_LENGTH);
+ }
+
+ wpc = WavpackCloseFile(wpc);
+ }
+
+ if (title && !*title)
+ {
+ char *p = (char*)filename + strlen (filename);
+
+ while (*p != '\\' && p >= filename) p--;
+ lstrcpyn(title, ++p, GETFILEINFO_TITLE_LENGTH);
+ }
+ }
+}
+
+void eq_set(int on, char data [10], int preamp)
+{
+ // most plug-ins can't even do an EQ anyhow.. I'm working on writing
+ // a generic PCM EQ, but it looks like it'll be a little too CPU
+ // consuming to be useful :)
+}
+
+static int read_samples(struct wpcnxt *cnxt, int num_samples);
+
+DWORD WINAPI __stdcall DecodeThread(void *b)
+{
+ int num_chans, sample_rate;
+ int done = 0;
+
+ memset(curr.error, 0, sizeof (curr.error));
+ num_chans = WavpackGetReducedChannels(curr.wpc);
+ sample_rate = WavpackGetSampleRate(curr.wpc);
+
+ while (!*((int *)b) )
+ {
+ if (seek_needed != -1)
+ {
+ int seek_position = seek_needed;
+ int bc = 0;
+
+ seek_needed = -1;
+
+ if (seek_position > getlength() - 1000 && getlength() > 1000)
+ seek_position = getlength() - 1000; // don't seek to last second
+
+ mod.outMod->Flush(decode_pos_ms = seek_position);
+
+ if (WavpackSeekSample(curr.wpc, (int)(sample_rate / 1000.0 * seek_position))) {
+ decode_pos_ms = (int)(WavpackGetSampleIndex(curr.wpc) * 1000.0 / sample_rate);
+ mod.outMod->Flush(decode_pos_ms);
+ continue;
+ }
+ else
+ done = 1;
+ }
+
+ if (done) {
+ mod.outMod->CanWrite();
+
+ if (!mod.outMod->IsPlaying()) {
+ PostMessage(mod.hMainWindow, WM_WA_MPEG_EOF, 0, 0);
+ return 0;
+ }
+
+ Sleep(10);
+ }
+ else if (mod.outMod->CanWrite() >= ((576 * num_chans * (curr.output_bits / 8)) << (mod.dsp_isactive () ? 1 : 0)))
+ {
+ int tsamples = read_samples (&curr, 576) * num_chans;
+ int tbytes = tsamples * (curr.output_bits/8);
+
+ if (tsamples)
+ {
+ mod.SAAddPCMData((char *) curr.sample_buffer, num_chans, curr.output_bits, decode_pos_ms);
+ mod.VSAAddPCMData((char *) curr.sample_buffer, num_chans, curr.output_bits, decode_pos_ms);
+ decode_pos_ms = (int)(WavpackGetSampleIndex(curr.wpc) * 1000.0 / sample_rate);
+
+ if (mod.dsp_isactive())
+ tbytes = mod.dsp_dosamples ((short *) curr.sample_buffer,
+ tsamples / num_chans, curr.output_bits, num_chans, sample_rate) * (num_chans * (curr.output_bits/8));
+
+ mod.outMod->Write ((char *) curr.sample_buffer, tbytes);
+ }
+ else
+ done = 1;
+ }
+ else
+ {
+ mod.SetInfo((int) ((WavpackGetInstantBitrate (curr.wpc) + 500.0) / 1000.0), -1, -1, 1);
+ Sleep(20);
+ }
+ }
+
+ return 0;
+}
+
+/********* These functions provide the "transcoding" mode of winamp. *********/
+
+extern "C" __declspec (dllexport) intptr_t winampGetExtendedRead_open (const char *fn, int *size, int *bps, int *nch, int *srate)
+{
+ struct wpcnxt *cnxt = (struct wpcnxt *)malloc(sizeof (struct wpcnxt));
+ int num_chans, sample_rate, open_flags;
+ char error[128];
+
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "Read_open (%s)\n", fn);
+ debug_write (error);
+#endif
+
+ if (!cnxt)
+ return 0;
+
+ memset(cnxt, 0, sizeof (struct wpcnxt));
+ open_flags = OPEN_NORMALIZE | OPEN_WVC;
+
+ if (!(config_bits & ALLOW_MULTICHANNEL) || *nch == 2)
+ open_flags |= OPEN_2CH_MAX;
+
+ if (config_bits & (REPLAYGAIN_TRACK | REPLAYGAIN_ALBUM))
+ open_flags |= OPEN_TAGS;
+
+ cnxt->wpc = WavpackOpenFileInput(fn, error, open_flags, 0);
+
+ if (!cnxt->wpc) // error opening file, just return error
+ {
+ free (cnxt);
+ return 0;
+ }
+
+ num_chans = WavpackGetReducedChannels(cnxt->wpc);
+ sample_rate = WavpackGetSampleRate(cnxt->wpc);
+
+ if (num_chans > MAX_NCH)
+ {
+ WavpackCloseFile(cnxt->wpc);
+ free (cnxt);
+ return 0;
+ }
+
+ if (*bps != 16 && *bps != 24 && *bps != 32)
+ {
+ cnxt->output_bits = WavpackGetBitsPerSample(cnxt->wpc) > 16 ? 24 : 16;
+
+ if (config_bits & ALWAYS_16BIT)
+ cnxt->output_bits = 16;
+ else if ((config_bits & (REPLAYGAIN_TRACK | REPLAYGAIN_ALBUM)) &&
+ (config_bits & REPLAYGAIN_24BIT))
+ cnxt->output_bits = 24;
+ }
+ else
+ cnxt->output_bits = *bps;
+
+ if (num_chans > MAX_NCH) // don't allow too many channels!
+ {
+ WavpackCloseFile(cnxt->wpc);
+ free (cnxt);
+ return 0;
+ }
+
+ *nch = num_chans;
+ *srate = sample_rate;
+ *bps = cnxt->output_bits;
+ *size = WavpackGetNumSamples(cnxt->wpc) * (*bps / 8) * (*nch);
+
+ cnxt->play_gain = calculate_gain(cnxt->wpc);
+
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "Read_open success! nch=%d, srate=%d, bps=%d, size=%d\n",
+ *nch, *srate, *bps, *size);
+ debug_write (error);
+#endif
+
+ return (intptr_t) cnxt;
+}
+
+extern "C" __declspec (dllexport) intptr_t winampGetExtendedRead_getData (intptr_t handle, char *dest, int len, int *killswitch)
+{
+ struct wpcnxt *cnxt = (struct wpcnxt *)handle;
+ int num_chans = WavpackGetReducedChannels(cnxt->wpc);
+ int bytes_per_sample = num_chans * cnxt->output_bits / 8;
+ int used = 0;
+
+#ifdef DEBUG_CONSOLE
+ char error [128];
+#endif
+
+ while (used < len && !*killswitch)
+ {
+ int nsamples = (len - used) / bytes_per_sample, tsamples;
+
+ if (!nsamples)
+ break;
+ else if (nsamples > 576)
+ nsamples = 576;
+
+ tsamples = read_samples(cnxt, nsamples) * num_chans;
+
+ if (tsamples)
+ {
+ int tbytes = tsamples * (cnxt->output_bits/8);
+
+ memcpy (dest + used, cnxt->sample_buffer, tbytes);
+ used += tbytes;
+ }
+ else
+ break;
+ }
+
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "Read_getData (%d), actualy read %d\n", len, used);
+ debug_write (error);
+#endif
+
+ return used;
+}
+
+extern "C" __declspec (dllexport) int winampGetExtendedRead_setTime (intptr_t handle, int millisecs)
+{
+ struct wpcnxt *cnxt = (struct wpcnxt *) handle;
+ int sample_rate = WavpackGetSampleRate(cnxt->wpc);
+
+ return WavpackSeekSample(cnxt->wpc, (int)(sample_rate / 1000.0 * millisecs));
+}
+
+extern "C" __declspec (dllexport) void winampGetExtendedRead_close (intptr_t handle)
+{
+ struct wpcnxt *cnxt = (struct wpcnxt *) handle;
+
+#ifdef DEBUG_CONSOLE
+ char error [128];
+
+ sprintf (error, "Read_close ()\n");
+ debug_write (error);
+#endif
+
+ WavpackCloseFile(cnxt->wpc);
+ free (cnxt);
+}
+
+/* This is a generic function to read WavPack samples and convert them to a
+ * form usable by winamp. It includes conversion of any WavPack format
+ * (including ieee float) to 16, 24, or 32-bit integers (with noise shaping
+ * for the 16-bit case) and replay gain implementation (with optional soft
+ * clipping). It is used by both the regular "play" code and the newer
+ * transcoding functions.
+ *
+ * The num_samples parameter is the number of "composite" samples to
+ * convert and is limited currently to 576 samples for legacy reasons. The
+ * return value is the number of samples actually converted and will be
+ * equal to the number requested unless an error occurs or the end-of-file
+ * is encountered. The converted samples are stored (interleaved) at
+ * cnxt->sample_buffer[].
+ */
+
+static int read_samples (struct wpcnxt *cnxt, int num_samples)
+{
+ int num_chans = WavpackGetReducedChannels(cnxt->wpc), samples, tsamples;
+
+ samples = WavpackUnpackSamples(cnxt->wpc, (int32_t*) cnxt->sample_buffer, num_samples);
+ tsamples = samples * num_chans;
+
+ if (tsamples)
+ {
+ if (!(WavpackGetMode(cnxt->wpc) & MODE_FLOAT))
+ {
+ float scaler = (float) (1.0 / ((unsigned long) 1 << (WavpackGetBytesPerSample(cnxt->wpc) * 8 - 1)));
+ float *fptr = (float *) cnxt->sample_buffer;
+ long *lptr = cnxt->sample_buffer;
+ int cnt = tsamples;
+
+ while (cnt--)
+ *fptr++ = *lptr++ * scaler;
+ }
+
+ if (cnxt->play_gain != 1.0)
+ {
+ float *fptr = (float *) cnxt->sample_buffer;
+ int cnt = tsamples;
+ double outval;
+
+ while (cnt--)
+ {
+ outval = *fptr * cnxt->play_gain;
+
+ /*if (cnxt->soft_clipping)
+ {
+ if (outval > 0.75)
+ outval = 1.0 - (0.0625 / (outval - 0.5));
+ else if (outval < -0.75)
+ outval = -1.0 - (0.0625 / (outval + 0.5));
+ }*/
+
+ *fptr++ = (float) outval;
+ }
+ }
+
+ if (cnxt->output_bits == 16)
+ {
+ float *fptr = (float *) cnxt->sample_buffer;
+ short *sptr = (short *) cnxt->sample_buffer;
+ int cnt = samples, ch;
+
+ while (cnt--)
+ for (ch = 0; ch < num_chans; ++ch)
+ {
+ int dst;
+
+ *fptr -= cnxt->error [ch];
+
+ if (*fptr >= 1.0)
+ dst = 32767;
+ else if (*fptr <= -1.0)
+ dst = -32768;
+ else
+ dst = (int) floor (*fptr * 32768.0);
+
+ cnxt->error [ch] = (float)(dst / 32768.0 - *fptr++);
+ *sptr++ = dst;
+ }
+ }
+ else if (cnxt->output_bits == 24)
+ {
+ unsigned char *cptr = (unsigned char *) cnxt->sample_buffer;
+ float *fptr = (float *) cnxt->sample_buffer;
+ int cnt = tsamples;
+ long outval;
+
+ while (cnt--) {
+ if (*fptr >= 1.0)
+ outval = 8388607;
+ else if (*fptr <= -1.0)
+ outval = -8388608;
+ else
+ outval = (int) floor (*fptr * 8388608.0);
+
+ *cptr++ = (unsigned char) outval;
+ *cptr++ = (unsigned char) (outval >> 8);
+ *cptr++ = (unsigned char) (outval >> 16);
+ fptr++;
+ }
+ }
+ else if (cnxt->output_bits == 32)
+ {
+ float *fptr = (float *) cnxt->sample_buffer;
+ long *sptr = (long *) cnxt->sample_buffer;
+ int cnt = tsamples;
+
+ while (cnt--)
+ {
+ if (*fptr >= 1.0)
+ *sptr++ = 8388607 << 8;
+ else if (*fptr <= -1.0)
+ *sptr++ = -8388608 << 8;
+ else
+ *sptr++ = ((int) floor (*fptr * 8388608.0)) << 8;
+
+ fptr++;
+ }
+ }
+ }
+
+ return samples;
+}
+
+extern "C" __declspec (dllexport) In_Module * winampGetInModule2()
+{
+ return &mod;
+}
+
+// This code provides an interface between the reader callback mechanism that
+// WavPack uses internally and the standard fstream C library.
+
+static int32_t read_bytes(void *id, void *data, int32_t bcount)
+{
+ FILE *file = id ? *(FILE**)id : NULL;
+
+ if (file)
+ return (int32_t) fread(data, 1, bcount, file);
+ else
+ return 0;
+}
+
+static uint32_t get_pos(void *id)
+{
+ FILE *file = id ? *(FILE**)id : NULL;
+
+ if (file)
+ return ftell(file);
+ else
+ return -1;
+}
+
+static int set_pos_abs(void *id, uint32_t pos)
+{
+ FILE *file = id ? *(FILE**)id : NULL;
+
+ if (file)
+ return fseek(file, pos, SEEK_SET);
+ else
+ return 0;
+}
+
+static int set_pos_rel(void *id, int32_t delta, int mode)
+{
+ FILE *file = id ? *(FILE**)id : NULL;
+
+ if (file)
+ return fseek(file, delta, mode);
+ else
+ return -1;
+}
+
+static int push_back_byte(void *id, int c)
+{
+ FILE *file = id ? *(FILE**)id : NULL;
+
+ if (file)
+ return ungetc(c, file);
+ else
+ return EOF;
+}
+
+static uint32_t get_length(void *id)
+{
+ FILE *file = id ? *(FILE**)id : NULL;
+ struct stat statbuf;
+
+ if (!file || fstat (fileno (file), &statbuf) || !(statbuf.st_mode & S_IFREG))
+ return 0;
+ else
+ return statbuf.st_size;
+}
+
+static int can_seek(void *id)
+{
+ FILE *file = id ? *(FILE**)id : NULL;
+ struct stat statbuf;
+
+ return file && !fstat (fileno (file), &statbuf) && (statbuf.st_mode & S_IFREG);
+}
+
+static int32_t write_bytes(void *id, void *data, int32_t bcount)
+{
+ FILE *file = id ? *(FILE**)id : NULL;
+
+ if (file)
+ return (int32_t) fwrite (data, 1, bcount, file);
+ else
+ return 0;
+}
+
+static WavpackStreamReader freader = {
+ read_bytes, get_pos, set_pos_abs,
+ set_pos_rel, push_back_byte,
+ get_length, can_seek, write_bytes
+};
+
+/* These functions provide UNICODE support for the winamp media library */
+
+static int metadata_we_can_write(const char *metadata);
+
+static void close_context(struct wpcnxt *cxt)
+{
+ if (cxt->wpc)
+ WavpackCloseFile(cxt->wpc);
+
+ if (cxt->wv_id)
+ fclose(cxt->wv_id);
+
+ if (cxt->wvc_id)
+ fclose(cxt->wvc_id);
+
+ memset(cxt, 0, sizeof (*cxt));
+}
+
+#ifdef ANSI_METADATA
+
+extern "C" __declspec (dllexport) int winampGetExtendedFileInfo(char *filename, char *metadata, char *ret, int retlen)
+{
+ int open_flags = OPEN_TAGS;
+ char error[128];
+ int retval = 0;
+
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "winampGetExtendedFileInfo (%s)\n", metadata);
+ debug_write (error);
+#endif
+
+ if (!_stricmp(metadata, "type"))
+ {
+ ret[0] = '0';
+ ret[1] = 0;
+ return 1;
+ }
+ else if (!_stricmp(metadata, "family"))
+ {
+ int len;
+ const char *p;
+ if (!filename || !filename[0]) return 0;
+ len = lstrlen(filename);
+ if (len < 3 || '.' != filename[len - 3]) return 0;
+ p = &filename[len - 2];
+ if (!_stricmp(p, "wv")) { WASABI_API_LNGSTRING_BUF(IDS_FAMILY_STRING, ret, retlen); return 1; }
+ return 0;
+ }
+
+ if (!filename || !*filename)
+ return retval;
+
+ if (!_stricmp(metadata, "length")) { /* even if no file, return a 1 and write "0" */
+ StringCchPrintf(ret, retlen, "%d", 0);
+ retval = 1;
+ }
+
+ if (!info.wpc || strcmp(filename, info.lastfn) || !_stricmp(metadata, "formatinformation"))
+ {
+ close_context(&info);
+
+ if (!(info.wv_id = fopen(filename, "rb")))
+ return retval;
+
+ if (config_bits & ALLOW_WVC)
+ {
+ int length = strlen(filename) + 10;
+ char *wvc_name = (char *)malloc(length);
+
+ if (wvc_name)
+ {
+ lstrcpyn(wvc_name, filename, length);
+ StringCchCat(wvc_name, length, "c");
+ info.wvc_id = fopen(wvc_name, "rb");
+ free(wvc_name);
+ }
+ }
+
+ info.wpc = WavpackOpenFileInputEx(&freader, &info.wv_id, info.wvc_id ? &info.wvc_id : NULL, error, open_flags, 0);
+
+ if (!info.wpc)
+ {
+ close_context(&info);
+ return retval;
+ }
+
+ lstrcpyn(info.lastfn, filename, MAX_PATH);
+ info.w_lastfn [0] = 0;
+ }
+
+ if (!_stricmp(metadata, "formatinformation"))
+ {
+ wchar_t *temp = (wchar_t *)malloc(retlen * sizeof(wchar_t));
+ generate_format_string(info.wpc, temp, retlen, 0);
+ lstrcpyn(ret, AutoChar(temp), retlen);
+ free(temp);
+ retval = 1;
+ }
+ else if (!_stricmp(metadata, "length"))
+ {
+ StringCchPrintf(ret, retlen, "%d", (int)(WavpackGetNumSamples(info.wpc) * 1000.0 / WavpackGetSampleRate(info.wpc)));
+ retval = 1;
+ }
+ else if (!_stricmp(metadata, "lossless"))
+ {
+ StringCchPrintf (ret, retlen, "%d", (WavpackGetMode(info.wpc) & MODE_LOSSLESS) ? 1 : 0);
+ retval = 1;
+ }
+ else if (!_stricmp(metadata, "numsamples"))
+ {
+ StringCchPrintf(ret, retlen, "%d", WavpackGetNumSamples(info.wpc));
+ retval = 1;
+ }
+ else if (!_stricmp(metadata, "mime"))
+ {
+ lstrcpyn(ret, L"audio/x-wavpack", retlen);
+ retval = 1;
+ }
+ else if (!_stricmp(metadata, "gain"))
+ {
+ StringCchPrintf(ret, retlen, "%-+.2f dB", calculate_gain(info.wpc, false));
+ retval = 1;
+ }
+ else if (WavpackGetTagItem(info.wpc, metadata, ret, retlen))
+ {
+ if (!_stricmp(metadata, "rating"))
+ {
+ int rating = atoi(ret);
+ // appears to be generally 0-5 or 0-100
+ if (rating > 10) {
+ rating /= 20;
+ }
+ // or maybe we're dealing with a 1-10 range
+ else if (rating > 5) {
+ rating /= 2;
+ }
+ // otherwise it is hopefully in the 0-5 range
+
+ StringCchPrintf(ret, retlen, "%u", rating);
+ }
+ else
+ {
+ if (WavpackGetMode(info.wpc) & MODE_APETAG)
+ {
+ UTF8ToAnsi(ret, retlen);
+ }
+ }
+
+ retval = 1;
+ }
+ else if (metadata_we_can_write(metadata))
+ {
+ if (retlen)
+ *ret = 0;
+
+ retval = 1;
+ }
+
+ // This is a little ugly, but since the WavPack library has read the tags off the
+ // files, we can close the files (but not the WavPack context) now so that we don't
+ // leave handles open. We may access the file again for the "formatinformation"
+ // field, so we reopen the file if we get that one.
+
+ if (info.wv_id)
+ {
+ fclose(info.wv_id);
+ info.wv_id = NULL;
+ }
+
+ if (info.wvc_id)
+ {
+ fclose(info.wvc_id);
+ info.wvc_id = NULL;
+ }
+
+ return retval;
+}
+
+#endif
+
+#ifdef UNICODE_METADATA
+
+extern "C" __declspec (dllexport) int winampGetExtendedFileInfoW (wchar_t *filename, char *metadata, wchar_t *ret, int retlen)
+{
+ char error[128], res[256];
+ int open_flags = OPEN_TAGS;
+ int retval = 0;
+
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "winampGetExtendedFileInfoW (%s)\n", metadata);
+ debug_write (error);
+#endif
+
+ if (!_stricmp(metadata, "type"))
+ {
+ ret[0] = '0';
+ ret[1] = 0;
+ return 1;
+ }
+ else if (!_stricmp(metadata, "family"))
+ {
+ int len;
+ const wchar_t *p;
+ if (!filename || !filename[0]) return 0;
+ len = lstrlenW(filename);
+ if (len < 3 || L'.' != filename[len - 3]) return 0;
+ p = &filename[len - 2];
+ if (!_wcsicmp(p, L"wv")) { WASABI_API_LNGSTRINGW_BUF(IDS_FAMILY_STRING, ret, retlen); return 1; }
+ return 0;
+ }
+
+ if (!filename || !*filename)
+ return retval;
+
+ if (!_stricmp(metadata, "length")) /* even if no file, return a 1 and write "0" */
+ {
+ StringCchPrintfW(ret, retlen, L"%d", 0);
+ retval = 1;
+ }
+
+ if (!info.wpc || wcscmp(filename, info.w_lastfn) || !_stricmp(metadata, "formatinformation"))
+ {
+ close_context(&info);
+
+ if (!(info.wv_id = _wfopen(filename, L"rb")))
+ return retval;
+
+ if (config_bits & ALLOW_WVC) {
+ int length = wcslen(filename) + 10;
+ wchar_t *wvc_name = (wchar_t *)malloc(length * sizeof(wchar_t));
+
+ if (wvc_name) {
+ lstrcpynW(wvc_name, filename, length);
+ StringCchCatW(wvc_name, length, L"c");
+ info.wvc_id = _wfopen(wvc_name, L"rb");
+ free(wvc_name);
+ }
+ }
+
+ info.wpc = WavpackOpenFileInputEx(&freader, &info.wv_id, info.wvc_id ? &info.wvc_id : NULL, error, open_flags, 0);
+
+ if (!info.wpc)
+ {
+ close_context(&info);
+ return retval;
+ }
+
+ lstrcpynW(info.w_lastfn, filename, MAX_PATH);
+ info.lastfn[0] = 0;
+ }
+
+ if (!_stricmp(metadata, "formatinformation"))
+ {
+ generate_format_string(info.wpc, ret, retlen, 0);
+ retval = 1;
+ }
+ else if (!_stricmp (metadata, "length"))
+ {
+ StringCchPrintfW(ret, retlen, L"%d", (int)(WavpackGetNumSamples(info.wpc) * 1000.0 / WavpackGetSampleRate(info.wpc)));
+ retval = 1;
+ }
+ else if (!_stricmp(metadata, "lossless"))
+ {
+ StringCchPrintfW(ret, retlen, L"%d", (WavpackGetMode(info.wpc) & MODE_LOSSLESS) ? 1 : 0);
+ retval = 1;
+ }
+ else if (!_stricmp(metadata, "gain"))
+ {
+ StringCchPrintfW(ret, retlen, L"%-+.2f dB", calculate_gain(info.wpc, false));
+ retval = 1;
+ }
+ else if (!_stricmp(metadata, "numsamples"))
+ {
+ StringCchPrintfW(ret, retlen, L"%d", WavpackGetNumSamples(info.wpc));
+ retval = 1;
+ }
+ else if (!_stricmp(metadata, "mime"))
+ {
+ lstrcpynW(ret, L"audio/x-wavpack", retlen);
+ retval = 1;
+ }
+ else if (WavpackGetTagItem(info.wpc, metadata, res, sizeof (res)))
+ {
+ if (!_stricmp(metadata, "rating"))
+ {
+ int rating = atoi(res);
+ // appears to be generally 0-5 or 0-100
+ if (rating > 10) {
+ rating /= 20;
+ }
+ // or maybe we're dealing with a 1-10 range
+ else if (rating > 5) {
+ rating /= 2;
+ }
+ // otherwise it is hopefully in the 0-5 range
+
+ StringCchPrintfW(ret, retlen, L"%u", rating);
+ }
+ else
+ {
+ if (!(WavpackGetMode(info.wpc) & MODE_APETAG))
+ lstrcpynW(ret, AutoWide(res), retlen);
+ else
+ lstrcpynW(ret, AutoWide(res, CP_UTF8), retlen);
+ }
+
+ retval = 1;
+ }
+ else if (metadata_we_can_write (metadata))
+ {
+ if (retlen)
+ *ret = 0;
+
+ retval = 1;
+ }
+
+ // This is a little ugly, but since the WavPack library has read the tags off the
+ // files, we can close the files (but not the WavPack context) now so that we don't
+ // leave handles open. We may access the file again for the "formatinformation"
+ // field, so we reopen the file if we get that one.
+
+ if (info.wv_id)
+ {
+ fclose (info.wv_id);
+ info.wv_id = NULL;
+ }
+
+ if (info.wvc_id)
+ {
+ fclose (info.wvc_id);
+ info.wvc_id = NULL;
+ }
+
+ return retval;
+}
+
+#endif
+
+#ifdef ANSI_METADATA
+
+extern "C" int __declspec (dllexport) winampSetExtendedFileInfo(const char *filename, const char *metadata, char *val)
+{
+ char error[128];
+
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "winampSetExtendedFileInfo (%s=%s)\n", metadata, val);
+ debug_write (error);
+#endif
+
+ if (!filename || !*filename || !metadata_we_can_write(metadata))
+ return 0;
+
+ if (!edit.wpc || strcmp(filename, edit.lastfn))
+ {
+ if (edit.wpc)
+ WavpackCloseFile(edit.wpc);
+
+ edit.wpc = WavpackOpenFileInput(filename, error, OPEN_TAGS | OPEN_EDIT_TAGS, 0);
+
+ if (!edit.wpc)
+ return 0;
+
+ lstrcpyn(edit.lastfn, filename, MAX_PATH);
+ edit.w_lastfn [0] = 0;
+ }
+
+ if (strlen(val))
+ return WavpackAppendTagItem(edit.wpc, metadata, val, strlen (val));
+ else
+ return WavpackDeleteTagItem(edit.wpc, metadata);
+}
+
+#endif
+
+#ifdef UNICODE_METADATA
+
+extern "C" int __declspec (dllexport) winampSetExtendedFileInfoW(const wchar_t *filename, const char *metadata, wchar_t *val)
+{
+ char error[128], utf8_val[256];
+
+ lstrcpyn(utf8_val,AutoChar(val, CP_UTF8),sizeof(utf8_val) - 1);
+
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "winampSetExtendedFileInfoW (%s=%s)\n", metadata, utf8_val);
+ debug_write (error);
+#endif
+
+ if (!filename || !*filename || !metadata_we_can_write(metadata))
+ return 0;
+
+ if (!edit.wpc || wcscmp(filename, edit.w_lastfn))
+ {
+ if (edit.wpc)
+ {
+ WavpackCloseFile(edit.wpc);
+ edit.wpc = NULL;
+ }
+
+ if (edit.wv_id)
+ fclose(edit.wv_id);
+
+ if (!(edit.wv_id = _wfopen(filename, L"r+b")))
+ return 0;
+
+ edit.wpc = WavpackOpenFileInputEx(&freader, &edit.wv_id, NULL, error, OPEN_TAGS | OPEN_EDIT_TAGS, 0);
+
+ if (!edit.wpc)
+ {
+ fclose(edit.wv_id);
+ return 0;
+ }
+
+ lstrcpynW(edit.w_lastfn, filename, MAX_PATH);
+ edit.lastfn [0] = 0;
+ }
+
+ if (strlen(utf8_val))
+ return WavpackAppendTagItem(edit.wpc, metadata, utf8_val, strlen (utf8_val));
+ else
+ return WavpackDeleteTagItem(edit.wpc, metadata);
+}
+
+#endif
+
+extern "C" int __declspec (dllexport) winampWriteExtendedFileInfo(void)
+{
+#ifdef DEBUG_CONSOLE
+ debug_write ("winampWriteExtendedFileInfo ()\n");
+#endif
+
+ if (edit.wpc)
+ {
+ WavpackWriteTag(edit.wpc);
+ WavpackCloseFile(edit.wpc);
+ edit.wpc = NULL;
+ }
+
+ if (edit.wv_id)
+ {
+ fclose(edit.wv_id);
+ edit.wv_id = NULL;
+ }
+
+ close_context(&info); // make sure we re-read info on any open files
+ return 1;
+}
+
+// return 1 if you want winamp to show it's own file info dialogue, 0 if you want to show your own (via In_Module.InfoBox)
+// if returning 1, remember to implement winampGetExtendedFileInfo("formatinformation")!
+extern "C" __declspec(dllexport) int winampUseUnifiedFileInfoDlg(const wchar_t * fn)
+{
+ return 1;
+}
+
+static const char *writable_metadata [] = {
+ "track", "genre", "year", "comment", "artist",
+ "album", "title", "albumartist", "composer",
+ "publisher", "disc", "tool", "encoder", "bpm",
+ "category", "rating",
+ "replaygain_track_gain", "replaygain_track_peak",
+ "replaygain_album_gain", "replaygain_album_peak"
+};
+
+#define NUM_KNOWN_METADATA (sizeof (writable_metadata) / sizeof (writable_metadata [0]))
+
+static int metadata_we_can_write(const char *metadata)
+{
+ if (!metadata || !*metadata)
+ return 0;
+
+ for (int i = 0; i < NUM_KNOWN_METADATA; ++i)
+ if (!_stricmp(metadata, writable_metadata[i]))
+ return 1;
+
+ return 0;
+}
+
+static void generate_format_string(WavpackContext *wpc, wchar_t *string, int maxlen, int wide)
+{
+ int mode = WavpackGetMode(wpc);
+ unsigned char md5_sum[16];
+ wchar_t modes[256];
+ wchar_t fmt[256];
+
+ WASABI_API_LNGSTRINGW_BUF(IDS_ENCODER_VERSION, fmt, sizeof(fmt));
+ StringCchPrintfW(string, maxlen, fmt, WavpackGetVersion(wpc));
+ while (*string && string++ && maxlen--);
+
+ WASABI_API_LNGSTRINGW_BUF(IDS_SOURCE, fmt, sizeof (fmt));
+ StringCchPrintfW(string, maxlen, fmt, WavpackGetBitsPerSample(wpc),
+ WASABI_API_LNGSTRINGW((WavpackGetMode(wpc) & MODE_FLOAT) ? IDS_FLOATS : IDS_INTS),
+ WavpackGetSampleRate(wpc));
+ while (*string && string++ && maxlen--);
+
+ if (WavpackGetNumChannels(wpc) > 2)
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_MULTICHANNEL, fmt, sizeof (fmt));
+ StringCchPrintfW(string, maxlen, fmt, WavpackGetNumChannels(wpc));
+ while (*string && string++ && maxlen--);
+ }
+ else if (WavpackGetNumChannels(wpc) == 2)
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_STEREO, fmt, sizeof (fmt));
+ StringCchPrintfW(string, maxlen, fmt);
+ while (*string && string++ && maxlen--);
+ }
+ else
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_MONO, fmt, sizeof (fmt));
+ StringCchPrintfW(string, maxlen, fmt);
+ while (*string && string++ && maxlen--);
+ }
+
+ modes [0] = 0;
+
+ if (WavpackGetMode(wpc) & MODE_HYBRID)
+ {
+ StringCchCatW(modes, 256, WASABI_API_LNGSTRINGW(IDS_HYBRID));
+ StringCchCatW(modes, 256, L" ");
+ }
+
+ StringCchCatW(modes, 256, WASABI_API_LNGSTRINGW((WavpackGetMode(wpc) & MODE_LOSSLESS) ? IDS_LOSSLESS : IDS_LOSSY));
+
+ if (WavpackGetMode(wpc) & MODE_FAST)
+ StringCchCatW(modes, 256, WASABI_API_LNGSTRINGW(IDS_FAST));
+ else if (WavpackGetMode(wpc) & MODE_VERY_HIGH)
+ StringCchCatW(modes, 256, WASABI_API_LNGSTRINGW(IDS_VHIGH));
+ else if (WavpackGetMode(wpc) & MODE_HIGH)
+ StringCchCatW(modes, 256, WASABI_API_LNGSTRINGW(IDS_HIGH));
+
+ if (WavpackGetMode(wpc) & MODE_EXTRA)
+ StringCchCatW(modes, 256, WASABI_API_LNGSTRINGW(IDS_EXTRA));
+
+ StringCchPrintfW(string, maxlen, L"%s:%s %s\n",
+ WASABI_API_LNGSTRINGW(IDS_MODES),
+ (wide || lstrlenW(modes) < 24) ? L"" : L"\n", modes);
+ while (*string && string++ && maxlen--);
+
+ if (WavpackGetRatio(wpc) != 0.0)
+ {
+ wchar_t str_kbps[32];
+ StringCchPrintfW(string, maxlen, L"%s: %d %s \n",
+ WASABI_API_LNGSTRINGW(IDS_BITRATE),
+ (int)((WavpackGetAverageBitrate(wpc, TRUE) + 500.0) / 1000.0),
+ WASABI_API_LNGSTRINGW_BUF(IDS_KBPS, str_kbps, sizeof(str_kbps)));
+ while (*string && string++ && maxlen--);
+ StringCchPrintfW(string, maxlen, L"%s: %.2f : 1 \n",
+ WASABI_API_LNGSTRINGW(IDS_RATIO), 1.0 / WavpackGetRatio(wpc));
+ while (*string && string++ && maxlen--);
+ }
+
+ if (WavpackGetMD5Sum(wpc, md5_sum))
+ {
+ wchar_t md5s1 [17], md5s2 [17];
+ int i;
+
+ for (i = 0; i < 8; ++i)
+ {
+ StringCchPrintfW(md5s1 + i * 2, sizeof(md5s1), L"%02x", md5_sum [i]);
+ StringCchPrintfW(md5s2 + i * 2, sizeof(md5s2), L"%02x", md5_sum [i+8]);
+ }
+
+ StringCchPrintfW(string, maxlen, (wide ? L"%s: %s%s\n" : L"%s:\n %s\n %s\n"),
+ WASABI_API_LNGSTRINGW(IDS_MD5), md5s1, md5s2);
+ }
+}
+
+///////////////////// native "C" functions required for AlbumArt support ///////////////////////////
+
+#ifdef DEBUG_CONSOLE
+
+static char temp_buff [256];
+
+static char *wide2char (const wchar_t *src)
+{
+ char *dst = temp_buff;
+
+ while (*src)
+ *dst++ = (char) *src++;
+
+ *dst = 0;
+ return temp_buff;
+}
+
+#endif
+
+int WavPack_HandlesExtension(const wchar_t *extension)
+{
+ return !_wcsicmp(extension, L"wv");
+}
+
+int WavPack_GetAlbumArt(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mime_type)
+{
+ char *buffer;
+ char error[128];
+ int tag_size, i;
+ int retval = 1;
+
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "WavPack_GetAlbumArt (%s)\n", wide2char (type));
+ debug_write (error);
+#endif
+
+ if (!filename || !*filename || _wcsicmp(type, L"cover"))
+ return retval;
+
+ if (!info.wpc || wcscmp(filename, info.w_lastfn))
+ {
+ close_context(&info);
+
+ if (!(info.wv_id = _wfopen(filename, L"rb")))
+ return retval;
+
+ if (config_bits & ALLOW_WVC)
+ {
+ int length = wcslen(filename) + 10;
+ wchar_t *wvc_name = (wchar_t *)malloc(length * sizeof(wchar_t));
+
+ if (wvc_name)
+ {
+ lstrcpynW(wvc_name, filename, length);
+ StringCchCatW(wvc_name, length, L"c");
+ info.wvc_id = _wfopen(wvc_name, L"rb");
+ free(wvc_name);
+ }
+ }
+
+ info.wpc = WavpackOpenFileInputEx(&freader, &info.wv_id, info.wvc_id ? &info.wvc_id : NULL, error, OPEN_TAGS, 0);
+
+ if (!info.wpc)
+ {
+ close_context(&info);
+ return retval;
+ }
+
+ lstrcpynW(info.w_lastfn, filename, MAX_PATH);
+ info.lastfn[0] = 0;
+ }
+
+ tag_size = WavpackGetBinaryTagItem(info.wpc, "Cover Art (Front)", NULL, 0);
+
+ if (!tag_size)
+ return retval;
+
+ buffer = (char*)WASABI_API_MEMMGR->sysMalloc(tag_size);
+ WavpackGetBinaryTagItem(info.wpc, "Cover Art (Front)", buffer, tag_size);
+
+ for (i = 0; i < tag_size - 1; ++i)
+ if (!buffer[i] && strrchr(buffer, '.')) {
+ char *ext = strrchr(buffer, '.') + 1;
+ wchar_t *wcptr;
+
+ wcptr = *mime_type = (wchar_t*)WASABI_API_MEMMGR->sysMalloc(strlen(ext) * 2 + 2);
+
+ while (*ext)
+ *wcptr++ = *ext++;
+
+ *wcptr = 0;
+ *bits = buffer;
+ *len = tag_size - i - 1;
+ memmove(buffer, buffer + i + 1, *len);
+ retval = 0;
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "WavPack_GetAlbumArt (\"%s\", %d) success!\n", wide2char (*mime_type), *len);
+ debug_write (error);
+#endif
+ }
+
+ if (retval)
+ WASABI_API_MEMMGR->sysFree(buffer);
+
+ // This is a little ugly, but since the WavPack library has read the tags off the
+ // files, we can close the files (but not the WavPack context) now so that we don't
+ // leave handles open. We may access the file again for the "formatinformation"
+ // field, so we reopen the file if we get that one.
+
+ if (info.wv_id)
+ {
+ fclose(info.wv_id);
+ info.wv_id = NULL;
+ }
+
+ if (info.wvc_id)
+ {
+ fclose(info.wvc_id);
+ info.wvc_id = NULL;
+ }
+
+ return retval;
+}
+
+int WavPack_SetAlbumArt(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mime_type)
+{
+#if 1
+ return 2; // return 2 to indicate "read-only" cover art for now
+#else
+ char error [128], name [50], *cp;
+ int tag_size, retval = 0;
+ unsigned char *buffer;
+
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "WavPack_SetAlbumArt (%s)\n", wide2char (mime_type));
+ debug_write (error);
+#endif
+
+ if (!filename || !*filename || _wcsicmp (type, L"cover") || wcslen (mime_type) > 16)
+ return 1;
+
+ strcpy (name, "Cover Art (Front)");
+ cp = name + strlen (name);
+ *cp++ = '.';
+
+ while (*mime_type)
+ *cp++ = (char) *mime_type++;
+
+ *cp = 0;
+ tag_size = strlen (name) + 1 + len;
+ buffer = malloc (tag_size);
+ strcpy (buffer, name);
+ memcpy (buffer + strlen (buffer) + 1, bits, len);
+
+ if (!edit.wpc || wcscmp (filename, edit.w_lastfn)) {
+ if (edit.wpc) {
+ WavpackCloseFile (edit.wpc);
+ edit.wpc = NULL;
+ }
+
+ if (edit.wv_id)
+ fclose (edit.wv_id);
+
+ if (!(edit.wv_id = _wfopen (filename, L"r+b"))) {
+ free (buffer);
+ return 1;
+ }
+
+ edit.wpc = WavpackOpenFileInputEx (&freader, &edit.wv_id, NULL, error, OPEN_TAGS | OPEN_EDIT_TAGS, 0);
+
+ if (!edit.wpc) {
+ fclose (edit.wv_id);
+ free (buffer);
+ return 1;
+ }
+
+ wcscpy (edit.w_lastfn, filename);
+ edit.lastfn [0] = 0;
+ }
+
+ retval = WavpackAppendTagItem (edit.wpc, "Cover Art (Front)", buffer, tag_size);
+ free (buffer);
+
+ if (retval) {
+ winampWriteExtendedFileInfo ();
+ return 0;
+ }
+ else {
+ close_context (&edit);
+ return 1;
+ }
+#endif
+}
+
+int WavPack_DeleteAlbumArt(const wchar_t *filename, const wchar_t *type)
+{
+#if 1
+ return 2; // return 2 to indicate "read-only" cover art for now
+#else
+ char error [128];
+
+#ifdef DEBUG_CONSOLE
+ sprintf (error, "WavPack_DeleteAlbumArt ()\n");
+ debug_write (error);
+#endif
+
+ if (!filename || !*filename || _wcsicmp (type, L"cover"))
+ return 0;
+
+ if (!edit.wpc || wcscmp (filename, edit.w_lastfn)) {
+ if (edit.wpc) {
+ WavpackCloseFile (edit.wpc);
+ edit.wpc = NULL;
+ }
+
+ if (edit.wv_id)
+ fclose (edit.wv_id);
+
+ if (!(edit.wv_id = _wfopen (filename, L"r+b")))
+ return 1;
+
+ edit.wpc = WavpackOpenFileInputEx (&freader, &edit.wv_id, NULL, error, OPEN_TAGS | OPEN_EDIT_TAGS, 0);
+
+ if (!edit.wpc) {
+ fclose (edit.wv_id);
+ return 1;
+ }
+
+ wcscpy (edit.w_lastfn, filename);
+ edit.lastfn [0] = 0;
+ }
+
+ if (WavpackDeleteTagItem (edit.wpc, "Cover Art (Front)")) {
+ winampWriteExtendedFileInfo ();
+ return 0;
+ }
+ else {
+ close_context (&edit);
+ return 1;
+ }
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// This function uses the ReplayGain mode selected by the user and the info //
+// stored in the specified tag to determine the gain value used to play the //
+// file and whether "soft clipping" is required. Note that the gain is in //
+// voltage scaling (not dB), so a value of 1.0 (not 0.0) is unity gain. //
+//////////////////////////////////////////////////////////////////////////////
+
+static float calculate_gain(WavpackContext *wpc, bool allowDefault)
+{
+ if (AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain", false))
+ {
+ float dB = 0, peak = 1.0f;
+ char gain[128] = "", peakVal[128] = "";
+ _locale_t C_locale = WASABI_API_LNG->Get_C_NumericLocale();
+
+ switch (AGAVE_API_CONFIG->GetUnsigned(playbackConfigGroupGUID, L"replaygain_source", 0))
+ {
+ case 0: // track
+ if ((!WavpackGetTagItem(wpc, "replaygain_track_gain", gain, sizeof(gain)) || !gain[0])
+ && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
+ WavpackGetTagItem(wpc, "replaygain_album_gain", gain, sizeof(gain));
+
+ if ((!WavpackGetTagItem(wpc, "replaygain_track_peak", peakVal, sizeof(peakVal)) || !peakVal[0])
+ && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
+ WavpackGetTagItem(wpc, "replaygain_album_peak", peakVal, sizeof(peakVal));
+ break;
+ case 1:
+ if ((!WavpackGetTagItem(wpc, "replaygain_album_gain", gain, sizeof(gain)) || !gain[0])
+ && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
+ WavpackGetTagItem(wpc, "replaygain_track_gain", gain, sizeof(gain));
+
+ if ((!WavpackGetTagItem(wpc, "replaygain_album_peak", peakVal, sizeof(peakVal)) || !peakVal[0])
+ && !AGAVE_API_CONFIG->GetBool(playbackConfigGroupGUID, L"replaygain_preferred_only", false))
+ WavpackGetTagItem(wpc, "replaygain_track_peak", peakVal, sizeof(peakVal));
+ break;
+ }
+
+ if (gain[0])
+ {
+ if (gain[0] == L'+')
+ dB = (float)_atof_l(&gain[1],C_locale);
+ else
+ dB = (float)_atof_l(gain,C_locale);
+ }
+ else if (allowDefault)
+ {
+ dB = AGAVE_API_CONFIG->GetFloat(playbackConfigGroupGUID, L"non_replaygain", -6.0);
+ return powf(10.0f, dB / 20.0f);
+ }
+
+ if (peakVal[0])
+ {
+ peak = (float)_atof_l(peakVal,C_locale);
+ }
+
+ switch (AGAVE_API_CONFIG->GetUnsigned(playbackConfigGroupGUID, L"replaygain_mode", 1))
+ {
+ case 0: // apply gain
+ return powf(10.0f, dB / 20.0f);
+ case 1: // apply gain, but don't clip
+ return min(powf(10.0f, dB / 20.0f), 1.0f / peak);
+ case 2: // normalize
+ return 1.0f / peak;
+ case 3: // prevent clipping
+ if (peak > 1.0f)
+ return 1.0f / peak;
+ else
+ return 1.0f;
+ }
+ }
+
+ return 1.0f; // no gain
+}
+
+// Convert a Ansi string into its Unicode UTF-8 format equivalent. The
+// conversion is done in-place so the maximum length of the string buffer must
+// be specified because the string may become longer or shorter. If the
+// resulting string will not fit in the specified buffer size then it is
+// truncated.
+#ifdef OLD_INFO_DIALOG
+static void AnsiToUTF8(char *string, int len)
+{
+ int max_chars = (int) strlen(string);
+ wchar_t *temp = (wchar_t *) malloc((max_chars + 1) * 2);
+
+ MultiByteToWideChar(CP_ACP, 0, string, -1, temp, max_chars + 1);
+ lstrcpyn(string, AutoChar(temp, CP_UTF8), len);
+ free(temp);
+}
+#endif
+
+// Convert Unicode UTF-8 string to wide format. UTF-8 string must be NULL
+// terminated. Resulting wide string must be able to fit in provided space
+// and will also be NULL terminated. The number of characters converted will
+// be returned (not counting terminator).
+
+static int UTF8ToWideChar(const char *pUTF8, wchar_t *pWide)
+{
+ int trail_bytes = 0;
+ int chrcnt = 0;
+
+ while (*pUTF8)
+ {
+ if (*pUTF8 & 0x80)
+ {
+ if (*pUTF8 & 0x40)
+ {
+ if (trail_bytes)
+ {
+ trail_bytes = 0;
+ chrcnt++;
+ }
+ else
+ {
+ char temp = *pUTF8;
+
+ while (temp & 0x80)
+ {
+ trail_bytes++;
+ temp <<= 1;
+ }
+
+ pWide [chrcnt] = temp >> trail_bytes--;
+ }
+ }
+ else if (trail_bytes)
+ {
+ pWide [chrcnt] = (pWide [chrcnt] << 6) | (*pUTF8 & 0x3f);
+
+ if (!--trail_bytes)
+ chrcnt++;
+ }
+ }
+ else
+ pWide [chrcnt++] = *pUTF8;
+
+ pUTF8++;
+ }
+
+ pWide [chrcnt] = 0;
+ return chrcnt;
+}
+
+// Convert a Unicode UTF-8 format string into its Ansi equivalent. The
+// conversion is done in-place so the maximum length of the string buffer must
+// be specified because the string may become longer or shorter. If the
+// resulting string will not fit in the specified buffer size then it is
+// truncated.
+
+static void UTF8ToAnsi(char *string, int len)
+{
+ int max_chars = (int)strlen(string);
+ wchar_t *temp = (wchar_t *)malloc((max_chars + 1) * 2);
+ int act_chars = UTF8ToWideChar(string, temp);
+
+ while (act_chars)
+ {
+ memset (string, 0, len);
+
+ if (WideCharToMultiByte(CP_ACP, 0, temp, act_chars, string, len - 1, NULL, NULL))
+ break;
+ else
+ act_chars--;
+ }
+
+ if (!act_chars)
+ *string = 0;
+
+ free (temp);
+}
+
+extern "C" __declspec(dllexport) int winampUninstallPlugin(HINSTANCE hDllInst, HWND hwndDlg, int param)
+{
+ // as we're not hooking anything and have no settings we can support an on-the-fly uninstall action
+ return IN_PLUGIN_UNINSTALL_NOW;
+} \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/resource.h b/Src/Plugins/Input/in_wv/resource.h
new file mode 100644
index 00000000..dfeadd62
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/resource.h
@@ -0,0 +1,49 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by wavpack.rc
+//
+#define IDS_DISABLED 106
+#define IDS_USE_TRACK 107
+#define IDS_USE_ALBUM 108
+#define IDS_JUST_CLIP 109
+#define IDS_SOFT_CLIP 110
+#define IDS_PREVENT_CLIP 111
+#define IDS_ABOUT 112
+#define IDS_FORMAT 113
+#define IDS_ENCODER_VERSION 114
+#define IDS_SOURCE 115
+#define IDS_MULTICHANNEL 116
+#define IDS_MONO 117
+#define IDS_STEREO 118
+#define IDS_HYBRID 119
+#define IDS_LOSSLESS 120
+#define IDS_LOSSY 121
+#define IDS_INTS 122
+#define IDS_FLOATS 123
+#define IDS_MODES 124
+#define IDS_FAST 125
+#define IDS_HIGH 126
+#define IDS_VHIGH 127
+#define IDS_EXTRA 128
+#define IDS_BITRATE 129
+#define IDS_RATIO 130
+#define IDS_KBPS 131
+#define IDS_MD5 132
+#define IDS_DESCRIPTION 133
+#define IDS_STRING134 134
+#define IDS_FILETYPE 134
+#define IDS_ABOUT_MESSAGE 135
+#define IDS_FAMILY_STRING 136
+#define IDS_GUID 65535
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 136
+#define _APS_NEXT_COMMAND_VALUE 40002
+#define _APS_NEXT_CONTROL_VALUE 1027
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/Agave/AlbumArt/svc_albumArtProvider.h b/Src/Plugins/Input/in_wv/wasabi/Agave/AlbumArt/svc_albumArtProvider.h
new file mode 100644
index 00000000..563b7689
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Agave/AlbumArt/svc_albumArtProvider.h
@@ -0,0 +1,73 @@
+#ifndef NULLSOFT_AGAVE_SVC_ALBUMARTPROVIDER_H
+#define NULLSOFT_AGAVE_SVC_ALBUMARTPROVIDER_H
+
+#include "../../bfc/dispatch.h"
+#include "../../bfc/std_mkncc.h" // for MKnCC()
+
+enum
+{
+ ALBUMARTPROVIDER_SUCCESS = 0,
+ ALBUMARTPROVIDER_FAILURE = 1,
+ ALBUMARTPROVIDER_READONLY = 2,
+
+ ALBUMARTPROVIDER_TYPE_EMBEDDED = 0, // contained within another file (e.g. inside id3v2 tag)
+ ALBUMARTPROVIDER_TYPE_DATABASE = 1, // cached in a database somewhere (e.g. ipod artwork DB)
+ ALBUMARTPROVIDER_TYPE_FOLDER = 2, // sitting on a folder somewhere (e.g. folder.jpg)
+};
+class svc_albumArtProvider : public Dispatchable
+{
+protected:
+ svc_albumArtProvider() {}
+ ~svc_albumArtProvider() {}
+public:
+
+ static FOURCC getServiceType() { return svc_albumArtProvider::SERVICETYPE; }
+ bool IsMine(const wchar_t *filename);
+ int ProviderType();
+ // implementation note: use WASABI_API_MEMMGR to alloc bits and mimetype, so that the recipient can free through that
+ int GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mimeType);
+ int SetAlbumArtData(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mimeType);
+ int DeleteAlbumArt(const wchar_t *filename, const wchar_t *type);
+
+ DISPATCH_CODES
+ {
+ SVC_ALBUMARTPROVIDER_PROVIDERTYPE = 0,
+ SVC_ALBUMARTPROVIDER_GETALBUMARTDATA = 10,
+ SVC_ALBUMARTPROVIDER_ISMINE = 20,
+ SVC_ALBUMARTPROVIDER_SETALBUMARTDATA = 30,
+ SVC_ALBUMARTPROVIDER_DELETEALBUMART = 40,
+ };
+
+ enum
+ {
+ SERVICETYPE = MK3CC('a','a','p')
+ };
+
+};
+
+inline bool svc_albumArtProvider::IsMine(const wchar_t *filename)
+{
+ return _call(SVC_ALBUMARTPROVIDER_ISMINE, false, filename);
+}
+
+inline int svc_albumArtProvider::ProviderType()
+{
+ return _call(SVC_ALBUMARTPROVIDER_PROVIDERTYPE, (int)ALBUMARTPROVIDER_TYPE_EMBEDDED);
+}
+
+inline int svc_albumArtProvider::GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mimeType)
+{
+ return _call(SVC_ALBUMARTPROVIDER_GETALBUMARTDATA, (int)ALBUMARTPROVIDER_FAILURE, filename, type, bits, len, mimeType);
+}
+
+inline int svc_albumArtProvider::SetAlbumArtData(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mimeType)
+{
+ return _call(SVC_ALBUMARTPROVIDER_SETALBUMARTDATA, (int)ALBUMARTPROVIDER_FAILURE, filename, type, bits, len, mimeType);
+}
+
+inline int svc_albumArtProvider::DeleteAlbumArt(const wchar_t *filename, const wchar_t *type)
+{
+ return _call(SVC_ALBUMARTPROVIDER_DELETEALBUMART, (int)ALBUMARTPROVIDER_FAILURE, filename, type);
+}
+
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/Agave/Config/api_config.h b/Src/Plugins/Input/in_wv/wasabi/Agave/Config/api_config.h
new file mode 100644
index 00000000..934671ae
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Agave/Config/api_config.h
@@ -0,0 +1,123 @@
+#ifndef NULLSOFT_AGAVE_API_CONFIG_H
+#define NULLSOFT_AGAVE_API_CONFIG_H
+
+#include "../../bfc/dispatch.h"
+#include "ifc_configgroup.h"
+
+enum
+{
+ CONFIG_SUCCESS = 0,
+ CONFIG_FAILURE = 1,
+ CONFIG_GROUPNOTFOUND = 2,
+ CONFIG_ITEMNOTFOUND = 3,
+};
+
+class api_config : public Dispatchable
+{
+protected:
+ api_config() {}
+ ~api_config() {}
+public:
+ ifc_configgroup *GetGroup(GUID groupGUID);
+ void RegisterGroup(ifc_configgroup *newGroup);
+
+ /* Shortcut methods */
+ bool GetBool(GUID groupGUID, const wchar_t *configItem, bool defaultValue);
+ uintptr_t GetUnsigned(GUID groupGUID, const wchar_t *configItem, uintptr_t defaultValue);
+ intptr_t GetInt(GUID groupGUID, const wchar_t *configItem, intptr_t defaultValue);
+ float GetFloat(GUID groupGUID, const wchar_t *configItem, float defaultValue);
+ const wchar_t *GetString(GUID groupGUID, const wchar_t *configItem, const wchar_t *defaultValue);
+ ifc_configitem *GetItem(GUID groupGUID, const wchar_t *configItem);
+public:
+ DISPATCH_CODES
+ {
+ API_CONFIG_GETGROUP = 10,
+ API_CONFIG_REGISTERGROUP = 20,
+ };
+};
+
+inline ifc_configgroup *api_config::GetGroup(GUID groupGUID)
+{
+ return _call(API_CONFIG_GETGROUP, (ifc_configgroup *)0, groupGUID);
+}
+
+inline void api_config::RegisterGroup(ifc_configgroup *newGroup)
+{
+ _voidcall(API_CONFIG_REGISTERGROUP, newGroup);
+}
+
+inline bool api_config::GetBool(GUID groupGUID, const wchar_t *configItem, bool defaultValue)
+{
+ ifc_configgroup *group = GetGroup(groupGUID);
+ if (group)
+ {
+ ifc_configitem *item = group->GetItem(configItem);
+ if (item)
+ return item->GetBool();
+ }
+ return defaultValue;
+}
+
+inline uintptr_t api_config::GetUnsigned(GUID groupGUID, const wchar_t *configItem, uintptr_t defaultValue)
+{
+ ifc_configgroup *group = GetGroup(groupGUID);
+ if (group)
+ {
+ ifc_configitem *item = group->GetItem(configItem);
+ if (item)
+ return item->GetUnsigned();
+ }
+ return defaultValue;
+}
+
+inline intptr_t api_config::GetInt(GUID groupGUID, const wchar_t *configItem, intptr_t defaultValue)
+{
+ ifc_configgroup *group = GetGroup(groupGUID);
+ if (group)
+ {
+ ifc_configitem *item = group->GetItem(configItem);
+ if (item)
+ return item->GetInt();
+ }
+ return defaultValue;
+}
+
+inline float api_config::GetFloat(GUID groupGUID, const wchar_t *configItem, float defaultValue)
+{
+ ifc_configgroup *group = GetGroup(groupGUID);
+ if (group)
+ {
+ ifc_configitem *item = group->GetItem(configItem);
+ if (item)
+ return item->GetFloat();
+ }
+ return defaultValue;
+}
+
+inline const wchar_t *api_config::GetString(GUID groupGUID, const wchar_t *configItem, const wchar_t *defaultValue)
+{
+ ifc_configgroup *group = GetGroup(groupGUID);
+ if (group)
+ {
+ ifc_configitem *item = group->GetItem(configItem);
+ if (item)
+ return item->GetString();
+ }
+ return defaultValue;
+}
+
+inline ifc_configitem *api_config::GetItem(GUID groupGUID, const wchar_t *configItem)
+{
+ ifc_configgroup *group = GetGroup(groupGUID);
+ if (group)
+ {
+ return group->GetItem(configItem);
+ }
+ return 0;
+}
+
+// {AEFBF8BE-E0AA-4318-8CC1-4353410B64DC}
+static const GUID AgaveConfigGUID =
+{ 0xaefbf8be, 0xe0aa, 0x4318, { 0x8c, 0xc1, 0x43, 0x53, 0x41, 0xb, 0x64, 0xdc } };
+
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/Agave/Config/ifc_configgroup.h b/Src/Plugins/Input/in_wv/wasabi/Agave/Config/ifc_configgroup.h
new file mode 100644
index 00000000..d6f21ec8
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Agave/Config/ifc_configgroup.h
@@ -0,0 +1,35 @@
+#ifndef NULLSOFT_AGAVE_IFC_CONFIGGROUP_H
+#define NULLSOFT_AGAVE_IFC_CONFIGGROUP_H
+
+#include "../../bfc/dispatch.h"
+#include "../../bfc/platform/types.h"
+#include "../../bfc/platform/guid.h"
+#include "ifc_configitem.h"
+
+class ifc_configgroup : public Dispatchable
+{
+protected:
+ ifc_configgroup() {}
+ ~ifc_configgroup() {}
+public:
+ ifc_configitem *GetItem(const wchar_t *name);
+ GUID GetGUID();
+public:
+ DISPATCH_CODES
+ {
+ IFC_CONFIGGROUP_GETITEM = 10,
+ IFC_CONFIGGROUP_GETGUID = 20,
+ };
+
+};
+
+inline ifc_configitem *ifc_configgroup::GetItem(const wchar_t *name)
+{
+ return _call(IFC_CONFIGGROUP_GETITEM, (ifc_configitem *)0, name);
+}
+
+inline GUID ifc_configgroup::GetGUID()
+{
+ return _call(IFC_CONFIGGROUP_GETGUID, (GUID)INVALID_GUID);
+}
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/Agave/Config/ifc_configitem.h b/Src/Plugins/Input/in_wv/wasabi/Agave/Config/ifc_configitem.h
new file mode 100644
index 00000000..6f5a8ae3
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Agave/Config/ifc_configitem.h
@@ -0,0 +1,200 @@
+#ifndef NULLSOFT_AGAVE_IFC_CONFIGITEM_H
+#define NULLSOFT_AGAVE_IFC_CONFIGITEM_H
+
+#include "../../bfc/dispatch.h"
+#include <stddef.h>
+/*
+notes:
+The Set() functions are "public-facing", meaning that they can be called by anyone. If you want to make your config item read-only,
+then simply don't implement these. You can always make "private" Set functions in your implementation.
+
+SetStringInternal and GetStringInternal are written for use with classes to load and save from INI files (or XML files or whatever).
+It's up to you to figure out a clever way to encode yourself.
+
+*/
+
+enum
+{
+ CONFIG_ITEM_TYPE_STRING = 0,
+ CONFIG_ITEM_TYPE_INT = 1,
+ CONFIG_ITEM_TYPE_UNSIGNED =2,
+ CONFIG_ITEM_TYPE_BOOL =3,
+ CONFIG_ITEM_TYPE_BINARY =4,
+ CONFIG_ITEM_TYPE_INT_ARRAY = 5,
+};
+
+class ifc_configitem : public Dispatchable
+{
+protected:
+ ifc_configitem() {}
+ ~ifc_configitem() {}
+public:
+ const wchar_t *GetName();
+ int GetType();
+
+ const wchar_t *GetString();
+ void SetString(const wchar_t *stringValue);
+
+ intptr_t GetInt();
+ void SetInt(intptr_t intValue);
+
+ uintptr_t GetUnsigned();
+ void SetUnsigned(uintptr_t unsignedValue);
+
+ bool GetBool();
+ void SetBool(bool boolValue);
+
+ float GetFloat();
+ void SetFloat(float floatValue);
+
+ size_t GetBinarySize();
+ size_t GetBinaryData(void *data, size_t bytes); // returns bytes written
+ void SetBinaryData(void *data, size_t bytes);
+
+ size_t GetIntArrayElements();
+ size_t GetIntArray(intptr_t *array, size_t elements); // returns elements written
+ void SetIntArray(intptr_t *array, size_t elements);
+
+ const wchar_t *GetStringInternal(); // gets a string suitable for saving in an INI file or XML
+ void SetStringInternal(const wchar_t *internalString);
+
+public:
+ DISPATCH_CODES
+ {
+ IFC_CONFIGITEM_GETNAME = 10,
+ IFC_CONFIGITEM_GETTYPE = 20,
+
+ IFC_CONFIGITEM_GETSTRING= 30,
+ IFC_CONFIGITEM_SETSTRING= 40,
+
+ IFC_CONFIGITEM_GETINT= 50,
+ IFC_CONFIGITEM_SETINT= 60,
+
+ IFC_CONFIGITEM_GETUNSIGNED= 70,
+ IFC_CONFIGITEM_SETUNSIGNED= 80,
+
+ IFC_CONFIGITEM_GETBOOL= 90,
+ IFC_CONFIGITEM_SETBOOL= 100,
+
+ IFC_CONFIGITEM_GETBINARYSIZE= 110,
+ IFC_CONFIGITEM_GETBINARYDATA= 120,
+ IFC_CONFIGITEM_SETBINARYDATA= 130,
+
+ IFC_CONFIGITEM_GETINTARRAYELEMENTS= 140,
+ IFC_CONFIGITEM_GETINTARRAY= 150,
+ IFC_CONFIGITEM_SETINTARRAY= 160,
+
+ IFC_CONFIGITEM_GETSTRINGINTERNAL= 170,
+ IFC_CONFIGITEM_SETSTRINGINTERNAL= 180,
+
+ IFC_CONFIGITEM_GETFLOAT= 190,
+ IFC_CONFIGITEM_SETFLOAT= 200,
+ };
+};
+
+
+
+inline const wchar_t *ifc_configitem::GetName()
+{
+ return _call(IFC_CONFIGITEM_GETNAME, (const wchar_t *)0);
+}
+
+inline int ifc_configitem::GetType()
+{
+ return _call(IFC_CONFIGITEM_GETTYPE, (int)0);
+}
+
+inline const wchar_t *ifc_configitem::GetString()
+{
+ return _call(IFC_CONFIGITEM_GETSTRING, (const wchar_t *)0);
+}
+
+inline void ifc_configitem::SetString(const wchar_t *stringValue)
+{
+ _voidcall(IFC_CONFIGITEM_SETSTRING, stringValue);
+}
+
+
+inline intptr_t ifc_configitem::GetInt()
+{
+ return _call(IFC_CONFIGITEM_GETINT, (intptr_t)0);
+}
+#pragma warning(push)
+#pragma warning(disable: 4244)
+inline void ifc_configitem::SetInt(intptr_t intValue)
+{
+ _voidcall(IFC_CONFIGITEM_SETINT, intValue);
+}
+#pragma warning(pop)
+
+inline uintptr_t ifc_configitem::GetUnsigned()
+{
+ return _call(IFC_CONFIGITEM_GETUNSIGNED, (uintptr_t)0);
+}
+
+inline void ifc_configitem::SetUnsigned(uintptr_t unsignedValue)
+{
+ _voidcall(IFC_CONFIGITEM_SETUNSIGNED, unsignedValue);
+}
+
+
+inline bool ifc_configitem::GetBool()
+{
+ return _call(IFC_CONFIGITEM_GETBOOL, (bool)false);
+}
+
+inline void ifc_configitem::SetBool(bool boolValue)
+{
+ _voidcall(IFC_CONFIGITEM_SETBOOL, boolValue);
+}
+
+inline size_t ifc_configitem::GetBinarySize()
+{
+ return _call(IFC_CONFIGITEM_GETBINARYSIZE, (size_t)0);
+}
+
+inline size_t ifc_configitem::GetBinaryData(void *data, size_t bytes)
+{
+ return _call(IFC_CONFIGITEM_GETBINARYDATA, (size_t)0, data, bytes);
+}
+
+inline void ifc_configitem::SetBinaryData(void *data, size_t bytes)
+{
+ _voidcall(IFC_CONFIGITEM_SETBINARYDATA, data, bytes);
+}
+
+inline size_t ifc_configitem::GetIntArrayElements()
+{
+ return _call(IFC_CONFIGITEM_GETINTARRAYELEMENTS, (size_t)0);
+}
+
+inline size_t ifc_configitem::GetIntArray(intptr_t *array, size_t elements)
+{
+ return _call(IFC_CONFIGITEM_GETINTARRAY, (size_t)0, array, elements);
+}
+inline void ifc_configitem::SetIntArray(intptr_t *array, size_t elements)
+{
+ _voidcall(IFC_CONFIGITEM_SETINTARRAY, array, elements);
+}
+
+inline const wchar_t *ifc_configitem::GetStringInternal()
+{
+ return _call(IFC_CONFIGITEM_GETSTRINGINTERNAL, (const wchar_t *)0);
+}
+inline void ifc_configitem::SetStringInternal(const wchar_t *internalString)
+{
+ _voidcall(IFC_CONFIGITEM_SETSTRINGINTERNAL, internalString);
+}
+
+inline float ifc_configitem::GetFloat()
+{
+ return _call(IFC_CONFIGITEM_GETFLOAT, (float)0);
+}
+
+inline void ifc_configitem::SetFloat(float floatValue)
+{
+ _voidcall(IFC_CONFIGITEM_SETFLOAT, floatValue);
+}
+
+
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/Agave/Language/api_language.h b/Src/Plugins/Input/in_wv/wasabi/Agave/Language/api_language.h
new file mode 100644
index 00000000..426a1c3c
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Agave/Language/api_language.h
@@ -0,0 +1,315 @@
+#ifndef NULLSOFT_API_LANGUAGE_H
+#define NULLSOFT_API_LANGUAGE_H
+
+#include "../../bfc/dispatch.h"
+#include "lang.h"
+#include <locale.h>
+
+#if (_MSC_VER <= 1200)
+ struct threadlocaleinfostruct;
+ struct threadmbcinfostruct;
+ typedef struct threadlocaleinfostruct * pthreadlocinfo;
+ typedef struct threadmbcinfostruct * pthreadmbcinfo;
+
+ typedef struct localeinfo_struct
+ {
+ pthreadlocinfo locinfo;
+ pthreadmbcinfo mbcinfo;
+ } _locale_tstruct, *_locale_t;
+#endif
+
+class api_language : public Dispatchable
+{
+protected:
+ api_language() {}
+ ~api_language() {}
+public:
+ char *GetString(HINSTANCE hinst, HINSTANCE owner, UINT uID, char *str=NULL, size_t maxlen=0);
+ wchar_t *GetStringW(HINSTANCE hinst, HINSTANCE owner, UINT uID, wchar_t *str=NULL, size_t maxlen=0);
+
+ char *GetStringFromGUID(const GUID guid, HINSTANCE owner, UINT uID, char *str=NULL, size_t maxlen=0);
+ wchar_t *GetStringFromGUIDW(const GUID guid, HINSTANCE owner, UINT uID, wchar_t *str=NULL, size_t maxlen=0);
+
+ HINSTANCE FindDllHandleByGUID(GUID guid);
+ HINSTANCE FindDllHandleByString(const char* str);
+ HINSTANCE FindDllHandleByStringW(const wchar_t* str);
+ HINSTANCE StartLanguageSupport(HINSTANCE hinstance, const GUID guid);
+
+ const wchar_t *GetLanguageFolder();
+
+ #define LANG_IDENT_STR 0
+ #define LANG_LANG_CODE 1
+ #define LANG_COUNTRY_CODE 2
+ const wchar_t *GetLanguageIdentifier(int mode);
+
+ HWND CreateLDialogParam(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param);
+ INT_PTR LDialogBoxParam(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param);
+ HMENU LoadLMenu(HINSTANCE localised, HINSTANCE original, UINT id);
+
+ HWND CreateLDialogParamW(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param);
+ INT_PTR LDialogBoxParamW(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param);
+ HMENU LoadLMenuW(HINSTANCE localised, HINSTANCE original, UINT id);
+
+ void* LoadResourceFromFile(HINSTANCE hinst, HINSTANCE owner, LPCTSTR lpType, LPCTSTR lpName, DWORD* size);
+ void* LoadResourceFromFileW(HINSTANCE hinst, HINSTANCE owner, LPCWSTR lpType, LPCWSTR lpName, DWORD* size);
+
+ HACCEL LoadAcceleratorsA(HINSTANCE hinst, HINSTANCE owner, LPCSTR lpTableName);
+ HACCEL LoadAcceleratorsW(HINSTANCE hinst, HINSTANCE owner, LPCWSTR lpTableName);
+
+ // Implemented in 5.58+
+ // When called this will attempt to set the locale used for numeric representation
+ // to that of the user running the current Winamp instance as long as the language
+ // and country identifiers match those reported within the language pack (if used)
+ //
+ // If you're running under a different thread then this will need to be called as
+ // the locale is set on a per thread basis which generally means anything under the
+ // Winamp process will be handled correctly unless a UI aspect is running under a
+ // different thread. Internally this is called within winamp.exe and vis_milk2.dll
+ BOOL UseUserNumericLocale();
+
+ // Get_C_NumericLocale() is a wrapper for _create_locale(LC_NUMERIC, "C") which can
+ // then be used in _atof_l(..), _sscanf_l(..) or other locale based functions when
+ // you need to process numbers without localisation handling ie the "C" locale.
+ // This function is provided for convenience unless you want to do it all manually.
+ _locale_t Get_C_NumericLocale();
+
+public:
+ DISPATCH_CODES
+ {
+ API_LANGUAGE_GETSTRING = 10,
+ API_LANGUAGE_GETSTRINGW = 11,
+
+ API_LANGUAGE_GETSTRINGFROMGUID = 12,
+ API_LANGUAGE_GETSTRINGFROMGUIDW = 13,
+
+ API_LANGUAGE_GETHINSTANCEBYGUID = 20,
+ API_LANGUAGE_GETHINSTANCEBYNAME = 21,
+ API_LANGUAGE_GETHINSTANCEBYNAMEW = 22,
+
+ API_LANGUAGE_STARTUP = 30,
+ API_LANGUAGE_SHUTDOWN = 31,
+
+ API_LANGUAGE_GETLANGUAGEFOLDER=40,
+
+ API_LANGUAGE_CREATELDIALOGPARAM=50,
+ API_LANGUAGE_LDIALOGBOXPARAM=51,
+ API_LANGUAGE_LOADLMENU=52,
+ API_LANGUAGE_CREATELDIALOGPARAMW=53,
+ API_LANGUAGE_LDIALOGBOXPARAMW=54,
+ API_LANGUAGE_LOADLMENUW=55,
+
+ API_LANGUAGE_GETLANGUAGEIDENTIFIER=60,
+
+ API_LANGUAGE_LOADRESOURCEFROMFILE=70,
+ API_LANGUAGE_LOADRESOURCEFROMFILEW=71,
+
+ API_LANGUAGE_LOADACCELERATORSA=80,
+ API_LANGUAGE_LOADACCELERATORSW=81,
+
+ // Implemented in 5.58+
+ // See UseUserNumericLocale notes
+ API_LANGUAGE_USEUSERNUMERICLOCALE=90,
+ API_LANGUAGE_GET_C_NUMERICLOCALE=91,
+ };
+};
+
+inline char *api_language::GetString(HINSTANCE hinst, HINSTANCE owner, UINT uID, char *str, size_t maxlen)
+{
+ return _call(API_LANGUAGE_GETSTRING, (char * )0, hinst, owner, uID, str, maxlen);
+}
+
+inline wchar_t *api_language::GetStringW(HINSTANCE hinst, HINSTANCE owner, UINT uID, wchar_t *str, size_t maxlen)
+{
+ return _call(API_LANGUAGE_GETSTRINGW, (wchar_t * )0, hinst, owner, uID, str, maxlen);
+}
+
+inline char *api_language::GetStringFromGUID(const GUID guid, HINSTANCE owner, UINT uID, char *str, size_t maxlen)
+{
+ return _call(API_LANGUAGE_GETSTRINGFROMGUID, (char * )0, guid, owner, uID, str, maxlen);
+}
+
+inline wchar_t *api_language::GetStringFromGUIDW(const GUID guid, HINSTANCE owner, UINT uID, wchar_t *str, size_t maxlen)
+{
+ return _call(API_LANGUAGE_GETSTRINGFROMGUIDW, (wchar_t * )0, guid, owner, uID, str, maxlen);
+}
+
+inline HINSTANCE api_language::FindDllHandleByGUID(const GUID guid)
+{
+ return _call(API_LANGUAGE_GETHINSTANCEBYGUID, (HINSTANCE )0, guid);
+}
+
+inline HINSTANCE api_language::FindDllHandleByString(const char* str)
+{
+ return _call(API_LANGUAGE_GETHINSTANCEBYNAME, (HINSTANCE )0, str);
+}
+
+inline HINSTANCE api_language::FindDllHandleByStringW(const wchar_t* str)
+{
+ return _call(API_LANGUAGE_GETHINSTANCEBYNAMEW, (HINSTANCE )0, str);
+}
+
+inline HINSTANCE api_language::StartLanguageSupport(HINSTANCE hinstance, const GUID guid)
+{
+ return _call(API_LANGUAGE_STARTUP, (HINSTANCE )0, hinstance, guid);
+}
+
+inline const wchar_t *api_language::GetLanguageFolder()
+{
+ return _call(API_LANGUAGE_GETLANGUAGEFOLDER, (const wchar_t *)0);
+}
+
+inline HWND api_language::CreateLDialogParam(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param)
+{
+ return _call(API_LANGUAGE_CREATELDIALOGPARAM, (HWND)0, localised, original, id, parent, proc, param);
+}
+
+inline INT_PTR api_language::LDialogBoxParam(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param)
+{
+ return _call(API_LANGUAGE_LDIALOGBOXPARAM, (INT_PTR)0, localised, original, id, parent, proc, param);
+}
+
+inline HMENU api_language::LoadLMenu(HINSTANCE localised, HINSTANCE original, UINT id)
+{
+ return _call(API_LANGUAGE_LOADLMENU, (HMENU)0, localised, original, id);
+}
+
+inline HWND api_language::CreateLDialogParamW(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param)
+{
+ return _call(API_LANGUAGE_CREATELDIALOGPARAMW, (HWND)0, localised, original, id, parent, proc, param);
+}
+
+inline INT_PTR api_language::LDialogBoxParamW(HINSTANCE localised, HINSTANCE original, UINT id, HWND parent, DLGPROC proc, LPARAM param)
+{
+ return _call(API_LANGUAGE_LDIALOGBOXPARAMW, (INT_PTR)0, localised, original, id, parent, proc, param);
+}
+
+inline HMENU api_language::LoadLMenuW(HINSTANCE localised, HINSTANCE original, UINT id)
+{
+ return _call(API_LANGUAGE_LOADLMENUW, (HMENU)0, localised, original, id);
+}
+
+inline const wchar_t *api_language::GetLanguageIdentifier(int mode)
+{
+ return _call(API_LANGUAGE_GETLANGUAGEIDENTIFIER, (const wchar_t *)0, mode);
+}
+
+inline void *api_language::LoadResourceFromFile(HINSTANCE hinst, HINSTANCE owner, LPCTSTR lpType, LPCTSTR lpName, DWORD* size)
+{
+ return _call(API_LANGUAGE_LOADRESOURCEFROMFILE, (void*)0, hinst, owner, lpType, lpName, size);
+}
+
+inline void *api_language::LoadResourceFromFileW(HINSTANCE hinst, HINSTANCE owner, LPCWSTR lpType, LPCWSTR lpName, DWORD* size)
+{
+ return _call(API_LANGUAGE_LOADRESOURCEFROMFILEW, (void*)0, hinst, owner, lpType, lpName, size);
+}
+
+inline HACCEL api_language::LoadAcceleratorsA(HINSTANCE hinst, HINSTANCE owner, LPCSTR lpTableName)
+{
+ return _call(API_LANGUAGE_LOADACCELERATORSA, (HACCEL)NULL, hinst, owner, lpTableName);
+}
+
+inline HACCEL api_language::LoadAcceleratorsW(HINSTANCE hinst, HINSTANCE owner, LPCWSTR lpTableName)
+{
+ return _call(API_LANGUAGE_LOADACCELERATORSA, (HACCEL)NULL, hinst, owner, lpTableName);
+}
+
+inline BOOL api_language::UseUserNumericLocale()
+{
+ return _call(API_LANGUAGE_USEUSERNUMERICLOCALE, (BOOL)0);
+}
+
+inline _locale_t api_language::Get_C_NumericLocale()
+{
+ return _call(API_LANGUAGE_GET_C_NUMERICLOCALE, (_locale_t)0);
+}
+
+
+// utility macros and relevant predefined variables for use with the service + macros
+extern api_language *languageManager;
+#define WASABI_API_LNG languageManager
+
+extern HINSTANCE api_localised_hinstance;
+#define WASABI_API_LNG_HINST api_localised_hinstance
+
+extern HINSTANCE api_orig_hinstance;
+#define WASABI_API_ORIG_HINST api_orig_hinstance
+
+#define WASABI_API_LNGSTR WASABI_API_LNG->GetString
+// use this is you want a temp copy of the string
+#define WASABI_API_LNGSTRING(uID) \
+ WASABI_API_LNGSTR(WASABI_API_LNG_HINST,WASABI_API_ORIG_HINST,uID)
+// use this is you want a temp copy of the string but need it to fallback to a different module
+#define WASABI_API_LNGSTRING_HINST(hinst,uID) \
+ WASABI_API_LNGSTR(WASABI_API_LNG_HINST,hinst,uID)
+// use this is you want a copy of the string
+#define WASABI_API_LNGSTRING_BUF(uID,buf,len) \
+ WASABI_API_LNGSTR(WASABI_API_LNG_HINST,WASABI_API_ORIG_HINST,uID,buf,len)
+// use this is you want a copy of the string but need it to fallback to a different module
+#define WASABI_API_LNGSTRING_HINST_BUF(hinst,uID,buf,len) \
+ WASABI_API_LNGSTR(WASABI_API_LNG_HINST,hinst,uID,buf,len)
+
+// unicode versions of the above macros
+#define WASABI_API_LNGSTRW WASABI_API_LNG->GetStringW
+#define WASABI_API_LNGSTRINGW(uID) \
+ WASABI_API_LNGSTRW(WASABI_API_LNG_HINST,WASABI_API_ORIG_HINST,uID)
+#define WASABI_API_LNGSTRINGW_HINST(hinst,uID) \
+ WASABI_API_LNGSTRW(WASABI_API_LNG_HINST,hinst,uID)
+#define WASABI_API_LNGSTRINGW_BUF(uID,buf,len) \
+ WASABI_API_LNGSTRW(WASABI_API_LNG_HINST,WASABI_API_ORIG_HINST,uID,buf,len)
+#define WASABI_API_LNGSTRINGW_BUF_HINST(hinst,uID,buf,len) \
+ WASABI_API_LNGSTRW(WASABI_API_LNG_HINST,hinst,uID,buf,len)
+
+// Dialog handling functions (will revert back to the non-localised version if not valid/present)
+#define WASABI_API_CREATEDIALOGPARAM(id, parent, proc, param) \
+ WASABI_API_LNG->CreateLDialogParam(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, param)
+#define WASABI_API_CREATEDIALOG(id, parent, proc) \
+ WASABI_API_LNG->CreateLDialogParam(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, 0)
+
+#define WASABI_API_CREATEDIALOGPARAMW(id, parent, proc, param) \
+ WASABI_API_LNG->CreateLDialogParamW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, param)
+#define WASABI_API_CREATEDIALOGW(id, parent, proc) \
+ WASABI_API_LNG->CreateLDialogParamW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, 0)
+
+#define WASABI_API_DIALOGBOXPARAM(id, parent, proc, param) \
+ WASABI_API_LNG->LDialogBoxParam(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, param)
+#define WASABI_API_DIALOGBOX(id, parent, proc) \
+ WASABI_API_LNG->LDialogBoxParam(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, 0)
+
+#define WASABI_API_DIALOGBOXPARAMW(id, parent, proc, param) \
+ WASABI_API_LNG->LDialogBoxParamW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, param)
+#define WASABI_API_DIALOGBOXW(id, parent, proc) \
+ WASABI_API_LNG->LDialogBoxParamW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id, parent, (DLGPROC)proc, 0)
+
+#define WASABI_API_LOADMENU(id) \
+ WASABI_API_LNG->LoadLMenu(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id)
+#define WASABI_API_LOADMENUW(id) \
+ WASABI_API_LNG->LoadLMenuW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, id)
+
+
+#define WASABI_API_LOADACCELERATORSA(__id) \
+ WASABI_API_LNG->LoadAcceleratorsA(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, MAKEINTRESOURCEA(__id))
+#define WASABI_API_LOADACCELERATORSW(__id) \
+ WASABI_API_LNG->LoadAcceleratorsW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, MAKEINTRESOURCEW(__id))
+
+#ifdef UNICODE
+#define WASABI_API_LOADACCELERATORS WASABI_API_LOADACCELERATORSW
+#else
+#define WASABI_API_LOADACCELERATORS WASABI_API_LOADACCELERATORSA
+#endif
+
+#define WASABI_API_START_LANG(orig_hinst, guid) \
+{ \
+ WASABI_API_ORIG_HINST = orig_hinst; \
+ WASABI_API_LNG_HINST = WASABI_API_LNG->StartLanguageSupport(WASABI_API_ORIG_HINST,guid); \
+}
+
+#define WASABI_API_LOADRESFROMFILE(lpType, lpName, size) \
+ WASABI_API_LNG->LoadResourceFromFile(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, lpType, lpName, size)
+#define WASABI_API_LOADRESFROMFILEW(lpType, lpName, size) \
+ WASABI_API_LNG->LoadResourceFromFileW(WASABI_API_LNG_HINST, WASABI_API_ORIG_HINST, lpType, lpName, size)
+
+// {30AED4E5-EF10-4277-8D49-27AB5570E891}
+static const GUID languageApiGUID =
+{ 0x30aed4e5, 0xef10, 0x4277, { 0x8d, 0x49, 0x27, 0xab, 0x55, 0x70, 0xe8, 0x91 } };
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Agave/Language/lang.h b/Src/Plugins/Input/in_wv/wasabi/Agave/Language/lang.h
new file mode 100644
index 00000000..59cd684a
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Agave/Language/lang.h
@@ -0,0 +1,595 @@
+#ifndef _LANG_GUIDS_H_
+#define _LANG_GUIDS_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// this is just the stringtable id and the
+// stringtable block where the guid is stored
+#define LANG_DLL_GUID_STRING_ID 65535
+#define LANG_DLL_GUID_BLOCK_ID 4096
+
+// this is the stringtable id in winamp.exe's lng file where
+// the language of the lang pack is declared.
+// the actual string is defined as language_code-country_code
+// e.g.
+// en-US - US English
+// en-GB - UK English
+#define LANG_PACK_LANG_ID 65534
+
+// this is the indentifiers required as of 5.57+ for the localisation
+// 'about page' shown in supporting language packs in the 'about' box
+#define LANG_DLL_AUTHOR_HOMEPAGE 65533
+#define LANG_DLL_AUTHOR_HOMEPAGE2 65532
+#define LANG_DLL_ABOUT_TRANSLATION_DLG_ID 1378
+
+// this holds all of the guids that will be used in modules lng files
+// using these will allow you to make use of the language resources
+// between plugins / for 3rd party plugins for compatability support
+
+// {A0099AA7-F980-45cf-818D-64EAA9F4EF4B}
+static const GUID WinampLangGUID =
+{ 0xa0099aa7, 0xf980, 0x45cf, { 0x81, 0x8d, 0x64, 0xea, 0xa9, 0xf4, 0xef, 0x4b } };
+
+// {0E844B2A-70E8-4007-A73A-E9C05DB3F06D}
+static const GUID WinampALangGUID =
+{ 0xe844b2a, 0x70e8, 0x4007, { 0xa7, 0x3a, 0xe9, 0xc0, 0x5d, 0xb3, 0xf0, 0x6d } };
+
+// {250FAA3C-20CD-49db-A932-67B1C0191B0E}
+static const GUID GenHotkeysLangGUID =
+{ 0x250faa3c, 0x20cd, 0x49db, { 0xa9, 0x32, 0x67, 0xb1, 0xc0, 0x19, 0x1b, 0xe } };
+
+// {25B50046-5B31-418b-B77E-1B0D140D64ED}
+static const GUID GenTrayLangGUID =
+{ 0x25b50046, 0x5b31, 0x418b, { 0xb7, 0x7e, 0x1b, 0xd, 0x14, 0xd, 0x64, 0xed } };
+
+// {3D968813-F245-40ad-8589-5599C754B924}
+static const GUID GenMlLangGUID =
+{ 0x3d968813, 0xf245, 0x40ad, { 0x85, 0x89, 0x55, 0x99, 0xc7, 0x54, 0xb9, 0x24 } };
+
+// {A3A1E7C0-761B-4391-A08A-F0D7AF38931C}
+static const GUID MlBookmarkLangGUID =
+{ 0xa3a1e7c0, 0x761b, 0x4391, { 0xa0, 0x8a, 0xf0, 0xd7, 0xaf, 0x38, 0x93, 0x1c } };
+
+// {40450D34-E85A-428c-A01C-B2546BF23CE0}
+static const GUID MlDashboardLangGUID =
+{ 0x40450d34, 0xe85a, 0x428c, { 0xa0, 0x1c, 0xb2, 0x54, 0x6b, 0xf2, 0x3c, 0xe0 } };
+
+// {168BA411-7E26-4749-98F0-FF02810D9B51}
+static const GUID MlADDONSLangGUID =
+{ 0x168ba411, 0x7e26, 0x4749, { 0x98, 0xf0, 0xff, 0x2, 0x81, 0xd, 0x9b, 0x51 } };
+
+// {7F31F590-6602-45c9-B3F8-F61AE05BD1D3}
+static const GUID MlNowPlayingLangGUID =
+{ 0x7f31f590, 0x6602, 0x45c9, { 0xb3, 0xf8, 0xf6, 0x1a, 0xe0, 0x5b, 0xd1, 0xd3 } };
+
+// {F8756C00-11D2-4857-8C50-163AE4A57783}
+static const GUID MlHistoryLangGUID =
+{ 0xf8756c00, 0x11d2, 0x4857, { 0x8c, 0x50, 0x16, 0x3a, 0xe4, 0xa5, 0x77, 0x83 } };
+
+// {5E766B4F-818E-4f14-9C42-0902B2C571DC}
+static const GUID MlPlaylistsLangGUID =
+{ 0x5e766b4f, 0x818e, 0x4f14, { 0x9c, 0x42, 0x9, 0x2, 0xb2, 0xc5, 0x71, 0xdc } };
+
+// {D006C700-557E-43c7-A580-B4C50C56957A}
+static const GUID MlOnlineLangGUID =
+{ 0xd006c700, 0x557e, 0x43c7, { 0xa5, 0x80, 0xb4, 0xc5, 0xc, 0x56, 0x95, 0x7a } };
+
+// {5F633543-148D-48cc-B683-DA82F592CF28}
+static const GUID MlReplayGainLangGUID =
+{ 0x5f633543, 0x148d, 0x48cc, { 0xb6, 0x83, 0xda, 0x82, 0xf5, 0x92, 0xcf, 0x28 } };
+
+// {699B8BA5-B292-4aba-8047-D46B0DF4E1D6}
+static const GUID MlTranscodeLangGUID =
+{ 0x699b8ba5, 0xb292, 0x4aba, { 0x80, 0x47, 0xd4, 0x6b, 0xd, 0xf4, 0xe1, 0xd6 } };
+
+// {34DF1A2D-7EAD-41ab-B1A7-9AFA6DE2AFF1}
+static const GUID EncWavLangGUID =
+{ 0x34df1a2d, 0x7ead, 0x41ab, { 0xb1, 0xa7, 0x9a, 0xfa, 0x6d, 0xe2, 0xaf, 0xf1 } };
+
+// {33BC12FD-E7F7-42ec-8FE3-2D8BD3A977C2}
+static const GUID EncWMALangGUID =
+{ 0x33bc12fd, 0xe7f7, 0x42ec, { 0x8f, 0xe3, 0x2d, 0x8b, 0xd3, 0xa9, 0x77, 0xc2 } };
+
+// {8FBADBBB-B4D5-47d9-A723-5C8C8E88EE73}
+static const GUID EncAACLangGUID =
+{ 0x8fbadbbb, 0xb4d5, 0x47d9, { 0xa7, 0x23, 0x5c, 0x8c, 0x8e, 0x88, 0xee, 0x73 } };
+
+// {F1534ECA-6E64-42c2-9781-812E61154515}
+static const GUID EncLameLangGUID =
+{ 0xf1534eca, 0x6e64, 0x42c2, { 0x97, 0x81, 0x81, 0x2e, 0x61, 0x15, 0x45, 0x15 } };
+
+// deprecated enc_flac.dll based on FLAKE
+// {5C0BA1EE-5A59-47cc-BC28-5B9F0C5EA1B7}
+static const GUID EncFlakeLangGUID =
+{ 0x5c0ba1ee, 0x5a59, 0x47cc, { 0xbc, 0x28, 0x5b, 0x9f, 0xc, 0x5e, 0xa1, 0xb7 } };
+
+// {A23C2B70-C66B-475e-8A67-E0F33FD5BD12}
+static const GUID EncVorbisLangGUID =
+{ 0xa23c2b70, 0xc66b, 0x475e, { 0x8a, 0x67, 0xe0, 0xf3, 0x3f, 0xd5, 0xbd, 0x12 } };
+
+// {D40620FB-E44B-47b3-98EE-8E5A089C0C94}
+static const GUID tagzLangGUID =
+{ 0xd40620fb, 0xe44b, 0x47b3, { 0x98, 0xee, 0x8e, 0x5a, 0x8, 0x9c, 0xc, 0x94 } };
+
+// {06A3F81D-043D-4b5c-B341-590ED7053492}
+static const GUID MlLocalLangGUID =
+{ 0x6a3f81d, 0x43d, 0x4b5c, { 0xb3, 0x41, 0x59, 0xe, 0xd7, 0x5, 0x34, 0x92 } };
+
+// {706549D3-D813-45dd-9A0B-E3793A1B63A8}
+static const GUID MlDownloadsLangGUID =
+{ 0x706549d3, 0xd813, 0x45dd, { 0x9a, 0xb, 0xe3, 0x79, 0x3a, 0x1b, 0x63, 0xa8 } };
+
+// {1FF327B2-A41D-4c67-A58A-EB09BA1470D3}
+static const GUID MlWireLangGUID =
+{ 0x1ff327b2, 0xa41d, 0x4c67, { 0xa5, 0x8a, 0xeb, 0x9, 0xba, 0x14, 0x70, 0xd3 } };
+
+// {04C986EE-9CE3-4369-820D-A64394C63D60}
+static const GUID MlPMPLangGUID =
+{ 0x4c986ee, 0x9ce3, 0x4369, { 0x82, 0xd, 0xa6, 0x43, 0x94, 0xc6, 0x3d, 0x60 } };
+
+// {E553C1A4-5DE2-4838-8000-FDF8DC377DD4}
+static const GUID PmpUSBLangGUID =
+{ 0xe553c1a4, 0x5de2, 0x4838, { 0x80, 0x0, 0xfd, 0xf8, 0xdc, 0x37, 0x7d, 0xd4 } };
+
+// {01C3E74C-261E-45e2-AA30-ED4039DCD3A2}
+static const GUID PmpP4SLangGUID =
+{ 0x1c3e74c, 0x261e, 0x45e2, { 0xaa, 0x30, 0xed, 0x40, 0x39, 0xdc, 0xd3, 0xa2 } };
+
+// {4F5B2300-19D1-4390-BE04-89019441100B}
+static const GUID PmpNJBLangGUID =
+{ 0x4f5b2300, 0x19d1, 0x4390, { 0xbe, 0x4, 0x89, 0x1, 0x94, 0x41, 0x10, 0xb } };
+
+// {B81F32B8-4AA4-4eba-8798-95F13812F638}
+static const GUID PmpACTIVESYNCLangGUID =
+{ 0xb81f32b8, 0x4aa4, 0x4eba, { 0x87, 0x98, 0x95, 0xf1, 0x38, 0x12, 0xf6, 0x38 } };
+
+// {C2EE3DA5-B29B-42a0-AB5E-B202393435D6}
+static const GUID PmpIPODLangGUID =
+{ 0xc2ee3da5, 0xb29b, 0x42a0, { 0xab, 0x5e, 0xb2, 0x2, 0x39, 0x34, 0x35, 0xd6 } };
+
+// {2C913A2F-CD49-40a1-8F1A-8EF7C2A22229}
+static const GUID MlDiscLangGUID =
+{ 0x2c913a2f, 0xcd49, 0x40a1, { 0x8f, 0x1a, 0x8e, 0xf7, 0xc2, 0xa2, 0x22, 0x29 } };
+
+// {1A710E67-5180-49ac-8102-105856ED0A2F}
+static const GUID OutDiskLangGUID =
+{ 0x1a710e67, 0x5180, 0x49ac, { 0x81, 0x2, 0x10, 0x58, 0x56, 0xed, 0xa, 0x2f } };
+
+// {858FBF71-9878-4d86-BFDD-8FEA8361238C}
+static const GUID VisNFSFLangGUID =
+{ 0x858fbf71, 0x9878, 0x4d86, { 0xbf, 0xdd, 0x8f, 0xea, 0x83, 0x61, 0x23, 0x8c } };
+
+// {BE608673-B723-4a59-9EBA-52DC77109E10}
+static const GUID VisAVSLangGUID =
+{ 0xbe608673, 0xb723, 0x4a59, { 0x9e, 0xba, 0x52, 0xdc, 0x77, 0x10, 0x9e, 0x10 } };
+
+// {226275F6-3318-4d4b-A6B3-5B1B5B077BE8}
+static const GUID VisMilkdropLangGUID =
+{ 0x226275f6, 0x3318, 0x4d4b, { 0xa6, 0xb3, 0x5b, 0x1b, 0x5b, 0x7, 0x7b, 0xe8 } };
+
+// {C5D175F1-E4E4-47ee-B85C-4EDC6B026A35}
+static const GUID VisMilk2LangGUID =
+{ 0xc5d175f1, 0xe4e4, 0x47ee, { 0xb8, 0x5c, 0x4e, 0xdc, 0x6b, 0x2, 0x6a, 0x35 } };
+
+// {87DCEEC2-1EC3-4c59-BED4-E8F42232C7D8}
+static const GUID InCDDALangGUID =
+{ 0x87dceec2, 0x1ec3, 0x4c59, { 0xbe, 0xd4, 0xe8, 0xf4, 0x22, 0x32, 0xc7, 0xd8 } };
+
+// {20395FD0-AC67-446d-B8D0-D88BFD3174FC}
+static const GUID IndshowLangGUID =
+{ 0x20395fd0, 0xac67, 0x446d, { 0xb8, 0xd0, 0xd8, 0x8b, 0xfd, 0x31, 0x74, 0xfc } };
+
+// {9475116B-F8C4-4dff-BC19-9601B238557D}
+static const GUID InFlacLangGUID =
+{ 0x9475116b, 0xf8c4, 0x4dff, { 0xbc, 0x19, 0x96, 0x1, 0xb2, 0x38, 0x55, 0x7d } };
+
+// {EA1C197A-D227-474c-A9FD-1C79DE722BDD}
+static const GUID InLineInLangGUID =
+{ 0xea1c197a, 0xd227, 0x474c, { 0xa9, 0xfd, 0x1c, 0x79, 0xde, 0x72, 0x2b, 0xdd } };
+
+// {96374982-0142-41a5-AEDE-244505C45D30}
+static const GUID InWavLangGUID =
+{ 0x96374982, 0x142, 0x41a5, { 0xae, 0xde, 0x24, 0x45, 0x5, 0xc4, 0x5d, 0x30 } };
+
+// {5C5BCA4E-279E-4867-8E24-58C8B186959A}
+static const GUID InVorbisLangGUID =
+{ 0x5c5bca4e, 0x279e, 0x4867, { 0x8e, 0x24, 0x58, 0xc8, 0xb1, 0x86, 0x95, 0x9a } };
+
+// {A786C0B0-69DE-49e2-9461-4F592808B0B3}
+static const GUID ndeLangGUID =
+{ 0xa786c0b0, 0x69de, 0x49e2, { 0x94, 0x61, 0x4f, 0x59, 0x28, 0x8, 0xb0, 0xb3 } };
+
+// {11B847DB-29A7-47ac-B386-43B40385B817}
+static const GUID InNSVLangGUID =
+{ 0x11b847db, 0x29a7, 0x47ac, { 0xb3, 0x86, 0x43, 0xb4, 0x3, 0x85, 0xb8, 0x17 } };
+
+// {5F24DF00-C163-4eaa-AB9D-22F106588C25}
+static const GUID MLOrbLangGUID =
+{ 0x5f24df00, 0xc163, 0x4eaa, { 0xab, 0x9d, 0x22, 0xf1, 0x6, 0x58, 0x8c, 0x25 } };
+
+// {0FED0FEE-C995-4499-AB47-E2482336C046}
+static const GUID InMidiLangGUID =
+{ 0xfed0fee, 0xc995, 0x4499, { 0xab, 0x47, 0xe2, 0x48, 0x23, 0x36, 0xc0, 0x46 } };
+
+// {F30C75C1-D284-4cd5-9CED-2BD9E7869438}
+static const GUID InMp4LangGUID =
+{ 0xf30c75c1, 0xd284, 0x4cd5, { 0x9c, 0xed, 0x2b, 0xd9, 0xe7, 0x86, 0x94, 0x38 } };
+
+// {CD3EEF98-011C-4213-BC16-3F91C937B9B8}
+static const GUID InMp3LangGUID =
+{ 0xcd3eef98, 0x11c, 0x4213, { 0xbc, 0x16, 0x3f, 0x91, 0xc9, 0x37, 0xb9, 0xb8 } };
+
+// {A1A39D49-671A-4c2f-AE42-BEA134EAF6A9}
+static const GUID InModLangGUID =
+{ 0xa1a39d49, 0x671a, 0x4c2f, { 0xae, 0x42, 0xbe, 0xa1, 0x34, 0xea, 0xf6, 0xa9 } };
+
+// {4B567AEB-89CE-4881-9D7D-B31D7B65979A}
+static const GUID DspSpsLangGUID =
+{ 0x4b567aeb, 0x89ce, 0x4881, { 0x9d, 0x7d, 0xb3, 0x1d, 0x7b, 0x65, 0x97, 0x9a } };
+
+// {004A91D9-CCD6-44e5-973A-4B7045C4662B}
+static const GUID OutWaveLangGUID =
+{ 0x4a91d9, 0xccd6, 0x44e5, { 0x97, 0x3a, 0x4b, 0x70, 0x45, 0xc4, 0x66, 0x2b } };
+
+// {A812F3D3-633B-4af6-8749-3BA75290BAC0}
+static const GUID OutDSLangGUID =
+{ 0xa812f3d3, 0x633b, 0x4af6, { 0x87, 0x49, 0x3b, 0xa7, 0x52, 0x90, 0xba, 0xc0 } };
+
+// {C5B78F09-3222-4a64-AA98-F1ABC5A9E355}
+static const GUID InWmLangGUID =
+{ 0xc5b78f09, 0x3222, 0x4a64, { 0xaa, 0x98, 0xf1, 0xab, 0xc5, 0xa9, 0xe3, 0x55 } };
+
+// {C14FAE1D-B410-459f-B008-1A8BE3633000}
+static const GUID burnlibLangGUID =
+{ 0xc14fae1d, 0xb410, 0x459f, { 0xb0, 0x8, 0x1a, 0x8b, 0xe3, 0x63, 0x30, 0x0 } };
+
+// {ACD05A75-030B-4943-A100-540DAD98FB00}
+static const GUID GenFFLangGUID =
+{ 0xacd05a75, 0x30b, 0x4943, { 0xa1, 0x0, 0x54, 0xd, 0xad, 0x98, 0xfb, 0x0 } };
+
+// {0CE0174D-8334-479e-B322-9D80D48FC74D}
+static const GUID MlPlgLangGUID =
+{ 0xce0174d, 0x8334, 0x479e, { 0xb3, 0x22, 0x9d, 0x80, 0xd4, 0x8f, 0xc7, 0x4d } };
+
+// {9E398E5F-EDEC-4dd8-A40D-E29B385A88C0}
+static const GUID playlistLangGUID =
+{ 0x9e398e5f, 0xedec, 0x4dd8, { 0xa4, 0xd, 0xe2, 0x9b, 0x38, 0x5a, 0x88, 0xc0 } };
+
+// {092A97EF-7DC0-41a7-80D1-90DEEB18F12D}
+static const GUID GenCrasherLangGUID =
+{ 0x92a97ef, 0x7dc0, 0x41a7, { 0x80, 0xd1, 0x90, 0xde, 0xeb, 0x18, 0xf1, 0x2d } };
+
+// {D8DBA660-90BD-431d-8F4E-189D6ACB407E}
+static const GUID MlAutoTagLangGUID =
+{ 0xd8dba660, 0x90bd, 0x431d, { 0x8f, 0x4e, 0x18, 0x9d, 0x6a, 0xcb, 0x40, 0x7e } };
+
+// {EC959D43-9122-4807-B928-7B46207AFA49}
+static const GUID InFlvLangGUID =
+{ 0xec959d43, 0x9122, 0x4807, { 0xb9, 0x28, 0x7b, 0x46, 0x20, 0x7a, 0xfa, 0x49 } };
+
+// {2430A7AC-317D-4d64-B33C-E1452A6384A2}
+static const GUID InSwfLangGUID =
+{ 0x2430a7ac, 0x317d, 0x4d64, { 0xb3, 0x3c, 0xe1, 0x45, 0x2a, 0x63, 0x84, 0xa2 } };
+
+// {22661553-8D22-4012-8D3B-0FF8FE57A9ED}
+static const GUID MlImpexLangGUID =
+{ 0x22661553, 0x8d22, 0x4012, { 0x8d, 0x3b, 0xf, 0xf8, 0xfe, 0x57, 0xa9, 0xed } };
+
+// {73760073-560C-433b-BC59-3FCC94CDEA4A}
+static const GUID EncFlacLangGUID =
+{ 0x73760073, 0x560c, 0x433b, { 0xbc, 0x59, 0x3f, 0xcc, 0x94, 0xcd, 0xea, 0x4a } };
+
+// {95C65BA3-3C34-40ec-AE74-8D2C60AAE3C8}
+static const GUID authLangGUID =
+{ 0x95c65ba3, 0x3c34, 0x40ec, { 0xae, 0x74, 0x8d, 0x2c, 0x60, 0xaa, 0xe3, 0xc8 } };
+
+// {CA36E14A-3742-4edc-A40F-2BC87F26B347}
+static const GUID InAviLangGUID =
+{ 0xca36e14a, 0x3742, 0x4edc, { 0xa4, 0xf, 0x2b, 0xc8, 0x7f, 0x26, 0xb3, 0x47 } };
+
+// {5BDA8055-292D-4fcd-8404-884C2A34A8F9}
+static const GUID InMkvLangGUID =
+{ 0x5bda8055, 0x292d, 0x4fcd, { 0x84, 0x4, 0x88, 0x4c, 0x2a, 0x34, 0xa8, 0xf9 } };
+
+// {0233DC7B-7060-43e5-8354-D2F2C7C7611D}
+static const GUID GenMudLangGUID =
+{ 0x233dc7b, 0x7060, 0x43e5, { 0x83, 0x54, 0xd2, 0xf2, 0xc7, 0xc7, 0x61, 0x1d } };
+
+// {DCCF5A41-D16B-452b-8B7A-CFCA3360D8E8}
+static const GUID omBrowserLangGUID =
+{ 0xdccf5a41, 0xd16b, 0x452b, { 0x8b, 0x7a, 0xcf, 0xca, 0x33, 0x60, 0xd8, 0xe8 } };
+
+// Winamp Android plugin (pmp_android.dll)
+// {EBFF6E00-39D8-45e6-B3EC-E3B07A45E6B0}
+static const GUID PmpAndroidLangGUID =
+{ 0xebff6e00, 0x39d8, 0x45e6, { 0xb3, 0xec, 0xe3, 0xb0, 0x7a, 0x45, 0xe6, 0xb0 } };
+
+// Winamp Wifi plugin (pmp_wifi.dll)
+// {3066887B-CA40-4683-897F-4416FE349D7E}
+static const GUID PmpWifiLangGUID =
+{ 0x3066887b, 0xca40, 0x4683, { 0x89, 0x7f, 0x44, 0x16, 0xfe, 0x34, 0x9d, 0x7e } };
+
+
+/*
+** These are guids for known 3rd party lng files
+*/
+
+// WavPack Input plugin (in_wv.dll)
+// {6DE2E465-690E-4df1-B6E2-2A9B33ED3DBB}
+static const GUID InWvLangGuid =
+{ 0x6de2e465, 0x690e, 0x4df1, { 0xb6, 0xe2, 0x2a, 0x9b, 0x33, 0xed, 0x3d, 0xbb } };
+
+// Nullsoft Waveform Wrapper plugin (in_wav.dll)
+// {1CED00E8-4B1B-4e10-A188-9A7C6BBEB421}
+static const GUID InWavLangGuid =
+{ 0x1ced00e8, 0x4b1b, 0x4e10, { 0xa1, 0x88, 0x9a, 0x7c, 0x6b, 0xbe, 0xb4, 0x21 } };
+
+// Jump To File Extra (JTFE) plugin (gen_jumpex.dll)
+// Note: this used to be {243355FE-8B16-48d2-89C3-FD80B3902875} but was changed with
+// v1.1 (the build in 5.58) due to mass of changes to the file to ensure that
+// this will work correctly if an old / partial file is present in the langpack
+// {4693FA7D-2055-4b36-A239-0AD998B5A884}
+static const GUID GenJTFELangGUID =
+{ 0x4693fa7d, 0x2055, 0x4b36, { 0xa2, 0x39, 0xa, 0xd9, 0x98, 0xb5, 0xa8, 0x84 } };
+
+
+// Time Restore & Autoplay (TRAP) plugin (gen_timerestore.dll)
+// {75854C46-1F1A-4fae-B3FA-EEA6B253490E}
+static const GUID GenTRAPLangGUID =
+{ 0x75854c46, 0x1f1a, 0x4fae, { 0xb3, 0xfa, 0xee, 0xa6, 0xb2, 0x53, 0x49, 0xe } };
+
+// Playlist File Remover (PLFR) plugin (gen_play_remove.dll)
+// {58D8276F-12DD-44a7-A930-AA336BC8BA9A}
+static const GUID GenPLFRLangGUID =
+{ 0x58d8276f, 0x12dd, 0x44a7, { 0xa9, 0x30, 0xaa, 0x33, 0x6b, 0xc8, 0xba, 0x9a } };
+
+// Skin Manager plugin (gen_skinmanager.dll)
+// {D877C116-0201-44b2-A003-335C0600BF7A}
+static const GUID GenSkinManagerGUID =
+{ 0xd877c116, 0x201, 0x44b2, { 0xa0, 0x3, 0x33, 0x5c, 0x6, 0x0, 0xbf, 0x7a } };
+
+// Playlist Undo plugin (gen_undo.dll)
+// {3050F3A7-DADB-459f-900A-A8A224B7F32D}
+static const GUID GenUndoLangGUID =
+{ 0x3050f3a7, 0xdadb, 0x459f, { 0x90, 0xa, 0xa8, 0xa2, 0x24, 0xb7, 0xf3, 0x2d } };
+
+// Playlist Separator plugin (in_text.dll)
+// {505CAF53-D00E-4580-AA67-B31DEA6FE946}
+static const GUID InTextLangGUID =
+{ 0x505caf53, 0xd00e, 0x4580, { 0xaa, 0x67, 0xb3, 0x1d, 0xea, 0x6f, 0xe9, 0x46 } };
+
+// One for Nunz plugin (gen_nunzio.dll)
+// {CB659857-7468-40ef-BC51-844449253780}
+static const GUID GenOne4NunzLangGUID =
+{ 0xcb659857, 0x7468, 0x40ef, { 0xbc, 0x51, 0x84, 0x44, 0x49, 0x25, 0x37, 0x80 } };
+
+// Save File As plugin (gen_saveas.dll)
+// {71174948-4965-4f61-90F5-E53FF30E6578}
+static const GUID GenSaveAsLangGUID =
+{ 0x71174948, 0x4965, 0x4f61, { 0x90, 0xf5, 0xe5, 0x3f, 0xf3, 0xe, 0x65, 0x78 } };
+
+// Yar-matey! Playlist Copier plugin (gen_yar.dll)
+// {9725C8BF-B577-4d72-93EF-5FB41D88FFC2}
+static const GUID GenYarLangGUID =
+{ 0x9725c8bf, 0xb577, 0x4d72, { 0x93, 0xef, 0x5f, 0xb4, 0x1d, 0x88, 0xff, 0xc2 } };
+
+// Album Art plugin (gen_classicart.dll)
+// {EAD1E933-6D75-4c2c-B9C4-B4D7F06B7D8D}
+static const GUID GenClasicArtGUID =
+{ 0xead1e933, 0x6d75, 0x4c2c, { 0xb9, 0xc4, 0xb4, 0xd7, 0xf0, 0x6b, 0x7d, 0x8d } };
+
+// Windows 7 Taskbar Integration plugin (gen_win7shell.dll)
+// {7204A532-5D37-415d-B431-272C953B7459}
+static const GUID GenWin7ShellLangGUID =
+{ 0x7204a532, 0x5d37, 0x415d, { 0xb4, 0x31, 0x27, 0x2c, 0x95, 0x3b, 0x74, 0x59 } };
+
+// Find File on Disk plugin (gen_find_on_disk.dll)
+// {8CCF206C-1EA0-484e-88A3-943B4C4AF272}
+static const GUID GenFFODLangGUID =
+{ 0x8ccf206c, 0x1ea0, 0x484e, { 0x88, 0xa3, 0x94, 0x3b, 0x4c, 0x4a, 0xf2, 0x72 } };
+
+// ML Bookmark Categoriser plugin (ml_bkmk.dll)
+// {C3BC5F81-B400-4c64-BCC5-3B758D6BE2E1}
+static const GUID MlBkCatLangGUID =
+{ 0xc3bc5f81, 0xb400, 0x4c64, { 0xbc, 0xc5, 0x3b, 0x75, 0x8d, 0x6b, 0xe2, 0xe1 } };
+
+// Lite'n Winamp Preferences plugin (gen_nopro.dll)
+// {E6C98DDD-FC99-4ccc-B845-79A81B8C1959}
+static const GUID GenNoProLangGUID =
+{ 0xe6c98ddd, 0xfc99, 0x4ccc, { 0xb8, 0x45, 0x79, 0xa8, 0x1b, 0x8c, 0x19, 0x59 } };
+
+// ML Enqueue & Play plugin (ml_enqplay.dll)
+// {0DF6B872-74C3-4236-BE78-E1EAE665C62D}
+static const GUID MlEnqPlayLangGUID =
+{ 0xdf6b872, 0x74c3, 0x4236, { 0xbe, 0x78, 0xe1, 0xea, 0xe6, 0x65, 0xc6, 0x2d } };
+
+// YMAMP (in_ym.dll)
+// {C5F9EFFA-4727-4075-9017-A6BAE72B848C}
+static const GUID InYMAMPLangGUID =
+{ 0xc5f9effa, 0x4727, 0x4075, { 0x90, 0x17, 0xa6, 0xba, 0xe7, 0x2b, 0x84, 0x8c } };
+
+// SNESAmp wrapper (in_snes.dll + in_snes.trb + in_snes_trb.lng)
+// {7B2084F6-B7A7-449b-A133-12F1916F188E}
+static const GUID InSNESWrapperLangGUID =
+{ 0x7b2084f6, 0xb7a7, 0x449b, { 0xa1, 0x33, 0x12, 0xf1, 0x91, 0x6f, 0x18, 0x8e } };
+
+// View Current File Information Hotkey (gen_wolfgang) plugin
+// {E16E2C50-71AB-4188-9193-B9D5FB127F97}
+static const GUID GenWolfgangLangGUID =
+{ 0xe16e2c50, 0x71ab, 0x4188, { 0x91, 0x93, 0xb9, 0xd5, 0xfb, 0x12, 0x7f, 0x97 } };
+
+// Mute Hotkey (gen_mute) plugin
+// {E87B8C7F-51DA-442c-BB2A-D5F941318853}
+static const GUID GenMuteLangGUID =
+{ 0xe87b8c7f, 0x51da, 0x442c, { 0xbb, 0x2a, 0xd5, 0xf9, 0x41, 0x31, 0x88, 0x53 } };
+
+// Play Random Song Hotkey (gen_prs) plugin
+// {1112230B-6928-4f20-BD0E-F559FE6AD66E}
+static const GUID GenPRSLangGUID =
+{ 0x1112230b, 0x6928, 0x4f20, { 0xbd, 0xe, 0xf5, 0x59, 0xfe, 0x6a, 0xd6, 0x6e } };
+
+// Randomise Playlist Hotkey (gen_grp) plugin
+// {554151CC-ADEC-4bdc-8A96-7812BF69058D}
+static const GUID GenRandPLLangGUID =
+{ 0x554151cc, 0xadec, 0x4bdc, { 0x8a, 0x96, 0x78, 0x12, 0xbf, 0x69, 0x5, 0x8d } };
+
+// Clear Current Playlist Hotkey (gen_gcp) plugin
+// {1C71FF32-D2E1-403b-B39C-897AF7F4B4AE}
+static const GUID GenCleardPLLangGUID =
+{ 0x1c71ff32, 0xd2e1, 0x403b, { 0xb3, 0x9c, 0x89, 0x7a, 0xf7, 0xf4, 0xb4, 0xae } };
+
+// EQ Hotkeys (gen_eq_hotkeys) plugin
+// {4EA319B6-955A-4519-807E-A36EEDDC6224}
+static const GUID GenEQGHKLangGUID =
+{ 0x4ea319b6, 0x955a, 0x4519, { 0x80, 0x7e, 0xa3, 0x6e, 0xed, 0xdc, 0x62, 0x24 } };
+
+// Auto EQ (gen_autoeq) plugin
+// {5A2E5855-239A-44a6-A49B-1F495BBFD0D6}
+static const GUID GenAutoEQLangGUID =
+{ 0x5a2e5855, 0x239a, 0x44a6, { 0xa4, 0x9b, 0x1f, 0x49, 0x5b, 0xbf, 0xd0, 0xd6 } };
+
+// CD Menu Tweaker (gen_cd_menu.dll)
+// {A609C17B-44F3-47d8-9B76-C660FF5D3739}
+static const GUID GenCDMenuTweakLangGUID =
+{ 0xa609c17b, 0x44f3, 0x47d8, { 0x9b, 0x76, 0xc6, 0x60, 0xff, 0x5d, 0x37, 0x39 } };
+
+// Three Mode Repeat (gen_3mode.dll)
+// {81EE2A10-80E9-4d22-B363-AEA820AE988F}
+static const GUID Gen3ModeLangGUID =
+{ 0x81ee2a10, 0x80e9, 0x4d22, { 0xb3, 0x63, 0xae, 0xa8, 0x20, 0xae, 0x98, 0x8f } };
+
+// Taskbar Text Mod (gen_ttm.dll)
+// {BBFD3662-DBDF-417a-AAAC-23914D55F24B}
+static const GUID GenTTMLangGUID =
+{ 0xbbfd3662, 0xdbdf, 0x417a, { 0xaa, 0xac, 0x23, 0x91, 0x4d, 0x55, 0xf2, 0x4b } };
+
+// OS Pos Restorer (gen_os_diag.dll)
+// {B5A3AD19-2180-45d7-AFFE-80D2B7575CD1}
+static const GUID GenOSDiagLangGUID =
+{ 0xb5a3ad19, 0x2180, 0x45d7, { 0xaf, 0xfe, 0x80, 0xd2, 0xb7, 0x57, 0x5c, 0xd1 } };
+
+// Shuffle Restorer (gen_shuffle_restorer.dll)
+// {B13ED906-B8E9-4753-B03F-351B05A6E250}
+static const GUID GenShuffleRestorerLangGUID =
+{ 0xb13ed906, 0xb8e9, 0x4753, { 0xb0, 0x3f, 0x35, 0x1b, 0x5, 0xa6, 0xe2, 0x50 } };
+
+// Shuffle Change Blocker (gen_shufblock.dll)
+// {FCCFABF2-6EF3-4651-A43C-F7CA38176889}
+static const GUID GenShuffleBlockerLangGUID =
+{ 0xfccfabf2, 0x6ef3, 0x4651, { 0xa4, 0x3c, 0xf7, 0xca, 0x38, 0x17, 0x68, 0x89 } };
+
+// Single Click 'n' Play (gen_singleclick.dll)
+// {AF67A1E2-8827-4fa3-9F9F-3A3DE2886022}
+static const GUID GenSingleClickLangGUID =
+{ 0xaf67a1e2, 0x8827, 0x4fa3, { 0x9f, 0x9f, 0x3a, 0x3d, 0xe2, 0x88, 0x60, 0x22 } };
+
+// No Minimise (gen_no_min.dll)
+// {8BCF7C51-6F88-455f-88FD-0B6911650997}
+static const GUID GenNoMinimiseLangGUID =
+{ 0x8bcf7c51, 0x6f88, 0x455f, { 0x88, 0xfd, 0xb, 0x69, 0x11, 0x65, 0x9, 0x97 } };
+
+// Repeater (gen_repeater.dll)
+// {1C4C8774-8BBC-4f11-851E-936BF5C85E96}
+static const GUID GenRepeaterLangGUID =
+{ 0x1c4c8774, 0x8bbc, 0x4f11, { 0x85, 0x1e, 0x93, 0x6b, 0xf5, 0xc8, 0x5e, 0x96 } };
+
+// Alt Close (gen_alt_close.dll)
+// {0FD70024-FA0E-4f4f-A0D4-CD560913C146}
+static const GUID GenAltCloseLangGUID =
+{ 0xfd70024, 0xfa0e, 0x4f4f, { 0xa0, 0xd4, 0xcd, 0x56, 0x9, 0x13, 0xc1, 0x46 } };
+
+// ML Exporter (ml_exporter.dll)
+// {3B441F40-E8E9-46bf-B399-556FB6CD4295}
+static const GUID MLExporterLangGUID =
+{ 0x3b441f40, 0xe8e9, 0x46bf, { 0xb3, 0x99, 0x55, 0x6f, 0xb6, 0xcd, 0x42, 0x95 } };
+
+// Silence Detector DSP (dsp_silence_detect.dll)
+// {15CCEBE6-C1F5-4246-A7B0-A6E66025C01C}
+static const GUID DspSilenceDetectLangGUID =
+{ 0x15ccebe6, 0xc1f5, 0x4246, { 0xa7, 0xb0, 0xa6, 0xe6, 0x60, 0x25, 0xc0, 0x1c } };
+
+// Skinned Preferences (gen_prefs_skin.dll)
+// {AE99B23F-0E51-4a99-9AB0-21AEA7B4B3CA}
+static const GUID GenSkinPrefsLangGUID =
+{ 0xae99b23f, 0xe51, 0x4a99, { 0x9a, 0xb0, 0x21, 0xae, 0xa7, 0xb4, 0xb3, 0xca } };
+
+// Jump to Track (gen_jtt.dll)
+// {D7D804A3-0794-4761-B43B-4873E5B41873}
+static const GUID GenJTTLangGUID =
+{ 0xd7d804a3, 0x794, 0x4761, { 0xb4, 0x3b, 0x48, 0x73, 0xe5, 0xb4, 0x18, 0x73 } };
+
+// Jump to Time Extra (gen_jumptotime.dll)
+// {9B5DC220-F06A-44cc-909E-D2157513F280}
+static const GUID GenJumpToTimeLangGUID =
+{ 0x9b5dc220, 0xf06a, 0x44cc, { 0x90, 0x9e, 0xd2, 0x15, 0x75, 0x13, 0xf2, 0x80 } };
+
+// Jumper (gen_jumper.dll)
+// {5D793BF9-0903-4bc9-A78D-D10AB92C7EE5}
+static const GUID GenJumperLangGUID =
+{ 0x5d793bf9, 0x903, 0x4bc9, { 0xa7, 0x8d, 0xd1, 0xa, 0xb9, 0x2c, 0x7e, 0xe5 } };
+
+// One Click Show and Hide (gen_one_click.dll)
+// {8F3FCFB3-1F5A-43c6-A71E-891026479301}
+static const GUID GenOneClickLangGUID =
+{ 0x8f3fcfb3, 0x1f5a, 0x43c6, { 0xa7, 0x1e, 0x89, 0x10, 0x26, 0x47, 0x93, 0x1 } };
+
+// Playback Excluder (gen_exclude.dll)
+// {15C44197-EBC5-4cc7-B935-EDE40C9C1AF6}
+static const GUID GenPlaybackExluderLangGUID =
+{ 0x15c44197, 0xebc5, 0x4cc7, { 0xb9, 0x35, 0xed, 0xe4, 0xc, 0x9c, 0x1a, 0xf6 } };
+
+// Close to Notification Area (gen_d3x7r0.dll)
+// {2A3BC93A-99FF-469a-A94B-576218CF6265}
+static const GUID GenCloseToNotAreaLangGUID =
+{ 0x2a3bc93a, 0x99ff, 0x469a, { 0xa9, 0x4b, 0x57, 0x62, 0x18, 0xcf, 0x62, 0x65 } };
+
+// Crop Die (gen_crop_die.dll)
+// {9E79066C-58C5-41b9-9361-C1951DA989CD}
+static const GUID GenCropDieLangGUID =
+{ 0x9e79066c, 0x58c5, 0x41b9, { 0x93, 0x61, 0xc1, 0x95, 0x1d, 0xa9, 0x89, 0xcd } };
+
+// Play Selected Song Hotkey (gen_gpss.dll)
+// {94E8B2B6-685F-484b-9938-EC929F6874EC}
+static const GUID GenPlaySelGHKLangGUID =
+{ 0x94e8b2b6, 0x685f, 0x484b, { 0x99, 0x38, 0xec, 0x92, 0x9f, 0x68, 0x74, 0xec } };
+
+// Close After Current (gen_cac.dll)
+// {8B6A33FB-A6C5-49a0-A52A-0A0F14913BB2}
+static const GUID GenCACLangGUID =
+{ 0x8b6a33fb, 0xa6c5, 0x49a0, { 0xa5, 0x2a, 0xa, 0xf, 0x14, 0x91, 0x3b, 0xb2 } };
+
+// Enhancer Wrapper DSP (dsp_enhancer.dll)
+// {78842EF6-CCA2-410c-9E23-C498ABB24373}
+static const GUID DspEnhancerLangGUID =
+{ 0x78842ef6, 0xcca2, 0x410c, { 0x9e, 0x23, 0xc4, 0x98, 0xab, 0xb2, 0x43, 0x73 } };
+
+// Shutdown on Close (gen_soc.dll)
+// {CAE88304-4A0B-46e5-8B50-BEDFAE00FA6A}
+static const GUID GenSOCLangGUID =
+{ 0xcae88304, 0x4a0b, 0x46e5, { 0x8b, 0x50, 0xbe, 0xdf, 0xae, 0x0, 0xfa, 0x6a } };
+
+// Mouse Wheel Blocker (gen_mwblock.dll)
+// {C9D6697C-4C7B-4aec-A4C7-45395F0771EA}
+static const GUID GenMouseWheelBlockLangGUID =
+{ 0xc9d6697c, 0x4c7b, 0x4aec, { 0xa4, 0xc7, 0x45, 0x39, 0x5f, 0x7, 0x71, 0xea } };
+
+// ML Icon Control plugin (ml_icon_control.dll)
+// {4A55AE4D-B3CB-42df-A94E-53588FD761BA}
+static const GUID MlIconControlLangGUID=
+{ 0x4a55ae4d, 0xb3cb, 0x42df, { 0xa9, 0x4e, 0x53, 0x58, 0x8f, 0xd7, 0x61, 0xba } };
+
+// File Copier plug-in (gen_copy.dll)
+// {A2121FC9-6FC3-4a56-88F2-A36FF64D10EA}
+static const GUID GenFileCopierLangGUID =
+{ 0xa2121fc9, 0x6fc3, 0x4a56, { 0x88, 0xf2, 0xa3, 0x6f, 0xf6, 0x4d, 0x10, 0xea } };
+
+// Shoutcast Source DSP plug-in
+// {FD4D4A01-C337-4144-85D7-00678B3B2D2D}
+static const GUID DspShoutcastLangGUID =
+{ 0xfd4d4a01, 0xc337, 0x4144, { 0x85, 0xd7, 0x0, 0x67, 0x8b, 0x3b, 0x2d, 0x2d } };
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Wasabi.cpp b/Src/Plugins/Input/in_wv/wasabi/Wasabi.cpp
new file mode 100644
index 00000000..12d0eca3
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Wasabi.cpp
@@ -0,0 +1,161 @@
+#include "Winamp/in2.h"
+#include "Winamp/wa_ipc.h"
+#include "Wasabi.h"
+
+AlbumArtFactory albumArtFactory;
+
+class WavPack_AlbumArtProvider : public svc_albumArtProvider
+{
+public:
+ bool IsMine(const wchar_t *filename);
+ int ProviderType();
+ // implementation note: use WASABI_API_MEMMGR to alloc bits and mimetype, so that the recipient can free through that
+ int GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mimeType);
+ int SetAlbumArtData(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mimeType);
+ int DeleteAlbumArt(const wchar_t *filename, const wchar_t *type);
+protected:
+ RECVS_DISPATCH;
+};
+
+static const wchar_t *GetLastCharactercW(const wchar_t *string)
+{
+ if (!string || !*string)
+ return string;
+
+ return CharPrevW(string, string+lstrlenW(string));
+}
+
+static const wchar_t *scanstr_backW(const wchar_t *str, const wchar_t *toscan, const wchar_t *defval)
+{
+ const wchar_t *s = GetLastCharactercW(str);
+ if (!str[0]) return defval;
+ if (!toscan || !toscan[0]) return defval;
+ while (1)
+ {
+ const wchar_t *t = toscan;
+ while (*t)
+ {
+ if (*t == *s) return s;
+ t = CharNextW(t);
+ }
+ t = CharPrevW(str, s);
+ if (t == s)
+ return defval;
+ s = t;
+ }
+}
+
+static const wchar_t *extensionW(const wchar_t *fn)
+{
+ const wchar_t *end = scanstr_backW(fn, L"./\\", 0);
+ if (!end)
+ return (fn+lstrlenW(fn));
+
+ if (*end == L'.')
+ return end+1;
+
+ return (fn+lstrlenW(fn));
+}
+
+int WavPack_HandlesExtension(const wchar_t *extension);
+bool WavPack_AlbumArtProvider::IsMine(const wchar_t *filename)
+{
+ const wchar_t *extension = extensionW(filename);
+ if (extension && *extension)
+ {
+ return WavPack_HandlesExtension(extension) != 0;
+ }
+ return false;
+}
+
+int WavPack_AlbumArtProvider::ProviderType()
+{
+ return ALBUMARTPROVIDER_TYPE_EMBEDDED;
+}
+
+int WavPack_GetAlbumArt(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mime_type);
+int WavPack_AlbumArtProvider::GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mime_type)
+{
+ return WavPack_GetAlbumArt(filename, type, bits, len, mime_type);
+}
+
+int WavPack_SetAlbumArt(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mime_type);
+int WavPack_AlbumArtProvider::SetAlbumArtData(const wchar_t *filename, const wchar_t *type, void *bits, size_t len, const wchar_t *mime_type)
+{
+ return WavPack_SetAlbumArt(filename, type, bits, len, mime_type);
+}
+
+int WavPack_DeleteAlbumArt(const wchar_t *filename, const wchar_t *type);
+int WavPack_AlbumArtProvider::DeleteAlbumArt(const wchar_t *filename, const wchar_t *type)
+{
+ return WavPack_DeleteAlbumArt(filename, type);
+}
+
+#define CBCLASS WavPack_AlbumArtProvider
+START_DISPATCH;
+CB(SVC_ALBUMARTPROVIDER_PROVIDERTYPE, ProviderType);
+CB(SVC_ALBUMARTPROVIDER_GETALBUMARTDATA, GetAlbumArtData);
+CB(SVC_ALBUMARTPROVIDER_ISMINE, IsMine);
+CB(SVC_ALBUMARTPROVIDER_SETALBUMARTDATA, SetAlbumArtData);
+CB(SVC_ALBUMARTPROVIDER_DELETEALBUMART, DeleteAlbumArt);
+END_DISPATCH;
+#undef CBCLASS
+
+static WavPack_AlbumArtProvider albumArtProvider;
+
+// {A558560E-4334-446a-9219-E1F34F518ADE}
+static const GUID wavpack_albumartproviderGUID =
+{ 0xa558560e, 0x4334, 0x446a, { 0x92, 0x19, 0xe1, 0xf3, 0x4f, 0x51, 0x8a, 0xde } };
+
+FOURCC AlbumArtFactory::GetServiceType()
+{
+ return svc_albumArtProvider::SERVICETYPE;
+}
+
+const char *AlbumArtFactory::GetServiceName()
+{
+ return "WavPack Album Art Provider";
+}
+
+GUID AlbumArtFactory::GetGUID()
+{
+ return wavpack_albumartproviderGUID;
+}
+
+void *AlbumArtFactory::GetInterface(int global_lock)
+{
+ return &albumArtProvider;
+}
+
+int AlbumArtFactory::SupportNonLockingInterface()
+{
+ return 1;
+}
+
+int AlbumArtFactory::ReleaseInterface(void *ifc)
+{
+ return 1;
+}
+
+const char *AlbumArtFactory::GetTestString()
+{
+ return 0;
+}
+
+int AlbumArtFactory::ServiceNotify(int msg, int param1, int param2)
+{
+ return 1;
+}
+
+#define CBCLASS AlbumArtFactory
+START_DISPATCH;
+CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
+CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
+CB(WASERVICEFACTORY_GETGUID, GetGUID)
+CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
+CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
+CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
+CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
+CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Wasabi.h b/Src/Plugins/Input/in_wv/wasabi/Wasabi.h
new file mode 100644
index 00000000..c606fac7
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Wasabi.h
@@ -0,0 +1,66 @@
+#ifndef NULLSOFT_API_H
+#define NULLSOFT_API_H
+
+#include "api/service/api_service.h"
+extern api_service *serviceManager;
+#define WASABI_API_SVC serviceManager
+
+#include "api/service/waservicefactory.h"
+
+#include "Agave/Config/api_config.h"
+extern api_config *configApi;
+#define AGAVE_API_CONFIG configApi
+
+#include "api/memmgr/api_memmgr.h"
+extern api_memmgr *memmgr;
+#define WASABI_API_MEMMGR memmgr
+
+#include "Agave/Language/api_language.h"
+
+#include "Agave/AlbumArt/svc_albumArtProvider.h"
+
+template <class api_T>
+static void ServiceBuild(api_T *&api_t, GUID factoryGUID_t)
+{
+ if (WASABI_API_SVC)
+ {
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(factoryGUID_t);
+ if (factory)
+ api_t = (api_T *)factory->getInterface();
+ }
+}
+
+template <class api_T>
+static void ServiceRelease(api_T *api_t, GUID factoryGUID_t)
+{
+ if (WASABI_API_SVC)
+ {
+ waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(factoryGUID_t);
+ if (factory)
+ factory->releaseInterface(api_t);
+ }
+}
+
+class AlbumArtFactory : public waServiceFactory
+{
+public:
+ FOURCC GetServiceType();
+ const char *GetServiceName();
+ GUID GetGUID();
+ void *GetInterface(int global_lock);
+ int SupportNonLockingInterface();
+ int ReleaseInterface(void *ifc);
+ const char *GetTestString();
+ int ServiceNotify(int msg, int param1, int param2);
+
+protected:
+ RECVS_DISPATCH;
+};
+
+extern AlbumArtFactory albumArtFactory;
+
+// {B6CB4A7C-A8D0-4c55-8E60-9F7A7A23DA0F}
+static const GUID playbackConfigGroupGUID =
+{ 0xb6cb4a7c, 0xa8d0, 0x4c55, { 0x8e, 0x60, 0x9f, 0x7a, 0x7a, 0x23, 0xda, 0xf } };
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Winamp/DSP.H b/Src/Plugins/Input/in_wv/wasabi/Winamp/DSP.H
new file mode 100644
index 00000000..465fb0a1
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Winamp/DSP.H
@@ -0,0 +1,65 @@
+#ifndef NULLSOFT_WINAMP_DSP_H
+#define NULLSOFT_WINAMP_DSP_H
+// DSP plugin interface
+
+// notes:
+// any window that remains in foreground should optimally pass unused
+// keystrokes to the parent (winamp's) window, so that the user
+// can still control it. As for storing configuration,
+// Configuration data should be stored in <dll directory>\plugin.ini
+// (look at the vis plugin for configuration code)
+
+typedef struct winampDSPModule {
+ char *description; // description
+ HWND hwndParent; // parent window (filled in by calling app)
+ HINSTANCE hDllInstance; // instance handle to this DLL (filled in by calling app)
+
+ void (*Config)(struct winampDSPModule *this_mod); // configuration dialog (if needed)
+ int (*Init)(struct winampDSPModule *this_mod); // 0 on success, creates window, etc (if needed)
+
+ // modify waveform samples: returns number of samples to actually write
+ // (typically numsamples, but no more than twice numsamples, and no less than half numsamples)
+ // numsamples should always be at least 128. should, but I'm not sure
+ int (*ModifySamples)(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate);
+
+ void (*Quit)(struct winampDSPModule *this_mod); // called when unloading
+
+ void *userData; // user data, optional
+} winampDSPModule;
+
+typedef struct {
+ int version; // DSP_HDRVER
+ char *description; // description of library
+ winampDSPModule* (*getModule)(int); // module retrieval function
+ int (*sf)(int key); // DSP_HDRVER == 0x21
+} winampDSPHeader;
+
+// exported symbols
+#ifdef USE_DSP_HDR_HWND
+typedef winampDSPHeader* (*winampDSPGetHeaderType)(HWND);
+#define DSP_HDRVER 0x22
+
+#else
+
+typedef winampDSPHeader* (*winampDSPGetHeaderType)(HWND);
+// header version: 0x20 == 0.20 == winamp 2.0
+#define DSP_HDRVER 0x20
+#endif
+
+// return values from the winampUninstallPlugin(HINSTANCE hdll, HWND parent, int param)
+// which determine if we can uninstall the plugin immediately or on winamp restart
+#define DSP_PLUGIN_UNINSTALL_NOW 0x0
+#define DSP_PLUGIN_UNINSTALL_REBOOT 0x1
+//
+// uninstall support was added from 5.0+ and uninstall now support from 5.5+
+// it is down to you to ensure that if uninstall now is returned that it will not cause a crash
+// (ie don't use if you've been subclassing the main window)
+
+// Version note:
+//
+// Added passing of Winamp's main hwnd in the call to the exported winampDSPHeader()
+// which allows for primarily the use of localisation features with the bundled plugins.
+// If you want to use the new version then either you can edit you version of dsp.h or
+// you can add USE_DSP_HDR_HWND to your project's defined list or before use of dsp.h
+//
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Winamp/GEN.H b/Src/Plugins/Input/in_wv/wasabi/Winamp/GEN.H
new file mode 100644
index 00000000..b010c100
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Winamp/GEN.H
@@ -0,0 +1,37 @@
+#ifndef NULLSOFT_WINAMP_GEN_H
+#define NULLSOFT_WINAMP_GEN_H
+
+#include <windows.h>
+
+#define GEN_INIT_SUCCESS 0
+
+// return values from the winampUninstallPlugin(HINSTANCE hdll, HWND parent, int param)
+// which determine if we can uninstall the plugin immediately or on winamp restart
+//
+// uninstall support was added from 5.0+ and uninstall now support from 5.5+
+// it is down to you to ensure that if uninstall now is returned that it will not cause a crash
+// (ie don't use if you've been subclassing the main window)
+#define GEN_PLUGIN_UNINSTALL_NOW 0x1
+#define GEN_PLUGIN_UNINSTALL_REBOOT 0x0
+
+typedef struct {
+ int version;
+ char *description;
+ int (*init)();
+ void (*config)();
+ void (*quit)();
+ HWND hwndParent;
+ HINSTANCE hDllInstance;
+} winampGeneralPurposePlugin;
+
+#define GPPHDR_VER 0x10
+#ifdef __cplusplus
+extern "C" {
+#endif
+//extern winampGeneralPurposePlugin *gen_plugins[256];
+typedef winampGeneralPurposePlugin * (*winampGeneralPurposePluginGetter)();
+#ifdef __cplusplus
+}
+#endif
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Winamp/IN2.H b/Src/Plugins/Input/in_wv/wasabi/Winamp/IN2.H
new file mode 100644
index 00000000..67e1a2e4
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Winamp/IN2.H
@@ -0,0 +1,138 @@
+
+#ifndef NULLSOFT_WINAMP_IN2H
+#define NULLSOFT_WINAMP_IN2H
+#include "out.h"
+
+// note: exported symbol is now winampGetInModule2.
+
+#define IN_UNICODE 0x0F000000
+
+#ifdef UNICODE_INPUT_PLUGIN
+#define in_char wchar_t
+#define IN_VER (IN_UNICODE | 0x100)
+#else
+#define in_char char
+#define IN_VER 0x100
+#endif
+
+#define IN_MODULE_FLAG_USES_OUTPUT_PLUGIN 1
+// By default, Winamp assumes that your input plugin wants to use Winamp's EQ, and doesn't do replay gain
+// if you handle any of these yourself (EQ, Replay Gain adjustments), then set these flags accordingly
+#define IN_MODULE_FLAG_EQ 2 // set this if you do your own EQ
+#define IN_MODULE_FLAG_REPLAYGAIN 8 // set this if you adjusted volume for replay gain
+ // for tracks with no replay gain metadata, you should clear this flag
+ // UNLESS you handle "non_replaygain" gain adjustment yourself
+#define IN_MODULE_FLAG_REPLAYGAIN_PREAMP 16 // use this if you queried for the replay gain preamp parameter and used it
+ // this parameter is new to 5.54
+typedef struct
+{
+ int version; // module type (IN_VER)
+ char *description; // description of module, with version string
+
+ HWND hMainWindow; // winamp's main window (filled in by winamp)
+ HINSTANCE hDllInstance; // DLL instance handle (Also filled in by winamp)
+
+ char *FileExtensions; // "mp3\0Layer 3 MPEG\0mp2\0Layer 2 MPEG\0mpg\0Layer 1 MPEG\0"
+ // May be altered from Config, so the user can select what they want
+
+ int is_seekable; // is this stream seekable?
+ int UsesOutputPlug; // does this plug-in use the output plug-ins? (musn't ever change, ever :)
+ // note that this has turned into a "flags" field
+ // see IN_MODULE_FLAG_*
+
+ void (*Config)(HWND hwndParent); // configuration dialog
+ void (*About)(HWND hwndParent); // about dialog
+
+ void (*Init)(); // called at program init
+ void (*Quit)(); // called at program quit
+
+#define GETFILEINFO_TITLE_LENGTH 2048
+ void (*GetFileInfo)(const in_char *file, in_char *title, int *length_in_ms); // if file == NULL, current playing is used
+
+#define INFOBOX_EDITED 0
+#define INFOBOX_UNCHANGED 1
+ int (*InfoBox)(const in_char *file, HWND hwndParent);
+
+ int (*IsOurFile)(const in_char *fn); // called before extension checks, to allow detection of mms://, etc
+ // playback stuff
+ int (*Play)(const in_char *fn); // return zero on success, -1 on file-not-found, some other value on other (stopping winamp) error
+ void (*Pause)(); // pause stream
+ void (*UnPause)(); // unpause stream
+ int (*IsPaused)(); // ispaused? return 1 if paused, 0 if not
+ void (*Stop)(); // stop (unload) stream
+
+ // time stuff
+ int (*GetLength)(); // get length in ms
+ int (*GetOutputTime)(); // returns current output time in ms. (usually returns outMod->GetOutputTime()
+ void (*SetOutputTime)(int time_in_ms); // seeks to point in stream (in ms). Usually you signal your thread to seek, which seeks and calls outMod->Flush()..
+
+ // volume stuff
+ void (*SetVolume)(int volume); // from 0 to 255.. usually just call outMod->SetVolume
+ void (*SetPan)(int pan); // from -127 to 127.. usually just call outMod->SetPan
+
+ // in-window builtin vis stuff
+
+ void (*SAVSAInit)(int maxlatency_in_ms, int srate); // call once in Play(). maxlatency_in_ms should be the value returned from outMod->Open()
+ // call after opening audio device with max latency in ms and samplerate
+ void (*SAVSADeInit)(); // call in Stop()
+
+
+ // simple vis supplying mode
+ void (*SAAddPCMData)(void *PCMData, int nch, int bps, int timestamp);
+ // sets the spec data directly from PCM data
+ // quick and easy way to get vis working :)
+ // needs at least 576 samples :)
+
+ // advanced vis supplying mode, only use if you're cool. Use SAAddPCMData for most stuff.
+ int (*SAGetMode)(); // gets csa (the current type (4=ws,2=osc,1=spec))
+ // use when calling SAAdd()
+ int (*SAAdd)(void *data, int timestamp, int csa); // sets the spec data, filled in by winamp
+
+
+ // vis stuff (plug-in)
+ // simple vis supplying mode
+ void (*VSAAddPCMData)(void *PCMData, int nch, int bps, int timestamp); // sets the vis data directly from PCM data
+ // quick and easy way to get vis working :)
+ // needs at least 576 samples :)
+
+ // advanced vis supplying mode, only use if you're cool. Use VSAAddPCMData for most stuff.
+ int (*VSAGetMode)(int *specNch, int *waveNch); // use to figure out what to give to VSAAdd
+ int (*VSAAdd)(void *data, int timestamp); // filled in by winamp, called by plug-in
+
+
+ // call this in Play() to tell the vis plug-ins the current output params.
+ void (*VSASetInfo)(int srate, int nch); // <-- Correct (benski, dec 2005).. old declaration had the params backwards
+
+
+ // dsp plug-in processing:
+ // (filled in by winamp, calld by input plug)
+
+ // returns 1 if active (which means that the number of samples returned by dsp_dosamples
+ // could be greater than went in.. Use it to estimate if you'll have enough room in the
+ // output buffer
+ int (*dsp_isactive)();
+
+ // returns number of samples to output. This can be as much as twice numsamples.
+ // be sure to allocate enough buffer for samples, then.
+ int (*dsp_dosamples)(short int *samples, int numsamples, int bps, int nch, int srate);
+
+
+ // eq stuff
+ void (*EQSet)(int on, char data[10], int preamp); // 0-64 each, 31 is +0, 0 is +12, 63 is -12. Do nothing to ignore.
+
+ // info setting (filled in by winamp)
+ void (*SetInfo)(int bitrate, int srate, int stereo, int synched); // if -1, changes ignored? :)
+
+ Out_Module *outMod; // filled in by winamp, optionally used :)
+} In_Module;
+
+// return values from the winampUninstallPlugin(HINSTANCE hdll, HWND parent, int param)
+// which determine if we can uninstall the plugin immediately or on winamp restart
+//
+// uninstall support was added from 5.0+ and uninstall now support from 5.5+
+// it is down to you to ensure that if uninstall now is returned that it will not cause a crash
+// (ie don't use if you've been subclassing the main window)
+#define IN_PLUGIN_UNINSTALL_NOW 0x1
+#define IN_PLUGIN_UNINSTALL_REBOOT 0x0
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Winamp/api_audiostream.h b/Src/Plugins/Input/in_wv/wasabi/Winamp/api_audiostream.h
new file mode 100644
index 00000000..7a8c8289
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Winamp/api_audiostream.h
@@ -0,0 +1,65 @@
+#ifndef NULLSOFT_API_AUDIOSTREAM_H
+#define NULLSOFT_API_AUDIOSTREAM_H
+
+#include <bfc/dispatch.h>
+
+class api_audiostream : public Dispatchable
+{
+protected:
+ api_audiostream() {}
+ ~api_audiostream() {}
+public:
+ /* returns number of bytes written to buffer.
+ * a return value of 0 means EOF
+ */
+ size_t ReadAudio(void *buffer, size_t sizeBytes); // TODO: killswitch and error code
+
+ size_t ReadAudio(void *buffer, size_t, int *killswitch, int *errorCode);
+ /* Seeks to a point in the stream in milliseconds
+ * returns TRUE if successful, FALSE otherwise
+ */
+ int SeekToTimeMs(int millisecs);
+
+ /* returns 1 if this stream is seekable using SeekToTime, 0 otherwise
+ */
+ int CanSeek();
+public:
+ DISPATCH_CODES
+ {
+ API_AUDIOSTREAM_READAUDIO = 10,
+ API_AUDIOSTREAM_READAUDIO2 = 11,
+ API_AUDIOSTREAM_SEEKTOTIMEMS = 20,
+ API_AUDIOSTREAM_CANSEEK = 30,
+ };
+};
+
+inline size_t api_audiostream::ReadAudio(void *buffer, size_t sizeBytes)
+{
+ return _call(API_AUDIOSTREAM_READAUDIO, (size_t)0, buffer, sizeBytes);
+}
+
+inline size_t api_audiostream::ReadAudio(void *buffer, size_t sizeBytes, int *killswitch, int *errorCode)
+{
+ void *params[4] = { &buffer, &sizeBytes, &killswitch, &errorCode};
+ size_t retval;
+
+ if (_dispatch(API_AUDIOSTREAM_READAUDIO2, &retval, params, 4))
+ return retval;
+ else
+ {
+ *errorCode=0;
+ return ReadAudio(buffer, sizeBytes);
+ }
+}
+
+inline int api_audiostream::SeekToTimeMs(int millisecs)
+{
+ return _call(API_AUDIOSTREAM_SEEKTOTIMEMS, (int)0, millisecs);
+}
+
+inline int api_audiostream::CanSeek()
+{
+ return _call(API_AUDIOSTREAM_CANSEEK, (int)0);
+}
+
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/Winamp/api_decodefile.h b/Src/Plugins/Input/in_wv/wasabi/Winamp/api_decodefile.h
new file mode 100644
index 00000000..9c4d366e
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Winamp/api_decodefile.h
@@ -0,0 +1,99 @@
+#ifndef NULLSOFT_API_DECODEFILE_H
+#define NULLSOFT_API_DECODEFILE_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+#include "api_audiostream.h"
+
+enum
+{
+ API_DECODEFILE_SUCCESS = 0,
+ API_DECODEFILE_FAILURE = 1,
+
+ API_DECODEFILE_UNSUPPORTED = 2, // type is unsupported
+ API_DECODEFILE_NO_INTERFACE = 3, // type is supported, but plugin does provide any interfaces for direct decoding
+ API_DECODEFILE_WINAMP_PRO = 4, // user has to pay $$$ to do this
+ API_DECODEFILE_NO_RIGHTS = 5, // user is not allowed to decode this file (e.g. DRM)
+ API_DECODEFILE_BAD_RESAMPLE = 6, // Winamp is unable to resample this file to CDDA format (stereo 16bit 44.1kHz)
+};
+
+enum
+{
+ AUDIOPARAMETERS_FLOAT = 1,
+};
+struct AudioParameters
+{
+public:
+ AudioParameters() : bitsPerSample(0), channels(0), sampleRate(0), sampleRateReal(0.f), sizeBytes((size_t) - 1), errorCode(API_DECODEFILE_SUCCESS), flags(0)
+ {}
+ size_t bitsPerSample;
+ size_t channels;
+ size_t sampleRate;
+ float sampleRateReal; // yes this is duplicate.
+ int flags;
+ size_t sizeBytes; // total size of decoded file, (size_t)-1 means don't know
+ int errorCode;
+};
+
+class api_decodefile : public Dispatchable
+{
+public:
+ /* OpenAudioBackground gives you back an api_audiostream that you can use to get decompressed bits
+ * if it returns 0, check parameters->errorCode for the failure reason
+ * fill parameters with desired values (0 if you don't care)
+ * the decoder will _do its best_ to satisfy your passed-in audio parameters
+ * but this API does not guarantee them, so be sure to check the parameters struct after the function returns
+ * it's **UP TO YOU** to do any necessary conversion (sample rate, channels, bits-per-sample) if the decoder can't do it
+ */
+ api_audiostream *OpenAudioBackground(const wchar_t *filename, AudioParameters *parameters);
+ /* OpenAudio is the same as OpenAudioBackground
+ * but, it will use the input plugin system to decode if necessary
+ * so it's best to use this in a separate winamp.exe
+ * to be honest, it was designed for internal use in the CD burner
+ * so it's best not to use this one at all
+ */
+ api_audiostream *OpenAudio(const wchar_t *filename, AudioParameters *parameters);
+
+ void CloseAudio(api_audiostream *audioStream);
+ /* verifies that a decoder exists to decompress this filename.
+ this is not a guarantee tgat the file is openable, just that it can be matched to a decoder */
+ bool DecoderExists(const wchar_t *filename);
+public:
+ DISPATCH_CODES
+ {
+ API_DECODEFILE_OPENAUDIO = 10,
+ API_DECODEFILE_OPENAUDIO2 = 11,
+ API_DECODEFILE_CLOSEAUDIO = 20,
+ API_DECODEFILE_DECODEREXISTS = 30,
+ };
+};
+
+inline api_audiostream *api_decodefile::OpenAudio(const wchar_t *filename, AudioParameters *parameters)
+{
+ return _call(API_DECODEFILE_OPENAUDIO, (api_audiostream *)0, filename, parameters);
+}
+
+inline api_audiostream *api_decodefile::OpenAudioBackground(const wchar_t *filename, AudioParameters *parameters)
+{
+ return _call(API_DECODEFILE_OPENAUDIO2, (api_audiostream *)0, filename, parameters);
+}
+
+
+inline void api_decodefile::CloseAudio(api_audiostream *audioStream)
+{
+ _voidcall(API_DECODEFILE_CLOSEAUDIO, audioStream);
+}
+
+inline bool api_decodefile::DecoderExists(const wchar_t *filename)
+{
+ return _call(API_DECODEFILE_DECODEREXISTS, (bool)true, filename); // we default to true so that an old implementation doesn't break completely
+}
+
+// {9B4188F5-4295-48ab-B50C-F2B0BB56D242}
+static const GUID decodeFileGUID =
+ {
+ 0x9b4188f5, 0x4295, 0x48ab, { 0xb5, 0xc, 0xf2, 0xb0, 0xbb, 0x56, 0xd2, 0x42 }
+ };
+
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Winamp/api_random.h b/Src/Plugins/Input/in_wv/wasabi/Winamp/api_random.h
new file mode 100644
index 00000000..d0618f16
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Winamp/api_random.h
@@ -0,0 +1,78 @@
+#ifndef NULLSOFT_API_RANDOM_H
+#define NULLSOFT_API_RANDOM_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+
+typedef int (*RandomGenerator)(void);
+typedef unsigned long (*UnsignedRandomGenerator)(void);
+
+class api_random : public Dispatchable
+{
+protected:
+ api_random() {}
+ ~api_random() {}
+public:
+ RandomGenerator GetFunction();
+ UnsignedRandomGenerator GetUnsignedFunction();
+ int GetNumber();
+ int GetPositiveNumber();
+ float GetFloat(); // [0-1]
+ float GetFloat_LessThanOne(); // [0-1)
+ float GetFloat_LessThanOne_NotZero(); // (0-1)
+ double GetDouble(); // [0-1)
+public:
+ DISPATCH_CODES
+ {
+ API_RANDOM_GETFUNCTION = 10,
+ API_RANDOM_GETFUNCTION_UNSIGNED = 11,
+ API_RANDOM_GETNUMBER = 20,
+ API_RANDOM_GETPOSITIVENUMBER = 30,
+ API_RANDOM_GETFLOAT = 40,
+ API_RANDOM_GETFLOAT2 = 41,
+ API_RANDOM_GETFLOAT3 = 42,
+ API_RANDOM_GETDOUBLE = 50,
+ };
+};
+
+inline RandomGenerator api_random::GetFunction()
+{
+ return _call(API_RANDOM_GETFUNCTION, (RandomGenerator )0);
+}
+inline UnsignedRandomGenerator api_random::GetUnsignedFunction()
+{
+ return _call(API_RANDOM_GETFUNCTION_UNSIGNED, (UnsignedRandomGenerator )0);
+}
+
+inline int api_random::GetNumber()
+{
+ return _call(API_RANDOM_GETNUMBER, 0);
+}
+inline int api_random::GetPositiveNumber()
+{
+ return _call(API_RANDOM_GETPOSITIVENUMBER, 0);
+}
+inline float api_random::GetFloat()
+{
+ return _call(API_RANDOM_GETFLOAT, 0.f);
+}
+inline float api_random::GetFloat_LessThanOne()
+{
+ return _call(API_RANDOM_GETFLOAT2, 0.f);
+}
+inline float api_random::GetFloat_LessThanOne_NotZero()
+{
+ return _call(API_RANDOM_GETFLOAT3, 0.f);
+}
+inline double api_random::GetDouble()
+{
+ return _call(API_RANDOM_GETDOUBLE, 0.);
+}
+
+// {CB401CAB-CC10-48f7-ADB7-9D1D24B40E0C}
+static const GUID randomApiGUID =
+{ 0xcb401cab, 0xcc10, 0x48f7, { 0xad, 0xb7, 0x9d, 0x1d, 0x24, 0xb4, 0xe, 0xc } };
+
+
+#endif
+
diff --git a/Src/Plugins/Input/in_wv/wasabi/Winamp/api_wa5component.h b/Src/Plugins/Input/in_wv/wasabi/Winamp/api_wa5component.h
new file mode 100644
index 00000000..da43396b
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Winamp/api_wa5component.h
@@ -0,0 +1,34 @@
+#ifndef __WASABI_API_WA5COMPONENT_H_
+#define __WASABI_API_WA5COMPONENT_H_
+
+#include <bfc/dispatch.h>
+class api_service;
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+class NOVTABLE api_wa5component : public Dispatchable
+{
+public:
+ DISPATCH_CODES
+ {
+ API_WA5COMPONENT_REGISTERSERVICES = 10,
+ API_WA5COMPONENT_DEREEGISTERSERVICES = 20,
+ };
+
+ void RegisterServices(api_service *service);
+ void DeregisterServices(api_service *service);
+#ifdef WIN32 // this is a kind of a hack (might be better to create a function that winamp calls to pass it)
+ HMODULE hModule;
+#endif
+};
+inline void api_wa5component::RegisterServices(api_service *service)
+{
+ _voidcall(API_WA5COMPONENT_REGISTERSERVICES, service);
+}
+
+inline void api_wa5component::DeregisterServices(api_service *service)
+{
+ _voidcall(API_WA5COMPONENT_DEREEGISTERSERVICES, service);
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Winamp/ipc_pe.h b/Src/Plugins/Input/in_wv/wasabi/Winamp/ipc_pe.h
new file mode 100644
index 00000000..2d013a9f
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Winamp/ipc_pe.h
@@ -0,0 +1,56 @@
+#ifndef __IPC_PE_H
+#define __IPC_PE_H
+
+#define IPC_PE_GETCURINDEX 100 // returns current idx
+#define IPC_PE_GETINDEXTOTAL 101 // returns number of items
+#define IPC_PE_GETINDEXINFO 102 // (copydata) lpData is of type callbackinfo, callback is called with copydata/fileinfo structure and msg IPC_PE_GETINDEXINFORESULT
+#define IPC_PE_GETINDEXINFORESULT 103 // callback message for IPC_PE_GETINDEXINFO
+#define IPC_PE_DELETEINDEX 104 // lParam = index
+#define IPC_PE_SWAPINDEX 105 // (lParam & 0xFFFF0000) >> 16 = from, (lParam & 0xFFFF) = to
+#define IPC_PE_INSERTFILENAME 106 // (copydata) lpData is of type fileinfo
+#define IPC_PE_GETDIRTY 107 // returns 1 if the playlist changed since the last IPC_PE_SETCLEAN
+#define IPC_PE_SETCLEAN 108 // resets the dirty flag until next modification
+#define IPC_PE_GETIDXFROMPOINT 109 // pass a point parm, return a playlist index
+#define IPC_PE_SAVEEND 110 // pass index to save from
+#define IPC_PE_RESTOREEND 111 // no parm
+#define IPC_PE_GETNEXTSELECTED 112 // same as IPC_PLAYLIST_GET_NEXT_SELECTED for the main window
+#define IPC_PE_GETSELECTEDCOUNT 113
+#define IPC_PE_INSERTFILENAMEW 114 // (copydata) lpData is of type fileinfoW
+#define IPC_PE_GETINDEXINFO_TITLE 115 // like IPC_PE_GETINDEXINFO, but writes the title to char file[MAX_PATH] instead of filename
+#define IPC_PE_GETINDEXINFORESULT_TITLE 116 // callback message for IPC_PE_GETINDEXINFO
+typedef struct {
+ char file[MAX_PATH];
+ int index;
+ } fileinfo;
+
+typedef struct {
+ wchar_t file[MAX_PATH];
+ int index;
+ } fileinfoW;
+
+typedef struct {
+ HWND callback;
+ int index;
+ } callbackinfo;
+
+// the following messages are in_process ONLY
+
+#define IPC_PE_GETINDEXTITLE 200 // lParam = pointer to fileinfo2 struct
+#define IPC_PE_GETINDEXTITLEW 201 // lParam = pointer to fileinfo2W struct
+#define IPC_PE_GETINDEXINFO_INPROC 202 // lParam = pointer to fileinfo struct
+#define IPC_PE_GETINDEXINFOW_INPROC 203 // lParam = pointer to fileinfoW struct
+
+typedef struct {
+ int fileindex;
+ char filetitle[256];
+ char filelength[16];
+ } fileinfo2;
+
+typedef struct
+{
+ int fileindex;
+ wchar_t filetitle[256];
+ wchar_t filelength[16];
+ } fileinfo2W;
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Winamp/wa_dlg.h b/Src/Plugins/Input/in_wv/wasabi/Winamp/wa_dlg.h
new file mode 100644
index 00000000..e6edd49d
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Winamp/wa_dlg.h
@@ -0,0 +1,436 @@
+/*
+** Copyright (C) 2003-2008 Nullsoft, Inc.
+**
+** This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held
+** liable for any damages arising from the use of this software.
+**
+** Permission is granted to anyone to use this software for any purpose, including commercial applications, and to
+** alter it and redistribute it freely, subject to the following restrictions:
+**
+** 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
+** If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+**
+** 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+**
+** 3. This notice may not be removed or altered from any source distribution.
+**
+*/
+
+#ifndef _WA_DLG_H_
+#define _WA_DLG_H_
+
+#include "wa_ipc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ 1) gen.bmp has a generic window frame for plugins to use.
+ its format is similar to the minibrowser's.
+ In addition gen.bmp includes a font for the titlebar, in both
+ highlight and no-highlight modes. The font is variable width,
+ and it uses the first color before the letter A as the delimiter.
+ The no-highlight form of letter must be the same width as the
+ highlight form.
+ 2) genex.bmp has button and scrollbar images, as well as some individual
+ pixels that describe the colors for the dialog. The button and
+ scrollbar images should be self explanatory (note that the buttons
+ have 4 pixel sized edges that are not stretched, and the center is
+ stretched), and the scrollbars do something similar.
+ The colors start at (48,0) and run every other pixel. The meaning
+ of each pixel is:
+ x=48: item background (background to edits, listviews etc)
+ x=50: item foreground (text color of edit/listview, etc)
+ x=52: window background (used to set the bg color for the dialog)
+ x=54: button text color
+ x=56: window text color
+ x=58: color of dividers and sunken borders
+ x=60: selection color for playlists
+ x=62: listview header background color
+ x=64: listview header text color
+ x=66: listview header frame top color
+ x=68: listview header frame middle color
+ x=70: listview header frame bottom color
+ x=72: listview header empty color
+ x=74: scrollbar foreground color
+ x=76: scrollbar background color
+ x=78: inverse scrollbar foreground color
+ x=80: inverse scrollbar background color
+ x=82: scrollbar dead area color
+ x=84: listview/treeview selection bar text color (active)
+ x=86: listview/treeview selection bar back color (active)
+ x=88: listview/treeview selection bar text color (inactive)
+ x=90: listview/treeview selection bar back color (inactive)
+ x=92: alternate item background
+ x=94: alternate item foreground
+*/
+
+#define DCW_SUNKENBORDER 0x00010000
+#define DCW_DIVIDER 0x00020000
+
+enum
+{
+ WADLG_ITEMBG,
+ WADLG_ITEMFG,
+ WADLG_WNDBG,
+ WADLG_BUTTONFG,
+ WADLG_WNDFG,
+ WADLG_HILITE,
+ WADLG_SELCOLOR,
+ WADLG_LISTHEADER_BGCOLOR,
+ WADLG_LISTHEADER_FONTCOLOR,
+ WADLG_LISTHEADER_FRAME_TOPCOLOR,
+ WADLG_LISTHEADER_FRAME_MIDDLECOLOR,
+ WADLG_LISTHEADER_FRAME_BOTTOMCOLOR,
+ WADLG_LISTHEADER_EMPTY_BGCOLOR,
+ WADLG_SCROLLBAR_FGCOLOR,
+ WADLG_SCROLLBAR_BGCOLOR,
+ WADLG_SCROLLBAR_INV_FGCOLOR,
+ WADLG_SCROLLBAR_INV_BGCOLOR,
+ WADLG_SCROLLBAR_DEADAREA_COLOR,
+ WADLG_SELBAR_FGCOLOR,
+ WADLG_SELBAR_BGCOLOR,
+ WADLG_INACT_SELBAR_FGCOLOR,
+ WADLG_INACT_SELBAR_BGCOLOR,
+ WADLG_ITEMBG2,
+ WADLG_ITEMFG2,
+ WADLG_NUM_COLORS
+};
+
+typedef enum _WACURSOR // used in IPC_GETSKINCURSORS
+{
+ WACURSOR_VOLUME = 0, // volume & balane
+ WACURSOR_POSITION = 1, // position
+ WACURSOR_BTN_WINSHADE = 2, // winshade
+ WACURSOR_BTN_MINIMIZE = 3, // minimize
+ WACURSOR_BTN_CLOSE = 4, // close
+ WACURSOR_MENU = 5, // main menu
+ WACURSOR_TITLEBAR = 6, // title bar
+ WACURSOR_SONGNAME = 7,
+ WACURSOR_NORMAL = 8,
+ WACURSOR_WINSHADE_BTN_WINSHADE = 9,
+ WACURSOR_WINSHADE_BTN_MINIMIZE = 10,
+ WACURSOR_WINSHADE_POSITION = 11,
+ WACURSOR_WINSHADE_BTN_CLOSE = 12,
+ WACURSOR_WINSHADE_MENU = 13,
+ WACURSOR_WINSHADE_NORMAL = 14,
+ WACURSOR_PL_BTN_WINSHADE = 15,
+ WACURSOR_PL_BTN_CLOSE = 16,
+ WACURSOR_PL_TITLEBAR = 17,
+ WACURSOR_PL_VSCROLL = 18,
+ WACURSOR_PL_RESIZE = 19,
+ WACURSOR_PL_NORMAL = 20,
+ WACURSOR_PL_WINSHADE_BTN_WINSHADE = 21,
+ WACURSOR_PL_WINSHADE_BTN_CLOSE = 22,
+ WACURSOR_PL_WINSHADE_HSIZE = 23,
+ WACURSOR_PL_WINSHADE_NORMAL = 24,
+ WACURSOR_EQ_SLIDER = 25,
+ WACURSOR_EQ_BTN_CLOSE = 26,
+ WACURSOR_EQ_TITLEBAR = 27,
+ WACURSOR_EQ_NORMAL = 28,
+} WACURSOR;
+
+void WADlg_init(HWND hwndWinamp); // call this on init, or on WM_DISPLAYCHANGE
+void WADlg_close();
+int WADlg_getColor(int idx);
+int WADlg_initted();
+
+LRESULT WADlg_handleDialogMsgs(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); //
+void WADlg_DrawChildWindowBorders(HWND hwndDlg, int *tab, int tabsize); // each entry in tab would be the id | DCW_*
+
+HBITMAP WADlg_getBitmap();
+
+/// define WA_DLG_IMPLEMENT in one of your source files before including this .h
+// if you are making a media library plugin, you dont need to do this, look at view_ex for
+// an example of how to get the function *'s via an IPC message.
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef WA_DLG_IMPLEMENT
+
+static HBRUSH wadlg_lastbrush=0;
+static HBITMAP wadlg_bitmap=0; // load this manually
+static int wadlg_colors[WADLG_NUM_COLORS];
+static int wadlg_defcolors[WADLG_NUM_COLORS]=
+{
+ RGB(0,0,0),
+ RGB(0,255,0),
+ RGB(36,36,60),
+ RGB(57,56,66),
+ RGB(255,255,255),
+ RGB(132,148,165),
+ RGB(0,0,198),
+ RGB(36*2,36*2,60*2),
+ RGB(255,255,255),
+ RGB(36*3,36*3,60*3),
+ RGB(36,36,60),
+ RGB(36*0.5,36*0.5,60*0.5),
+ RGB(36,36,60),
+ RGB(36*1,36*1,60*1),
+ RGB(36*1,36*1,60*1),
+ RGB(121,130,150),
+ RGB(78,88,110),
+ RGB(36*1,36*1,60*1),
+ RGB(255,255,255),
+ RGB(0,0,180),
+ RGB(0,255,0),
+ RGB(0,0,128),
+ RGB(0,0,0),
+ RGB(0,255,0),
+};
+
+int WADlg_initted()
+{
+ return !!wadlg_bitmap;
+}
+
+int WADlg_getColor(int idx)
+{
+ if (idx < 0 || idx >= WADLG_NUM_COLORS) return 0;
+ return wadlg_colors[idx];
+}
+
+HBITMAP WADlg_getBitmap()
+{
+ return wadlg_bitmap;
+}
+
+void WADlg_init(HWND hwndWinamp) // call this on init, or on WM_DISPLAYCHANGE
+{
+ if (wadlg_bitmap) DeleteObject(wadlg_bitmap);
+ wadlg_bitmap = (HBITMAP) SendMessage(hwndWinamp,WM_WA_IPC,0,IPC_GET_GENSKINBITMAP);
+ if (wadlg_bitmap)
+ {
+ HDC tmpDC=CreateCompatibleDC(NULL);
+ HGDIOBJ o=SelectObject(tmpDC,(HGDIOBJ)wadlg_bitmap);
+ int defbgcol=GetPixel(tmpDC,111,0);
+ for (int x = 0; x < WADLG_NUM_COLORS; x ++)
+ {
+ int a=GetPixel(tmpDC,48+x*2,0);
+ if (a == CLR_INVALID || a == RGB(0,198,255) || a == defbgcol)
+ {
+ //defaults for old skins
+ if (x == WADLG_SELBAR_FGCOLOR || x == WADLG_INACT_SELBAR_FGCOLOR) a=wadlg_colors[WADLG_WNDFG];
+ else if (x == WADLG_SELBAR_BGCOLOR || x == WADLG_INACT_SELBAR_BGCOLOR)
+ {
+ a=wadlg_colors[WADLG_SELCOLOR];
+ if (x == WADLG_INACT_SELBAR_BGCOLOR)
+ a=((a/2)&0x7F7F7F)+(((wadlg_colors[WADLG_WNDBG])/2)&0x7F7F7F);
+ }
+ else if (x == WADLG_ITEMBG2)
+ {
+ a=wadlg_colors[WADLG_ITEMBG];
+ }
+ else if (x == WADLG_ITEMFG2)
+ {
+ a=wadlg_colors[WADLG_ITEMFG];
+ }
+ else a=wadlg_defcolors[x];
+ }
+ wadlg_colors[x]=a;
+ }
+
+ SelectObject(tmpDC,o);
+ DeleteDC(tmpDC);
+ }
+}
+
+void WADlg_close()
+{
+ if (wadlg_bitmap) DeleteObject(wadlg_bitmap);
+ wadlg_bitmap=0;
+ if (wadlg_lastbrush) DeleteObject(wadlg_lastbrush);
+ wadlg_lastbrush=0;
+}
+
+void WADlg_dotLine(HDC hdc, int left, int top, int len, int vert)
+{
+ for(int i=(top&1);i<len-1;i+=2)
+ {
+ if(vert)
+ {
+ MoveToEx(hdc,left,top+i,NULL);
+ LineTo(hdc,left,top+i+1);
+ }
+ else
+ {
+ MoveToEx(hdc,left+i,top,NULL);
+ LineTo(hdc,left+i+1,top);
+ }
+ }
+}
+
+LRESULT WADlg_handleDialogMsgs(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg == WM_DRAWITEM)
+ {
+ DRAWITEMSTRUCT *di = (DRAWITEMSTRUCT *)lParam;
+ if (di->CtlType == ODT_BUTTON) {
+ wchar_t wt[256];
+ RECT r;
+ GetDlgItemTextW(hwndDlg,(INT)wParam,wt,sizeof(wt)/sizeof(*wt));
+
+ HDC hdc = CreateCompatibleDC(di->hDC);
+ HBITMAP hbmpOld = (HBITMAP)SelectObject(hdc, wadlg_bitmap);
+
+ r=di->rcItem;
+ SetStretchBltMode(di->hDC,COLORONCOLOR);
+
+ int yoffs = (di->itemState & ODS_SELECTED) ? 15 : 0;
+
+ BitBlt(di->hDC,r.left,r.top,4,4,hdc,0,yoffs,SRCCOPY); // top left
+ StretchBlt(di->hDC,r.left+4,r.top,r.right-r.left-4-4,4,hdc,4,yoffs,47-4-4,4,SRCCOPY); // top center
+ BitBlt(di->hDC,r.right-4,r.top,4,4,hdc,47-4,yoffs,SRCCOPY); // top right
+
+ StretchBlt(di->hDC,r.left,r.top+4,4,r.bottom-r.top-4-4,hdc,0,4+yoffs,4,15-4-4,SRCCOPY); // left edge
+ StretchBlt(di->hDC,r.right-4,r.top+4,4,r.bottom-r.top-4-4,hdc,47-4,4+yoffs,4,15-4-4,SRCCOPY); // right edge
+
+ // center
+ StretchBlt(di->hDC,r.left+4,r.top+4,r.right-r.left-4-4,r.bottom-r.top-4-4,hdc,4,4+yoffs,47-4-4,15-4-4,SRCCOPY);
+
+ BitBlt(di->hDC,r.left,r.bottom-4,4,4,hdc,0,15-4+yoffs,SRCCOPY); // bottom left
+ StretchBlt(di->hDC,r.left+4,r.bottom-4,r.right-r.left-4-4,4,hdc,4,15-4+yoffs,47-4-4,4,SRCCOPY); // bottom center
+ BitBlt(di->hDC,r.right-4,r.bottom-4,4,4,hdc,47-4,15-4+yoffs,SRCCOPY); // bottom right
+
+ // draw text
+ SetBkMode(di->hDC,TRANSPARENT);
+
+ // this will do a different style for the button text depending on enabled state of the button
+ COLORREF colour = wadlg_colors[WADLG_BUTTONFG];
+ if(!IsWindowEnabled(di->hwndItem)){
+ COLORREF fg = wadlg_colors[WADLG_WNDFG],
+ bg = wadlg_colors[WADLG_WNDBG];
+ colour = RGB((GetRValue(fg)+GetRValue(bg))/2,
+ (GetGValue(fg)+GetGValue(bg))/2,
+ (GetBValue(fg)+GetBValue(bg))/2);
+ }
+ SetTextColor(di->hDC,colour);
+
+ if (di->itemState & ODS_SELECTED) {r.left+=2; r.top+=2;}
+ DrawTextW(di->hDC,wt,-1,&r,DT_VCENTER|DT_SINGLELINE|DT_CENTER);
+
+ SelectObject(hdc, hbmpOld);
+ DeleteDC(hdc);
+
+ if(GetFocus()==di->hwndItem) {
+ HPEN hpen, hpenOld;
+ hpen =CreatePen(PS_SOLID,0,RGB(0,0,0));
+ hpenOld = (HPEN)SelectObject(di->hDC, hpen);
+ WADlg_dotLine(di->hDC,r.left+2,r.top+2,r.right-r.left-3,0);
+ WADlg_dotLine(di->hDC,r.right-3,r.top+2,r.bottom-r.top-3,1);
+ WADlg_dotLine(di->hDC,r.left+2,r.top+2,r.bottom-r.top-3,1);
+ WADlg_dotLine(di->hDC,r.left+2,r.bottom-3,r.right-r.left-3,0);
+ SelectObject(di->hDC, hpenOld);
+ DeleteObject(hpen);
+ }
+ }
+ }
+
+ switch(uMsg)
+ {
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLORDLG:
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLORSTATIC:
+ case WM_CTLCOLOREDIT:
+ {
+ int bgcolor=(uMsg == WM_CTLCOLOREDIT || uMsg == WM_CTLCOLORLISTBOX) ? wadlg_colors[WADLG_ITEMBG] : (uMsg == WM_CTLCOLORBTN ? wadlg_colors[WADLG_ITEMBG] : wadlg_colors[WADLG_WNDBG]);
+ LOGBRUSH lb={BS_SOLID,GetNearestColor((HDC)wParam,bgcolor)};
+ if (wadlg_lastbrush) DeleteObject(wadlg_lastbrush);
+ wadlg_lastbrush=CreateBrushIndirect(&lb);
+ SetTextColor((HDC)wParam,uMsg == WM_CTLCOLORSTATIC ? wadlg_colors[WADLG_WNDFG] : wadlg_colors[WADLG_ITEMFG]);
+ SetBkColor((HDC)wParam,lb.lbColor);
+ return (LRESULT)wadlg_lastbrush;
+ }
+ }
+ return 0;
+}
+
+static int RectInRect(RECT *rect1, RECT *rect2)
+{
+ // this has a bias towards true
+
+ // this could probably be optimized a lot
+ return ((rect1->top >= rect2->top && rect1->top <= rect2->bottom) ||
+ (rect1->bottom >= rect2->top && rect1->bottom <= rect2->bottom) ||
+ (rect2->top >= rect1->top && rect2->top <= rect1->bottom) ||
+ (rect2->bottom >= rect1->top && rect2->bottom <= rect1->bottom)) // vertical intersect
+ &&
+ ((rect1->left >= rect2->left && rect1->left <= rect2->right) ||
+ (rect1->right >= rect2->left && rect1->right <= rect2->right) ||
+ (rect2->left >= rect1->left && rect2->left <= rect1->right) ||
+ (rect2->right >= rect1->left && rect2->right <= rect1->right)) // horiz intersect
+ ;
+}
+
+static void WADlg_removeFromRgn(HRGN hrgn, int left, int top, int right, int bottom)
+{
+ HRGN rgn2=CreateRectRgn(left,top,right,bottom);
+ CombineRgn(hrgn,hrgn,rgn2,RGN_DIFF);
+ DeleteObject(rgn2);
+}
+
+void WADlg_DrawChildWindowBorders(HWND hwndDlg, int *tab, int tabsize)
+{
+ PAINTSTRUCT ps;
+ BeginPaint(hwndDlg,&ps);
+ HRGN hrgn = (ps.fErase) ? CreateRectRgnIndirect(&ps.rcPaint) : NULL;
+ HPEN pen = CreatePen(PS_SOLID, 0, wadlg_colors[WADLG_HILITE]);
+ HGDIOBJ o = SelectObject(ps.hdc, pen);
+
+ while (tabsize--)
+ {
+ RECT r;
+ int a = *tab++;
+ GetWindowRect(GetDlgItem(hwndDlg, a & 0xffff),&r);
+ MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&r, 2);
+
+ if (RectInRect(&ps.rcPaint,&r))
+ {
+ if ((a & 0xffff0000) == DCW_SUNKENBORDER)
+ {
+ MoveToEx(ps.hdc,r.left,r.bottom,NULL);
+ LineTo(ps.hdc,r.right,r.bottom);
+ LineTo(ps.hdc,r.right,r.top-1);
+ if(hrgn)
+ {
+ WADlg_removeFromRgn(hrgn,r.left,r.bottom,r.right,r.bottom+1);
+ WADlg_removeFromRgn(hrgn,r.right,r.top,r.right+1,r.bottom);
+ }
+ }
+ else if ((a & 0xffff0000) == DCW_DIVIDER)
+ {
+ if (r.right - r.left < r.bottom - r.top) // vertical
+ {
+ int left=(r.left+r.right)/2;
+ MoveToEx(ps.hdc,left,r.top,NULL);
+ LineTo(ps.hdc,left,r.bottom+1);
+ if(hrgn) WADlg_removeFromRgn(hrgn,left,r.top,left+1,r.bottom);
+ }
+ else // horiz
+ {
+ int top=(r.top+r.bottom)/2;
+ MoveToEx(ps.hdc,r.left,top,NULL);
+ LineTo(ps.hdc,r.right+1,top);
+ if(hrgn) WADlg_removeFromRgn(hrgn,r.left,top,r.right,top+1);
+ }
+ }
+ }
+ }
+
+ SelectObject(ps.hdc, o);
+ DeleteObject(pen);
+
+ if(hrgn)
+ {
+ //erase bkgnd while clipping out our own drawn stuff (for flickerless display)
+ HBRUSH b = CreateSolidBrush(wadlg_colors[WADLG_WNDBG]);
+ FillRgn(ps.hdc,hrgn,b);
+ DeleteObject(b);
+ DeleteObject(hrgn);
+ }
+ EndPaint(hwndDlg,&ps);
+}
+#endif
+
+#endif//_WA_DLG_H_ \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Winamp/wa_hotkeys.h b/Src/Plugins/Input/in_wv/wasabi/Winamp/wa_hotkeys.h
new file mode 100644
index 00000000..6739a576
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Winamp/wa_hotkeys.h
@@ -0,0 +1,39 @@
+#ifndef WA_HOTKEYS
+#define WA_HOTKEYS
+
+//#define IPC_GEN_HOTKEYS_ADD xxxx //pass a genHotkeysAddStruct * struct in data
+//
+//To get the IPC_GEN_HOTKEYS_ADD IPC number, do this:
+//
+// genhotkeys_add_ipc=SendMessage(winampWindow,WM_WA_IPC,(WPARAM)&"GenHotkeysAdd",IPC_REGISTER_WINAMP_IPCMESSAGE);
+//
+//Then you can use:
+//
+// PostMessage(winampWindow,WM_WA_IPC,(WPARAM)&myGenHotkeysAddStruct,genhotkeys_add_ipc);
+//
+
+//flags for the genHotkeysAddStruct struct
+#define HKF_BRING_TO_FRONT 0x1 // calls SetForegroundWindow before sending the message
+#define HKF_HWND_WPARAM 0x2 // sets wParam with Winamp's window handle
+#define HKF_COPY 0x4 // copies returned text to the clipboard
+#define HKF_PLPOS_WPARAM 0x8 // sets wParam with current pledit position
+#define HKF_ISPLAYING_WL 0x10 // sets wParam to genHotkeysAddStruct's wParam if playing, lParam if not
+ // uses IPC_ISPLAYING to check if playing
+#define HKF_SHOWHIDE 0x20 // brings Winamp to front or minimizes Winamp if already at front
+#define HKF_NOSENDMSG 0x40 // don't send any message to the winamp window
+
+#define HKF_DISABLED 0x80000000
+
+typedef struct {
+ char *name; //name that will appear in the Global Hotkeys preferences panel
+ DWORD flags; //one or more flags from above
+ UINT uMsg; //message that will be sent to winamp's main window (must always be !=NULL)
+ WPARAM wParam; //wParam that will be sent to winamp's main window
+ LPARAM lParam; //lParam that will be sent to winamp's main window
+ char *id; //unique string to identify this command - case insensitive
+ HWND wnd; //set the HWND to send message (or 0 for main winamp window)
+
+ int extended[6]; //for future extension - always set to zero!
+} genHotkeysAddStruct;
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/Winamp/wa_ipc.h b/Src/Plugins/Input/in_wv/wasabi/Winamp/wa_ipc.h
new file mode 100644
index 00000000..dd2559b5
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/Winamp/wa_ipc.h
@@ -0,0 +1,2468 @@
+/*
+** Copyright (C) 1997-2008 Nullsoft, Inc.
+**
+** This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held
+** liable for any damages arising from the use of this software.
+**
+** Permission is granted to anyone to use this software for any purpose, including commercial applications, and to
+** alter it and redistribute it freely, subject to the following restrictions:
+**
+** 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
+** If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+**
+** 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+**
+** 3. This notice may not be removed or altered from any source distribution.
+**
+*/
+
+#ifndef _WA_IPC_H_
+#define _WA_IPC_H_
+
+#include <windows.h>
+#include <stddef.h>
+#if (_MSC_VER <= 1200)
+typedef int intptr_t;
+#endif
+/*
+** This is the modern replacement for the classic 'frontend.h'. Most of these
+** updates are designed for in-process use, i.e. from a plugin.
+**
+*/
+
+/* Most of the IPC_* messages involve sending the message in the form of:
+** result = SendMessage(hwnd_winamp,WM_WA_IPC,(parameter),IPC_*);
+** Where different then this is specified (typically with WM_COPYDATA variants)
+**
+** When you use SendMessage(hwnd_winamp,WM_WA_IPC,(parameter),IPC_*) and specify a IPC_*
+** which is not currently implemented/supported by the Winamp version being used then it
+** will return 1 for 'result'. This is a good way of helping to check if an api being
+** used which returns a function pointer, etc is even going to be valid.
+*/
+
+#define WM_WA_IPC WM_USER
+
+#define WINAMP_VERSION_MAJOR(winampVersion) ((winampVersion & 0x0000FF00) >> 12)
+#define WINAMP_VERSION_MINOR(winampVersion) (winampVersion & 0x000000FF) // returns, i.e. 0x12 for 5.12 and 0x10 for 5.1...
+
+
+#define IPC_GETVERSION 0
+/* int version = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVERSION);
+**
+** The version returned will be 0x20yx for Winamp 2.yx.
+** Versions previous to Winamp 2.0 typically (but not always) use 0x1zyx for 1.zx.
+** Just a bit weird but that's the way it goes.
+**
+** For Winamp 5.x it uses the format 0x50yx for Winamp 5.yx
+** e.g. 5.01 -> 0x5001
+** 5.09 -> 0x5009
+** 5.1 -> 0x5010
+**
+** Notes: For 5.02 this api will return the same value as for a 5.01 build.
+** For 5.07 this api will return the same value as for a 5.06 build.
+*/
+
+
+#define IPC_GETVERSIONSTRING 1
+
+
+#define IPC_GETREGISTEREDVERSION 770
+/* (requires Winamp 5.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETREGISTEREDVERSION);
+**
+** This will open the Winamp Preferences and show the Winamp Pro page.
+*/
+
+
+typedef struct {
+ const char *filename;
+ const char *title;
+ int length;
+} enqueueFileWithMetaStruct; // send this to a IPC_PLAYFILE in a non WM_COPYDATA,
+// and you get the nice desired result. if title is NULL, it is treated as a "thing",
+// otherwise it's assumed to be a file (for speed)
+
+typedef struct {
+ const wchar_t *filename;
+ const wchar_t *title;
+ int length;
+} enqueueFileWithMetaStructW;
+
+#define IPC_PLAYFILE 100 // dont be fooled, this is really the same as enqueufile
+#define IPC_ENQUEUEFILE 100
+#define IPC_PLAYFILEW 1100
+#define IPC_ENQUEUEFILEW 1100
+/* This is sent as a WM_COPYDATA with IPC_PLAYFILE as the dwData member and the string
+** of the file / playlist to be enqueued into the playlist editor as the lpData member.
+** This will just enqueue the file or files since you can use this to enqueue a playlist.
+** It will not clear the current playlist or change the playback state.
+**
+** COPYDATASTRUCT cds = {0};
+** cds.dwData = IPC_ENQUEUEFILE;
+** cds.lpData = (void*)"c:\\test\\folder\\test.mp3";
+** cds.cbData = lstrlen((char*)cds.lpData)+1; // include space for null char
+** SendMessage(hwnd_winamp,WM_COPYDATA,0,(LPARAM)&cds);
+**
+**
+** With 2.9+ and all of the 5.x versions you can send this as a normal WM_WA_IPC
+** (non WM_COPYDATA) with an enqueueFileWithMetaStruct as the param.
+** If the title member is null then it is treated as a "thing" otherwise it will be
+** assumed to be a file (for speed).
+**
+** enqueueFileWithMetaStruct eFWMS = {0};
+** eFWMS.filename = "c:\\test\\folder\\test.mp3";
+** eFWMS.title = "Whipping Good";
+** eFWMS.length = 300; // this is the number of seconds for the track
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)&eFWMS,IPC_ENQUEUEFILE);
+*/
+
+
+#define IPC_DELETE 101
+#define IPC_DELETE_INT 1101
+/* SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_DELETE);
+** Use this api to clear Winamp's internal playlist.
+** You should not need to use IPC_DELETE_INT since it is used internally by Winamp when
+** it is dealing with some lame Windows Explorer issues (hard to believe that!).
+*/
+
+
+#define IPC_STARTPLAY 102
+#define IPC_STARTPLAY_INT 1102
+/* SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_STARTPLAY);
+** Sending this will start playback and is almost the same as hitting the play button.
+** The IPC_STARTPLAY_INT version is used internally and you should not need to use it
+** since it won't be any fun.
+*/
+
+
+#define IPC_CHDIR 103
+/* This is sent as a WM_COPYDATA type message with IPC_CHDIR as the dwData value and the
+** directory you want to change to as the lpData member.
+**
+** COPYDATASTRUCT cds = {0};
+** cds.dwData = IPC_CHDIR;
+** cds.lpData = (void*)"c:\\download";
+** cds.cbData = lstrlen((char*)cds.lpData)+1; // include space for null char
+** SendMessage(hwnd_winamp,WM_COPYDATA,0,(LPARAM)&cds);
+**
+** The above example will make Winamp change to the directory 'C:\download'.
+*/
+
+
+#define IPC_ISPLAYING 104
+/* int res = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING);
+** This is sent to retrieve the current playback state of Winamp.
+** If it returns 1, Winamp is playing.
+** If it returns 3, Winamp is paused.
+** If it returns 0, Winamp is not playing.
+*/
+
+
+#define IPC_GETOUTPUTTIME 105
+/* int res = SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETOUTPUTTIME);
+** This api can return two different sets of information about current playback status.
+**
+** If mode = 0 then it will return the position (in ms) of the currently playing track.
+** Will return -1 if Winamp is not playing.
+**
+** If mode = 1 then it will return the current track length (in seconds).
+** Will return -1 if there are no tracks (or possibly if Winamp cannot get the length).
+**
+** If mode = 2 then it will return the current track length (in milliseconds).
+** Will return -1 if there are no tracks (or possibly if Winamp cannot get the length).
+*/
+
+
+#define IPC_JUMPTOTIME 106
+/* (requires Winamp 1.60+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME);
+** This api sets the current position (in milliseconds) for the currently playing song.
+** The resulting playback position may only be an approximate time since some playback
+** formats do not provide exact seeking e.g. mp3
+** This returns -1 if Winamp is not playing, 1 on end of file, or 0 if it was successful.
+*/
+
+
+#define IPC_GETMODULENAME 109
+#define IPC_EX_ISRIGHTEXE 666
+/* usually shouldnt bother using these, but here goes:
+** send a WM_COPYDATA with IPC_GETMODULENAME, and an internal
+** flag gets set, which if you send a normal WM_WA_IPC message with
+** IPC_EX_ISRIGHTEXE, it returns whether or not that filename
+** matches. lame, I know.
+*/
+
+
+#define IPC_WRITEPLAYLIST 120
+/* (requires Winamp 1.666+)
+** int cur = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_WRITEPLAYLIST);
+**
+** IPC_WRITEPLAYLIST will write the current playlist to '<winampdir>\\Winamp.m3u' and
+** will also return the current playlist position (see IPC_GETLISTPOS).
+**
+** This is kinda obsoleted by some of the newer 2.x api items but it still is good for
+** use with a front-end program (instead of a plug-in) and you want to see what is in the
+** current playlist.
+**
+** This api will only save out extended file information in the #EXTINF entry if Winamp
+** has already read the data such as if the file was played of scrolled into view. If
+** Winamp has not read the data then you will only find the file with its filepath entry
+** (as is the base requirements for a m3u playlist).
+*/
+
+
+#define IPC_SETPLAYLISTPOS 121
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS)
+** IPC_SETPLAYLISTPOS sets the playlist position to the specified 'position'.
+** It will not change playback status or anything else. It will just set the current
+** position in the playlist and will update the playlist view if necessary.
+**
+** If you use SendMessage(hwnd_winamp,WM_COMMAND,MAKEWPARAM(WINAMP_BUTTON2,0),0);
+** after using IPC_SETPLAYLISTPOS then Winamp will start playing the file at 'position'.
+*/
+
+
+#define IPC_SETVOLUME 122
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME);
+** IPC_SETVOLUME sets the volume of Winamp (between the range of 0 to 255).
+**
+** If you pass 'volume' as -666 then the message will return the current volume.
+** int curvol = SendMessage(hwnd_winamp,WM_WA_IPC,-666,IPC_SETVOLUME);
+*/
+
+
+#define IPC_GETVOLUME(hwnd_winamp) SendMessage(hwnd_winamp,WM_WA_IPC,-666,IPC_SETVOLUME)
+/* (requires Winamp 2.0+)
+** int curvol = IPC_GETVOLUME(hwnd_winamp);
+** This will return the current volume of Winamp or
+*/
+
+
+#define IPC_SETPANNING 123
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,panning,IPC_SETPANNING);
+** IPC_SETPANNING sets the panning of Winamp from 0 (left) to 255 (right).
+**
+** At least in 5.x+ this works from -127 (left) to 127 (right).
+**
+** If you pass 'panning' as -666 to this api then it will return the current panning.
+** int curpan = SendMessage(hwnd_winamp,WM_WA_IPC,-666,IPC_SETPANNING);
+*/
+
+
+#define IPC_GETLISTLENGTH 124
+/* (requires Winamp 2.0+)
+** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH);
+** IPC_GETLISTLENGTH returns the length of the current playlist as the number of tracks.
+*/
+
+
+#define IPC_GETLISTPOS 125
+/* (requires Winamp 2.05+)
+** int pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS);
+** IPC_GETLISTPOS returns the current playlist position (which is shown in the playlist
+** editor as a differently coloured text entry e.g is yellow for the classic skin).
+**
+** This api is a lot like IPC_WRITEPLAYLIST but a lot faster since it does not have to
+** write out the whole of the current playlist first.
+*/
+
+
+#define IPC_GETINFO 126
+/* (requires Winamp 2.05+)
+** int inf=SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETINFO);
+** IPC_GETINFO returns info about the current playing song. The value
+** it returns depends on the value of 'mode'.
+** Mode Meaning
+** ------------------
+** 0 Samplerate, in kilohertz (i.e. 44)
+** 1 Bitrate (i.e. 128)
+** 2 Channels (i.e. 2)
+** 3 (5+) Video LOWORD=w HIWORD=h
+** 4 (5+) > 65536, string (video description)
+** 5 (5.25+) Samplerate, in hertz (i.e. 44100)
+*/
+
+
+#define IPC_GETEQDATA 127
+/* (requires Winamp 2.05+)
+** int data=SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
+** IPC_GETEQDATA queries the status of the EQ.
+** The value returned depends on what 'pos' is set to:
+** Value Meaning
+** ------------------
+** 0-9 The 10 bands of EQ data. 0-63 (+20db - -20db)
+** 10 The preamp value. 0-63 (+20db - -20db)
+** 11 Enabled. zero if disabled, nonzero if enabled.
+** 12 Autoload. zero if disabled, nonzero if enabled.
+*/
+
+
+#define IPC_SETEQDATA 128
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SETEQDATA);
+** IPC_SETEQDATA sets the value of the last position retrieved
+** by IPC_GETEQDATA. This is pretty lame, and we should provide
+** an extended version that lets you do a MAKELPARAM(pos,value).
+** someday...
+
+ new (2.92+):
+ if the high byte is set to 0xDB, then the third byte specifies
+ which band, and the bottom word specifies the value.
+*/
+
+
+#define IPC_ADDBOOKMARK 129
+#define IPC_ADDBOOKMARKW 131
+/* (requires Winamp 2.4+)
+** This is sent as a WM_COPYDATA using IPC_ADDBOOKMARK as the dwData value and the
+** directory you want to change to as the lpData member. This will add the specified
+** file / url to the Winamp bookmark list.
+**
+** COPYDATASTRUCT cds = {0};
+** cds.dwData = IPC_ADDBOOKMARK;
+** cds.lpData = (void*)"http://www.blah.com/listen.pls";
+** cds.cbData = lstrlen((char*)cds.lpData)+1; // include space for null char
+** SendMessage(hwnd_winamp,WM_COPYDATA,0,(LPARAM)&cds);
+**
+**
+** In Winamp 5.0+ we use this as a normal WM_WA_IPC and the string is null separated as
+** the filename and then the title of the entry.
+**
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(char*)"filename\0title\0",IPC_ADDBOOKMARK);
+**
+** This will notify the library / bookmark editor that a bookmark was added.
+** Note that using this message in this context does not actually add the bookmark.
+** Do not use, it is essentially just a notification type message :)
+*/
+
+
+#define IPC_INSTALLPLUGIN 130
+/* This is not implemented (and is very unlikely to be done due to safety concerns).
+** If it was then you could do a WM_COPYDATA with a path to a .wpz and it would then
+** install the plugin for you.
+**
+** COPYDATASTRUCT cds = {0};
+** cds.dwData = IPC_INSTALLPLUGIN;
+** cds.lpData = (void*)"c:\\path\\to\\file.wpz";
+** cds.cbData = lstrlen((char*)cds.lpData)+1; // include space for null char
+** SendMessage(hwnd_winamp,WM_COPYDATA,0,(LPARAM)&cds);
+*/
+
+
+#define IPC_RESTARTWINAMP 135
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_RESTARTWINAMP);
+** IPC_RESTARTWINAMP will restart Winamp (isn't that obvious ? :) )
+** If this fails to make Winamp start after closing then there is a good chance one (or
+** more) of the currently installed plugins caused Winamp to crash on exit (either as a
+** silent crash or a full crash log report before it could call itself start again.
+*/
+
+
+#define IPC_ISFULLSTOP 400
+/* (requires winamp 2.7+ I think)
+** int ret=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISFULLSTOP);
+** This is useful for when you're an output plugin and you want to see if the stop/close
+** happening is a full stop or if you are just between tracks. This returns non zero if
+** it is a full stop or zero if it is just a new track.
+** benski> i think it's actually the other way around -
+** !0 for EOF and 0 for user pressing stop
+*/
+
+
+#define IPC_INETAVAILABLE 242
+/* (requires Winamp 2.05+)
+** int val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_INETAVAILABLE);
+** IPC_INETAVAILABLE will return 1 if an Internet connection is available for Winamp and
+** relates to the internet connection type setting on the main general preferences page
+** in the Winamp preferences.
+*/
+
+
+#define IPC_UPDTITLE 243
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_UPDTITLE);
+** IPC_UPDTITLE will ask Winamp to update the information about the current title and
+** causes GetFileInfo(..) in the input plugin associated with the current playlist entry
+** to be called. This can be called such as when an input plugin is buffering a file so
+** that it can cause the buffer percentage to appear in the playlist.
+*/
+
+
+#define IPC_REFRESHPLCACHE 247
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_REFRESHPLCACHE);
+** IPC_REFRESHPLCACHE will flush the playlist cache buffer and you send this if you want
+** Winamp to go refetch the titles for all of the entries in the current playlist.
+**
+** 5.3+: pass a wchar_t * string in wParam, and it'll do a strnicmp() before clearing the cache
+*/
+
+
+#define IPC_GET_SHUFFLE 250
+/* (requires Winamp 2.4+)
+** int val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_SHUFFLE);
+** IPC_GET_SHUFFLE returns the status of the shuffle option.
+** If set then it will return 1 and if not set then it will return 0.
+*/
+
+
+#define IPC_GET_REPEAT 251
+/* (requires Winamp 2.4+)
+** int val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_REPEAT);
+** IPC_GET_REPEAT returns the status of the repeat option.
+** If set then it will return 1 and if not set then it will return 0.
+*/
+
+
+#define IPC_SET_SHUFFLE 252
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_SHUFFLE);
+** IPC_SET_SHUFFLE sets the status of the shuffle option.
+** If 'value' is 1 then shuffle is turned on.
+** If 'value' is 0 then shuffle is turned off.
+*/
+
+
+#define IPC_SET_REPEAT 253
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_REPEAT);
+** IPC_SET_REPEAT sets the status of the repeat option.
+** If 'value' is 1 then shuffle is turned on.
+** If 'value' is 0 then shuffle is turned off.
+*/
+
+
+#define IPC_ENABLEDISABLE_ALL_WINDOWS 259 // 0xdeadbeef to disable
+/* (requires Winamp 2.9+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(enable?0:0xdeadbeef),IPC_ENABLEDISABLE_ALL_WINDOWS);
+** Sending this message with 0xdeadbeef as the param will disable all winamp windows and
+** any other values will enable all of the Winamp windows again. When disabled you won't
+** get any response on clicking or trying to do anything to the Winamp windows. If the
+** taskbar icon is shown then you may still have control ;)
+*/
+
+
+#define IPC_GETWND 260
+/* (requires Winamp 2.9+)
+** HWND h=SendMessage(hwnd_winamp,WM_WA_IPC,IPC_GETWND_xxx,IPC_GETWND);
+** returns the HWND of the window specified.
+*/
+ #define IPC_GETWND_EQ 0 // use one of these for the param
+ #define IPC_GETWND_PE 1
+ #define IPC_GETWND_MB 2
+ #define IPC_GETWND_VIDEO 3
+#define IPC_ISWNDVISIBLE 261 // same param as IPC_GETWND
+
+
+/************************************************************************
+***************** in-process only (WE LOVE PLUGINS)
+************************************************************************/
+
+#define IPC_SETSKINW 199
+#define IPC_SETSKIN 200
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"skinname",IPC_SETSKIN);
+** IPC_SETSKIN sets the current skin to "skinname". Note that skinname
+** can be the name of a skin, a skin .zip file, with or without path.
+** If path isn't specified, the default search path is the winamp skins
+** directory.
+*/
+
+
+#define IPC_GETSKIN 201
+#define IPC_GETSKINW 1201
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)skinname_buffer,IPC_GETSKIN);
+** IPC_GETSKIN puts the directory where skin bitmaps can be found
+** into skinname_buffer.
+** skinname_buffer must be MAX_PATH characters in length.
+** When using a .zip'd skin file, it'll return a temporary directory
+** where the ZIP was decompressed.
+*/
+
+
+#define IPC_EXECPLUG 202
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"vis_file.dll",IPC_EXECPLUG);
+** IPC_EXECPLUG executes a visualization plug-in pointed to by WPARAM.
+** the format of this string can be:
+** "vis_whatever.dll"
+** "vis_whatever.dll,0" // (first mod, file in winamp plug-in dir)
+** "C:\\dir\\vis_whatever.dll,1"
+*/
+
+
+#define IPC_GETPLAYLISTFILE 211
+#define IPC_GETPLAYLISTFILEW 214
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE);
+** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index].
+** returns a pointer to it. returns NULL on error.
+*/
+
+
+#define IPC_GETPLAYLISTTITLE 212
+#define IPC_GETPLAYLISTTITLEW 213
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE);
+**
+** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index].
+** returns a pointer to it. returns NULL on error.
+*/
+
+
+#define IPC_GETHTTPGETTER 240
+/* retrieves a function pointer to a HTTP retrieval function.
+** if this is unsupported, returns 1 or 0.
+** the function should be:
+** int (*httpRetrieveFile)(HWND hwnd, char *url, char *file, char *dlgtitle);
+** if you call this function, with a parent window, a URL, an output file, and a dialog title,
+** it will return 0 on successful download, 1 on error.
+*/
+
+
+#define IPC_GETHTTPGETTERW 1240
+/* int (*httpRetrieveFileW)(HWND hwnd, char *url, wchar_t *file, wchar_t *dlgtitle); */
+
+
+#define IPC_MBOPEN 241
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_MBOPEN);
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPEN);
+** IPC_MBOPEN will open a new URL in the minibrowser. if url is NULL, it will open the Minibrowser window.
+*/
+
+
+#define IPC_CHANGECURRENTFILE 245
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)file,IPC_CHANGECURRENTFILE);
+** IPC_CHANGECURRENTFILE will set the current playlist item.
+*/
+
+
+#define IPC_CHANGECURRENTFILEW 1245
+/* (requires Winamp 5.3+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)file,IPC_CHANGECURRENTFILEW);
+** IPC_CHANGECURRENTFILEW will set the current playlist item.
+*/
+
+
+#define IPC_GETMBURL 246
+/* (requires Winamp 2.2+)
+** char buffer[4096]; // Urls can be VERY long
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)buffer,IPC_GETMBURL);
+** IPC_GETMBURL will retrieve the current Minibrowser URL into buffer.
+** buffer must be at least 4096 bytes long.
+*/
+
+
+#define IPC_MBBLOCK 248
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_MBBLOCK);
+**
+** IPC_MBBLOCK will block the Minibrowser from updates if value is set to 1
+*/
+
+
+#define IPC_MBOPENREAL 249
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPENREAL);
+**
+** IPC_MBOPENREAL works the same as IPC_MBOPEN except that it will works even if
+** IPC_MBBLOCK has been set to 1
+*/
+
+
+#define IPC_ADJUST_OPTIONSMENUPOS 280
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_OPTIONSMENUPOS);
+** moves where winamp expects the Options menu in the main menu. Useful if you wish to insert a
+** menu item above the options/skins/vis menus.
+*/
+
+
+#define IPC_GET_HMENU 281
+/* (requires Winamp 2.9+)
+** HMENU hMenu=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GET_HMENU);
+** values for data:
+** 0 : main popup menu
+** 1 : main menubar file menu
+** 2 : main menubar options menu
+** 3 : main menubar windows menu
+** 4 : main menubar help menu
+** other values will return NULL.
+*/
+
+
+#define IPC_GET_EXTENDED_FILE_INFO 290 //pass a pointer to the following struct in wParam
+#define IPC_GET_EXTENDED_FILE_INFO_HOOKABLE 296
+/* (requires Winamp 2.9+)
+** to use, create an extendedFileInfoStruct, point the values filename and metadata to the
+** filename and metadata field you wish to query, and ret to a buffer, with retlen to the
+** length of that buffer, and then SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_GET_EXTENDED_FILE_INFO);
+** the results should be in the buffer pointed to by ret.
+** returns 1 if the decoder supports a getExtendedFileInfo method
+*/
+typedef struct {
+ const char *filename;
+ const char *metadata;
+ char *ret;
+ size_t retlen;
+} extendedFileInfoStruct;
+
+
+#define IPC_GET_BASIC_FILE_INFO 291 //pass a pointer to the following struct in wParam
+typedef struct {
+ const char *filename;
+
+ int quickCheck; // set to 0 to always get, 1 for quick, 2 for default (if 2, quickCheck will be set to 0 if quick wasnot used)
+
+ // filled in by winamp
+ int length;
+ char *title;
+ int titlelen;
+} basicFileInfoStruct;
+
+
+#define IPC_GET_BASIC_FILE_INFOW 1291 //pass a pointer to the following struct in wParam
+typedef struct {
+ const wchar_t *filename;
+
+ int quickCheck; // set to 0 to always get, 1 for quick, 2 for default (if 2, quickCheck will be set to 0 if quick wasnot used)
+
+ // filled in by winamp
+ int length;
+ wchar_t *title;
+ int titlelen;
+} basicFileInfoStructW;
+
+
+#define IPC_GET_EXTLIST 292 //returns doublenull delimited. GlobalFree() it when done. if data is 0, returns raw extlist, if 1, returns something suitable for getopenfilename
+#define IPC_GET_EXTLISTW 1292 // wide char version of above
+
+
+#define IPC_INFOBOX 293
+typedef struct {
+ HWND parent;
+ char *filename;
+} infoBoxParam;
+
+
+#define IPC_INFOBOXW 1293
+typedef struct {
+ HWND parent;
+ const wchar_t *filename;
+} infoBoxParamW;
+
+
+#define IPC_SET_EXTENDED_FILE_INFO 294 //pass a pointer to the a extendedFileInfoStruct in wParam
+/* (requires Winamp 2.9+)
+** to use, create an extendedFileInfoStruct, point the values filename and metadata to the
+** filename and metadata field you wish to write in ret. (retlen is not used). and then
+** SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_SET_EXTENDED_FILE_INFO);
+** returns 1 if the metadata is supported
+** Call IPC_WRITE_EXTENDED_FILE_INFO once you're done setting all the metadata you want to update
+*/
+
+
+#define IPC_WRITE_EXTENDED_FILE_INFO 295
+/* (requires Winamp 2.9+)
+** writes all the metadata set thru IPC_SET_EXTENDED_FILE_INFO to the file
+** returns 1 if the file has been successfully updated, 0 if error
+*/
+
+
+#define IPC_FORMAT_TITLE 297
+typedef struct
+{
+ char *spec; // NULL=default winamp spec
+ void *p;
+
+ char *out;
+ int out_len;
+
+ char * (*TAGFUNC)(const char * tag, void * p); //return 0 if not found
+ void (*TAGFREEFUNC)(char * tag,void * p);
+} waFormatTitle;
+
+
+#define IPC_FORMAT_TITLE_EXTENDED 298 // similiar to IPC_FORMAT_TITLE, but falls back to Winamp's %tags% if your passed tag function doesn't handle it
+typedef struct
+{
+ const wchar_t *filename;
+ int useExtendedInfo; // set to 1 if you want the Title Formatter to query the input plugins for any tags that your tag function fails on
+ const wchar_t *spec; // NULL=default winamp spec
+ void *p;
+
+ wchar_t *out;
+ int out_len;
+
+ wchar_t * (*TAGFUNC)(const wchar_t * tag, void * p); //return 0 if not found, -1 for empty tag
+ void (*TAGFREEFUNC)(wchar_t *tag, void *p);
+} waFormatTitleExtended;
+
+
+#define IPC_COPY_EXTENDED_FILE_INFO 299
+typedef struct
+{
+ const char *source;
+ const char *dest;
+} copyFileInfoStruct;
+
+
+#define IPC_COPY_EXTENDED_FILE_INFOW 1299
+typedef struct
+{
+ const wchar_t *source;
+ const wchar_t *dest;
+} copyFileInfoStructW;
+
+
+typedef struct {
+ int (*inflateReset)(void *strm);
+ int (*inflateInit_)(void *strm,const char *version, int stream_size);
+ int (*inflate)(void *strm, int flush);
+ int (*inflateEnd)(void *strm);
+ unsigned long (*crc32)(unsigned long crc, const unsigned char *buf, unsigned int len);
+} wa_inflate_struct;
+
+#define IPC_GETUNCOMPRESSINTERFACE 331
+/* returns a function pointer to uncompress().
+** int (*uncompress)(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen);
+** right out of zlib, useful for decompressing zlibbed data.
+** if you pass the parm of 0x10100000, it will return a wa_inflate_struct * to an inflate API.
+*/
+
+
+typedef struct _prefsDlgRec {
+ HINSTANCE hInst; // dll instance containing the dialog resource
+ int dlgID; // resource identifier of the dialog
+ void *proc; // window proceedure for handling the dialog defined as
+ // LRESULT CALLBACK PrefsPage(HWND,UINT,WPARAM,LPARAM)
+
+ char *name; // name shown for the prefs page in the treelist
+ intptr_t where; // section in the treelist the prefs page is to be added to
+ // 0 for General Preferences
+ // 1 for Plugins
+ // 2 for Skins
+ // 3 for Bookmarks (no longer in the 5.0+ prefs)
+ // 4 for Prefs (the old 'Setup' section - no longer in 5.0+)
+
+ intptr_t _id;
+ struct _prefsDlgRec *next; // no longer implemented as a linked list, now used by Winamp for other means
+} prefsDlgRec;
+
+typedef struct _prefsDlgRecW {
+ HINSTANCE hInst; // dll instance containing the dialog resource
+ int dlgID; // resource identifier of the dialog
+ void *proc; // window proceedure for handling the dialog defined as
+ // LRESULT CALLBACK PrefsPage(HWND,UINT,WPARAM,LPARAM)
+
+ wchar_t *name; // name shown for the prefs page in the treelist
+ intptr_t where; // section in the treelist the prefs page is to be added to
+ // 0 for General Preferences
+ // 1 for Plugins
+ // 2 for Skins
+ // 3 for Bookmarks (no longer in the 5.0+ prefs)
+ // 4 for Prefs (the old 'Setup' section - no longer in 5.0+)
+
+ intptr_t _id;
+ struct _prefsDlgRec *next; // no longer implemented as a linked list, now used by Winamp for other means
+} prefsDlgRecW;
+
+#define IPC_ADD_PREFS_DLG 332
+#define IPC_ADD_PREFS_DLGW 1332
+#define IPC_REMOVE_PREFS_DLG 333
+/* (requires Winamp 2.9+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)&prefsRec,IPC_ADD_PREFS_DLG);
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)&prefsRec,IPC_REMOVE_PREFS_DLG);
+**
+** IPC_ADD_PREFS_DLG:
+** To use this you need to allocate a prefsDlgRec structure (either on the heap or with
+** some global data but NOT on the stack) and then initialise the members of the structure
+** (see the definition of the prefsDlgRec structure above).
+**
+** hInst - dll instance of where the dialog resource is located.
+** dlgID - id of the dialog resource.
+** proc - dialog window procedure for the prefs dialog.
+** name - name of the prefs page as shown in the preferences list.
+** where - see above for the valid locations the page can be added.
+**
+** Then you do SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)&prefsRec,IPC_ADD_PREFS_DLG);
+**
+** example:
+**
+** prefsDlgRec* prefsRec = 0;
+** prefsRec = GlobalAlloc(GPTR,sizeof(prefsDlgRec));
+** prefsRec->hInst = hInst;
+** prefsRec->dlgID = IDD_PREFDIALOG;
+** prefsRec->name = "Pref Page";
+** prefsRec->where = 0;
+** prefsRec->proc = PrefsPage;
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)&prefsRec,IPC_ADD_PREFS_DLG);
+**
+**
+** IPC_REMOVE_PREFS_DLG:
+** To use you pass the address of the same prefsRec you used when adding the prefs page
+** though you shouldn't really ever have to do this but it's good to clean up after you
+** when you're plugin is being unloaded.
+**
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)&prefsRec,IPC_REMOVE_PREFS_DLG);
+**
+** IPC_ADD_PREFS_DLGW
+** requires Winamp 5.53+
+*/
+
+
+#define IPC_OPENPREFSTOPAGE 380
+/* SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)&prefsRec,IPC_OPENPREFSTOPAGE);
+**
+** There are two ways of opening a preferences page.
+**
+** The first is to pass an id of a builtin preferences page (see below for ids) or a
+** &prefsDlgRec of the preferences page to open and this is normally done if you are
+** opening a prefs page you added yourself.
+**
+** If the page id does not or the &prefsRec is not valid then the prefs dialog will be
+** opened to the first page available (usually the Winamp Pro page).
+**
+** (requires Winamp 5.04+)
+** Passing -1 for param will open the preferences dialog to the last page viewed.
+**
+** Note: v5.0 to 5.03 had a bug in this api
+**
+** On the first call then the correct prefs page would be opened to but on the next call
+** the prefs dialog would be brought to the front but the page would not be changed to the
+** specified.
+** In 5.04+ it will change to the prefs page specified if the prefs dialog is already open.
+*/
+
+/* Builtin Preference page ids (valid for 5.0+)
+** (stored in the lParam member of the TVITEM structure from the tree item)
+**
+** These can be useful if you want to detect a specific prefs page and add things to it
+** yourself or something like that ;)
+**
+** Winamp Pro 20
+** General Preferences 0
+** File Types 1
+** Playlist 23
+** Titles 21
+** Playback 42 (added in 5.25)
+** Station Info 41 (added in 5.11 & removed in 5.5)
+** Video 24
+** Localization 25 (added in 5.5)
+** Skins 40
+** Classic Skins 22
+** Plugins 30
+** Input 31
+** Output 32
+** Visualisation 33
+** DSP/Effect 34
+** General Purpose 35
+**
+** Note:
+** Custom page ids begin from 60
+** The value of the normal custom pages (Global Hotkeys, Jump To File, etc) is not
+** guaranteed since it depends on the order in which the plugins are loaded which can
+** change on different systems.
+**
+** Global Hotkeys, Jump To File, Media Library (under General Preferences and child pages),
+** Media Library (under Plugins), Portables, CD Ripping and Modern Skins are custom pages
+** created by the plugins shipped with Winamp.
+*/
+
+
+#define IPC_GETINIFILE 334
+/* (requires Winamp 2.9+)
+** char *ini=(char*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETINIFILE);
+** This returns a pointer to the full file path of winamp.ini.
+**
+** char ini_path[MAX_PATH] = {0};
+**
+** void GetIniFilePath(HWND hwnd){
+** if(SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVERSION) >= 0x2900){
+** // this gets the string of the full ini file path
+** lstrcpyn(ini_path,(char*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETINIFILE),sizeof(ini_path));
+** }
+** else{
+** char* p = ini_path;
+** p += GetModuleFileName(0,ini_path,sizeof(ini_path)) - 1;
+** while(p && *p != '.'){p--;}
+** lstrcpyn(p+1,"ini",sizeof(ini_path));
+** }
+** }
+*/
+
+
+#define IPC_GETINIDIRECTORY 335
+/* (requires Winamp 2.9+)
+** char *dir=(char*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETINIDIRECTORY);
+** This returns a pointer to the directory where winamp.ini can be found and is
+** useful if you want store config files but you don't want to use winamp.ini.
+*/
+
+
+#define IPC_GETPLUGINDIRECTORY 336
+/* (requires Winamp 5.11+)
+** char *plugdir=(char*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETPLUGINDIRECTORY);
+** This returns a pointer to the directory where Winamp has its plugins stored and is
+** useful if you want store config files in plugins.ini in the plugins folder or for
+** accessing any local files in the plugins folder.
+*/
+
+
+#define IPC_GETM3UDIRECTORY 337
+/* (requires Winamp 5.11+)
+** char *m3udir=(char*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETM3UDIRECTORY);
+** This returns a pointer to the directory where winamp.m3u (and winamp.m3u8 if supported) is stored in.
+*/
+
+
+#define IPC_GETM3UDIRECTORYW 338
+/* (requires Winamp 5.3+)
+** wchar_t *m3udirW=(wchar_t*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETM3UDIRECTORYW);
+** This returns a pointer to the directory where winamp.m3u (and winamp.m3u8 if supported) is stored in.
+*/
+
+
+#define IPC_SPAWNBUTTONPOPUP 361 // param =
+// 0 = eject
+// 1 = previous
+// 2 = next
+// 3 = pause
+// 4 = play
+// 5 = stop
+
+
+#define IPC_OPENURLBOX 360
+/* (requires Winamp 5.0+)
+** HGLOBAL hglobal = (HGLOBAL)SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(HWND)parent,IPC_OPENURLBOX);
+** You pass a hwnd for the dialog to be parented to (which modern skin support uses).
+** This will return a HGLOBAL that needs to be freed with GlobalFree() if this worked.
+*/
+
+
+#define IPC_OPENFILEBOX 362
+/* (requires Winamp 5.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(HWND)parent,IPC_OPENFILEBOX);
+** You pass a hwnd for the dialog to be parented to (which modern skin support uses).
+*/
+
+
+#define IPC_OPENDIRBOX 363
+/* (requires Winamp 5.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(HWND)parent,IPC_OPENDIRBOX);
+** You pass a hwnd for the dialog to be parented to (which modern skin support uses).
+*/
+
+
+#define IPC_SETDIALOGBOXPARENT 364
+/* (requires Winamp 5.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(HWND)parent,IPC_SETDIALOGBOXPARENT);
+** Pass 'parent' as the window which will be used as the parent for a number of the built
+** in Winamp dialogs and is useful when you are taking over the whole of the UI so that
+** the dialogs will not appear at the bottom right of the screen since the main winamp
+** window is located at 3000x3000 by gen_ff when this is used. Call this again with
+** parent = null to reset the parent back to the orginal Winamp window.
+*/
+
+#define IPC_GETDIALOGBOXPARENT 365
+/* (requires Winamp 5.51+)
+** HWND hwndParent = SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)0, IPC_GETDIALOGBOXPARENT);
+** hwndParent can/must be passed to all modal dialogs (including MessageBox) thats uses winamp as a parent
+*/
+
+#define IPC_UPDATEDIALOGBOXPARENT 366
+/* (requires Winamp 5.53+)
+** if you previous called IPC_SETDIALOGBOXPARENT, call this every time your window resizes
+*/
+
+#define IPC_DRO_MIN 401 // reserved for DrO
+#define IPC_SET_JTF_COMPARATOR 409
+/* pass me an int (__cdecl *)(const char *, const char *) in wParam */
+#define IPC_SET_JTF_COMPARATOR_W 410
+/* pass me an int (__cdecl *)(const wchar_t *, const wchar_t *) in wParam ... maybe someday :) */
+#define IPC_SET_JTF_DRAWTEXT 416
+
+#define IPC_DRO_MAX 499
+
+
+// pass 0 for a copy of the skin HBITMAP
+// pass 1 for name of font to use for playlist editor likeness
+// pass 2 for font charset
+// pass 3 for font size
+#define IPC_GET_GENSKINBITMAP 503
+
+
+typedef struct
+{
+ HWND me; //hwnd of the window
+
+ #define EMBED_FLAGS_NORESIZE 0x1
+ // set this bit to keep window from being resizable
+
+ #define EMBED_FLAGS_NOTRANSPARENCY 0x2
+ // set this bit to make gen_ff turn transparency off for this window
+
+ #define EMBED_FLAGS_NOWINDOWMENU 0x4
+ // set this bit to prevent gen_ff from automatically adding your window to the right-click menu
+
+ #define EMBED_FLAGS_GUID 0x8
+ // (5.31+) call SET_EMBED_GUID(yourEmbedWindowStateStruct, GUID) to define a GUID for this window
+
+ #define SET_EMBED_GUID(windowState, windowGUID) { windowState->flags |= EMBED_FLAGS_GUID; *((GUID *)&windowState->extra_data[4])=windowGUID; }
+ #define GET_EMBED_GUID(windowState) (*((GUID *)&windowState->extra_data[4]))
+
+ int flags; // see above
+
+ RECT r;
+ void *user_ptr; // for application use
+ int extra_data[64]; // for internal winamp use
+} embedWindowState;
+
+#define IPC_GET_EMBEDIF 505
+/* (requires Winamp 2.9+)
+** HWND myframe = (HWND)SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)&wa_wnd,IPC_GET_EMBEDIF);
+**
+** or
+**
+** HWND myframe = 0;
+** HWND (*embed)(embedWindowState *params)=0;
+** *(void**)&embed = (void*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_EMBEDIF);
+** myframe = embed(&wa_wnd);
+**
+** You pass an embedWindowState* and it will return a hwnd for the frame window or if you
+** pass wParam as null then it will return a HWND embedWindow(embedWindowState *);
+*/
+
+#define IPC_SKINWINDOW 534
+
+typedef struct __SKINWINDOWPARAM
+{
+ HWND hwndToSkin;
+ GUID windowGuid;
+} SKINWINDOWPARAM;
+
+
+
+#define IPC_EMBED_ENUM 532
+typedef struct embedEnumStruct
+{
+ int (*enumProc)(embedWindowState *ws, struct embedEnumStruct *param); // return 1 to abort
+ int user_data; // or more :)
+} embedEnumStruct;
+ // pass
+
+
+#define IPC_EMBED_ISVALID 533
+/* (requires Winamp 2.9+)
+** int valid = SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)embedhwnd,IPC_EMBED_ISVALID);
+** Pass a hwnd in the wParam to this to check if the hwnd is a valid embed window or not.
+*/
+
+
+#define IPC_CONVERTFILE 506
+/* (requires Winamp 2.92+)
+** Converts a given file to a different format (PCM, MP3, etc...)
+** To use, pass a pointer to a waFileConvertStruct struct
+** This struct can be either on the heap or some global
+** data, but NOT on the stack. At least, until the conversion is done.
+**
+** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE);
+**
+** Return value:
+** 0: Can't start the conversion. Look at myConvertStruct->error for details.
+** 1: Conversion started. Status messages will be sent to the specified callbackhwnd.
+** Be sure to call IPC_CONVERTFILE_END when your callback window receives the
+** IPC_CB_CONVERT_DONE message.
+*/
+typedef struct
+{
+ char *sourcefile; // "c:\\source.mp3"
+ char *destfile; // "c:\\dest.pcm"
+ intptr_t destformat[8]; // like 'PCM ',srate,nch,bps.
+ //hack alert! you can set destformat[6]=mmioFOURCC('I','N','I',' '); and destformat[7]=(int)my_ini_file; (where my_ini_file is a char*)
+ HWND callbackhwnd; // window that will receive the IPC_CB_CONVERT notification messages
+
+ //filled in by winamp.exe
+ char *error; //if IPC_CONVERTFILE returns 0, the reason will be here
+
+ int bytes_done; //you can look at both of these values for speed statistics
+ int bytes_total;
+ int bytes_out;
+
+ int killswitch; // don't set it manually, use IPC_CONVERTFILE_END
+ intptr_t extra_data[64]; // for internal winamp use
+} convertFileStruct;
+
+
+#define IPC_CONVERTFILEW 515
+// (requires Winamp 5.36+)
+typedef struct
+{
+ wchar_t *sourcefile; // "c:\\source.mp3"
+ wchar_t *destfile; // "c:\\dest.pcm"
+ intptr_t destformat[8]; // like 'PCM ',srate,nch,bps.
+ //hack alert! you can set destformat[6]=mmioFOURCC('I','N','I',' '); and destformat[7]=(int)my_ini_file; (where my_ini_file is a char*)
+ HWND callbackhwnd; // window that will receive the IPC_CB_CONVERT notification messages
+
+ //filled in by winamp.exe
+ wchar_t *error; //if IPC_CONVERTFILE returns 0, the reason will be here
+
+ int bytes_done; //you can look at both of these values for speed statistics
+ int bytes_total;
+ int bytes_out;
+
+ int killswitch; // don't set it manually, use IPC_CONVERTFILE_END
+ intptr_t extra_data[64]; // for internal winamp use
+} convertFileStructW;
+
+
+#define IPC_CONVERTFILE_END 507
+/* (requires Winamp 2.92+)
+** Stop/ends a convert process started from IPC_CONVERTFILE
+** You need to call this when you receive the IPC_CB_CONVERTDONE message or when you
+** want to abort a conversion process
+**
+** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE_END);
+**
+** No return value
+*/
+
+
+#define IPC_CONVERTFILEW_END 516
+// (requires Winamp 5.36+)
+
+typedef struct {
+ HWND hwndParent;
+ int format;
+
+ //filled in by winamp.exe
+ HWND hwndConfig;
+ int extra_data[8];
+ //hack alert! you can set extra_data[6]=mmioFOURCC('I','N','I',' '); and extra_data[7]=(int)my_ini_file; (where my_ini_file is a char*)
+} convertConfigStruct;
+
+
+#define IPC_CONVERT_CONFIG 508
+#define IPC_CONVERT_CONFIG_END 509
+
+typedef struct
+{
+ void (*enumProc)(intptr_t user_data, const char *desc, int fourcc);
+ intptr_t user_data;
+} converterEnumFmtStruct;
+#define IPC_CONVERT_CONFIG_ENUMFMTS 510
+/* (requires Winamp 2.92+)
+*/
+
+typedef struct
+{
+ char cdletter;
+ char *playlist_file;
+ HWND callback_hwnd;
+
+ //filled in by winamp.exe
+ char *error;
+} burnCDStruct;
+#define IPC_BURN_CD 511
+/* (requires Winamp 5.0+)
+*/
+
+typedef struct
+{
+ convertFileStruct *cfs;
+ int priority;
+} convertSetPriority;
+
+
+#define IPC_CONVERT_SET_PRIORITY 512
+
+typedef struct
+{
+ convertFileStructW *cfs;
+ int priority;
+} convertSetPriorityW;
+
+
+#define IPC_CONVERT_SET_PRIORITYW 517
+// (requires Winamp 5.36+)
+
+typedef struct
+{
+ unsigned int format; //fourcc value
+ char *item; // config item, eg "bitrate"
+ char *data; // buffer to recieve, or buffer that contains the data
+ int len; // length of the data buffer (only used when getting a config item)
+ char *configfile; // config file to read from
+} convertConfigItem;
+
+
+#define IPC_CONVERT_CONFIG_SET_ITEM 513 // returns TRUE if successful
+#define IPC_CONVERT_CONFIG_GET_ITEM 514 // returns TRUE if successful
+
+
+typedef struct
+{
+ const char *filename;
+ char *title; // 2048 bytes
+ int length;
+ int force_useformatting; // can set this to 1 if you want to force a url to use title formatting shit
+} waHookTitleStruct;
+
+#define IPC_HOOK_TITLES 850
+/* (requires Winamp 5.0+)
+** If you hook this message and modify the information then make sure to return TRUE.
+** If you don't hook the message then make sure you pass it on through the subclass chain.
+**
+** LRESULT CALLBACK WinampWndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
+** {
+** LRESULT ret = CallWindowProc((WNDPROC)WinampProc,hwnd,umsg,wParam,lParam);
+**
+** if(message==WM_WA_IPC && lParam==IPC_HOOK_TITLES)
+** {
+** waHookTitleStruct *ht = (waHookTitleStruct *) wParam;
+** // Doing ATF stuff with ht->title, whatever...
+** return TRUE;
+** }
+** return ret;
+** }
+*/
+
+typedef struct
+{
+ const wchar_t *filename;
+ wchar_t *title; // 2048 characters
+ int length;
+ int force_useformatting; // can set this to 1 if you want to force a url to use title formatting shit
+} waHookTitleStructW;
+#define IPC_HOOK_TITLESW 851
+/* (requires Winamp 5.3+)
+** See information on IPC_HOOK_TITLES for how to process this.
+*/
+
+
+#define IPC_GETSADATAFUNC 800
+// 0: returns a char *export_sa_get() that returns 150 bytes of data
+// 1: returns a export_sa_setreq(int want);
+
+
+#define IPC_GETVUDATAFUNC 801
+// 0: returns a int export_vu_get(int channel) that returns 0-255 (or -1 for bad channel)
+
+
+#define IPC_ISMAINWNDVISIBLE 900
+/* (requires Winamp 5.0+)
+** int visible=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISMAINWNDVISIBLE);
+** You send this to Winamp to query if the main window is visible or not such as by
+** unchecking the option in the main right-click menu. If the main window is visible then
+** this will return 1 otherwise it returns 0.
+*/
+
+
+typedef struct
+{
+ int numElems;
+ int *elems;
+ HBITMAP bm; // set if you want to override
+} waSetPlColorsStruct;
+
+#define IPC_SETPLEDITCOLORS 920
+/* (requires Winamp 5.0+)
+** This is sent by gen_ff when a modern skin is being loaded to set the colour scheme for
+** the playlist editor. When sent numElems is usually 6 and matches with the 6 possible
+** colours which are provided be pledit.txt from the classic skins. The elems array is
+** defined as follows:
+**
+** elems = 0 => normal text
+** elems = 1 => current text
+** elems = 2 => normal background
+** elems = 3 => selected background
+** elems = 4 => minibroswer foreground
+** elems = 5 => minibroswer background
+**
+** if(uMsg == WM_WA_IPC && lParam == IPC_SETPLEDITCOLORS)
+** {
+** waSetPlColorsStruct* colStr = (waSetPlColorsStruct*)wp;
+** if(colStr)
+** {
+** // set or inspect the colours being used (basically for gen_ff's benefit)
+** }
+** }
+*/
+
+
+typedef struct
+{
+ HWND wnd;
+ int xpos; // in screen coordinates
+ int ypos;
+} waSpawnMenuParms;
+
+// waSpawnMenuParms2 is used by the menubar submenus
+typedef struct
+{
+ HWND wnd;
+ int xpos; // in screen coordinates
+ int ypos;
+ int width;
+ int height;
+} waSpawnMenuParms2;
+
+// the following IPC use waSpawnMenuParms as parameter
+#define IPC_SPAWNEQPRESETMENU 933
+#define IPC_SPAWNFILEMENU 934 //menubar
+#define IPC_SPAWNOPTIONSMENU 935 //menubar
+#define IPC_SPAWNWINDOWSMENU 936 //menubar
+#define IPC_SPAWNHELPMENU 937 //menubar
+#define IPC_SPAWNPLAYMENU 938 //menubar
+#define IPC_SPAWNPEFILEMENU 939 //menubar
+#define IPC_SPAWNPEPLAYLISTMENU 940 //menubar
+#define IPC_SPAWNPESORTMENU 941 //menubar
+#define IPC_SPAWNPEHELPMENU 942 //menubar
+#define IPC_SPAWNMLFILEMENU 943 //menubar
+#define IPC_SPAWNMLVIEWMENU 944 //menubar
+#define IPC_SPAWNMLHELPMENU 945 //menubar
+#define IPC_SPAWNPELISTOFPLAYLISTS 946
+
+
+#define WM_WA_SYSTRAY WM_USER+1
+/* This is sent by the system tray when an event happens (you might want to simulate it).
+**
+** if(uMsg == WM_WA_SYSTRAY)
+** {
+** switch(lParam)
+** {
+** // process the messages sent from the tray
+** }
+** }
+*/
+
+
+#define WM_WA_MPEG_EOF WM_USER+2
+/* Input plugins send this when they are done playing back the current file to inform
+** Winamp or anyother installed plugins that the current
+**
+** if(uMsg == WM_WA_MPEG_EOF)
+** {
+** // do what is needed here
+** }
+*/
+
+
+//// video stuff
+
+#define IPC_IS_PLAYING_VIDEO 501 // returns >1 if playing, 0 if not, 1 if old version (so who knows):)
+#define IPC_GET_IVIDEOOUTPUT 500 // see below for IVideoOutput interface
+#define VIDEO_MAKETYPE(A,B,C,D) ((A) | ((B)<<8) | ((C)<<16) | ((D)<<24))
+#define VIDUSER_SET_INFOSTRING 0x1000
+#define VIDUSER_GET_VIDEOHWND 0x1001
+#define VIDUSER_SET_VFLIP 0x1002
+#define VIDUSER_SET_TRACKSELINTERFACE 0x1003 // give your ITrackSelector interface as param2
+#define VIDUSER_OPENVIDEORENDERER 0x1004
+#define VIDUSER_CLOSEVIDEORENDERER 0x1005
+#define VIDUSER_GETPOPUPMENU 0x1006
+#define VIDUSER_SET_INFOSTRINGW 0x1007
+
+typedef struct
+{
+ int w;
+ int h;
+ int vflip;
+ double aspectratio;
+ unsigned int fmt;
+} VideoOpenStruct;
+
+#ifndef NO_IVIDEO_DECLARE
+#ifdef __cplusplus
+
+class VideoOutput;
+class SubsItem;
+
+#ifndef _NSV_DEC_IF_H_
+struct YV12_PLANE {
+ unsigned char* baseAddr;
+ long rowBytes;
+} ;
+
+struct YV12_PLANES {
+ YV12_PLANE y;
+ YV12_PLANE u;
+ YV12_PLANE v;
+};
+#endif
+
+class IVideoOutput
+{
+ public:
+ virtual ~IVideoOutput() { }
+ virtual int open(int w, int h, int vflip, double aspectratio, unsigned int fmt)=0;
+ virtual void setcallback(LRESULT (*msgcallback)(void *token, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam), void *token) { (void)token; (void)msgcallback; /* to eliminate warning C4100 */ }
+ virtual void close()=0;
+ virtual void draw(void *frame)=0;
+ virtual void drawSubtitle(SubsItem *item) {UNREFERENCED_PARAMETER(item); }
+ virtual void showStatusMsg(const char *text) {UNREFERENCED_PARAMETER(text); }
+ virtual int get_latency() { return 0; }
+ virtual void notifyBufferState(int bufferstate) { UNREFERENCED_PARAMETER(bufferstate); } /* 0-255*/
+ virtual INT_PTR extended(INT_PTR param1, INT_PTR param2, INT_PTR param3) { UNREFERENCED_PARAMETER(param1); UNREFERENCED_PARAMETER(param2); UNREFERENCED_PARAMETER(param3); return 0; } // Dispatchable, eat this!
+};
+
+class ITrackSelector
+{
+ public:
+ virtual int getNumAudioTracks()=0;
+ virtual void enumAudioTrackName(int n, const char *buf, int size)=0;
+ virtual int getCurAudioTrack()=0;
+ virtual int getNumVideoTracks()=0;
+ virtual void enumVideoTrackName(int n, const char *buf, int size)=0;
+ virtual int getCurVideoTrack()=0;
+
+ virtual void setAudioTrack(int n)=0;
+ virtual void setVideoTrack(int n)=0;
+};
+
+#endif //cplusplus
+#endif//NO_IVIDEO_DECLARE
+
+// these messages are callbacks that you can grab by subclassing the winamp window
+
+// wParam =
+#define IPC_CB_WND_EQ 0 // use one of these for the param
+#define IPC_CB_WND_PE 1
+#define IPC_CB_WND_MB 2
+#define IPC_CB_WND_VIDEO 3
+#define IPC_CB_WND_MAIN 4
+
+#define IPC_CB_ONSHOWWND 600
+#define IPC_CB_ONHIDEWND 601
+
+#define IPC_CB_GETTOOLTIP 602
+
+#define IPC_CB_MISC 603
+ #define IPC_CB_MISC_TITLE 0 // start of playing/stop/pause
+ #define IPC_CB_MISC_VOLUME 1 // volume/pan
+ #define IPC_CB_MISC_STATUS 2 // start playing/stop/pause/ffwd/rwd
+ #define IPC_CB_MISC_EQ 3
+ #define IPC_CB_MISC_INFO 4
+ #define IPC_CB_MISC_VIDEOINFO 5
+ #define IPC_CB_MISC_TITLE_RATING 6 // (5.5+ for when the rating is changed via the songticker menu on current file)
+
+/* Example of using IPC_CB_MISC_STATUS to detect the start of track playback with 5.x
+**
+** if(lParam == IPC_CB_MISC && wParam == IPC_CB_MISC_STATUS)
+** {
+** if(SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING) == 1 &&
+** !SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETOUTPUTTIME))
+** {
+** char* file = (char*)SendMessage(hwnd_winamp,WM_WA_IPC,
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS),IPC_GETPLAYLISTFILE);
+** // only output if a valid file was found
+** if(file)
+** {
+** MessageBox(hwnd_winamp,file,"starting",0);
+** // or do something else that you need to do
+** }
+** }
+** }
+*/
+
+
+#define IPC_CB_CONVERT_STATUS 604 // param value goes from 0 to 100 (percent)
+#define IPC_CB_CONVERT_DONE 605
+
+
+#define IPC_ADJUST_FFWINDOWSMENUPOS 606
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFWINDOWSMENUPOS);
+** This will move where Winamp expects the freeform windows in the menubar windows main
+** menu. This is useful if you wish to insert a menu item above extra freeform windows.
+*/
+
+
+#define IPC_ISDOUBLESIZE 608
+/* (requires Winamp 5.0+)
+** int dsize=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISDOUBLESIZE);
+** You send this to Winamp to query if the double size mode is enabled or not.
+** If it is on then this will return 1 otherwise it will return 0.
+*/
+
+
+#define IPC_ADJUST_FFOPTIONSMENUPOS 609
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFOPTIONSMENUPOS);
+** moves where winamp expects the freeform preferences item in the menubar windows main
+** menu. This is useful if you wish to insert a menu item above the preferences item.
+**
+** Note: This setting was ignored by gen_ff until it was fixed in 5.1
+** gen_ff would assume thatthe menu position was 11 in all cases and so when you
+** had two plugins attempting to add entries into the main right click menu it
+** would cause the 'colour themes' submenu to either be incorrectly duplicated or
+** to just disappear.instead.
+*/
+
+
+#define IPC_GETTIMEDISPLAYMODE 610
+/* (requires Winamp 5.0+)
+** int mode=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETTIMEDISPLAYMODE);
+** This will return the status of the time display i.e. shows time elapsed or remaining.
+** This returns 0 if Winamp is displaying time elapsed or 1 for the time remaining.
+*/
+
+
+#define IPC_SETVISWND 611
+/* (requires Winamp 5.0+)
+** int viswnd=(HWND)SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(HWND)viswnd,IPC_SETVISWND);
+** This allows you to set a window to receive the following message commands (which are
+** used as part of the modern skin integration).
+** When you have finished or your visualisation is closed then send wParam as zero to
+** ensure that things are correctly tidied up.
+*/
+
+/* The following messages are received as the LOWORD(wParam) of the WM_COMMAND message.
+** See %SDK%\winamp\wa5vis.txt for more info about visualisation integration in Winamp.
+*/
+#define ID_VIS_NEXT 40382
+#define ID_VIS_PREV 40383
+#define ID_VIS_RANDOM 40384
+#define ID_VIS_FS 40389
+#define ID_VIS_CFG 40390
+#define ID_VIS_MENU 40391
+
+
+#define IPC_GETVISWND 612
+/* (requires Winamp 5.0+)
+** int viswnd=(HWND)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVISWND);
+** This returns a HWND to the visualisation command handler window if set by IPC_SETVISWND.
+*/
+
+
+#define IPC_ISVISRUNNING 613
+/* (requires Winamp 5.0+)
+** int visrunning=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISVISRUNNING);
+** This will return 1 if a visualisation is currently running and 0 if one is not running.
+*/
+
+
+#define IPC_CB_VISRANDOM 628 // param is status of random
+
+
+#define IPC_SETIDEALVIDEOSIZE 614
+/* (requires Winamp 5.0+)
+** This is sent by Winamp back to itself so it can be trapped and adjusted as needed with
+** the desired width in HIWORD(wParam) and the desired height in LOWORD(wParam).
+**
+** if(uMsg == WM_WA_IPC){
+** if(lParam == IPC_SETIDEALVIDEOSIZE){
+** wParam = MAKEWPARAM(height,width);
+** }
+** }
+*/
+
+
+#define IPC_GETSTOPONVIDEOCLOSE 615
+/* (requires Winamp 5.0+)
+** int sovc=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETSTOPONVIDEOCLOSE);
+** This will return 1 if 'stop on video close' is enabled and 0 if it is disabled.
+*/
+
+
+#define IPC_SETSTOPONVIDEOCLOSE 616
+/* (requires Winamp 5.0+)
+** int sovc=SendMessage(hwnd_winamp,WM_WA_IPC,enabled,IPC_SETSTOPONVIDEOCLOSE);
+** Set enabled to 1 to enable and 0 to disable the 'stop on video close' option.
+*/
+
+
+typedef struct {
+ HWND hwnd;
+ int uMsg;
+ WPARAM wParam;
+ LPARAM lParam;
+} transAccelStruct;
+
+#define IPC_TRANSLATEACCELERATOR 617
+/* (requires Winamp 5.0+)
+** (deprecated as of 5.53x+)
+*/
+
+typedef struct {
+ int cmd;
+ int x;
+ int y;
+ int align;
+} windowCommand; // send this as param to an IPC_PLCMD, IPC_MBCMD, IPC_VIDCMD
+
+
+#define IPC_CB_ONTOGGLEAOT 618
+
+
+#define IPC_GETPREFSWND 619
+/* (requires Winamp 5.0+)
+** HWND prefs = (HWND)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETPREFSWND);
+** This will return a handle to the preferences dialog if it is open otherwise it will
+** return zero. A simple check with the OS api IsWindow(..) is a good test if it's valid.
+**
+** e.g. this will open (or close if already open) the preferences dialog and show if we
+** managed to get a valid
+** SendMessage(hwnd_winamp,WM_COMMAND,MAKEWPARAM(WINAMP_OPTIONS_PREFS,0),0);
+** MessageBox(hwnd_winamp,(IsWindow((HWND)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETPREFSWND))?"Valid":"Not Open"),0,MB_OK);
+*/
+
+
+#define IPC_SET_PE_WIDTHHEIGHT 620
+/* (requires Winamp 5.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)&point,IPC_SET_PE_WIDTHHEIGHT);
+** You pass a pointer to a POINT structure which holds the width and height and Winamp
+** will set the playlist editor to that size (this is used by gen_ff on skin changes).
+** There does not appear to be any bounds limiting with this so it is possible to create
+** a zero size playlist editor window (which is a pretty silly thing to do).
+*/
+
+
+#define IPC_GETLANGUAGEPACKINSTANCE 621
+/* (requires Winamp 5.0+)
+** HINSTANCE hInst = (HINSTANCE)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLANGUAGEPACKINSTANCE);
+** This will return the HINSTANCE to the currently used language pack file for winamp.exe
+**
+** (5.5+)
+** If you pass 1 in wParam then you will have zero returned if a language pack is in use.
+** if(!SendMessage(hwnd_winamp,WM_WA_IPC,1,IPC_GETLANGUAGEPACKINSTANCE)){
+** // winamp is currently using a language pack
+** }
+**
+** If you pass 2 in wParam then you will get the path to the language pack folder.
+** wchar_t* lngpackfolder = (wchar_t*)SendMessage(hwnd_winamp,WM_WA_IPC,2,IPC_GETLANGUAGEPACKINSTANCE);
+**
+** If you pass 3 in wParam then you will get the path to the currently extracted language pack.
+** wchar_t* lngpack = (wchar_t*)SendMessage(hwnd_winamp,WM_WA_IPC,3,IPC_GETLANGUAGEPACKINSTANCE);
+**
+** If you pass 4 in wParam then you will get the name of the currently used language pack.
+** wchar_t* lngname = (char*)SendMessage(hwnd_winamp,WM_WA_IPC,4,IPC_GETLANGUAGEPACKINSTANCE);
+*/
+#define LANG_IDENT_STR 0
+#define LANG_LANG_CODE 1
+#define LANG_COUNTRY_CODE 2
+/*
+** (5.51+)
+** If you pass 5 in LOWORD(wParam) then you will get the ident string/code string
+** (based on the param passed in the HIWORD(wParam) of the currently used language pack.
+** The string returned with LANG_IDENT_STR is used to represent the language that the
+** language pack is intended for following ISO naming conventions for consistancy.
+**
+** wchar_t* ident_str = (wchar_t*)SendMessage(hwnd_winamp,WM_WA_IPC,MAKEWPARAM(5,LANG_XXX),IPC_GETLANGUAGEPACKINSTANCE);
+**
+** e.g.
+** For the default language it will return the following for the different LANG_XXX codes
+** LANG_IDENT_STR -> "en-US" (max buffer size of this is 9 wchar_t)
+** LANG_LANG_CODE -> "en" (language code)
+** LANG_COUNTRY_CODE -> "US" (country code)
+**
+** On pre 5.51 installs you can get LANG_IDENT_STR using the following method
+** (you'll have to custom process the string returned if you want the langugage or country but that's easy ;) )
+**
+** #define LANG_PACK_LANG_ID 65534 (if you don't have lang.h)
+** HINSTANCE hInst = (HINSTANCE)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLANGUAGEPACKINSTANCE);
+** TCHAR buffer[9] = {0};
+** LoadString(hInst,LANG_PACK_LANG_ID,buffer,sizeof(buffer));
+**
+**
+**
+** The following example shows how using the basic api will allow you to load the playlist
+** context menu resource from the currently loaded language pack or it will fallback to
+** the default winamp.exe instance.
+**
+** HINSTANCE lang = (HINSTANCE)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLANGUAGEPACKINSTANCE);
+** HMENU popup = GetSubMenu(GetSubMenu((LoadMenu(lang?lang:GetModuleHandle(0),MAKEINTRESOURCE(101))),2),5);
+** // do processing as needed on the menu before displaying it
+** TrackPopupMenuEx(orig,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,rc.left,rc.bottom,hwnd_owner,0);
+** DestroyMenu(popup);
+**
+** If you need a specific menu handle then look at IPC_GET_HMENU for more information.
+*/
+
+
+#define IPC_CB_PEINFOTEXT 622 // data is a string, ie: "04:21/45:02"
+
+
+#define IPC_CB_OUTPUTCHANGED 623 // output plugin was changed in config
+
+
+#define IPC_GETOUTPUTPLUGIN 625
+/* (requires Winamp 5.0+)
+** char* outdll = (char*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETOUTPUTPLUGIN);
+** This returns a string of the current output plugin's dll name.
+** e.g. if the directsound plugin was selected then this would return 'out_ds.dll'.
+*/
+
+
+#define IPC_SETDRAWBORDERS 626
+/* (requires Winamp 5.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,enabled,IPC_SETDRAWBORDERS);
+** Set enabled to 1 to enable and 0 to disable drawing of the playlist editor and winamp
+** gen class windows (used by gen_ff to allow it to draw its own window borders).
+*/
+
+
+#define IPC_DISABLESKINCURSORS 627
+/* (requires Winamp 5.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,enabled,IPC_DISABLESKINCURSORS);
+** Set enabled to 1 to enable and 0 to disable the use of skinned cursors.
+*/
+
+
+#define IPC_GETSKINCURSORS 628
+/* (requires Winamp 5.36+)
+** data = (WACURSOR)cursorId. (check wa_dlg.h for values)
+*/
+
+
+#define IPC_CB_RESETFONT 629
+
+
+#define IPC_IS_FULLSCREEN 630
+/* (requires Winamp 5.0+)
+** int val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_IS_FULLSCREEN);
+** This will return 1 if the video or visualisation is in fullscreen mode or 0 otherwise.
+*/
+
+
+#define IPC_SET_VIS_FS_FLAG 631
+/* (requires Winamp 5.0+)
+** A vis should send this message with 1/as param to notify winamp that it has gone to or has come back from fullscreen mode
+*/
+
+
+#define IPC_SHOW_NOTIFICATION 632
+
+
+#define IPC_GETSKININFO 633
+#define IPC_GETSKININFOW 1633
+/* (requires Winamp 5.0+)
+** This is a notification message sent to the main Winamp window by itself whenever it
+** needs to get information to be shown about the current skin in the 'Current skin
+** information' box on the main Skins page in the Winamp preferences.
+**
+** When this notification is received and the current skin is one you are providing the
+** support for then you return a valid buffer for Winamp to be able to read from with
+** information about it such as the name of the skin file.
+**
+** if(uMsg == WM_WA_IPC && lParam == IPC_GETSKININFO){
+** if(is_our_skin()){
+** return is_our_skin_name();
+** }
+** }
+*/
+
+
+#define IPC_GET_MANUALPLADVANCE 634
+/* (requires Winamp 5.03+)
+** int val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_MANUALPLADVANCE);
+** IPC_GET_MANUALPLADVANCE returns the status of the Manual Playlist Advance.
+** If enabled this will return 1 otherwise it will return 0.
+*/
+
+
+#define IPC_SET_MANUALPLADVANCE 635
+/* (requires Winamp 5.03+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_MANUALPLADVANCE);
+** IPC_SET_MANUALPLADVANCE sets the status of the Manual Playlist Advance option.
+** Set value = 1 to turn it on and value = 0 to turn it off.
+*/
+
+
+#define IPC_GET_NEXT_PLITEM 636
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_EOF_GET_NEXT_PLITEM);
+**
+** Sent to Winamp's main window when an item has just finished playback or the next
+** button has been pressed and requesting the new playlist item number to go to.
+**
+** Subclass this message in your application to return the new item number.
+** Return -1 for normal Winamp operation (default) or the new item number in
+** the playlist to be played instead of the originally selected next track.
+*/
+
+
+#define IPC_GET_PREVIOUS_PLITEM 637
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_EOF_GET_PREVIOUS_PLITEM);
+**
+** Sent to Winamp's main window when the previous button has been pressed and Winamp is
+** requesting the new playlist item number to go to.
+**
+** Return -1 for normal Winamp operation (default) or the new item number in
+** the playlist to be played instead of the originally selected previous track.
+**
+** This is primarily provided for the JTFE plugin (gen_jumpex.dll).
+*/
+
+
+#define IPC_IS_WNDSHADE 638
+/* (requires Winamp 5.04+)
+** int is_shaded=SendMessage(hwnd_winamp,WM_WA_IPC,wnd,IPC_IS_WNDSHADE);
+** Pass 'wnd' as an id as defined for IPC_GETWND or pass -1 to query the status of the
+** main window. This returns 1 if the window is in winshade mode and 0 if it is not.
+** Make sure you only test for this on a 5.04+ install otherwise you get a false result.
+** (See the notes about unhandled WM_WA_IPC messages).
+*/
+
+
+#define IPC_SETRATING 639
+/* (requires Winamp 5.04+ with ML)
+** int rating=SendMessage(hwnd_winamp,WM_WA_IPC,rating,IPC_SETRATING);
+** This will allow you to set the 'rating' on the current playlist entry where 'rating'
+** is an integer value from 0 (no rating) to 5 (5 stars).
+**
+** The following example should correctly allow you to set the rating for any specified
+** playlist entry assuming of course that you're trying to get a valid playlist entry.
+**
+** void SetPlaylistItemRating(int item_to_set, int rating_to_set){
+** int cur_pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS);
+** SendMessage(hwnd_winamp,WM_WA_IPC,item_to_set,IPC_SETPLAYLISTPOS);
+** SendMessage(hwnd_winamp,WM_WA_IPC,rating_to_set,IPC_SETRATING);
+** SendMessage(hwnd_winamp,WM_WA_IPC,cur_pos,IPC_SETPLAYLISTPOS);
+** }
+*/
+
+
+#define IPC_GETRATING 640
+/* (requires Winamp 5.04+ with ML)
+** int rating=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETRATING);
+** This returns the current playlist entry's rating between 0 (no rating) to 5 (5 stars).
+**
+** The following example should correctly allow you to get the rating for any specified
+** playlist entry assuming of course that you're trying to get a valid playlist entry.
+**
+** int GetPlaylistItemRating(int item_to_get, int rating_to_set){
+** int cur_pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS), rating = 0;
+** SendMessage(hwnd_winamp,WM_WA_IPC,item_to_get,IPC_SETPLAYLISTPOS);
+** rating = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETRATING);
+** SendMessage(hwnd_winamp,WM_WA_IPC,cur_pos,IPC_SETPLAYLISTPOS);
+** return rating;
+** }
+*/
+
+
+#define IPC_GETNUMAUDIOTRACKS 641
+/* (requires Winamp 5.04+)
+** int n = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETNUMAUDIOTRACKS);
+** This will return the number of audio tracks available from the currently playing item.
+*/
+
+
+#define IPC_GETNUMVIDEOTRACKS 642
+/* (requires Winamp 5.04+)
+** int n = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETNUMVIDEOTRACKS);
+** This will return the number of video tracks available from the currently playing item.
+*/
+
+
+#define IPC_GETAUDIOTRACK 643
+/* (requires Winamp 5.04+)
+** int cur = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETAUDIOTRACK);
+** This will return the id of the current audio track for the currently playing item.
+*/
+
+
+#define IPC_GETVIDEOTRACK 644
+/* (requires Winamp 5.04+)
+** int cur = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVIDEOTRACK);
+** This will return the id of the current video track for the currently playing item.
+*/
+
+
+#define IPC_SETAUDIOTRACK 645
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,track,IPC_SETAUDIOTRACK);
+** This allows you to switch to a new audio track (if supported) in the current playing file.
+*/
+
+
+#define IPC_SETVIDEOTRACK 646
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,track,IPC_SETVIDEOTRACK);
+** This allows you to switch to a new video track (if supported) in the current playing file.
+*/
+
+
+#define IPC_PUSH_DISABLE_EXIT 647
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_PUSH_DISABLE_EXIT);
+** This will let you disable or re-enable the UI exit functions (close button, context
+** menu, alt-f4). Remember to call IPC_POP_DISABLE_EXIT when you are done doing whatever
+** was required that needed to prevent exit otherwise you have to kill the Winamp process.
+*/
+
+
+#define IPC_POP_DISABLE_EXIT 648
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_POP_DISABLE_EXIT);
+** See IPC_PUSH_DISABLE_EXIT
+*/
+
+
+#define IPC_IS_EXIT_ENABLED 649
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_IS_EXIT_ENABLED);
+** This will return 0 if the 'exit' option of Winamp's menu is disabled and 1 otherwise.
+*/
+
+
+#define IPC_IS_AOT 650
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_IS_AOT);
+** This will return the status of the always on top flag.
+** Note: This may not match the actual TOPMOST window flag while another fullscreen
+** application is focused if the user has the 'Disable always on top while fullscreen
+** applications are focused' option under the General Preferences page is checked.
+*/
+
+
+#define IPC_USES_RECYCLEBIN 651
+/* (requires Winamp 5.09+)
+** int use_bin=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_USES_RECYCLEBIN);
+** This will return 1 if the deleted file should be sent to the recycle bin or
+** 0 if deleted files should be deleted permanently (default action for < 5.09).
+**
+** Note: if you use this on pre 5.09 installs of Winamp then it will return 1 which is
+** not correct but is due to the way that SendMessage(..) handles un-processed messages.
+** Below is a quick case for checking if the returned value is correct.
+**
+** if(SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_USES_RECYCLEBIN) &&
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVERSION)>=0x5009)
+** {
+** // can safely follow the option to recycle the file
+** }
+** else
+* {
+** // need to do a permanent delete of the file
+** }
+*/
+
+
+#define IPC_FLUSHAUDITS 652
+/*
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_FLUSHAUDITS);
+**
+** Will flush any pending audits in the global audits queue
+**
+*/
+
+#define IPC_GETPLAYITEM_START 653
+#define IPC_GETPLAYITEM_END 654
+
+
+#define IPC_GETVIDEORESIZE 655
+#define IPC_SETVIDEORESIZE 656
+
+
+#define IPC_INITIAL_SHOW_STATE 657
+/* (requires Winamp 5.36+)
+** int show_state = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_INITIAL_SHOW_STATE);
+** returns the processed value of nCmdShow when Winamp was started
+** (see MSDN documentation the values passed to WinMain(..) for what this should be)
+**
+** e.g.
+** if(SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_INITIAL_SHOW_STATE) == SW_SHOWMINIMIZED){
+** // we are starting minimised so process as needed (keep our window hidden)
+** }
+**
+** Useful for seeing if winamp was run minimised on startup so you can act accordingly.
+** On pre-5.36 versions this will effectively return SW_NORMAL/SW_SHOWNORMAL due to the
+** handling of unknown apis returning 1 from Winamp.
+*/
+
+// >>>>>>>>>>> Next is 658
+
+#define IPC_PLCMD 1000
+
+#define PLCMD_ADD 0
+#define PLCMD_REM 1
+#define PLCMD_SEL 2
+#define PLCMD_MISC 3
+#define PLCMD_LIST 4
+
+//#define IPC_MBCMD 1001
+
+#define MBCMD_BACK 0
+#define MBCMD_FORWARD 1
+#define MBCMD_STOP 2
+#define MBCMD_RELOAD 3
+#define MBCMD_MISC 4
+
+#define IPC_VIDCMD 1002
+
+#define VIDCMD_FULLSCREEN 0
+#define VIDCMD_1X 1
+#define VIDCMD_2X 2
+#define VIDCMD_LIB 3
+#define VIDPOPUP_MISC 4
+
+//#define IPC_MBURL 1003 //sets the URL
+//#define IPC_MBGETCURURL 1004 //copies the current URL into wParam (have a 4096 buffer ready)
+//#define IPC_MBGETDESC 1005 //copies the current URL description into wParam (have a 4096 buffer ready)
+//#define IPC_MBCHECKLOCFILE 1006 //checks that the link file is up to date (otherwise updates it). wParam=parent HWND
+//#define IPC_MBREFRESH 1007 //refreshes the "now playing" view in the library
+//#define IPC_MBGETDEFURL 1008 //copies the default URL into wParam (have a 4096 buffer ready)
+
+#define IPC_STATS_LIBRARY_ITEMCNT 1300 // updates library count status
+
+/*
+** IPC's in the message range 2000 - 3000 are reserved internally for freeform messages.
+** These messages are taken from ff_ipc.h which is part of the Modern skin integration.
+*/
+
+#define IPC_FF_FIRST 2000
+
+#define IPC_FF_COLOURTHEME_CHANGE IPC_FF_ONCOLORTHEMECHANGED
+#define IPC_FF_ONCOLORTHEMECHANGED IPC_FF_FIRST + 3
+/*
+** This is a notification message sent when the user changes the colour theme in a Modern
+** skin and can also be detected when the Modern skin is first loaded as the gen_ff plugin
+** applies relevant settings and styles (like the colour theme).
+**
+** The value of wParam is the name of the new color theme being switched to.
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(const char*)colour_theme_name,IPC_FF_ONCOLORTHEMECHANGED);
+**
+** (IPC_FF_COLOURTHEME_CHANGE is the name i (DrO) was using before getting a copy of
+** ff_ipc.h with the proper name in it).
+*/
+
+
+#define IPC_FF_ISMAINWND IPC_FF_FIRST + 4
+/*
+** int ismainwnd = (HWND)SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(HWND)test_wnd,IPC_FF_ISMAINWND);
+**
+** This allows you to determine if the window handle passed to it is a modern skin main
+** window or not. If it is a main window or any of its windowshade variants then it will
+** return 1.
+**
+** Because of the way modern skins are implemented, it is possible for this message to
+** return a positive test result for a number of window handles within the current Winamp
+** process. This appears to be because you can have a visible main window, a compact main
+** window and also a winshaded version.
+**
+** The following code example below is one way of seeing how this api works since it will
+** enumerate all windows related to Winamp at the time and allows you to process as
+** required when a detection happens.
+**
+**
+** EnumThreadWindows(GetCurrentThreadId(),enumWndProc,0);
+**
+** BOOL CALLBACK enumWndProc(HWND hwnd, LPARAM lParam){
+**
+** if(SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)hwnd,IPC_FF_ISMAINWND)){
+** // do processing in here
+** // or continue the enum for other main windows (if they exist)
+** // and just comment out the line below
+** return 0;
+** }
+** return 1;
+** }
+*/
+
+
+#define IPC_FF_GETCONTENTWND IPC_FF_FIRST + 5
+/*
+** HWND wa2embed = (HWND)SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(HWND)test_wnd,IPC_FF_GETCONTENTWND);
+**
+** This will return the Winamp 2 window that is embedded in the window's container
+** i.e. if hwnd is the playlist editor windowshade hwnd then it will return the Winamp 2
+** playlist editor hwnd.
+**
+** If no content is found such as the window has nothing embedded then this will return
+** the hwnd passed to it.
+*/
+
+
+#define IPC_FF_NOTIFYHOTKEY IPC_FF_FIRST + 6
+/*
+** This is a notification message sent when the user uses a global hotkey combination
+** which had been registered with the gen_hotkeys plugin.
+**
+** The value of wParam is the description of the hotkey as passed to gen_hotkeys.
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(const char*)hotkey_desc,IPC_FF_NOTIFYHOTKEY);
+*/
+
+#define IPC_FF_LAST 3000
+
+
+/*
+** General IPC messages in Winamp
+**
+** All notification messages appear in the lParam of the main window message proceedure.
+*/
+
+
+#define IPC_GETDROPTARGET 3001
+/* (requires Winamp 5.0+)
+** IDropTarget* IDrop = (IDropTarget*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETDROPTARGET);
+**
+** You call this to retrieve a copy of the IDropTarget interface which Winamp created for
+** handling external drag and drop operations on to it's Windows. This is only really
+** useful if you're providing an alternate interface and want your Windows to provide the
+** same drag and drop support as Winamp normally provides the user. Check out MSDN or
+** your prefered search facility for more information about the IDropTarget interface and
+** what's needed to handle it in your own instance.
+*/
+
+
+#define IPC_PLAYLIST_MODIFIED 3002
+/* (requires Winamp 5.0+)
+** This is a notification message sent to the main Winamp window whenever the playlist is
+** modified in any way e.g. the addition/removal of a playlist entry.
+**
+** It is not a good idea to do large amounts of processing in this notification since it
+** will slow down Winamp as playlist entries are modified (especially when you're adding
+** in a large playlist).
+**
+** if(uMsg == WM_WA_IPC && lParam == IPC_PLAYLIST_MODIFIED)
+** {
+** // do what you need to do here
+** }
+*/
+
+
+#define IPC_PLAYING_FILE 3003
+/* (requires Winamp 5.0+)
+** This is a notification message sent to the main Winamp window when playback begins for
+** a file. This passes the full filepath in the wParam of the message received.
+**
+** if(uMsg == WM_WA_IPC && lParam == IPC_PLAYING_FILE)
+** {
+** // do what you need to do here, e.g.
+** process_file((char*)wParam);
+** }
+*/
+
+
+#define IPC_PLAYING_FILEW 13003
+/* (requires Winamp 5.0+)
+** This is a notification message sent to the main Winamp window when playback begins for
+** a file. This passes the full filepath in the wParam of the message received.
+**
+** if(uMsg == WM_WA_IPC && lParam == IPC_PLAYING_FILEW)
+** {
+** // do what you need to do here, e.g.
+** process_file((wchar_t*)wParam);
+** }
+*/
+
+
+#define IPC_FILE_TAG_MAY_HAVE_UPDATED 3004
+#define IPC_FILE_TAG_MAY_HAVE_UPDATEDW 3005
+/* (requires Winamp 5.0+)
+** This is a notification message sent to the main Winamp window when a file's tag
+** (e.g. id3) may have been updated. This appears to be sent when the InfoBox(..) function
+** of the associated input plugin returns a 1 (which is the file information dialog/editor
+** call normally).
+**
+** if(uMsg == WM_WA_IPC && lParam == IPC_FILE_TAG_MAY_HAVE_UPDATED)
+** {
+** // do what you need to do here, e.g.
+** update_info_on_file_update((char*)wParam);
+** }
+*/
+
+
+#define IPC_ALLOW_PLAYTRACKING 3007
+/* (requires Winamp 5.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,allow,IPC_ALLOW_PLAYTRACKING);
+** Send allow as nonzero to allow play tracking and zero to disable the mode.
+*/
+
+
+#define IPC_HOOK_OKTOQUIT 3010
+/* (requires Winamp 5.0+)
+** This is a notification message sent to the main Winamp window asking if it's okay to
+** close or not. Return zero to prevent Winamp from closing or return anything non-zero
+** to allow Winamp to close.
+**
+** The best implementation of this option is to let the message pass through to the
+** original window proceedure since another plugin may want to have a say in the matter
+** with regards to Winamp closing.
+**
+** if(uMsg == WM_WA_IPC && lParam == IPC_HOOK_OKTOQUIT)
+** {
+** // do what you need to do here, e.g.
+** if(no_shut_down())
+** {
+** return 1;
+** }
+** }
+*/
+
+
+#define IPC_WRITECONFIG 3011
+/* (requires Winamp 5.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,write_type,IPC_WRITECONFIG);
+**
+** Send write_type as 2 to write all config settings and the current playlist.
+**
+** Send write_type as 1 to write the playlist and common settings.
+** This won't save the following ini settings::
+**
+** defext, titlefmt, proxy, visplugin_name, dspplugin_name, check_ft_startup,
+** visplugin_num, pe_fontsize, visplugin_priority, visplugin_autoexec, dspplugin_num,
+** sticon, splash, taskbar, dropaotfs, ascb_new, ttips, riol, minst, whichicon,
+** whichicon2, addtolist, snap, snaplen, parent, hilite, disvis, rofiob, shownumsinpl,
+** keeponscreen, eqdsize, usecursors, fixtitles, priority, shuffle_morph_rate,
+** useexttitles, bifont, inet_mode, ospb, embedwnd_freesize, no_visseh
+** (the above was valid for 5.1)
+**
+** Send write_type as 0 to write the common and less common settings and no playlist.
+*/
+
+
+#define IPC_UPDATE_URL 3012
+// pass the URL (char *) in lparam, will be free()'d on done.
+
+
+#define IPC_GET_RANDFUNC 3015 // returns a function to get a random number
+/* (requires Winamp 5.1+)
+** int (*randfunc)(void) = (int(*)(void))SendMessage(plugin.hwndParent,WM_WA_IPC,0,IPC_GET_RANDFUNC);
+** if(randfunc && randfunc != 1){
+** randfunc();
+** }
+**
+** This will return a positive 32-bit number (essentially 31-bit).
+** The check for a returned value of 1 is because that's the default return value from
+** SendMessage(..) when it is not handled so is good to check for it in this situation.
+*/
+
+
+#define IPC_METADATA_CHANGED 3017
+/* (requires Winamp 5.1+)
+** int changed=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)(char*)field,IPC_METADATA_CHANGED);
+** a plugin can SendMessage this to winamp if internal metadata has changes.
+** wParam should be a char * of what field changed
+**
+** Currently used for internal actions (and very few at that) the intent of this api is
+** to allow a plugin to call it when metadata has changed in the current playlist entry
+** e.g.a new id3v2 tag was found in a stream
+**
+** The wparam value can either be NULL or a pointer to an ansi string for the metadata
+** which has changed. This can be thought of as an advanced version of IPC_UPDTITLE and
+** could be used to allow for update of the current title when a specific tag changed.
+**
+** Not recommended to be used since there is not the complete handling implemented in
+** Winamp for it at the moment.
+*/
+
+
+#define IPC_SKIN_CHANGED 3018
+/* (requires Winamp 5.1+)
+** This is a notification message sent to the main Winamp window by itself whenever
+** the skin in use is changed. There is no information sent by the wParam for this.
+**
+** if(message == WM_WA_IPC && lparam == IPC_SKIN_CHANGED)
+** {
+** // do what you need to do to handle skin changes, e.g. call WADlg_init(hwnd_winamp);
+** }
+*/
+
+
+#define IPC_REGISTER_LOWORD_COMMAND 3019
+/* (requires Winamp 5.1+)
+** WORD id = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_REGISTER_LOWORD_COMMAND);
+** This will assign you a unique id for making your own commands such as for extra menu
+** entries. The starting value returned by this message will potentially change as and
+** when the main resource file of Winamp is updated with extra data so assumptions cannot
+** be made on what will be returned and plugin loading order will affect things as well.
+
+** 5.33+
+** If you want to reserve more than one id, you can pass the number of ids required in wParam
+*/
+
+
+#define IPC_GET_DISPATCH_OBJECT 3020 // gets winamp main IDispatch * (for embedded webpages)
+#define IPC_GET_UNIQUE_DISPATCH_ID 3021 // gives you a unique dispatch ID that won't conflict with anything in winamp's IDispatch *
+#define IPC_ADD_DISPATCH_OBJECT 3022 // add your own dispatch object into winamp's. This lets embedded webpages access your functions
+// pass a pointer to DispatchInfo (see below). Winamp makes a copy of all this data so you can safely delete it later
+typedef struct
+{
+ wchar_t *name; // filled in by plugin, make sure it's a unicode string!! (i.e. L"myObject" instead of "myObject).
+ struct IDispatch *dispatch; // filled in by plugin
+ DWORD id; // filled in by winamp on return
+} DispatchInfo;
+
+// see IPC_JSAPI2_GET_DISPATCH_OBJECT for version 2 of the Dispatchable scripting interface
+
+#define IPC_GET_PROXY_STRING 3023
+/* (requires Winamp 5.11+)
+** char* proxy_string=(char*)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_PROXY_STRING);
+** This will return the same string as is shown on the General Preferences page.
+*/
+
+
+#define IPC_USE_REGISTRY 3024
+/* (requires Winamp 5.11+)
+** int reg_enabled=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_USE_REGISTRY);
+** This will return 0 if you should leave your grubby hands off the registry (i.e. for
+** lockdown mode). This is useful if Winamp is run from a USB drive and you can't alter
+** system settings, etc.
+*/
+
+
+#define IPC_GET_API_SERVICE 3025
+/* (requires Winamp 5.12+)
+** api_service* api_service = (api_service)SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_API_SERVICE);
+** This api will return Winamp's api_service pointer (which is what Winamp3 used, heh).
+** If this api is not supported in the Winamp version that is being used at the time then
+** the returned value from this api will be 1 which is a good version check.
+**
+** As of 5.12 there is support for .w5s plugins which reside in %WinampDir%\System and
+** are intended for common code that can be shared amongst other plugins e.g. jnetlib.w5s
+** which contains jnetlib in one instance instead of being duplicated multiple times in
+** all of the plugins which need internet access.
+**
+** Details on the .w5s specifications will come at some stage (possibly).
+*/
+
+
+typedef struct {
+ const wchar_t *filename;
+ const wchar_t *metadata;
+ wchar_t *ret;
+ size_t retlen;
+} extendedFileInfoStructW;
+
+#define IPC_GET_EXTENDED_FILE_INFOW 3026
+/* (requires Winamp 5.13+)
+** Pass a pointer to the above struct in wParam
+*/
+
+
+#define IPC_GET_EXTENDED_FILE_INFOW_HOOKABLE 3027
+#define IPC_SET_EXTENDED_FILE_INFOW 3028
+/* (requires Winamp 5.13+)
+** Pass a pointer to the above struct in wParam
+*/
+
+
+#define IPC_PLAYLIST_GET_NEXT_SELECTED 3029
+/* (requires 5.2+)
+** int pl_item = SendMessage(hwnd_winamp,WM_WA_IPC,start,IPC_PLAYLIST_GET_NEXT_SELECTED);
+**
+** This works just like the ListView_GetNextItem(..) macro for ListView controls.
+** 'start' is the index of the playlist item that you want to begin the search after or
+** set this as -1 for the search to begin with the first item of the current playlist.
+**
+** This will return the index of the selected playlist according to the 'start' value or
+** it returns -1 if there is no selection or no more selected items according to 'start'.
+**
+** Quick example:
+**
+** int sel = -1;
+** // keep incrementing the start of the search so we get all of the selected entries
+** while((sel = SendMessage(hwnd_winamp,WM_WA_IPC,sel,IPC_PLAYLIST_GET_NEXT_SELECTED))!=-1){
+** // show the playlist file entry of the selected item(s) if there were any
+** MessageBox(hwnd_winamp,(char*)SendMessage(hwnd_winamp,WM_WA_IPC,sel,IPC_GETPLAYLISTFILE),0,0);
+** }
+*/
+
+
+#define IPC_PLAYLIST_GET_SELECTED_COUNT 3030
+/* (requires 5.2+)
+** int selcnt = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_PLAYLIST_GET_SELECTED_COUNT);
+** This will return the number of selected playlist entries.
+*/
+
+
+#define IPC_GET_PLAYING_FILENAME 3031
+// returns wchar_t * of the currently playing filename
+
+#define IPC_OPEN_URL 3032
+// send either ANSI or Unicode string (it'll figure it out, but it MUST start with "h"!, so don't send ftp:// or anything funny)
+// you can also send this one from another process via WM_COPYDATA (unicode only)
+
+
+#define IPC_USE_UXTHEME_FUNC 3033
+/* (requires Winamp 5.35+)
+** int ret = SendMessage(hwnd_winamp,WM_WA_IPC,param,IPC_USE_UXTHEME_FUNC);
+** param can be IPC_ISWINTHEMEPRESENT or IPC_ISAEROCOMPOSITIONACTIVE or a valid hwnd.
+**
+** If you pass a hwnd then it will apply EnableThemeDialogTexture(ETDT_ENABLETAB)
+** so your tabbed dialogs can use the correct theme (on supporting OSes ie XP+).
+**
+** Otherwise this will return a value based on the param passed (as defined below).
+** For compatability, the return value will be zero on success (as 1 is returned
+** for unsupported ipc calls on older Winamp versions)
+*/
+ #define IPC_ISWINTHEMEPRESENT 0
+/* This will return 0 if uxtheme.dll is present
+** int isthemethere = !SendMessage(hwnd_winamp,WM_WA_IPC,IPC_ISWINTHEMEPRESENT,IPC_USE_UXTHEME_FUNC);
+*/
+ #define IPC_ISAEROCOMPOSITIONACTIVE 1
+/* This will return 0 if aero composition is active
+** int isaero = !SendMessage(hwnd_winamp,WM_WA_IPC,IPC_ISAEROCOMPOSITIONACTIVE,IPC_USE_UXTHEME_FUNC);
+*/
+
+
+#define IPC_GET_PLAYING_TITLE 3034
+// returns wchar_t * of the current title
+
+
+#define IPC_CANPLAY 3035
+// pass const wchar_t *, returns an in_mod * or 0
+
+
+typedef struct {
+ // fill these in...
+ size_t size; // init to sizeof(artFetchData)
+ HWND parent; // parent window of the dialogue
+
+ // fill as much of these in as you can, otherwise leave them 0
+ const wchar_t *artist;
+ const wchar_t *album;
+ int year, amgArtistId, amgAlbumId;
+
+ int showCancelAll; // if set to 1, this shows a "Cancel All" button on the dialogue
+
+ // winamp will fill these in if the call returns successfully:
+ void* imgData; // a buffer filled with compressed image data. free with WASABI_API_MEMMGR->sysFree()
+ int imgDataLen; // the size of the buffer
+ wchar_t type[10]; // eg: "jpg"
+ const wchar_t *gracenoteFileId; // if you know it
+} artFetchData;
+
+#define IPC_FETCH_ALBUMART 3036
+/* pass an artFetchData*. This will show a dialog guiding the use through choosing art, and return when it's finished
+** return values:
+** 1: error showing dialog
+** 0: success
+** -1: cancel was pressed
+** -2: cancel all was pressed
+*/
+
+#define IPC_JSAPI2_GET_DISPATCH_OBJECT 3037
+/* pass your service's unique ID, as a wchar_t * string, in wParam
+** Winamp will copy the string, so don't worry about keeping it around
+** An IDispatch * object will be returned (cast the return value from SendMessage)
+** This IDispatch can be used for scripting/automation/VB interaction
+** Pass to IE via IDocHostUIHandler::GetExternal and it will become window.external in javscript
+*/
+
+#define IPC_REGISTER_WINAMP_IPCMESSAGE 65536
+/* (requires Winamp 5.0+)
+** DWORD id = SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)name,IPC_REGISTER_WINAMP_IPCMESSAGE);
+** The value 'id' returned is > 65536 and is incremented on subsequent calls for unique
+** 'name' values passed to it. By using the same 'name' in different plugins will allow a
+** common runtime api to be provided for the currently running instance of Winamp
+** e.g.
+** PostMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)my_param,registered_ipc);
+** Have a look at wa_hotkeys.h for an example on how this api is used in practice for a
+** custom WM_WA_IPC message.
+**
+** if(uMsg == WM_WA_IPC && lParam == id_from_register_winamp_ipcmessage){
+** // do things
+** }
+*/
+
+#endif//_WA_IPC_H_ \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/api/memmgr/api_memmgr.h b/Src/Plugins/Input/in_wv/wasabi/api/memmgr/api_memmgr.h
new file mode 100644
index 00000000..3f2448c3
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/api/memmgr/api_memmgr.h
@@ -0,0 +1,78 @@
+#ifndef __API_MEMMGR_H
+#define __API_MEMMGR_H
+
+#include "../../bfc/dispatch.h"
+#include "../../bfc/platform/types.h"
+
+class NOVTABLE api_memmgr : public Dispatchable
+{
+protected:
+ api_memmgr() {}
+ ~api_memmgr() {}
+
+public:
+ void *sysMalloc(size_t size);
+ void sysFree(void *ptr);
+ void *sysRealloc(void *ptr, size_t newsize);
+ void sysMemChanged(void *ptr);
+
+ DISPATCH_CODES
+ {
+ API_MEMMGR_SYSMALLOC = 0,
+ API_MEMMGR_SYSFREE = 10,
+ API_MEMMGR_SYSREALLOC = 20,
+ API_MEMMGR_SYSMEMCHANGED = 30,
+ };
+
+ // Some helper templates to new and delete objects with the memory manager
+ // you need to be cautious with Delete() and inheritance, particularly if you're dealing with a base class
+ // as the pointer to the derived class might not equal to the pointer to the base class, particularly with multiple inheritance
+ // e.g. class C : public A, public B {}; C c; assert((A*)&c == (B*)&c); will likely fail
+
+ template <class Class>
+ void New(Class **obj)
+ {
+ size_t toAlloc = sizeof(Class);
+ void *mem = sysMalloc(toAlloc);
+ *obj = new (mem) Class;
+ }
+
+ template <class Class>
+ void Delete(Class *obj)
+ {
+ if (obj)
+ {
+ obj->~Class();
+ sysFree(obj);
+ }
+ }
+};
+
+inline void *api_memmgr::sysMalloc(size_t size)
+{
+ return _call(API_MEMMGR_SYSMALLOC, (void *)NULL, size);
+}
+
+inline void api_memmgr::sysFree(void *ptr)
+{
+ _voidcall(API_MEMMGR_SYSFREE, ptr);
+}
+
+inline void *api_memmgr::sysRealloc(void *ptr, size_t newsize)
+{
+ return _call(API_MEMMGR_SYSREALLOC, (void *)NULL, ptr, newsize);
+}
+
+inline void api_memmgr::sysMemChanged(void *ptr)
+{
+ _voidcall(API_MEMMGR_SYSMEMCHANGED, ptr);
+}
+
+
+// {000CF46E-4DF6-4a43-BBE7-40E7A3EA02ED}
+static const GUID memMgrApiServiceGuid =
+{ 0xcf46e, 0x4df6, 0x4a43, { 0xbb, 0xe7, 0x40, 0xe7, 0xa3, 0xea, 0x2, 0xed } };
+
+//extern api_memmgr *memmgrApi;
+
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/api/service/api_service.h b/Src/Plugins/Input/in_wv/wasabi/api/service/api_service.h
new file mode 100644
index 00000000..44ef819d
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/api/service/api_service.h
@@ -0,0 +1,155 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:56:11 2003]
+//
+// File : api_service.h
+// Class : api_service
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __API_SERVICE_H
+#define __API_SERVICE_H
+
+#include "../../bfc/dispatch.h"
+#include "../../bfc/platform/types.h"
+
+namespace SvcNotify {
+ enum {
+ ONREGISTERED=100, // init yourself here -- not all other services are registered yet
+ ONSTARTUP=200, // everyone is initialized, safe to talk to other services
+ ONAPPRUNNING=210, // app is showing and processing events
+ ONSHUTDOWN=300, // studio is shutting down, release resources from other services
+ ONDEREGISTERED=400, // bye bye
+ ONDBREADCOMPLETE=500,// after db is read in (happens asynchronously after ONSTARTUP)
+ ONBEFORESHUTDOWN=600, // system is about to shutdown, call WASABI_API_APP->main_cancelShutdown() to cancel
+ };
+}
+
+ class waServiceFactory;
+
+// ----------------------------------------------------------------------------
+
+class NOVTABLE api_service: public Dispatchable {
+ protected:
+ api_service() {}
+ ~api_service() {}
+ public:
+ int service_register(waServiceFactory *svc);
+ int service_deregister(waServiceFactory *svc);
+ size_t service_getNumServices(FOURCC svc_type);
+ waServiceFactory *service_enumService(FOURCC svc_type, size_t n);
+ waServiceFactory *service_getServiceByGuid(GUID guid);
+ int service_lock(waServiceFactory *owner, void *svcptr);
+ int service_clientLock(void *svcptr);
+ int service_release(void *svcptr);
+ const char *service_getTypeName(FOURCC svc_type);
+ #ifdef WASABI_COMPILE_COMPONENTS
+ GUID service_getOwningComponent(void *svcptr);
+ GUID service_getLockingComponent(void *svcptr);
+ #endif // WASABI_COMPILE_COMPONENTS
+ int service_unlock(void *svcptr);
+ int service_isvalid(FOURCC svctype, waServiceFactory *service);
+ // removes "me" from the services list and finds a second service with the same GUID and puts it in the same position
+ // this is used by the lazy loader service factory - you shouldn't need it for any other purposes.
+ // returns 0 if compaction actually happened
+ int service_compactDuplicates(waServiceFactory *me);
+
+ protected:
+ enum {
+ API_SERVICE_SERVICE_REGISTER = 10,
+ API_SERVICE_SERVICE_DEREGISTER = 20,
+ API_SERVICE_SERVICE_GETNUMSERVICES = 30,
+ API_SERVICE_SERVICE_ENUMSERVICE = 40,
+ API_SERVICE_SERVICE_GETSERVICEBYGUID = 50,
+ API_SERVICE_SERVICE_LOCK = 60,
+ API_SERVICE_SERVICE_CLIENTLOCK = 70,
+ API_SERVICE_SERVICE_RELEASE = 80,
+ API_SERVICE_SERVICE_GETTYPENAME = 90,
+ #ifdef WASABI_COMPILE_COMPONENTS
+ API_SERVICE_SERVICE_GETOWNINGCOMPONENT = 100,
+ API_SERVICE_SERVICE_GETLOCKINGCOMPONENT = 110,
+ #endif // WASABI_COMPILE_COMPONENTS
+ API_SERVICE_SERVICE_UNLOCK = 120,
+ API_SERVICE_ISVALID = 130,
+ API_SERVICE_COMPACT_DUPLICATES = 140,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline int api_service::service_register(waServiceFactory *svc) {
+ int __retval = _call(API_SERVICE_SERVICE_REGISTER, (int)0, svc);
+ return __retval;
+}
+
+inline int api_service::service_deregister(waServiceFactory *svc) {
+ int __retval = _call(API_SERVICE_SERVICE_DEREGISTER, (int)0, svc);
+ return __retval;
+}
+
+inline size_t api_service::service_getNumServices(FOURCC svc_type) {
+ int __retval = _call(API_SERVICE_SERVICE_GETNUMSERVICES, (int)0, svc_type);
+ return __retval;
+}
+
+inline waServiceFactory *api_service::service_enumService(FOURCC svc_type, size_t n) {
+ waServiceFactory *__retval = _call(API_SERVICE_SERVICE_ENUMSERVICE, (waServiceFactory *)0, svc_type, n);
+ return __retval;
+}
+
+inline waServiceFactory *api_service::service_getServiceByGuid(GUID guid) {
+ waServiceFactory *__retval = _call(API_SERVICE_SERVICE_GETSERVICEBYGUID, (waServiceFactory *)0, guid);
+ return __retval;
+}
+
+inline int api_service::service_lock(waServiceFactory *owner, void *svcptr) {
+ int __retval = _call(API_SERVICE_SERVICE_LOCK, (int)0, owner, svcptr);
+ return __retval;
+}
+
+inline int api_service::service_clientLock(void *svcptr) {
+ int __retval = _call(API_SERVICE_SERVICE_CLIENTLOCK, (int)0, svcptr);
+ return __retval;
+}
+
+inline int api_service::service_release(void *svcptr) {
+ int __retval = _call(API_SERVICE_SERVICE_RELEASE, (int)0, svcptr);
+ return __retval;
+}
+
+inline const char *api_service::service_getTypeName(FOURCC svc_type) {
+ const char *__retval = _call(API_SERVICE_SERVICE_GETTYPENAME, (const char *)0, svc_type);
+ return __retval;
+}
+
+#ifdef WASABI_COMPILE_COMPONENTS
+inline GUID api_service::service_getOwningComponent(void *svcptr) {
+ GUID __retval = _call(API_SERVICE_SERVICE_GETOWNINGCOMPONENT, INVALID_GUID, svcptr);
+ return __retval;
+}
+
+inline GUID api_service::service_getLockingComponent(void *svcptr) {
+ GUID __retval = _call(API_SERVICE_SERVICE_GETLOCKINGCOMPONENT, INVALID_GUID, svcptr);
+ return __retval;
+}
+
+#endif // WASABI_COMPILE_COMPONENTS
+inline int api_service::service_unlock(void *svcptr) {
+ int __retval = _call(API_SERVICE_SERVICE_UNLOCK, (int)0, svcptr);
+ return __retval;
+}
+
+inline int api_service::service_isvalid(FOURCC svctype, waServiceFactory *service) {
+ int __retval = _call(API_SERVICE_ISVALID, (int)0, svctype, service);
+ return __retval;
+}
+
+inline int api_service::service_compactDuplicates(waServiceFactory *me)
+{
+ return _call(API_SERVICE_COMPACT_DUPLICATES, (int)1, me);
+}
+// ----------------------------------------------------------------------------
+
+
+extern api_service *serviceApi;
+
+#endif // __API_SERVICE_H
diff --git a/Src/Plugins/Input/in_wv/wasabi/api/service/services.h b/Src/Plugins/Input/in_wv/wasabi/api/service/services.h
new file mode 100644
index 00000000..264dea66
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/api/service/services.h
@@ -0,0 +1,68 @@
+#ifndef _SERVICES_H
+#define _SERVICES_H
+
+#include <bfc/std_mkncc.h> // for MKnCC()
+
+// lower-case service names are reserved by Nullsoft for future use
+// upper-case service names are for 3rd parties to extend the service system
+
+// if you have a service that is unique to a component, make it type
+// UNIQUE and register it by GUID
+
+
+namespace WaSvc {
+ enum {
+ NONE=MK4CC('n','o','n','e'),
+ UNIQUE=MK4CC('u','n','i','q'), // for unique services, enumed by GUID
+ OBJECT=MK4CC('o','b','j','f'), // for unique objects, enumed by GUID
+ CONTEXTCMD=MK4CC('c','c','m','d'), // context menu command svc_contextCmd.h
+ DEVICE=MK3CC('d','e','v'), // portable device svc_device.h
+ FILEREADER=MK4CC('f','s','r','d'), // file system reader (disk, zip, http)
+ FILESELECTOR=MK4CC('f','s','e','l'), // file selector svc_filesel.h
+ STORAGEVOLENUM=MK4CC('f','s','e','n'), // storage volume enumerator.
+ IMAGEGENERATOR=MK4CC('i','m','g','n'), // image generator svc_imggen.h
+ IMAGELOADER=MK4CC('i','m','g','l'), // image loader svc_imgload.h
+ IMAGEWRITER=MK4CC('i','m','g','w'), // image writer
+ ITEMMANAGER=MK4CC('i','m','g','r'), // item manager svc_itemmgr.h
+ PLAYLISTREADER=MK4CC('p','l','r','d'), // playlist reader - DEPRECATED - only for wa3
+ PLAYLISTWRITER=MK4CC('p','l','w','r'), // playlist writer - DEPRECATED - only for wa3
+ MEDIACONVERTER=MK4CC('c','o','n','v'), // media converter
+ MEDIACORE=MK4CC('c','o','r','e'), // media core
+ MEDIARECORDER=MK4CC('m','r','e','c'), // media recorder
+ SCRIPTOBJECT=MK4CC('m','a','k','i'), // third party script object
+// TRANSLATOR=MK4CC('x','l','a','t'), // text translator
+ WINDOWCREATE=MK4CC('w','n','d','c'), // window creator
+ XMLPROVIDER=MK4CC('x','m','l','p'), // xml provider
+ DB=MK2CC('d','b'), // database
+ SKINFILTER=MK4CC('f','l','t','r'), // bitmap/colorref skin filter
+ METADATA=MK4CC('m','t','d','t'), // play item meta data
+ METATAG=MK4CC('m','t','t','g'), // metadata tagging of play items
+ EVALUATOR=MK4CC('e','v','a','l'), // evaluate a string
+ MINIBROWSER=MK2CC('m','b'), // minibrowser
+ TOOLTIPSRENDERER=MK4CC('t','t','i','p'), // tooltips renderer
+ XUIOBJECT=MK4CC('x','u','i','o'), // xml gui objects
+ STRINGCONVERTER=MK4CC('u','t','f','8'), // unicode string conversion
+ ACTION=MK3CC('a','c','t'), // custom actions (ie: for buttons)
+ COREADMIN=MK4CC('c','a','d','m'), // core administrator
+ DROPTARGET=MK4CC('d','r','o','p'), // drop targets
+ OBJECTDIR=MK4CC('o','b','j','d'), // object directory
+ TEXTFEED=MK4CC('t','x','t','f'), // text feed, to send text to various XUI objects (ie: <Text> by using display="textfeedid"
+ ACCESSIBILITY=MK4CC('a','c','c','s'), // accessibility service
+ ACCESSIBILITYROLESERVER=MK4CC('r','o','l','e'), // accessibility roleServer services
+ EXPORTER=MK3CC('e','x','p'), // exporter
+ COLLECTION=MK4CC('c','l','c','t'), // named xml overridable collection
+ REDIRECT=MK4CC('r','e','d','r'), // filename redirect
+ FONTRENDER=MK4CC('f','o','n','t'), // font renderer (bitmap/truetype/freetype)
+ SRCCLASSFACTORY=MK4CC('c','l','f','a'), // source code class factory
+ SRCEDITOR=MK4CC('s','e','d','t'), // source code editor
+ MP4AUDIODECODER=MK4CC('m','4','a','d'), // mp4 audio decoder
+ PLAYLISTREADER_WA5=MK4CC('p','l','r','5'), // playlist reader
+ PLAYLISTWRITER_WA5=MK4CC('p','l','w','5'), // playlist writer
+ PLAYLISTHANDLER=MK3CC('p','l','h'), // playlist handler
+ TAGPROVIDER=MK4CC('t','a','g','z'), // tag provider (for ATF engine)
+ NSVFACTORY=MK4CC('n','s','v','f'), // NSV factory (to create NSV objects)
+ JSAPI2_APICREATOR=MK4CC('j','s','a','c'), // API Creator for the Javascript API
+ };
+};
+
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/api/service/waservicefactory.h b/Src/Plugins/Input/in_wv/wasabi/api/service/waservicefactory.h
new file mode 100644
index 00000000..99c32d3f
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/api/service/waservicefactory.h
@@ -0,0 +1,97 @@
+// ----------------------------------------------------------------------------
+// Generated by InterfaceFactory [Wed May 07 00:57:16 2003]
+//
+// File : waservicefactory.h
+// Class : waServiceFactory
+// class layer : Dispatchable Interface
+// ----------------------------------------------------------------------------
+
+#ifndef __WASERVICEFACTORY_H
+#define __WASERVICEFACTORY_H
+
+#include "../../bfc/dispatch.h"
+#include "../../bfc/nsguid.h"
+#include "api_service.h"
+// ----------------------------------------------------------------------------
+
+class NOVTABLE waServiceFactory: public Dispatchable {
+ protected:
+ waServiceFactory() throw() {}
+ ~waServiceFactory() throw() {}
+ protected:
+
+ public:
+ FOURCC getServiceType();
+ const char *getServiceName();
+ GUID getGuid();
+ void *getInterface(int global_lock = TRUE);
+ int supportNonLockingGetInterface();
+ int releaseInterface(void *ifc);
+ const wchar_t *getTestString();
+ int serviceNotify(int msg, intptr_t param1 = 0, intptr_t param2 = 0);
+
+ protected:
+ enum {
+ WASERVICEFACTORY_GETSERVICETYPE = 100,
+ WASERVICEFACTORY_GETSERVICENAME = 200,
+ WASERVICEFACTORY_GETGUID = 210,
+ WASERVICEFACTORY_GETINTERFACE = 300,
+ WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE = 301,
+ WASERVICEFACTORY_RELEASEINTERFACE = 310,
+ WASERVICEFACTORY_GETTESTSTRING = 500,
+ WASERVICEFACTORY_SERVICENOTIFY = 600,
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+inline FOURCC waServiceFactory::getServiceType() {
+ FOURCC __retval = _call(WASERVICEFACTORY_GETSERVICETYPE, (FOURCC)NULL);
+ return __retval;
+}
+
+inline const char *waServiceFactory::getServiceName() {
+ const char *__retval = _call(WASERVICEFACTORY_GETSERVICENAME, (const char *)0);
+ return __retval;
+}
+
+inline GUID waServiceFactory::getGuid() {
+ GUID __retval = _call(WASERVICEFACTORY_GETGUID, INVALID_GUID);
+ return __retval;
+}
+
+inline void *waServiceFactory::getInterface(int global_lock) {
+ void *__retval = _call(WASERVICEFACTORY_GETINTERFACE, (void *)NULL, global_lock);
+
+#if 0 // unused in Winamp 5
+ // -- generated code - edit in waservicefactoryi.h
+ // support old code that always locks even when global_lock==FALSE
+ if (!global_lock && __retval != NULL && !supportNonLockingGetInterface())
+ WASABI_API_SVC->service_unlock(__retval);
+#endif
+ return __retval;
+}
+
+inline int waServiceFactory::supportNonLockingGetInterface() {
+ int __retval = _call(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, (int)0);
+ return __retval;
+}
+
+inline int waServiceFactory::releaseInterface(void *ifc) {
+ int __retval = _call(WASERVICEFACTORY_RELEASEINTERFACE, (int)0, ifc);
+ return __retval;
+}
+
+inline const wchar_t *waServiceFactory::getTestString() {
+ return _call(WASERVICEFACTORY_GETTESTSTRING, (const wchar_t *)0);
+
+}
+
+inline int waServiceFactory::serviceNotify(int msg, intptr_t param1, intptr_t param2) {
+ int __retval = _call(WASERVICEFACTORY_SERVICENOTIFY, (int)0, msg, param1, param2);
+ return __retval;
+}
+
+// ----------------------------------------------------------------------------
+
+#endif // __WASERVICEFACTORY_H
diff --git a/Src/Plugins/Input/in_wv/wasabi/bfc/dispatch.h b/Src/Plugins/Input/in_wv/wasabi/bfc/dispatch.h
new file mode 100644
index 00000000..0d5b2002
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/bfc/dispatch.h
@@ -0,0 +1,559 @@
+#pragma once
+//#include <bfc/platform/platform.h>
+#include "platform/types.h"
+#include "platform/guid.h"
+
+#ifdef WIN32
+#ifndef NOVTABLE
+#define NOVTABLE __declspec(novtable)
+#endif
+#else
+#define NOVTABLE
+#endif
+class DispatchableCallback;
+
+#pragma warning(disable: 4786)
+#pragma warning(disable: 4275)
+#pragma warning(disable: 4100)
+
+enum
+{
+ DISPATCH_SUCCESS=0,
+ DISPATCH_FAILURE=1,
+};
+
+// TODO: define this to stdcall for linux, win64, mac
+#define WASABICALL
+
+class NOVTABLE Dispatchable {
+public:
+// // fake virtual destructor
+// void destruct() { _voidcall(DESTRUCT); }
+
+ // this is virtual so it is visible across modules
+ virtual int WASABICALL _dispatch(int msg, void *retval, void **params=0, int nparam=0)=0;
+
+
+ /* added 22 May 2007. these aren't used yet. To be used in the future
+ in the meantime, don't use negative numbers for your msg values */
+ size_t AddRef();
+ size_t Release();
+ int QueryInterface(GUID interface_guid, void **object);
+ enum
+ {
+ ADDREF=-1,
+ RELEASE=-2,
+ QUERYINTERFACE=-3,
+ };
+protected:
+// // protected real destructor
+// ~Dispatchable() {}
+ // helper templates to implement client-side methods
+ int _voidcall(int msg) {
+ return _dispatch(msg, 0);
+ }
+
+ template<class PARAM1>
+ int _voidcall(int msg, PARAM1 param1) {
+ void *params[1] = { &param1 };
+ return _dispatch(msg, 0, params, 1);
+ }
+
+ template<class PARAM1, class PARAM2>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2) {
+ void *params[2] = { &param1, &param2 };
+ return _dispatch(msg, 0, params, 2);
+ }
+
+ template<class PARAM1, class PARAM2, class PARAM3>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3) {
+ void *params[3] = { &param1, &param2, &param3 };
+ return _dispatch(msg, 0, params, 3);
+ }
+
+ template<class PARAM1, class PARAM2, class PARAM3, class PARAM4>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4) {
+ void *params[4] = { &param1, &param2, &param3, &param4 };
+ return _dispatch(msg, 0, params, 4);
+ }
+
+ template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5) {
+// void *params[4] = { &param1, &param2, &param3, &param4, &param5 }; // mig found another bug
+ void *params[5] = { &param1, &param2, &param3, &param4, &param5 };
+ return _dispatch(msg, 0, params, 5);
+ }
+
+ template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6) {
+// void *params[4] = { &param1, &param2, &param3, &param4, &param5, &param6 }; // mig found another bug
+ void *params[6] = { &param1, &param2, &param3, &param4, &param5, &param6 };
+ return _dispatch(msg, 0, params, 6);
+ }
+
+ template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7) {
+ void *params[7] = { &param1, &param2, &param3, &param4, &param5, &param6 , &param7 };
+ return _dispatch(msg, 0, params, 7);
+ }
+
+ template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8) {
+ void *params[8] = { &param1, &param2, &param3, &param4, &param5, &param6 , &param7 , &param8 };
+ return _dispatch(msg, 0, params, 8);
+ }
+
+ template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8, PARAM9 param9) {
+ void *params[9] = { &param1, &param2, &param3, &param4, &param5, &param6 , &param7 , &param8 , &param9 };
+ return _dispatch(msg, 0, params, 9);
+ }
+
+ template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8, PARAM9 param9, PARAM10 param10) {
+ void *params[10] = { &param1, &param2, &param3, &param4, &param5, &param6 , &param7 , &param8 , &param9 , &param10 };
+ return _dispatch(msg, 0, params, 10);
+ }
+
+ template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10, class PARAM11, class PARAM12, class PARAM13, class PARAM14>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8, PARAM9 param9, PARAM10 param10, PARAM11 param11, PARAM12 param12, PARAM13 param13, PARAM14 param14) {
+ void *params[14] = { &param1, &param2, &param3, &param4, &param5, &param6 , &param7 , &param8 , &param9 , &param10 , &param11 , &param12 , &param13 , &param14 };
+ return _dispatch(msg, 0, params, 14);
+ }
+
+ template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10, class PARAM11, class PARAM12, class PARAM13, class PARAM14, class PARAM15, class PARAM16>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8, PARAM9 param9, PARAM10 param10, PARAM11 param11, PARAM12 param12, PARAM13 param13, PARAM14 param14, PARAM15 param15, PARAM16 param16) {
+ void *params[16] = { &param1, &param2, &param3, &param4, &param5, &param6 , &param7 , &param8 , &param9 , &param10 , &param11 , &param12 , &param13 , &param14 , &param15 , &param16 };
+ return _dispatch(msg, 0, params, 16);
+ }
+
+ template<class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10, class PARAM11, class PARAM12, class PARAM13, class PARAM14, class PARAM15, class PARAM16, class PARAM17>
+ int _voidcall(int msg, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8, PARAM9 param9, PARAM10 param10, PARAM11 param11, PARAM12 param12, PARAM13 param13, PARAM14 param14, PARAM15 param15, PARAM16 param16, PARAM17 param17) {
+ void *params[17] = { &param1, &param2, &param3, &param4, &param5, &param6 , &param7 , &param8 , &param9 , &param10 , &param11 , &param12 , &param13 , &param14 , &param15 , &param16 , &param17 };
+ return _dispatch(msg, 0, params, 17);
+ }
+
+
+ template<class RETURN_TYPE>
+ RETURN_TYPE _call(int msg, RETURN_TYPE defval) {
+ RETURN_TYPE retval;
+ if (_dispatch(msg, &retval)) return retval;
+ return defval;
+ }
+
+ template<class RETURN_TYPE, class PARAM1>
+ RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1) {
+ void *params[1] = { &param1 };
+ RETURN_TYPE retval;
+ if (_dispatch(msg, &retval, params, 1)) return retval;
+ return defval;
+ }
+
+ template<class RETURN_TYPE, class PARAM1, class PARAM2>
+ RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2) {
+ void *params[2] = { &param1, &param2 };
+ RETURN_TYPE retval;
+ if (_dispatch(msg, &retval, params, 2)) return retval;
+ return defval;
+ }
+
+ template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3>
+ RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3) {
+ void *params[3] = { &param1, &param2, &param3 };
+ RETURN_TYPE retval;
+ if (_dispatch(msg, &retval, params, 3)) return retval;
+ return defval;
+ }
+
+ template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4>
+ RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4) {
+ void *params[4] = { &param1, &param2, &param3, &param4 };
+ RETURN_TYPE retval;
+ if (_dispatch(msg, &retval, params, 4)) return retval;
+ return defval;
+ }
+
+ template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5>
+ RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5) {
+ void *params[5] = { &param1, &param2, &param3, &param4, &param5 };
+ RETURN_TYPE retval;
+ if (_dispatch(msg, &retval, params, 5)) return retval;
+ return defval;
+ }
+
+ template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6>
+ RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6) {
+ void *params[6] = { &param1, &param2, &param3, &param4, &param5, &param6 };
+ RETURN_TYPE retval;
+ if (_dispatch(msg, &retval, params, 6)) return retval;
+ return defval;
+ }
+
+ template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7>
+ RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7) {
+ void *params[7] = { &param1, &param2, &param3, &param4, &param5, &param6, &param7 };
+ RETURN_TYPE retval;
+ if (_dispatch(msg, &retval, params, 7)) return retval;
+ return defval;
+ }
+
+ template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8>
+ RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8) {
+ void *params[8] = { &param1, &param2, &param3, &param4, &param5, &param6, &param7, &param8 };
+ RETURN_TYPE retval;
+ if (_dispatch(msg, &retval, params, 8)) return retval;
+ return defval;
+ }
+
+ template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9>
+ RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8, PARAM9 param9) {
+ void *params[9] = { &param1, &param2, &param3, &param4, &param5, &param6, &param7, &param8, &param9 };
+ RETURN_TYPE retval;
+ if (_dispatch(msg, &retval, params, 9)) return retval;
+ return defval;
+ }
+
+ template<class RETURN_TYPE, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10>
+ RETURN_TYPE _call(int msg, RETURN_TYPE defval, PARAM1 param1, PARAM2 param2, PARAM3 param3, PARAM4 param4, PARAM5 param5, PARAM6 param6, PARAM7 param7, PARAM8 param8, PARAM9 param9, PARAM10 param10) {
+ void *params[10] = { &param1, &param2, &param3, &param4, &param5, &param6, &param7, &param8, &param9, &param10 };
+ RETURN_TYPE retval;
+ if (_dispatch(msg, &retval, params, 10)) return retval;
+ return defval;
+ }
+
+ template <class CLASSNAME, class RETVAL>
+ void cb(RETVAL (CLASSNAME::*fn)(), void *retval, void **params) {
+ *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)();
+ }
+
+ template <class CLASSNAME>
+ void vcb(void (CLASSNAME::*fn)(), void *retval, void **params) {
+ (static_cast<CLASSNAME *>(this)->*fn)();
+ }
+
+ template <class CLASSNAME, class RETVAL, class PARAM1>
+ void cb(RETVAL (CLASSNAME::*fn)(PARAM1), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1);
+ }
+
+ template <class CLASSNAME, class PARAM1>
+ void vcb(void (CLASSNAME::*fn)(PARAM1), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1);
+ }
+
+ template <class CLASSNAME, class PARAM1, class PARAM2>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2);
+ }
+
+ template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2>
+ void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2);
+ }
+
+ // 3 params
+ template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3);
+ }
+
+ template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3>
+ void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3);
+ }
+
+ // 4 params
+ template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4);
+ }
+
+ template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4>
+ void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4);
+ }
+
+ // 5 params
+ template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5);
+ }
+
+ template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5>
+ void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5);
+ }
+
+ // 6 params
+ template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6);
+ }
+
+ template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6>
+ void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6);
+ }
+
+ // 7 params
+ template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7);
+ }
+
+ template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7>
+ void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
+ *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7);
+ }
+
+ // 8 params
+ template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
+ PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8);
+ }
+
+ template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8>
+ void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
+ PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
+ *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8);
+ }
+
+ // 9 params
+ template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8, PARAM9), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
+ PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
+ PARAM9 *p9 = static_cast<PARAM9*>(params[8]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9);
+ }
+
+ template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9>
+ void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8, PARAM9), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
+ PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
+ PARAM9 *p9 = static_cast<PARAM9*>(params[8]);
+ *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9);
+ }
+
+ // 10 params
+ template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8, PARAM9, PARAM10), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
+ PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
+ PARAM9 *p9 = static_cast<PARAM9*>(params[8]);
+ PARAM10 *p10 = static_cast<PARAM10*>(params[9]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10);
+ }
+
+ template <class CLASSNAME, class RETVAL, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10>
+ void cb(RETVAL (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8, PARAM9, PARAM10), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
+ PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
+ PARAM9 *p9 = static_cast<PARAM9*>(params[8]);
+ PARAM10 *p10 = static_cast<PARAM10*>(params[9]);
+ *static_cast<RETVAL*>(retval) = (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10);
+ }
+
+ // 14 params
+ template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10, class PARAM11, class PARAM12, class PARAM13, class PARAM14>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8, PARAM9, PARAM10, PARAM11, PARAM12, PARAM13, PARAM14), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
+ PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
+ PARAM9 *p9 = static_cast<PARAM9*>(params[8]);
+ PARAM10 *p10 = static_cast<PARAM10*>(params[9]);
+ PARAM11 *p11 = static_cast<PARAM11*>(params[10]);
+ PARAM12 *p12 = static_cast<PARAM12*>(params[11]);
+ PARAM13 *p13 = static_cast<PARAM13*>(params[12]);
+ PARAM14 *p14 = static_cast<PARAM14*>(params[13]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10, *p11, *p12, *p13, *p14);
+ }
+
+ // 16 params
+ template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10, class PARAM11, class PARAM12, class PARAM13, class PARAM14, class PARAM15, class PARAM16>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8, PARAM9, PARAM10, PARAM11, PARAM12, PARAM13, PARAM14, PARAM15, PARAM16), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
+ PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
+ PARAM9 *p9 = static_cast<PARAM9*>(params[8]);
+ PARAM10 *p10 = static_cast<PARAM10*>(params[9]);
+ PARAM11 *p11 = static_cast<PARAM11*>(params[10]);
+ PARAM12 *p12 = static_cast<PARAM12*>(params[11]);
+ PARAM13 *p13 = static_cast<PARAM13*>(params[12]);
+ PARAM14 *p14 = static_cast<PARAM14*>(params[13]);
+ PARAM15 *p15 = static_cast<PARAM15*>(params[14]);
+ PARAM16 *p16 = static_cast<PARAM16*>(params[15]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10, *p11, *p12, *p13, *p14, *p15, *p16);
+ }
+
+ // 17 params
+ template <class CLASSNAME, class PARAM1, class PARAM2, class PARAM3, class PARAM4, class PARAM5, class PARAM6, class PARAM7, class PARAM8, class PARAM9, class PARAM10, class PARAM11, class PARAM12, class PARAM13, class PARAM14, class PARAM15, class PARAM16, class PARAM17>
+ void vcb(void (CLASSNAME::*fn)(PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7, PARAM8, PARAM9, PARAM10, PARAM11, PARAM12, PARAM13, PARAM14, PARAM15, PARAM16, PARAM17), void *retval, void **params) {
+ PARAM1 *p1 = static_cast<PARAM1*>(params[0]);
+ PARAM2 *p2 = static_cast<PARAM2*>(params[1]);
+ PARAM3 *p3 = static_cast<PARAM3*>(params[2]);
+ PARAM4 *p4 = static_cast<PARAM4*>(params[3]);
+ PARAM5 *p5 = static_cast<PARAM5*>(params[4]);
+ PARAM6 *p6 = static_cast<PARAM6*>(params[5]);
+ PARAM7 *p7 = static_cast<PARAM7*>(params[6]);
+ PARAM8 *p8 = static_cast<PARAM8*>(params[7]);
+ PARAM9 *p9 = static_cast<PARAM9*>(params[8]);
+ PARAM10 *p10 = static_cast<PARAM10*>(params[9]);
+ PARAM11 *p11 = static_cast<PARAM11*>(params[10]);
+ PARAM12 *p12 = static_cast<PARAM12*>(params[11]);
+ PARAM13 *p13 = static_cast<PARAM13*>(params[12]);
+ PARAM14 *p14 = static_cast<PARAM14*>(params[13]);
+ PARAM15 *p15 = static_cast<PARAM15*>(params[14]);
+ PARAM16 *p16 = static_cast<PARAM16*>(params[15]);
+ PARAM17 *p17 = static_cast<PARAM17*>(params[16]);
+ (static_cast<CLASSNAME *>(this)->*fn)(*p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10, *p11, *p12, *p13, *p14, *p15, *p16, *p17);
+ }
+
+
+ enum { DESTRUCT=0xffff };
+};
+#define CB(x, y) case (x): cb(&CBCLASS::y, retval, params); break;
+#define VCB(x, y) case (x): vcb(&CBCLASS::y, retval, params); break;
+
+#define RECVS_DISPATCH virtual int WASABICALL _dispatch(int msg, void *retval, void **params=0, int nparam=0)
+
+#define START_DISPATCH \
+ int CBCLASS::_dispatch(int msg, void *retval, void **params, int nparam) { \
+ switch (msg) {
+#define START_DISPATCH_INLINE \
+ int WASABICALL CBCLASS::_dispatch(int msg, void *retval, void **params, int nparam) { \
+ switch (msg) {
+
+//FINISH case DESTRUCT: delete this; return 1;
+#define END_DISPATCH \
+ default: return 0; \
+ } \
+ return 1; \
+ }
+#define FORWARD_DISPATCH(x) \
+ default: return x::_dispatch(msg, retval, params, nparam); \
+ } \
+ return 1; \
+ }
+
+#define DISPATCH_CODES enum
+
+inline size_t Dispatchable::AddRef()
+{
+ return _call(Dispatchable::ADDREF, 0);
+}
+
+inline size_t Dispatchable::Release()
+{
+ return _call(Dispatchable::RELEASE, 0);
+}
+
+inline int Dispatchable::QueryInterface(GUID interface_guid, void **object)
+{
+ return _call(Dispatchable::QUERYINTERFACE, 0, interface_guid, object);
+}
diff --git a/Src/Plugins/Input/in_wv/wasabi/bfc/nsguid.h b/Src/Plugins/Input/in_wv/wasabi/bfc/nsguid.h
new file mode 100644
index 00000000..188150e4
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/bfc/nsguid.h
@@ -0,0 +1,37 @@
+#ifndef _NSGUID_H
+#define _NSGUID_H
+
+#include "platform/guid.h"
+//#include <bfc/common.h>
+
+// Some conversion functions to allow
+// us to have GUIDs translatable to and from other data types.
+class nsGUID {
+public:
+ // To the "Human Readable" character format.
+ // {1B3CA60C-DA98-4826-B4A9-D79748A5FD73}
+ static char *toChar(const GUID &guid, char *target);
+ static wchar_t *toCharW(const GUID &guid, wchar_t *target);
+ static GUID fromCharW(const wchar_t *source);
+ // To the "C Structure" character format.
+ // { 0x1b3ca60c, 0xda98, 0x4826, { 0xb4, 0xa9, 0xd7, 0x97, 0x48, 0xa5, 0xfd, 0x73 } };
+ static char *toCode(const GUID &guid, char *target);
+ static GUID fromCode(const char *source);
+
+ // Compare function, returns -1, 0, 1
+ static int compare(const GUID &a, const GUID &b);
+
+ // strlen("{xx xxx xxx-xxxx-xxxx-xxxx-xxx xxx xxx xxx}"
+ enum { GUID_STRLEN = 38 };
+
+#ifdef WASABI_COMPILE_CREATEGUID
+ static void createGuid(GUID *g);
+#endif
+};
+
+inline
+int operator <(const GUID &a, const GUID &b) {
+ return (nsGUID::compare(a, b) < 0);
+}
+
+#endif //_NSGUID_H
diff --git a/Src/Plugins/Input/in_wv/wasabi/bfc/platform/guid.h b/Src/Plugins/Input/in_wv/wasabi/bfc/platform/guid.h
new file mode 100644
index 00000000..b2f40f89
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/bfc/platform/guid.h
@@ -0,0 +1,24 @@
+#ifndef _GUID_H
+#define _GUID_H
+
+#include "types.h"
+#include "platform.h"
+
+
+#ifdef __cplusplus
+#ifndef GUID_EQUALS_DEFINED
+#define GUID_EQUALS_DEFINED
+#include <memory.h>
+static __inline int operator ==(const GUID &a, const GUID &b) {
+ return !memcmp(&a, &b, sizeof(GUID));
+}
+static __inline int operator !=(const GUID &a, const GUID &b) {
+ return !!memcmp(&a, &b, sizeof(GUID));
+}
+#endif //GUID_EQUALS_DEFINED
+#endif //__cplusplus
+
+static const GUID INVALID_GUID = { 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0} };
+static const GUID GENERIC_GUID = { 0xFFFFFFFF, 0xFFFF, 0xFFFF, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} };
+
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/bfc/platform/platform.h b/Src/Plugins/Input/in_wv/wasabi/bfc/platform/platform.h
new file mode 100644
index 00000000..46baf8a8
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/bfc/platform/platform.h
@@ -0,0 +1,500 @@
+#ifndef _PLATFORM_H
+#define _PLATFORM_H
+
+#include "types.h"
+#include "../std_mkncc.h" // for MKnCC
+
+#ifdef WIN32
+# include "win32.h"
+
+#define OSMODULEHANDLE HINSTANCE
+#define INVALIDOSMODULEHANDLE ((OSMODULEHANDLE)0)
+#define OSWINDOWHANDLE HWND
+#define INVALIDOSWINDOWHANDLE ((OSWINDOWHANDLE)0)
+#define OSICONHANDLE HICON
+#define INVALIDOSICONHANDLE ((OSICONHANDLE)0)
+#define OSCURSORHANDLE HICON
+#define INVALIDOSCURSORHANDLE ((OSCURSORHANDLE)0)
+#define OSTHREADHANDLE HANDLE
+#define INVALIDOSTHREADHANDLE ((OSTHREADHANDLE)0)
+#define OSREGIONHANDLE HRGN
+#define INVALIDOSREGIONHANDLE ((OSREGIONHANDLE)0)
+typedef HMENU OSMENUHANDLE;
+
+#define RGBA(r,g,b,a) ((ARGB32)((uint8_t)(r) | ((uint8_t)(g) << 8) | ((uint8_t)(b) << 16) | ((uint8_t)(a) << 24)))
+
+#ifndef PATH_MAX
+#define PATH_MAX MAX_PATH
+#endif
+
+#elif defined(LINUX)
+# include <bfc/platform/linux.h>
+#elif defined(__APPLE__)
+#include <Carbon/Carbon.h>
+
+typedef HIShapeRef OSREGIONHANDLE;
+typedef int OSCURSOR; // TODO: find a good one for this
+typedef int OSCURSORHANDLE; // TODO: find a good one for this
+typedef HIWindowRef OSWINDOWHANDLE;
+typedef void *OSMODULEHANDLE; // TODO:
+typedef CGContextRef HDC; // TODO: find a better name
+typedef MenuRef OSMENUHANDLE;
+typedef CGImageRef OSICONHANDLE;
+
+#ifdef __LITTLE_ENDIAN__
+#define RGBA(r,g,b,a) ((ARGB32)((uint8_t)(r) | ((uint8_t)(g) << 8) | ((uint8_t)(b) << 16) | ((uint8_t)(a) << 24)))
+#elif defined(__BIG_ENDIAN__)
+#define RGBA(r,g,b,a) ((ARGB32)((uint8_t)(a) | ((uint8_t)(r) << 8) | ((uint8_t)(g) << 16) | ((uint8_t)(b) << 24)))
+#else
+#error endian preprocessor symbol not defined
+#endif
+
+#define RGB(r,g,b) RGBA(r,g,b,0xFF)
+
+static const HIWindowRef INVALIDOSWINDOWHANDLE = 0; // TODO: maybe there's an apple-defined name for this
+#define INVALIDOSMODULEHANDLE 0
+#define INVALIDOSCURSORHANDLE 0
+
+typedef char OSFNCHAR;
+typedef char *OSFNSTR;
+
+typedef const char OSFNCCHAR;
+typedef const char *OSFNCSTR;
+
+#define FNT(x) x
+
+typedef struct tagRECT
+{
+ int left;
+ int top;
+ int right;
+ int bottom;
+}
+RECT;
+typedef RECT * LPRECT;
+
+inline RECT RECTFromHIRect(const HIRect *r)
+{
+ RECT rect;
+ rect.left = r->origin.x;
+ rect.right = r->origin.x + r->size.width;
+ rect.top = r->origin.y;
+ rect.bottom = r->origin.y + r->size.height;
+ return rect;
+}
+
+inline HIRect HIRectFromRECT(const RECT *r)
+{
+ HIRect rect;
+ rect.origin.x = r->left;
+ rect.origin.y = r->top;
+ rect.size.width = r->right - r->left;
+ rect.size.height = r->bottom - r->top;
+ return rect;
+}
+
+typedef struct tagPOINT
+{
+ int x;
+ int y;
+}
+POINT;
+typedef struct tagPOINT * LPPOINT;
+
+inline HIPoint HIPointFromPOINT(const POINT *pt)
+{
+ HIPoint p;
+ p.x = pt->x;
+ p.y = pt->y;
+ return p;
+}
+
+inline int MulDiv(int a, int b, int c)
+{
+ int s;
+ int v;
+
+ s = 0;
+ if (a < 0)
+ {
+ s = !s;
+ a = -a;
+ }
+ if (b < 0)
+ {
+ s = !s;
+ b = -b;
+ }
+ if (c < 0)
+ {
+ s = !s;
+ c = -c;
+ }
+ double d;
+ d = ((double)a * (double)b) / (double)c;
+ if (d >= 4294967296.)
+ return -1;
+ v = d;
+ if (s)
+ v = -v;
+ return v;
+}
+
+#else
+#error port me
+// Windows API dependant definitions for non-windows platforms
+
+#define __cdecl
+#define __stdcall
+#define WINAPI
+#define WINBASEAPI
+#define WINUSERAPI
+#define WINGDIAPI
+#define WINOLEAPI
+#define CALLBACK
+#define FARPROC void *
+
+#define FALSE 0
+#define TRUE 1
+
+#define ERROR 0
+
+#define CONST const
+#define VOID void
+
+typedef unsigned long DWORD;
+typedef unsigned short WORD;
+typedef unsigned char BYTE;
+typedef long LONG;
+typedef int INT;
+typedef int BOOL;
+typedef short SHORT;
+typedef void * PVOID;
+typedef void * LPVOID;
+
+typedef char CHAR;
+typedef unsigned short WCHAR;
+typedef char * LPSTR;
+typedef WCHAR * LPWSTR;
+typedef const char * LPCSTR;
+typedef const WCHAR * LPCWSTR;
+typedef LPWSTR PTSTR, LPTSTR;
+typedef LPCWSTR LPCTSTR;
+typedef char TCHAR;
+typedef WCHAR OLECHAR;
+
+typedef void * HANDLE;
+typedef void * HWND;
+typedef void * HDC;
+typedef void * HFONT;
+typedef void * HBITMAP;
+typedef void * HINSTANCE;
+typedef void * HICON;
+typedef void * HRGN;
+typedef void * HPEN;
+typedef void * HBRUSH;
+typedef void * HRSRC;
+typedef void * HGLOBAL;
+typedef void * HACCEL;
+typedef void * HMODULE;
+typedef void * HMENU;
+typedef void * HGDIOBJ;
+
+typedef void * ATOM;
+typedef void * CRITICAL_SECTION;
+typedef void * LPCRITICAL_SECTION;
+
+typedef UINT WPARAM;
+typedef UINT LPARAM;
+typedef LONG LRESULT;
+typedef UINT COLORREF;
+
+typedef LRESULT(*WNDPROC)(HWND, UINT, WPARAM, LPARAM);
+typedef BOOL CALLBACK WNDENUMPROC(HWND, LPARAM);
+typedef VOID CALLBACK *TIMERPROC(HWND, UINT, UINT, DWORD);
+
+typedef struct tagPOINT
+{
+ LONG x;
+ LONG y;
+}
+POINT;
+typedef struct tagPOINT * LPPOINT;
+
+typedef struct tagSIZE
+{
+ LONG cx;
+ LONG cy;
+}
+SIZE;
+
+
+typedef struct tagRECT
+{
+ LONG left;
+ LONG top;
+ LONG right;
+ LONG bottom;
+}
+RECT;
+typedef RECT * LPRECT;
+
+typedef struct _COORD
+{
+ SHORT X;
+ SHORT Y;
+}
+COORD, *PCOORD;
+
+typedef struct tagPAINTSTRUCT
+{
+ HDC hdc;
+ BOOL fErase;
+ RECT rcPaint;
+ BOOL fRestore;
+ BOOL fIncUpdate;
+ BYTE rgbReserved[32];
+}
+PAINTSTRUCT;
+
+typedef struct tagBITMAP
+{ /* bm */
+ int bmType;
+ int bmWidth;
+ int bmHeight;
+ int bmWidthBytes;
+ BYTE bmPlanes;
+ BYTE bmBitsPixel;
+ LPVOID bmBits;
+}
+BITMAP;
+
+typedef struct tagRGBQUAD
+{
+ BYTE rgbRed;
+ BYTE rgbGreen;
+ BYTE rgbBlue;
+ BYTE rgbReserved;
+}
+RGBQUAD;
+
+typedef struct tagBITMAPINFOHEADER
+{
+ DWORD biSize;
+ LONG biWidth;
+ LONG biHeight;
+ WORD biPlanes;
+ WORD biBitCount;
+ DWORD biCompression;
+ DWORD biSizeImage;
+ LONG biXPelsPerMeter;
+ LONG biYPelsPerMeter;
+ DWORD biClrUsed;
+ DWORD biClrImportant;
+}
+BITMAPINFOHEADER;
+
+typedef struct tagBITMAPINFO
+{
+ BITMAPINFOHEADER bmiHeader;
+ RGBQUAD bmiColors[1];
+}
+BITMAPINFO, *LPBITMAPINFO;
+
+typedef struct tagMSG
+{
+ HWND hwnd;
+ UINT message;
+ WPARAM wParam;
+ LPARAM lParam;
+ DWORD time;
+ POINT pt;
+}
+MSG;
+
+typedef MSG * LPMSG;
+
+typedef struct _RGNDATAHEADER
+{
+ DWORD dwSize;
+ DWORD iType;
+ DWORD nCount;
+ DWORD nRgnSize;
+ RECT rcBound;
+}
+RGNDATAHEADER, *PRGNDATAHEADER;
+
+typedef struct _RGNDATA
+{
+ RGNDATAHEADER rdh;
+ char Buffer[1];
+}
+RGNDATA, *PRGNDATA;
+
+// Windows messages
+
+#define WM_SYSCOMMAND 0x112
+#define WM_LBUTTONDOWN 0x201
+#define WM_LBUTTONUP 0x202
+#define WM_RBUTTONDOWN 0x204
+#define WM_RBUTTONUP 0x205
+
+#define WM_USER 0x400
+
+#define WS_EX_TOOLWINDOW 0x00000080L
+
+#define WS_OVERLAPPED 0x00000000L
+#define WS_MAXIMIZEBOX 0x00010000L
+#define WS_MINIMIZEBOX 0x00020000L
+#define WS_SYSMENU 0x00080000L
+#define WS_CAPTION 0x00C00000L
+#define WS_CLIPCHILDREN 0x02000000L
+#define WS_CLIPSIBLINGS 0x04000000L
+#define WS_VISIBLE 0x10000000L
+#define WS_CHILD 0x40000000L
+#define WS_POPUP 0x80000000L
+
+#define HWND_TOP ((HWND)0)
+#define HWND_TOPMOST ((HWND)-1)
+#define HWND_NOTOPMOST ((HWND)-2)
+
+#define GWL_STYLE (-16)
+
+#define GW_HWNDFIRST 0
+#define GW_HWNDNEXT 2
+
+#define SWP_NOMOVE 0x0002
+#define SWP_NOSIZE 0x0001
+#define SWP_SHOWWINDOW 0x0040
+#define SWP_DEFERERASE 0x2000
+#define SWP_NOZORDER 0x0004
+#define SWP_NOACTIVATE 0x0010
+
+#define SW_SHOW 5
+
+#define SC_MINIMIZE 0xF020
+#define SC_MAXIMIZE 0xF030
+#define SC_RESTORE 0xF120
+
+#define GCL_HICONSM (-34)
+#define GCL_HICON (-14)
+
+#define MB_OK 0
+#define MB_OKCANCEL 1
+#define MB_TASKMODAL 0x2000L
+
+#define IDOK 1
+#define IDCANCEL 2
+
+#define VK_SHIFT 0x10
+#define VK_CONTROL 0x11
+#define VK_MENU 0x12
+
+#define RT_RCDATA 10
+
+#define IMAGE_BITMAP 0
+
+#define LR_LOADFROMFILE 0x0010
+
+#define DIB_RGB_COLORS 0
+
+#define MAX_PATH 1024
+#define _MAX_PATH MAX_PATH
+#define _MAX_DRIVE 3
+#define _MAX_DIR 256
+#define _MAX_FNAME 256
+#define _MAX_EXT 256
+
+#define GMEM_FIXED 0x0
+#define GMEM_ZEROINIT 0x40
+#define GPTR (GMEM_FIXED | GMEM_ZEROINIT)
+
+#define SPI_GETWORKAREA 48
+
+#define SM_CXDOUBLECLK 36
+#define SM_CYDOUBLECLK 37
+
+#define COLORONCOLOR 3
+
+#define SRCCOPY (DWORD)0x00CC0020
+
+#define BI_RGB 0L
+
+#define NULLREGION 1
+
+#define DT_LEFT 0x00000000
+#define DT_CENTER 0x00000001
+#define DT_RIGHT 0x00000002
+#define DT_VCENTER 0x00000004
+#define DT_WORDBREAK 0x00000010
+#define DT_SINGLELINE 0x00000020
+#define DT_CALCRECT 0x00000400
+#define DT_NOPREFIX 0x00000800
+#define DT_PATH_ELLIPSIS 0x00004000
+#define DT_END_ELLIPSIS 0x00008000
+#define DT_MODIFYSTRING 0x00010000
+
+#define FW_NORMAL 400
+#define FW_BOLD 700
+
+#define FF_DONTCARE (0<<4)
+
+#define BLACK_BRUSH 4
+#define NULL_BRUSH 5
+
+#define PS_SOLID 0
+#define PS_DOT 2
+
+#define TRANSPARENT 1
+#define OPAQUE 2
+
+#define ANSI_CHARSET 0
+#define ANSI_VAR_FONT 12
+
+#define OUT_DEFAULT_PRECIS 0
+#define CLIP_DEFAULT_PRECIS 0
+
+#define PROOF_QUALITY 2
+
+#define VARIABLE_PITCH 2
+
+#define RGN_AND 1
+#define RGN_OR 2
+#define RGN_DIFF 4
+#define RGN_COPY 5
+
+#define RDH_RECTANGLES 1
+
+#define MAXLONG 0x7fffffff
+
+// define GUID
+#include <bfc/platform/guid.h>
+
+#endif /* not WIN32 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef __cplusplus
+#include <new>
+#else
+#include <new.h>
+#endif
+#include <limits.h>
+
+
+#ifdef WIN32
+#define OSPIPE HANDLE
+#define OSPROCESSID int
+#endif
+
+// Ode macro keyworkds
+#define DISPATCH_ // makes a method dispatchable, automatically assigns a free ID (requires Interface)
+#define DISPATCH(x) // makes a method dispatchable and specifies its ID (not duplicate check, requires Interface)
+#define NODISPATCH // prevents a method from being dispatched if the class is marked for dispatching by default
+#define EVENT // marks a method as being an event to which other classes can connect to receive notification (used by Script and DependentItem helpers)
+#define SCRIPT // exposes a method to script interfaces (requires Script helper)
+#define IN // Input parameter
+#define OUT // Output parameter
+#define INOUT // Input/Output parameter
+
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/bfc/platform/types.h b/Src/Plugins/Input/in_wv/wasabi/bfc/platform/types.h
new file mode 100644
index 00000000..9de1d7b1
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/bfc/platform/types.h
@@ -0,0 +1,78 @@
+#ifndef __WASABI_TYPES_H
+#define __WASABI_TYPES_H
+
+// first, some standard int types
+typedef unsigned int UINT;
+typedef signed int SINT;
+
+typedef unsigned char UCHAR;
+typedef signed char SCHAR;
+
+typedef unsigned long ARGB32;
+typedef unsigned long RGB32;
+
+typedef unsigned long ARGB24;
+typedef unsigned long RGB24;
+
+typedef unsigned short ARGB16;
+typedef unsigned short RGB16;
+
+typedef unsigned long FOURCC;
+
+#ifndef GUID_DEFINED
+ #define GUID_DEFINED
+
+ typedef struct _GUID
+ {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+ } GUID;
+/*
+#ifndef _REFCLSID_DEFINED
+#define REFGUID const GUID &
+#define _REFCLSID_DEFINED
+#endif
+*/
+#endif
+
+#if defined(_WIN32) && !defined(__GNUC__)
+#include <stddef.h>
+ // since windows doesn't have stdint.h
+ typedef unsigned __int64 uint64_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int8 uint8_t;
+ typedef __int64 int64_t;
+ typedef __int32 int32_t;
+ typedef __int16 int16_t;
+ typedef __int8 int8_t;
+ typedef size_t ssize_t;
+#else
+#include <stdint.h>
+#include <stddef.h>
+#include <inttypes.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+// this is for GUID == and !=
+#include <objbase.h>
+#ifndef GUID_EQUALS_DEFINED
+ #define GUID_EQUALS_DEFINED
+#endif
+
+
+#ifdef NULL
+ #undef NULL
+#endif
+#ifndef NULL
+ #define NULL 0
+#endif
+
+#ifdef _WIN32_WCE
+typedef int intptr_t;
+#endif
+#endif
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/bfc/platform/win32.h b/Src/Plugins/Input/in_wv/wasabi/bfc/platform/win32.h
new file mode 100644
index 00000000..16e61bee
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/bfc/platform/win32.h
@@ -0,0 +1,38 @@
+#ifndef _WIN32_H
+#define _WIN32_H
+
+#ifndef WIN32
+#error this file is only for win32
+#endif
+
+#ifndef _PLATFORM_H
+#error this file should only be included from platform.h
+#endif
+
+// this should be the *only* place windows.h gets included!
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#ifndef _WIN32_WCE
+#include <io.h>
+#endif
+
+#if defined(_MSC_VER) // msvc
+# define WASABIDLLEXPORT __declspec(dllexport)
+# if _MSC_VER >= 1100
+# define NOVTABLE __declspec(novtable)
+# endif
+#endif
+
+#define _TRY __try
+#define _EXCEPT(x) __except(x)
+
+#define OSPIPE HANDLE
+
+
+typedef WCHAR OSFNCHAR;
+typedef LPWSTR OSFNSTR;
+typedef LPCWSTR OSFNCSTR;
+
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/bfc/std_mkncc.h b/Src/Plugins/Input/in_wv/wasabi/bfc/std_mkncc.h
new file mode 100644
index 00000000..113e464d
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/bfc/std_mkncc.h
@@ -0,0 +1,11 @@
+#ifndef _STD_MKNCC
+#define _STD_MKNCC
+
+// note: this is endian-incompatible with win32's MAKEFOURCC
+// otoh, it shows up nicely in a debug register ;)
+
+#define MK4CC(a, b, c, d) ( (((unsigned long)a)<<24)|(((unsigned long)b)<<16)|(((unsigned long)c)<<8)|((unsigned long)d) )
+#define MK3CC(b, c, d) ( (((unsigned long)b)<<16)|(((unsigned long)c)<<8)|((unsigned long)d) )
+#define MK2CC(c, d) ( (((unsigned long)c)<<8)|((unsigned long)d) )
+
+#endif
diff --git a/Src/Plugins/Input/in_wv/wasabi/nu/AutoChar.h b/Src/Plugins/Input/in_wv/wasabi/nu/AutoChar.h
new file mode 100644
index 00000000..646df5d3
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/nu/AutoChar.h
@@ -0,0 +1,133 @@
+#ifndef NULLSOFT_AUTOCHARH
+#define NULLSOFT_AUTOCHARH
+#ifdef WIN32
+#include <windows.h>
+
+inline char *AutoCharDupN(const wchar_t *convert, size_t len, UINT codePage = CP_ACP, UINT flags=0)
+{
+ if (!convert)
+ return 0;
+ int size = WideCharToMultiByte(codePage, flags, convert, (int)len, 0, 0, NULL, NULL);
+
+ if (!size)
+ return 0;
+
+ char *narrow = (char *)malloc((size+1)*sizeof(char));
+
+ if (!WideCharToMultiByte(codePage, flags, convert, (int)len, narrow, size, NULL, NULL))
+ {
+ free(narrow);
+ narrow=0;
+ }
+ else
+ narrow[size]=0;
+
+ return narrow;
+}
+
+inline char *AutoCharDup(const wchar_t *convert, UINT codePage = CP_ACP, UINT flags=0)
+{
+ if (!convert)
+ return 0;
+ int size = WideCharToMultiByte(codePage, flags, convert, -1, 0, 0, NULL, NULL);
+
+ if (!size)
+ return 0;
+
+ char *narrow = (char *)malloc(size*sizeof(char));
+
+ if (!WideCharToMultiByte(codePage, flags, convert, -1, narrow, size, NULL, NULL))
+ {
+ free(narrow);
+ narrow=0;
+ }
+ return narrow;
+}
+
+class AutoChar
+{
+public:
+ AutoChar(const wchar_t *convert, UINT codePage = CP_ACP, UINT flags=0) : narrow(0)
+ {
+ narrow = AutoCharDup(convert, codePage, flags);
+ }
+ ~AutoChar()
+ {
+ free(narrow);
+ narrow=0;
+ }
+ operator const char *()
+ {
+ return narrow;
+ }
+ operator char *()
+ {
+ return narrow;
+ }
+protected:
+ AutoChar() : narrow(0)
+ {
+ }
+ char *narrow;
+};
+
+class AutoCharN : public AutoChar
+{
+public:
+ AutoCharN(const wchar_t *convert, size_t len, UINT codePage = CP_ACP, UINT flags=0)
+ {
+ narrow = AutoCharDupN(convert, len, codePage, flags);
+ }
+};
+#else
+#include <stdlib.h>
+#include <wchar.h>
+
+inline char *AutoCharDup(const wchar_t *convert)
+{
+ if (!convert)
+ return 0;
+
+ size_t size = wcslen(convert)+1;
+
+ if (!size)
+ return 0;
+
+ char *narrow = (char *)malloc(size*sizeof(char));
+
+ if (wcstombs(narrow, convert, size) == (size_t)-1)
+ {
+ free(narrow);
+ narrow=0;
+ }
+ return narrow;
+}
+
+
+class AutoChar
+{
+public:
+
+ AutoChar(const wchar_t *convert) : narrow(0)
+ {
+ narrow = AutoCharDup(convert);
+ }
+ ~AutoChar()
+ {
+ free(narrow);
+ narrow=0;
+ }
+ operator const char *()
+ {
+ return narrow;
+ }
+ operator char *()
+ {
+ return narrow;
+ }
+private:
+ char *narrow;
+};
+#endif
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wasabi/nu/AutoWide.h b/Src/Plugins/Input/in_wv/wasabi/nu/AutoWide.h
new file mode 100644
index 00000000..26f3edb1
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wasabi/nu/AutoWide.h
@@ -0,0 +1,86 @@
+#ifndef AUTOWIDEH
+#define AUTOWIDEH
+#ifdef WIN32
+#include <windows.h>
+
+inline wchar_t *AutoWideDup(const char *convert, UINT codePage=CP_ACP)
+{
+ wchar_t *wide = 0;
+ if (!convert)
+ return 0;
+
+ int size = MultiByteToWideChar(codePage, 0, convert, -1, 0,0);
+ if (!size)
+ return 0;
+
+ wide = (wchar_t *)malloc(size*sizeof(wchar_t));
+ if (!MultiByteToWideChar(codePage, 0, convert, -1, wide,size))
+ {
+ free(wide);
+ wide=0;
+ }
+ return wide;
+}
+
+class AutoWide
+{
+public:
+ AutoWide(const char *convert, UINT codePage=CP_ACP) : wide(0)
+ {
+ wide = AutoWideDup(convert, codePage);
+ }
+ ~AutoWide()
+ {
+ free(wide);
+ wide=0;
+ }
+ operator wchar_t *()
+ {
+ return wide;
+ }
+private:
+ wchar_t *wide;
+};
+#elif defined(__APPLE__)
+#include <string.h>
+inline wchar_t *AutoWideDup(const char *convert)
+{
+ wchar_t *wide=0;
+ if (!convert)
+ return 0;
+ int size = strlen(convert)+1;
+ if (!size)
+ return 0;
+
+ wide = (wchar_t *)malloc(size*sizeof(wchar_t));
+ if (mbstowcs(wide, convert, size) == (size_t)-1)
+ {
+ free(wide);
+ wide=0;
+ }
+ return wide;
+}
+
+class AutoWide
+{
+public:
+ AutoWide(const char *convert) : wide(0)
+ {
+ wide = AutoWideDup(convert);
+ }
+ ~AutoWide()
+ {
+ free(wide);
+ wide=0;
+ }
+ operator wchar_t *()
+ {
+ return wide;
+ }
+private:
+ wchar_t *wide;
+};
+
+#endif
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Input/in_wv/wavpack.rc b/Src/Plugins/Input/in_wv/wavpack.rc
new file mode 100644
index 00000000..d635263b
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/wavpack.rc
@@ -0,0 +1,118 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winresrc.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral (Default) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUD)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_ABOUT "WavPack Decoder"
+ IDS_ENCODER_VERSION "WavPack encoder version: %d\n"
+ IDS_SOURCE "Source: %d-bit %s at %d Hz \n"
+ IDS_MULTICHANNEL "Channels: %d (multichannel)\n"
+ IDS_MONO "Channels: 1 (mono)\n"
+ IDS_STEREO "Channels: 2 (stereo)\n"
+ IDS_HYBRID "hybrid"
+ IDS_LOSSLESS "lossless"
+ IDS_LOSSY "lossy"
+ IDS_INTS "ints"
+ IDS_FLOATS "floats"
+ IDS_MODES "Modes"
+ IDS_FAST ", fast"
+ IDS_HIGH ", high"
+ IDS_VHIGH ", v.high"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_EXTRA ", extra"
+ IDS_BITRATE "Average bitrate"
+ IDS_RATIO "Overall ratio"
+ IDS_KBPS "kbps"
+ IDS_MD5 "Original md5"
+ IDS_DESCRIPTION "WavPack Decoder v%s"
+ IDS_FILETYPE "WavPack Files (*.WV)"
+ IDS_ABOUT_MESSAGE "WavPack Decoder v%hs\nCopyright (c) %hs Conifer Software\n\nBuild date: %hs\n\nSee http://www.wavpack.com for information."
+ IDS_FAMILY_STRING "WavPack File"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_GUID "{6DE2E465-690E-4df1-B6E2-2A9B33ED3DBB}"
+END
+
+#endif // Neutral (Default) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winresrc.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/Input/in_wv/winamp.vcproj b/Src/Plugins/Input/in_wv/winamp.vcproj
new file mode 100644
index 00000000..528cebb4
--- /dev/null
+++ b/Src/Plugins/Input/in_wv/winamp.vcproj
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="winamp"
+ ProjectGUID="{1DB9C3E7-D670-46EB-B006-CCF94982D484}"
+ RootNamespace="winamp"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;WINAMP_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\in_wv.dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ RuntimeTypeInfo="false"
+ WarningLevel="3"
+ DebugInformationFormat="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\in_wv.dll"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ IgnoreDefaultLibraryNames=""
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ EntryPointSymbol=""
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="lng_generator.exe &quot;$(OutDir)\in_wv.dll&quot; /build&#x0D;&#x0A;copy &quot;$(OutDir)\in_wv.dll&quot; &quot;$(ProgramFiles)\Winamp\plugins&quot; /y&#x0D;&#x0A;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ <ProjectReference
+ ReferencedProjectIdentifier="{5CCCB9CF-0384-458F-BA08-72B73866840F}"
+ />
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\in2.h"
+ >
+ </File>
+ <File
+ RelativePath=".\out.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\wasabi\Wasabi.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\wavpack.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\wavpack.rc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\in_wv.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\wasabi\Wasabi.cpp"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>