diff options
Diffstat (limited to 'Src/Agave')
26 files changed, 2886 insertions, 0 deletions
diff --git a/Src/Agave/Agave.h b/Src/Agave/Agave.h new file mode 100644 index 00000000..278d6db1 --- /dev/null +++ b/Src/Agave/Agave.h @@ -0,0 +1,22 @@ +#pragma once + +#include <api/service/waServiceFactory.h> +#include <api/service/api_service.h> +#include <api/application/api_application.h> +#include <api/syscb/api_syscb.h> +#include <api/memmgr/api_memmgr.h> +#include "./Metadata/api_metadata.h" +#include "./Language/api_language.h" +#include "../Plugins/Library/ml_local/api_mldb.h" +#include "../ombrowser/obj_ombrowser.h" +#include "../Winamp/JSAPI2_api_security.h" +#include "./Config/api_config.h" +#include "./AlbumArt/api_albumart.h" +#include "../playlist/api_playlistmanager.h" +#include "../nu/threadpool/api_threadpool.h" +#include "../devices/api_devicemanager.h" +#include "../Winamp/api_stats.h" +#include "../Plugins/Library/ml_wire/api_podcasts.h" +#include "../Plugins/Library/ml_impex/api_importer.h" +#include "../Plugins/Library/ml_plg/api_playlist_generator.h" +#include "./ExplorerFindFile/api_explorerfindfile.h" diff --git a/Src/Agave/AlbumArt/api_albumart.cpp b/Src/Agave/AlbumArt/api_albumart.cpp new file mode 100644 index 00000000..93beabf5 --- /dev/null +++ b/Src/Agave/AlbumArt/api_albumart.cpp @@ -0,0 +1 @@ +#include "api_albumart.h" diff --git a/Src/Agave/AlbumArt/api_albumart.h b/Src/Agave/AlbumArt/api_albumart.h new file mode 100644 index 00000000..256c8dc1 --- /dev/null +++ b/Src/Agave/AlbumArt/api_albumart.h @@ -0,0 +1,124 @@ +#ifndef NULLSOFT_WINAMP_API_ALBUMART_H +#define NULLSOFT_WINAMP_API_ALBUMART_H + +#include <bfc/dispatch.h> +#include <bfc/platform/types.h> +#include <api/service/services.h> + +enum +{ + ALBUMART_SUCCESS = 0, + ALBUMART_FAILURE = 1, +}; + +enum +{ + ALBUMART_NONE = 0, + ALBUMART_EMBEDDED = 1, + ALBUMART_ALBUM = 2, + ALBUMART_NFO = 3, + ALBUMART_FILENAME = 4, + ALBUMART_FOLDER = 5, + ALBUMART_FRONT = 6, + ALBUMART_ARTWORK = 7, +}; + +class api_albumart : public Dispatchable +{ +protected: + api_albumart(){} + ~api_albumart(){} +public: + static FOURCC getServiceType() { return WaSvc::UNIQUE; } + // use WASABI_API_MEMMGR->sysFree on the bits you get back from here. + // if this function fails (return value != ALBUMART_SUCCESS), there is no guarantee about the values + // in w, h or bits. please, please, please don't check bits == 0 for success/failure + int GetAlbumArt(const wchar_t *filename, const wchar_t *type, int *w, int *h, ARGB32 **bits); + // hack alert + int GetAlbumArt_NoAMG(const wchar_t *filename, const wchar_t *type, int *w, int *h, ARGB32 **bits); + // use to get still-compressed data + int GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mimeType); + // use to get the origin of the artwork for the file, e.g. folder, embedded + int GetAlbumArtOrigin(const wchar_t *filename, const wchar_t *type, wchar_t **mimeType); + + // use WASABI_API_MEMMGR->sysFree to free types + int GetAlbumArtTypes(const wchar_t *filename, wchar_t **types); + + int GetValidAlbumArtTypes(const wchar_t *filename, wchar_t **types); + + // returns ALBUMART_SUCCESS or ALBUMART_FAILURE + // if mimeType is NULL, bits is ARGB32. w and h are not used for mimeTypes where the dimentions are in the data + // if bits is NULL, this removes albumart. + int SetAlbumArt(const wchar_t *filename, const wchar_t *type, int w, int h, const void *bits, size_t len, const wchar_t *mimeType); + + int DeleteAlbumArt(const wchar_t *filename, const wchar_t *type); + + // copies all album art from one file to another + // also copies bits like folder.jpg if the two files live in different places + // if you don't like the logic of this function, implement your own using svc_albumArtProvider directly + int CopyAlbumArt(const wchar_t *sourceFilename, const wchar_t *destinationFilename); + DISPATCH_CODES + { + API_ALBUMART_GETALBUMART = 10, + API_ALBUMART_GETALBUMART_NOAMG = 11, + API_ALBUMART_GETALBUMARTDATA = 12, + API_ALBUMART_GETALBUMARTORIGIN = 13, + API_ALBUMART_GETALBUMARTTYPES = 20, + API_ALBUMART_GETVALIDALBUMARTTYPES = 30, + API_ALBUMART_SETALBUMART = 40, + API_ALBUMART_DELETEALBUMART = 50, + API_ALBUMART_COPYALBUMART = 60, + }; +}; + +inline int api_albumart::GetAlbumArt(const wchar_t *filename, const wchar_t *type, int *w, int *h, ARGB32 **bits) +{ + return _call(API_ALBUMART_GETALBUMART, (int)ALBUMART_FAILURE, filename, type, w, h, bits); +} + +inline int api_albumart::GetAlbumArt_NoAMG(const wchar_t *filename, const wchar_t *type, int *w, int *h, ARGB32 **bits) +{ + return _call(API_ALBUMART_GETALBUMART_NOAMG, (int)ALBUMART_FAILURE, filename, type, w, h, bits); +} + +inline int api_albumart::GetAlbumArtData(const wchar_t *filename, const wchar_t *type, void **bits, size_t *len, wchar_t **mimeType) +{ + return _call(API_ALBUMART_GETALBUMARTDATA, (int)ALBUMART_FAILURE, filename, type, bits, len, mimeType); +} + +inline int api_albumart::GetAlbumArtOrigin(const wchar_t *filename, const wchar_t *type, wchar_t **mimeType) +{ + return _call(API_ALBUMART_GETALBUMARTORIGIN, (int)ALBUMART_FAILURE, filename, type, mimeType); +} + +inline int api_albumart::GetAlbumArtTypes(const wchar_t *filename, wchar_t **types) +{ + return _call(API_ALBUMART_GETALBUMARTTYPES, (int)ALBUMART_FAILURE, filename, types); +} + +inline int api_albumart::GetValidAlbumArtTypes(const wchar_t *filename, wchar_t **types) +{ + return _call(API_ALBUMART_GETVALIDALBUMARTTYPES, (int)ALBUMART_FAILURE, filename, types); +} + +inline int api_albumart::SetAlbumArt(const wchar_t *filename, const wchar_t *type, int w, int h, const void *bits, size_t len, const wchar_t *mimeType) +{ + return _call(API_ALBUMART_SETALBUMART, (int)ALBUMART_FAILURE, filename, type, w, h, bits, len, mimeType); +} + +inline int api_albumart::DeleteAlbumArt(const wchar_t *filename, const wchar_t *type) +{ + return _call(API_ALBUMART_DELETEALBUMART, (int)ALBUMART_FAILURE, filename, type); +} + +inline int api_albumart::CopyAlbumArt(const wchar_t *sourceFilename, const wchar_t *destinationFilename) +{ + return _call(API_ALBUMART_COPYALBUMART, (int)ALBUMART_FAILURE, sourceFilename, destinationFilename); +} + +// {AC4C4468-F91F-41f3-A5FA-E2B81DC6EB3A} +static const GUID albumArtGUID = +{ 0xac4c4468, 0xf91f, 0x41f3, { 0xa5, 0xfa, 0xe2, 0xb8, 0x1d, 0xc6, 0xeb, 0x3a } }; + + +#endif
\ No newline at end of file diff --git a/Src/Agave/AlbumArt/svc_albumArtProvider.h b/Src/Agave/AlbumArt/svc_albumArtProvider.h new file mode 100644 index 00000000..3dbc2a2f --- /dev/null +++ b/Src/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/Agave/Component/ifc_wa5component.h b/Src/Agave/Component/ifc_wa5component.h new file mode 100644 index 00000000..fb0a1b54 --- /dev/null +++ b/Src/Agave/Component/ifc_wa5component.h @@ -0,0 +1,43 @@ +#ifndef __WASABI_IFC_WA5COMPONENT_H_ +#define __WASABI_IFC_WA5COMPONENT_H_ + +#include <bfc/dispatch.h> + +class api_service; +#ifdef WIN32 +#include <windows.h> +#endif + +class NOVTABLE ifc_wa5component : public Dispatchable +{ +public: + DISPATCH_CODES + { + API_WA5COMPONENT_REGISTERSERVICES = 10, + API_WA5COMPONENT_REGISTERSERVICES_SAFE_MODE = 15, + API_WA5COMPONENT_DEREEGISTERSERVICES = 20, + }; + + void RegisterServices( api_service *service ); + void DeregisterServices( api_service *service ); + +#ifdef WIN32 + HMODULE hModule; +#else + void *dlLibrary; // pointer returned from dlopen +#endif +}; + +inline void ifc_wa5component::RegisterServices( api_service *service ) +{ + _voidcall( API_WA5COMPONENT_REGISTERSERVICES, service ); +} + +inline void ifc_wa5component::DeregisterServices( api_service *service ) +{ + _voidcall( API_WA5COMPONENT_DEREEGISTERSERVICES, service ); +} + +extern "C" typedef ifc_wa5component *(*GETCOMPONENT_FUNC)(); + +#endif
\ No newline at end of file diff --git a/Src/Agave/Config/api_config.h b/Src/Agave/Config/api_config.h new file mode 100644 index 00000000..d71885d6 --- /dev/null +++ b/Src/Agave/Config/api_config.h @@ -0,0 +1,135 @@ +#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 ); + + 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 } }; + +extern api_config *configApi; + +#ifndef AGAVE_API_CONFIG +#define AGAVE_API_CONFIG configApi +#endif // !AGAVE_API_CONFIG + +#endif
\ No newline at end of file diff --git a/Src/Agave/Config/ifc_configgroup.h b/Src/Agave/Config/ifc_configgroup.h new file mode 100644 index 00000000..20554865 --- /dev/null +++ b/Src/Agave/Config/ifc_configgroup.h @@ -0,0 +1,36 @@ +#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(); + + 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
\ No newline at end of file diff --git a/Src/Agave/Config/ifc_configitem.h b/Src/Agave/Config/ifc_configitem.h new file mode 100644 index 00000000..7a0f5180 --- /dev/null +++ b/Src/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
\ No newline at end of file diff --git a/Src/Agave/DecodeFile/api_decodefile.h b/Src/Agave/DecodeFile/api_decodefile.h new file mode 100644 index 00000000..c2b3c46a --- /dev/null +++ b/Src/Agave/DecodeFile/api_decodefile.h @@ -0,0 +1,104 @@ +#ifndef NULLSOFT_AGAVE_API_DECODEFILE_H +#define NULLSOFT_AGAVE_API_DECODEFILE_H + +#include <bfc/dispatch.h> +#include <bfc/platform/types.h> +#include "ifc_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) + API_DECODEFILE_FAIL_NO_WARN = 7, // we have already informed the user of an issue so do not show again e.g. CD playing so cannot also do a rip +}; + +enum +{ + AUDIOPARAMETERS_FLOAT = 1, + AUDIOPARAMETERS_MAXCHANNELS = 2, // set this if channels is meant to define an upper limit + // (e.g. setting channels=2 and flags |= AUDIOPARAMETERS_MAXCHANNELS means 1 or 2 channels is OK, but not more) + AUDIOPARAMETERS_MAXSAMPLERATE = 4, // like AUDIOPARAMETERS_MAXCHANNELS but for sample rate + AUDIOPARAMETERS_NON_INTERLEAVED = 8, // audio data is stored as separate buffers per channel. not currently implemented +}; + +struct AudioParameters +{ +public: + AudioParameters() : bitsPerSample(0), channels(0), sampleRate(0), sampleRateReal(0.f), flags(0), sizeBytes((size_t) - 1), errorCode(API_DECODEFILE_SUCCESS) + {} + uint32_t bitsPerSample; + uint32_t channels; + uint32_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 ifc_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 + */ + ifc_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 + */ + ifc_audiostream *OpenAudio(const wchar_t *filename, AudioParameters *parameters); + + void CloseAudio(ifc_audiostream *audioStream); + /* verifies that a decoder exists to decompress this filename. + this is not a guarantee that 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 ifc_audiostream *api_decodefile::OpenAudio(const wchar_t *filename, AudioParameters *parameters) +{ + return _call(API_DECODEFILE_OPENAUDIO, (ifc_audiostream *)0, filename, parameters); +} + +inline ifc_audiostream *api_decodefile::OpenAudioBackground(const wchar_t *filename, AudioParameters *parameters) +{ + return _call(API_DECODEFILE_OPENAUDIO2, (ifc_audiostream *)0, filename, parameters); +} + +inline void api_decodefile::CloseAudio(ifc_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/Agave/DecodeFile/ifc_audiostream.h b/Src/Agave/DecodeFile/ifc_audiostream.h new file mode 100644 index 00000000..586d704c --- /dev/null +++ b/Src/Agave/DecodeFile/ifc_audiostream.h @@ -0,0 +1,65 @@ +#ifndef NULLSOFT_AGAVE_IFC_AUDIOSTREAM_H +#define NULLSOFT_AGAVE_IFC_AUDIOSTREAM_H + +#include <bfc/dispatch.h> + +class ifc_audiostream : public Dispatchable +{ +protected: + ifc_audiostream() {} + ~ifc_audiostream() {} +public: + /* returns number of bytes written to buffer. + * a return value of 0 means EOF + */ + size_t ReadAudio(void *buffer, size_t sizeBytes); + + 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 + { + IFC_AUDIOSTREAM_READAUDIO = 10, + IFC_AUDIOSTREAM_READAUDIO2 = 11, + IFC_AUDIOSTREAM_SEEKTOTIMEMS = 20, + IFC_AUDIOSTREAM_CANSEEK = 30, + }; +}; + +inline size_t ifc_audiostream::ReadAudio(void *buffer, size_t sizeBytes) +{ + return _call(IFC_AUDIOSTREAM_READAUDIO, (size_t)0, buffer, sizeBytes); +} + +inline size_t ifc_audiostream::ReadAudio(void *buffer, size_t sizeBytes, int *killswitch, int *errorCode) +{ + void *params[4] = { &buffer, &sizeBytes, &killswitch, &errorCode}; + size_t retval; + + if (_dispatch(IFC_AUDIOSTREAM_READAUDIO2, &retval, params, 4)) + return retval; + else + { + *errorCode=0; + return ReadAudio(buffer, sizeBytes); + } +} + +inline int ifc_audiostream::SeekToTimeMs(int millisecs) +{ + return _call(IFC_AUDIOSTREAM_SEEKTOTIMEMS, (int)0, millisecs); +} + +inline int ifc_audiostream::CanSeek() +{ + return _call(IFC_AUDIOSTREAM_CANSEEK, (int)0); +} + +#endif diff --git a/Src/Agave/DecodeFile/ifc_raw_media_reader.h b/Src/Agave/DecodeFile/ifc_raw_media_reader.h new file mode 100644 index 00000000..cc86f1a9 --- /dev/null +++ b/Src/Agave/DecodeFile/ifc_raw_media_reader.h @@ -0,0 +1,26 @@ +#pragma once + +#include <bfc/dispatch.h> +#include <bfc/error.h> + +class ifc_raw_media_reader : public Dispatchable +{ +protected: + ifc_raw_media_reader() {} + ~ifc_raw_media_reader() {} + +public: + int Read(void *buffer, size_t buffer_size, size_t *bytes_read); + /* TODO: we'll probably need stuff in here like EndOfFile, determining a good buffer size, etc */ + + DISPATCH_CODES + { + RAW_READ + }; +}; + +inline int ifc_raw_media_reader::Read(void *buffer, size_t buffer_size, size_t *bytes_read) +{ + return _call(RAW_READ, (int)NErr_NotImplemented, buffer, buffer_size, bytes_read); +} + diff --git a/Src/Agave/DecodeFile/svc_raw_media_reader.h b/Src/Agave/DecodeFile/svc_raw_media_reader.h new file mode 100644 index 00000000..c70c8085 --- /dev/null +++ b/Src/Agave/DecodeFile/svc_raw_media_reader.h @@ -0,0 +1,32 @@ +#pragma once + +#include <bfc/dispatch.h> +#include "ifc_raw_media_reader.h" +#include <bfc/error.h> + +class svc_raw_media_reader : public Dispatchable +{ +protected: + svc_raw_media_reader() {} + ~svc_raw_media_reader() {} +public: + static FOURCC getServiceType() { return svc_raw_media_reader::SERVICETYPE; } + int CreateRawMediaReader(const wchar_t *filename, ifc_raw_media_reader **reader); +public: + DISPATCH_CODES + { + CREATERAWMEDIAREADER = 0, + }; + + + enum + { + SERVICETYPE = MK4CC('r','a','w','m') + }; +}; + +inline int svc_raw_media_reader::CreateRawMediaReader(const wchar_t *filename, ifc_raw_media_reader **reader) +{ + return _call(CREATERAWMEDIAREADER, (int)NErr_NotImplemented, filename, reader); +} + diff --git a/Src/Agave/Encode/ifc_audioFileEncoder.h b/Src/Agave/Encode/ifc_audioFileEncoder.h new file mode 100644 index 00000000..f0f7c3ce --- /dev/null +++ b/Src/Agave/Encode/ifc_audioFileEncoder.h @@ -0,0 +1,60 @@ +#pragma once +#include <bfc/dispatch.h> +class ifc_audioFileEncoder : public Dispatchable +{ +protected: + ifc_audioFileEncoder() {} + ~ifc_audioFileEncoder() {} +public: + /* + @param frame - frame number, optional (pass 0 every time if you don't have it). + it is used for special purposes and is not generally needed. + @param data - the input data (audio) + @param data_len - number of valid bytes in data + @param data_used - on return, set to the number of audio bytes read + + note for implementors: + it is highly recommended that implementation use all available input data, but it is not required. + + note for users: + if not all input data is read, you need to pass in the old data again + but have more available. This is likely to happen when the block size of the codec + does not match your buffer size + */ + int Feed(uint32_t frame, const void *data, size_t data_len, size_t *data_used); + + // same as above, but used when you have no more input to pass + // you can pass more audio data if you like (preferred if possible) + // or pass 0 for data & data_len if you passed all your data to Feed() + // note to implementors: + // for many implementations: close your encoder (e.g. vorbis) but not your file writer (e.g. ogg) + // note to users: + // you still need to call Finish(). + int Finish(uint32_t frame, const void *data, size_t data_len, size_t *data_used); + + // call this to do whatever necessary + // this is a separate call than Finish() because of time-constraints and the killswitch + // for many implementations: close your file writer object here, write seek table, etc. + // note to users: + // after this function succeeds, you may use the file (write metadata, etc) + int Finalize(int *killswitch); + + // @param block_size - on return, set to the 'natural' number of bytes that the audio encoder expects + // can be helpful for users of this object to do more efficient I/O + // optional (check the return value when you call this!) + // but recommended + int GetBlockSize(size_t *block_size); + + // @param fill_size - on return, set to the number of bytes needed to fill the audio encoder's current block + // might be 0 for some types (WAV). + // can be helpful for users of this object to do more efficient I/O + // optional (check the return value when you call this!) + // don't implement unless it's easy + int GetFillSize(size_t *fill_size); + + // @param bytes_written - on return, set to the number of encoded bytes written so far. + // used by the CD ripper to show a 'real time' bitrate + // optional (check the return value when you call this!) + // don't implement unless it's easy + int GetBytesWritten(size_t *bytes_written); +};
\ No newline at end of file diff --git a/Src/Agave/Encode/notes.txt b/Src/Agave/Encode/notes.txt new file mode 100644 index 00000000..1bd767e6 --- /dev/null +++ b/Src/Agave/Encode/notes.txt @@ -0,0 +1,23 @@ +notes for encoders
+
+====
+two types of encoders:
+1) File encoders. These write directly to a file.
+2) Stream encoders. These return the encoded audio data in a user-provided buffer
+
+For example, an AAC encoder could implement a file encoder for MP4/M4A files, but these aren't streamable.
+ADTS AAC however, would be streamable.
+
+====
+Two ways of feeding the data
+1) Push model. The user of the class passes data in a user-owned data buffer.
+2) Pull model. The implementor of the class pulls data from a user-provided callback (data is stored in an implementor-owned buffer)
+
+Push encoders should be used when the incoming audio data is not immediately available (live recording, CD ripping).
+Pull encoders should only be used when all the audio data is immediately available (e.g. WAV file).
+
+When in doubt, use a push encoder. Pull encoders offer a potential advantage of better memory usage (fewer memcpy's in most implementations), but a push encoder should serve all needs.
+
+====
+Note that encoders should be as non-blocking as possible (except for, obviously, computation, file I/O and thread synchronization for multi-core-aware encoders).
+It it not reommended to Sleep(), select() [network I/O], etc. Stick to what the API was designed for :)
diff --git a/Src/Agave/Encode/svc_audioFileEncoder.h b/Src/Agave/Encode/svc_audioFileEncoder.h new file mode 100644 index 00000000..7368a23b --- /dev/null +++ b/Src/Agave/Encode/svc_audioFileEncoder.h @@ -0,0 +1,64 @@ +#pragma once +/* +Service for creating Audio Encoders which encode straight to a file. + +This interface is not meant to do the encoding itself, it is a factory to create and destroy +encoder objects (ifc_audioFileEncoder) +*/ +#include <bfc/dispatch.h> +#include "ifc_audioFileEncoder.h" +#include "../DecodeFile/api_decodefile.h" // for AudioParameters struct +#include <bfc/std_mkncc.h> // for MKnCC() +class svc_audioFileEncoder : public Dispatchable +{ +protected: + svc_audioFileEncoder() {} + ~svc_audioFileEncoder() {} +public: + static FOURCC getServiceType() { return svc_albumArtProvider::SERVICETYPE; } + /* + General parameter notes (for all methods of this class): + @param profile is a filename of an INI file where the encoder settings are stored + @param parameters defines the input audio data. For methods where this parameter + is optional (default parameter value == 0), it is meant to be passed to optionally + limit configuration choices. For example, an AAC encoder could hide surround-sound + encoding options when parameters->channels == 2 + */ + + // return a user-friendly name for the encoder, + // e.g. "Nullsoft FLAC encoder v2.1" + const wchar_t *GetName(); + + // retrieve information about a particular profile + // @param profile_item information to retrieve. currently, there are only three defined strings + // "bitrate" -- retrieve an estimate bitrate (in kbps) for the profile + // "profile" -- retrieve a more specific name for a given profile (and optional input parameters) + // e.g. an AAC encoder could return "HE-AAC v2, 16kbps, MP4 File Format" or "AAC LC, ADTS stream" + // "settings" -- retrieve a string that codifies the settings in the profile + // for most codecs, this should mirror what the commandline string would be for the corresponding + // commandline codec (flac.exe, lame.exe, etc). + // e.g. "-V 2" + int GetProfileInfo(const wchar_t *profile, const wchar_t *profile_item, wchar_t *value, size_t value_cch, const AudioParameters *parameters = 0); + + // not currently used for anything + int SetProfileInfo(const wchar_t *profile, const wchar_t *profile_item, const wchar_t *value, AudioParameters *parameters = 0); + + // this function gets the party started. call after you have opened your input file (thru + // api_decodefile, for example) so you can pass in a valid parameters struct. + // @param filename destination filename + int Create(ifc_audioFileEncoder **encoder, const wchar_t *filename, const wchar_t *profile, const AudioParameters *parameters); + + // call this when you are done + void Destroy(ifc_audioFileEncoder *encoder); + + // if parent is NULL, pop up a modal dialog/window + // if parent is not NULL, return a modeless child dialog/window + HWND Configure(HWND parent, const wchar_t *profile, const AudioParameters *parameters = 0); + + + enum + { + SERVICETYPE = MK4CC('a','f','e', 'n') + }; + +};
\ No newline at end of file diff --git a/Src/Agave/ExplorerFindFile/api_explorerfindfile.h b/Src/Agave/ExplorerFindFile/api_explorerfindfile.h new file mode 100644 index 00000000..b9fb0411 --- /dev/null +++ b/Src/Agave/ExplorerFindFile/api_explorerfindfile.h @@ -0,0 +1,46 @@ +#ifndef NULLSOFT_API_EXPLORERFINDFILE_H +#define NULLSOFT_API_EXPLORERFINDFILE_H + +#include <bfc/dispatch.h> + +class api_explorerfindfile : public Dispatchable +{ +protected: + api_explorerfindfile() {} + ~api_explorerfindfile() {} +public: + BOOL AddFile(wchar_t* file); + BOOL ShowFiles(void); + void Reset(void); +public: + DISPATCH_CODES + { + API_EXPLORERFINDFILE_ADDFILE = 10, + API_EXPLORERFINDFILE_SHOWFILES = 11, + API_EXPLORERFINDFILE_RESET = 12, + }; +}; + +inline BOOL api_explorerfindfile::AddFile(wchar_t* file) +{ + return _call(API_EXPLORERFINDFILE_ADDFILE, (BOOL)0, file); +} + +inline BOOL api_explorerfindfile::ShowFiles(void) +{ + return _call(API_EXPLORERFINDFILE_SHOWFILES, (BOOL)0); +} + +inline void api_explorerfindfile::Reset(void) +{ + _voidcall(API_EXPLORERFINDFILE_RESET); +} + +extern api_explorerfindfile *ExplorerFindFileManager; +#define WASABI_API_EXPLORERFINDFILE ExplorerFindFileManager + +// {83D6CD21-D67A-4326-A5B2-E1EFD664ADB5} +static const GUID ExplorerFindFileApiGUID = +{ 0x83d6cd21, 0xd67a, 0x4326, { 0xa5, 0xb2, 0xe1, 0xef, 0xd6, 0x64, 0xad, 0xb5 } }; + +#endif
\ No newline at end of file diff --git a/Src/Agave/Language/api_language.h b/Src/Agave/Language/api_language.h new file mode 100644 index 00000000..09354531 --- /dev/null +++ b/Src/Agave/Language/api_language.h @@ -0,0 +1,330 @@ +#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* LoadResourceFromFileA(HINSTANCE hinst, HINSTANCE owner, LPCSTR lpType, LPCSTR 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(); + + // Implemented in 5.64+ + wchar_t* FormattedSizeString(wchar_t *out, int cchLen, __int64 size); + +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_LOADRESOURCEFROMFILEA = 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, + + // Implemented in 5.64+ + API_LANGUAGE_FORMATTEDSIZESTRING = 100, + }; +}; + +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::LoadResourceFromFileA(HINSTANCE hinst, HINSTANCE owner, LPCSTR lpType, LPCSTR lpName, DWORD* size) +{ + return _call(API_LANGUAGE_LOADRESOURCEFROMFILEA, (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); +} + +inline wchar_t *api_language::FormattedSizeString(wchar_t *out, int cchLen, __int64 size) +{ + return _call(API_LANGUAGE_FORMATTEDSIZESTRING, (wchar_t*)0, out, cchLen, size); +} + + +// 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 +//#ifdef UNICODE +//#define WASABI_API_LNGSTR WASABI_API_LNG->GetStringW +//#else +//#define WASABI_API_LNGSTR WASABI_API_LNG->GetStringA +//#endif +// 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_LOADRESFROMFILEA(lpType, lpName, size) \ + WASABI_API_LNG->LoadResourceFromFileA(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/Agave/Language/lang.h b/Src/Agave/Language/lang.h new file mode 100644 index 00000000..03595a1b --- /dev/null +++ b/Src/Agave/Language/lang.h @@ -0,0 +1,643 @@ +#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_LOCALIZED_HOMEPAGE 65531 +#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 } }; + +// {C1DE900F-8047-4B04-AE6B-8EACD9A9B8E1} +static const GUID MlNFTLangGUID = +{ 0xc1de900f, 0x8047, 0x4b04, { 0xae, 0x6b, 0x8e, 0xac, 0xd9, 0xa9, 0xb8, 0xe1 } }; + +// {DBF92DD3-766E-42E8-A4D2-AE1AC88CF2D1} +static const GUID MlFanZoneLangGUID = +{ 0xdbf92dd3, 0x766e, 0x42e8, { 0xa4, 0xd2, 0xae, 0x1a, 0xc8, 0x8c, 0xf2, 0xd1 } }; + +// // {4959A8EF-B760-4C33-B18C-715EF018B365} +static const GUID MlHotmixRadioLangGUID = +{ 0x4959a8ef, 0xb760, 0x4c33, { 0xb1, 0x8c, 0x71, 0x5e, 0xf0, 0x18, 0xb3, 0x65 } }; + +// {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 } }; + +// Fraunhofer AAC Encoder plugin (enc_fhgaac.dll) +// {E1763EF4-08AD-44a3-914A-8302748AB975} +static const GUID EncFhgAacLangGUID = +{ 0xe1763ef4, 0x8ad, 0x44a3, { 0x91, 0x4a, 0x83, 0x2, 0x74, 0x8a, 0xb9, 0x75 } }; + +// Nullsoft Ogg Demuxer (in_ogg.dll) +// {90B01366-39C1-47b2-99DC-BBAE2D4DC5BF} +static const GUID InOggLangGUID = +{ 0x90b01366, 0x39c1, 0x47b2, { 0x99, 0xdc, 0xbb, 0xae, 0x2d, 0x4d, 0xc5, 0xbf } }; + +// Winamp Cloud plugin (ml_cloud.dll) +// {0253CD84-4BB1-415b-B95B-B13EBD7EA6FD} +static const GUID MlCloudLangGUID = +{ 0x253cd84, 0x4bb1, 0x415b, { 0xb9, 0x5b, 0xb1, 0x3e, 0xbd, 0x7e, 0xa6, 0xfd } }; + +// Winamp Cloud Device plugin (pmp_cloud.dll) +// {5F99429F-43B0-4544-ABA0-DE5D9DA65283} +static const GUID PmpCloudLangGUID = +{ 0x5f99429f, 0x43b0, 0x4544, { 0xab, 0xa0, 0xde, 0x5d, 0x9d, 0xa6, 0x52, 0x83 } }; + +// {CA4D071B-4E9B-44fd-862A-783FC763B63D} +static const GUID MlDevicesLangGUID = +{ 0xca4d071b, 0x4e9b, 0x44fd, { 0x86, 0x2a, 0x78, 0x3f, 0xc7, 0x63, 0xb6, 0x3d } }; + +// {B5691276-95DB-4b5c-BA73-B904A38EFFBF} +static const GUID InModMPTLangGUID = +{ 0xb5691276, 0x95db, 0x4b5c, { 0xba, 0x73, 0xb9, 0x4, 0xa3, 0x8e, 0xff, 0xbf } }; + +// {CA8AD152-9760-4AA3-AC54-7464279C5D63} +static const GUID OutWasapiLangGUID = +{ 0xca8ad152, 0x9760, 0x4aa3, { 0xac, 0x54, 0x74, 0x64, 0x27, 0x9c, 0x5d, 0x63 } }; + + +/* +** 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 +// Note: this used to be {FD4D4A01-C337-4144-85D7-00678B3B2D2D} but was changed with +// v2.3.0 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 +// {88380E65-4068-49BA-8EA4-3F2AF12D0A4F} +static const GUID DspShoutcastLangGUID = +{ 0x88380e65, 0x4068, 0x49ba, { 0x8e, 0xa4, 0x3f, 0x2a, 0xf1, 0x2d, 0xa, 0x4f } }; + +#ifdef __cplusplus +} // extern "C" +#endif +#endif
\ No newline at end of file diff --git a/Src/Agave/Metadata/api_metadata.cpp b/Src/Agave/Metadata/api_metadata.cpp new file mode 100644 index 00000000..1eedadb9 --- /dev/null +++ b/Src/Agave/Metadata/api_metadata.cpp @@ -0,0 +1 @@ +#include "api_metadata.h"
\ No newline at end of file diff --git a/Src/Agave/Metadata/api_metadata.h b/Src/Agave/Metadata/api_metadata.h new file mode 100644 index 00000000..da3c2145 --- /dev/null +++ b/Src/Agave/Metadata/api_metadata.h @@ -0,0 +1,102 @@ +#ifndef NULLSOFT_AGAVE_METADATA_API_METADATA_H +#define NULLSOFT_AGAVE_METADATA_API_METADATA_H + +/** + ** Author: Ben Allison + ** original date: April 10, 2006 + */ +#include <bfc/dispatch.h> +#include "svc_metatag.h" + + +class api_metadata : public Dispatchable +{ +protected: + api_metadata() {} + ~api_metadata() {} + +public: + // replacement for IPC_GET_EXTENDED_FILE_INFO, it's slow, so only use for converting old code, or one-off metadata grabbing + int GetExtendedFileInfo(const wchar_t *filename, const wchar_t *tag, wchar_t *data, size_t dataLength); + + // replacement for IPC_SET_EXTENDED_FILE_INFO + int SetExtendedFileInfo(const wchar_t *filename, const wchar_t *tag, const wchar_t *data); + int WriteExtendedFileInfo(const wchar_t *filename); + + /** faster methods below. these return you an object that you can keep re-using (for a single file) + ** it's still your job to call svc_metaTag::metaTag_open() - see note [2] + ** call svc_metaTag::close() when you're done - see note [3] + */ + svc_metaTag *GetMetaTagObject(const wchar_t *filename, int flags=METATAG_ALL, GUID *exclude=0, int numExcludes=0); // see note [1] + svc_metaTag *GetMetaTagObject(const GUID metaTagGuid); // gets a specific svc_metaTag object by GUID + + /** + ** Retrieves a unique key for a given field name + ** if one already exists, that index is returned + ** returns -1 on failure/not implemented + **/ + uint32_t GenerateKey(const wchar_t *field); + + + DISPATCH_CODES + { + API_METADATA_GETEXTENDEDFILEINFO = 10, + API_METADATA_SETEXTENDEDFILEINFO = 11, + API_METADATA_WRITEEXTENDEDFILEINFO = 12, + API_METADATA_GETMETATAGOBJECT = 20, + API_METADATA_GETMETATAGOBJECTBYGUID = 30, + API_METADATA_GENERATEKEY = 40, + }; +}; + +/** + ** [1] flags can be set to only use certain metadata providers, file info, database, online lookup (CDDB, etc), guessing + ** exclude list can be use to exclude certain metatag GUIDs. This is useful for metadata services that need to look up metadata themselves + ** e.g. CDDB might need to get a Disc ID, media library wants to ask for info to fill itself in. Neither services wants to have themselves + ** be asked, and might not want a "guessing" metatag provider to be used, either. + ** [2] these methods could technically open the file also, but we've left that out to allow for some flexibility + ** e.g. someone might just be looking for the metaTag service name or GUID. + ** [3] you need to close it even if you never opened it. This allows the object to "self-destruct". + ** If we didn't do this, we would also have to pass back the service factory + ** + */ + +inline int api_metadata::GetExtendedFileInfo(const wchar_t *filename, const wchar_t *tag, wchar_t *data, size_t dataLength) +{ + return _call(API_METADATA_GETEXTENDEDFILEINFO, (int)0, filename, tag, data, dataLength); +} + +inline int api_metadata::SetExtendedFileInfo(const wchar_t *filename, const wchar_t *tag, const wchar_t *data) +{ + return _call(API_METADATA_SETEXTENDEDFILEINFO, (int)0, filename, tag, data); +} + +inline int api_metadata::WriteExtendedFileInfo(const wchar_t *filename) +{ + return _call(API_METADATA_WRITEEXTENDEDFILEINFO, (int)0, filename); +} + + +inline svc_metaTag *api_metadata::GetMetaTagObject(const wchar_t *filename, int flags, GUID *exclude, int numExcludes) +{ + return _call(API_METADATA_GETMETATAGOBJECT, (svc_metaTag *)NULL, filename, flags, exclude, numExcludes); +} + +inline svc_metaTag *api_metadata::GetMetaTagObject(const GUID metaTagGuid) +{ + return _call(API_METADATA_GETMETATAGOBJECTBYGUID, (svc_metaTag *)NULL, metaTagGuid); +} + +#pragma warning(push) +#pragma warning(disable : 4267) +inline uint32_t api_metadata::GenerateKey(const wchar_t *field) +{ + return _call(API_METADATA_GENERATEKEY, (uint32_t)-1); +} +#pragma warning(pop) + +// {DFA89F63-995A-407b-8BC8-827900440727} +static const GUID api_metadataGUID = +{ 0xdfa89f63, 0x995a, 0x407b, { 0x8b, 0xc8, 0x82, 0x79, 0x0, 0x44, 0x7, 0x27 } }; + +#endif diff --git a/Src/Agave/Metadata/ifc_metadataReader.h b/Src/Agave/Metadata/ifc_metadataReader.h new file mode 100644 index 00000000..16749795 --- /dev/null +++ b/Src/Agave/Metadata/ifc_metadataReader.h @@ -0,0 +1,107 @@ +#ifndef NULLSOFT_AGAVE_METADATA_IFC_METADATAREADER_H +#define NULLSOFT_AGAVE_METADATA_IFC_METADATAREADER_H + +#include <bfc/dispatch.h> + +class ifc_metadataReader : public Dispatchable +{ +protected: + ifc_metadataReader() + {} + ~ifc_metadataReader() + {} +public: + /* If there are multiple values for the same field, these functions will concatenate the values in some + manner as defined by the language pack */ + int GetField( const wchar_t *field, wchar_t *destination, size_t destinationCch ); + int GetFieldByKey( uint32_t field_key, wchar_t *destination, size_t destinationCch ); + + int GetIndexedField( const wchar_t *field, uint32_t index, wchar_t *destination, size_t destinationCch ); + int GetIndexedFieldByKey( uint32_t field_key, uint32_t index, wchar_t *destination, size_t destinationCch ); + + class ifc_fieldEnumerator : public Dispatchable + { + protected: + ifc_fieldEnumerator(); + ~ifc_fieldEnumerator(); + + public: + const wchar_t *GetField(); + uint32_t GetKey(); + int Next(); + + DISPATCH_CODES + { + DISP_GETFIELD = 0, + DISP_GETKEY = 1, + DISP_NEXT = 2, + }; + + }; + + enum + { + ENUMERATORFLAG_MULTIPLE_FIELDS = 0, // if multiple values of the same field are present, return each one + ENUMERATORFLAG_REMOVE_DUPLICATE_FIELDS = 1, // don't enumerate duplicate fields (with differing values) + }; + + ifc_fieldEnumerator *GetFieldEnumerator( int flags = ENUMERATORFLAG_MULTIPLE_FIELDS ); // Enumerate fields present in this file + + DISPATCH_CODES + { + DISP_GETFIELD = 0, + DISP_GETFIELDKEY = 1, + DISP_GETINDEXEDFIELD = 2, + DISP_GETINDEXEDFIELDBYKEY = 3, + DISP_GETFIELDENUMERATOR = 4, + }; + + enum + { + NOT_IMPLEMENTED = -1, + SUCCESS = 0, + FAILURE = 1, + END_OF_ITERATOR = 2, + }; +}; + +inline int ifc_metadataReader::GetField(const wchar_t *field, wchar_t *destination, size_t destinationCch) +{ + return _call(DISP_GETFIELD, (int)ifc_metadataReader::NOT_IMPLEMENTED, field, destination, destinationCch); +} + +inline int ifc_metadataReader::GetFieldByKey(uint32_t field_key, wchar_t *destination, size_t destinationCch) +{ + return _call(DISP_GETFIELDKEY, (int)ifc_metadataReader::NOT_IMPLEMENTED, field_key, destination, destinationCch); +} + +inline int ifc_metadataReader::GetIndexedField(const wchar_t *field, uint32_t index, wchar_t *destination, size_t destinationCch) +{ + return _call(DISP_GETINDEXEDFIELD, (int)ifc_metadataReader::NOT_IMPLEMENTED, field, index, destination, destinationCch); +} + +inline int ifc_metadataReader::GetIndexedFieldByKey(uint32_t field_key, uint32_t index, wchar_t *destination, size_t destinationCch) +{ + return _call(DISP_GETINDEXEDFIELDBYKEY, (int)ifc_metadataReader::NOT_IMPLEMENTED, field_key, index, destination, destinationCch); +} + +inline ifc_metadataReader::ifc_fieldEnumerator *ifc_metadataReader::GetFieldEnumerator(int flags) +{ + return _call(DISP_GETFIELDENUMERATOR, (ifc_metadataReader::ifc_fieldEnumerator *)0, flags); +} + +inline const wchar_t *ifc_metadataReader::ifc_fieldEnumerator::GetField() +{ + return _call(DISP_NEXT, (const wchar_t *)0); +} + +inline uint32_t ifc_metadataReader::ifc_fieldEnumerator::GetKey() +{ + return _call(DISP_NEXT, (int)ifc_metadataReader::NOT_IMPLEMENTED); +} + +inline int ifc_metadataReader::ifc_fieldEnumerator::Next() +{ + return _call(DISP_NEXT, (int)END_OF_ITERATOR); +} +#endif
\ No newline at end of file diff --git a/Src/Agave/Metadata/svc_metatag.h b/Src/Agave/Metadata/svc_metatag.h new file mode 100644 index 00000000..0f633926 --- /dev/null +++ b/Src/Agave/Metadata/svc_metatag.h @@ -0,0 +1,152 @@ +#ifndef NULLSOFT_AGAVE_SVC_METATAG_H +#define NULLSOFT_AGAVE_SVC_METATAG_H + +/** + ** Author: Ben Allison + ** original date: April 10, 2006 + */ +#include <bfc/dispatch.h> +#include <api/service/services.h> +#include <bfc/platform/types.h> +#include <bfc/std_mkncc.h> // for MKnCC() + +/* these two GUIDs are to allow you to QueryInterface between readers and writers */ +// {9FD00FBE-B707-4743-B630-CC14071EA443} +static const GUID AgaveMetadataReaderIID = +{ 0x9fd00fbe, 0xb707, 0x4743, { 0xb6, 0x30, 0xcc, 0x14, 0x7, 0x1e, 0xa4, 0x43 } }; + +// {3444E4AD-D6B3-4ac4-A08D-C3F935DC7B98} +static const GUID AgaveMetadataWriterIID = +{ 0x3444e4ad, 0xd6b3, 0x4ac4, { 0xa0, 0x8d, 0xc3, 0xf9, 0x35, 0xdc, 0x7b, 0x98 } }; + +enum +{ + METATAG_SUCCESS = 0, + METATAG_FAILED = 1, + + METATAG_UNKNOWN_TAG = 2, // the tag name isn't understood + METATAG_NO_METADATA = 3, // returned if the file has no metadata at all + METATAG_NOT_APPLICABLE = 4, + +}; + +enum +{ + METATYPE_STRING = 0, // always unicode! and always null terminated + METATYPE_FILENAME = 0, + METATYPE_INTEGER = 1, + METATYPE_UNSIGNED = 2, + METATYPE_SIZE = 2, + METATYPE_GUID = 3, + METATYPE_BINARY = 4, +}; + +// flags +enum +{ + METATAG_FILE_INFO = 0x1, + METATAG_ONLINE_LOOKUP = 0x2, + METATAG_CACHE_DB = 0x4, + METATAG_GUESS = 0x8, + METATAG_ALL = 0xFFFFFFFF +}; + +class svc_metaTag : public Dispatchable +{ +protected: + svc_metaTag() {} + ~svc_metaTag() {} + +public: + /* These methods are to be used by api_metadata */ + static FOURCC getServiceType() { return svc_metaTag::SERVICETYPE; } + const wchar_t *getName(); // i.e. "ID3v2" or something + GUID getGUID(); // this needs to be the same GUID that you use when registering your service factory + int getFlags(); // how this service gets its info + int isOurFile(const wchar_t *filename); + int metaTag_open(const wchar_t *filename); + void metaTag_close(); // self-destructs when this is called (you don't need to call serviceFactory->releaseInterface) + + /* user API starts here */ + const wchar_t *enumSupportedTag(int n, int *datatype = NULL); // returns a list of understood tags. might not be complete (see note [1]) + int getTagSize(const wchar_t *tag, size_t *sizeBytes); // always gives you BYTES, not characters (be careful with your strings) + int getMetaData(const wchar_t *tag, uint8_t *buf, int buflenBytes, int datatype = METATYPE_STRING); // buflen is BYTES, not characters (be careful with your strings) + int setMetaData(const wchar_t *tag, const uint8_t *buf, int buflenBytes, int datatype = METATYPE_STRING); +public: + DISPATCH_CODES + { + SVC_METATAG_GETNAME = 10, + SVC_METATAG_GETGUID = 20, + SVC_METATAG_GETFLAGS = 30, + SVC_METATAG_ISOURFILE = 40, + SVC_METATAG_OPEN = 50, + SVC_METATAG_CLOSE = 60, + SVC_METATAG_ENUMTAGS = 100, + SVC_METATAG_GETTAGSIZE = 110, + SVC_METATAG_GETMETADATA = 120, + SVC_METATAG_SETMETADATA = 130, + + }; + enum + { + SERVICETYPE = MK4CC('m','t','t','g') + }; +}; + +/** Notes: + ** [1] Many metadata getters rely on an underlying library, and some metadata systems (e.g. Vorbis) are open-ended. As a result, there might be no way of + ** generating a complete list +*/ + +inline const wchar_t *svc_metaTag::getName() +{ + return _call(SVC_METATAG_GETNAME, (const wchar_t*)NULL); +} + +inline GUID svc_metaTag::getGUID() +{ + return _call(SVC_METATAG_GETGUID, GUID_NULL); +} + +inline int svc_metaTag::getFlags() +{ + return _call(SVC_METATAG_GETFLAGS, 0); +} + +inline int svc_metaTag::isOurFile(const wchar_t *filename) +{ + return _call(SVC_METATAG_ISOURFILE, (int)0, filename); +} + +inline int svc_metaTag::metaTag_open(const wchar_t *filename) +{ + return _call(SVC_METATAG_OPEN, (int)METATAG_FAILED, filename); +} + +inline void svc_metaTag::metaTag_close() +{ + _voidcall(SVC_METATAG_CLOSE); +} + +inline const wchar_t *svc_metaTag::enumSupportedTag(int n, int *datatype) +{ + return _call(SVC_METATAG_ENUMTAGS, (const wchar_t *)NULL, n, datatype); +} + +inline int svc_metaTag::getTagSize(const wchar_t *tag, size_t *sizeBytes) +{ + return _call(SVC_METATAG_GETTAGSIZE, (int)0, tag, sizeBytes); +} + +inline int svc_metaTag::getMetaData(const wchar_t *tag, uint8_t *buf, int buflenBytes, int datatype) +{ + return _call(SVC_METATAG_GETMETADATA, (int)METATAG_FAILED, tag, buf, buflenBytes, datatype); +} + +inline int svc_metaTag::setMetaData(const wchar_t *tag, const uint8_t *buf, int buflenBytes, int datatype) +{ + return _call(SVC_METATAG_SETMETADATA, (int)METATAG_FAILED, tag, buf, buflenBytes, datatype); +} + + +#endif diff --git a/Src/Agave/PlaylistColouriser/api_playlist_colouriser.h b/Src/Agave/PlaylistColouriser/api_playlist_colouriser.h new file mode 100644 index 00000000..7e1ebddf --- /dev/null +++ b/Src/Agave/PlaylistColouriser/api_playlist_colouriser.h @@ -0,0 +1,154 @@ +#ifndef NULLSOFT_API_PLAYLIST_COLOURISER_H +#define NULLSOFT_API_PLAYLIST_COLOURISER_H + +/* +** Wasabi Playlist Colouriser API Interface v1.0 +** Note: This requires JTFE v1.2 and higher to work +** (Released: 28/09/2010) +** +** +** This header file provides the interfaces implemented by the JTFE plugin for other plugins and services to +** be able to make use of it's playlist colouriser which allows for highlighting of playlist entries in a +** different style to that currently defined by the skin in use to make for example queued items more visible. +** +** The interface allows for controlling aspects of the text colour and the background of playlist item entries +** as long as they exist in the playlist editor or there is data to show e.g. you cannot change the text colour +** of the time entry if there is no time entry shown such as for missing files or streams of unknown length). +** +** When specifying a colour, if you want the default skin colours to be used then you need to set the colour to +** be -1 +** +** To use this api assumes you know already how to make use of the wasabi service based system +** (see the more complete examples provided in the SDK). +** +** +** Example: +** +** The following psuedo code shows how to show a flashing inverted selection on the first item being queried in +** the current playlist editor's contents. +** +** // this will setup an inverted entry when the playlist is queried to be painted +** // you could setup a timer to cause a playlist painting event to make it flash +** // if you toggle the returned state on and off in the ExampleCheck(..) callback +** Colouriser ExampleColouriser = {COLOURISER_FULL_BKGND | COLOURISER_FULL_TEXT | +** COLOURISER_INVERTED | COLOURISER_INVERTED_TEXT, +** 0,-1,-1,-1,-1, ExampleCheck}; +** +** int ExampleCheck(int idx, wchar_t* file){ +** // will only apply the colouring on the first playlist item +** return (idx == 0); +** } +** +** // use this to get an instance of the service (returns null or 1 on error or not supported) +** if(!WASABI_API_COLOURISER) ServiceBuild(WASABI_API_COLOURISER,PlaylistColouriserApiGUID); +** +** +** // this can be used to add or update an existing colouriser instance +** // using COLOURISER_DISABLED in the flags to disable it if not needed +** if(!WASABI_API_COLOURISER->ColouriserExists(&ExampleColouriser)){ +** WASABI_API_COLOURISER->AddColouriser(&ExampleColouriser); +** } +** else{ +** WASABI_API_COLOURISER->UpdateColouriser(&ExampleColouriser); +** } +** +** // with the above, if you wanted to change the code to just change the text +** // colour of playlist item then you could use something like the following: +** ExampleColouriser.flags = COLOURISER_FULL_TEXT; +** ExampleColouriser.main_text = ExcludeColouriser.time_text = <specify_your_colour>; +*/ + +#if (_MSC_VER <= 1200) +typedef int intptr_t; +#endif + +#ifdef __cplusplus + +#include <bfc/dispatch.h> + +typedef struct{ + #define COLOURISER_TIME_BKGND 0x01 // override the time column background colour - uses time_bkgnd + #define COLOURISER_MAIN_BKGND 0x02 // override the main column background colour - uses main_bkgnd + #define COLOURISER_MAIN_BKGND_ALT 0x04 // allows for a different colour for the main column background + #define COLOURISER_FULL_BKGND COLOURISER_MAIN_BKGND | COLOURISER_TIME_BKGND + + #define COLOURISER_TIME_TEXT 0x10 // override the time column text colour - uses time_text + #define COLOURISER_MAIN_TEXT 0x20 // override the main column text colour - uses main_text + #define COLOURISER_FULL_TEXT COLOURISER_TIME_TEXT | COLOURISER_MAIN_TEXT + + #define COLOURISER_BLEND 0x40 // will attempt to blend the colour with the existing colours + + #define COLOURISER_DISABLED 0x1000 // set this when you require your colouriser to be ignored + #define COLOURISER_INVERTED 0x2000 // if colours are specified as -1 then use the inverse of the current skin values + #define COLOURISER_INVERTED_TEXT 0x4000 // if colours are specified as -1 then use the inverse of the current skin values + // this will only be used if COLOURISER_INVERTED is already specified + + int flags; // determine which colours are to be used / handled + int _me; // used to identify the colouriser - don't alter!!! + + // when using ColouriserColour(..) the value for query_colour is shown to the right + COLORREF time_bkgnd; // 0 + COLORREF main_bkgnd; // 1 + COLORREF time_text; // 2 + COLORREF main_text; // 3 + + // callback function to see if the colouriser's colours need to be used on the passed playlist item + int (*check)(int entry_index, wchar_t* entry_filepath); +} Colouriser; + +class api_playlist_colouriser : public Dispatchable +{ +protected: + api_playlist_colouriser() {} + ~api_playlist_colouriser() {} + +public: + BOOL AddColouriser(Colouriser* colouriser); + Colouriser* UpdateColouriser(Colouriser* colouriser); + BOOL ColourPicker(HWND parent_hwnd, UINT control_id, UINT options_id, Colouriser* colouriser, wchar_t* window_title, wchar_t* button_text); + BOOL ColouriserExists(Colouriser* colouriser); + COLORREF ColouriserColour(COLORREF current_colour, UINT query_colour); + +public: + DISPATCH_CODES + { + API_COLOURISER_ADD = 1, + API_COLOURISER_UPDATE = 2, + API_COLOURISER_COLOURPICKER = 3, + API_COLOURISER_EXISTS = 4, + API_COLOURISER_COLOUR = 5, + }; +}; + +inline BOOL api_playlist_colouriser::AddColouriser(Colouriser* colouriser) +{ + return _call(API_COLOURISER_ADD, (BOOL)0, colouriser); +} + +inline Colouriser* api_playlist_colouriser::UpdateColouriser(Colouriser* colouriser) +{ + return _call(API_COLOURISER_UPDATE, (Colouriser*)0, colouriser); +} + +inline BOOL api_playlist_colouriser::ColourPicker(HWND parent_hwnd, UINT control_id, UINT options_id, Colouriser* colouriser, wchar_t* window_title, wchar_t* button_text) +{ + return _call(API_COLOURISER_COLOURPICKER, (BOOL)0, parent_hwnd, control_id, options_id, colouriser, window_title, button_text); +} + +inline BOOL api_playlist_colouriser::ColouriserExists(Colouriser* colouriser) +{ + return _call(API_COLOURISER_EXISTS, (BOOL)0, colouriser); +} + +inline COLORREF api_playlist_colouriser::ColouriserColour(COLORREF current_colour, UINT query_colour) +{ + return _call(API_COLOURISER_COLOUR, (COLORREF)0, current_colour, query_colour); +} + +#endif + +// {B8B8DA7C-1F35-4a6d-95FA-C7E9651D5DC0} +static const GUID PlaylistColouriserApiGUID = +{ 0xb8b8da7c, 0x1f35, 0x4a6d, { 0x95, 0xfa, 0xc7, 0xe9, 0x65, 0x1d, 0x5d, 0xc0 } }; + +#endif
\ No newline at end of file diff --git a/Src/Agave/Queue/api_queue.h b/Src/Agave/Queue/api_queue.h new file mode 100644 index 00000000..272ced86 --- /dev/null +++ b/Src/Agave/Queue/api_queue.h @@ -0,0 +1,202 @@ +#ifndef NULLSOFT_API_QUEUE_H +#define NULLSOFT_API_QUEUE_H + +/* +** JTFE v1.0.1 Wasabi API interface +** (Released: 06/01/2010) +** +** +** This header file provides the interfaces implemented by the JTFE plugin for other plugins/services to be able +** to make use of it's queue which allows for Winamp's playback order to be overriden. +** +** To use this api assumes you know already how to make use of the wasabi service based system +** (see the more complete examples provided in the SDK). +** +** +** Example: +** +** The following psuedo code shows how to clear the current queue (if one exists) and will then add in a specifc +** file by the full path passed and also adding a file based on the position in the current playlist. +** +** if(!WASABI_API_QUEUEMGR) ServiceBuild(WASABI_API_QUEUEMGR,QueueManagerApiGUID); +** if(WASABI_API_QUEUEMGR){ +** // Clear the queue (if one exists) +** WASABI_API_QUEUEMGR->ClearQueue(); +** +** // Add the full file path (wchar_t_path_to_file) +** WASABI_API_QUEUEMGR->AddItemToQueue(0,1,wchar_t_path_to_file); +** +** // Add the first file in the playlist editor into the queue +** WASABI_API_QUEUEMGR->AddItemToQueue(0,0,0); +** } +** +** +** Notes: +** +** This header only provides access to the functions it exports. Some actions like the MoveQueuedItem(s) functions +** have not been implemented in this api even though they are internally implemented. In future releases of the +** plugin it is hoped that these (and another useful/requested) apis will also be implemented and provided. +** +** Changes: +** v1.0.1 - Fixes EnableQueueAdvance(..) and IsQueueAdvanceEnabled(..) interfaces not correctly defined in this file +** - Fixes crash when calling IsQueueAdvanceEnabled(..) (if previous issue was manually corrected) +** +*/ + +#if (_MSC_VER <= 1200) +typedef int intptr_t; +#endif + +enum PLAYLIST_TYPE {M3U_PLAYLIST=0x0, PLS_PLAYLIST=0x1, M3U8_PLAYLIST=0x2}; +enum MOVE_MODE {MOVE_TOP_OF_LIST=-2, MOVE_UP_LIST=-1, MOVE_DOWN_LIST=1, MOVE_END_OF_LIST=2, MOVE_END_TO_START=3 }; + +#ifdef __cplusplus + +#include <bfc/dispatch.h> + +class api_queue : public Dispatchable +{ +protected: + api_queue() {} + ~api_queue() {} + +public: + // main handling functions of the queue to add/remove/clear all + BOOL AddItemToQueue(int item, int update_now, wchar_t* file); + void RemoveQueuedItem(int item, int no_update=0); + void ClearQueue(void); + + /* + ** handling functions to allow for querying/manipulating of the queue items + ** note: need to have a consistancy in the functions and all that... + ** + ** use GetNumberOfQueuedItems() and then loop upto that via GetQueuedItemFromIndex(..) to get item id of the queue + */ + int GetNumberOfQueuedItems(void); + int GetQueuedItemFromIndex(int idx); + wchar_t* GetQueuedItemFilePath(int item); + int GetQueuedItemPlaylistPosition(int item); + int IsItemQueuedMultipleTimes(int item, int test_only); // returns how many times an item is showing in the queue + + // Note: these are to be implemented after JTFE 1.0 + //BOOL MoveQueuedItem(int item, int mode/*MOVE_MODE*/); + //BOOL MoveQueuedItems(int* items, int mode/*MOVE_MODE*/); + + /* + ** miscellaneous actions available on the queue + */ + void RandomiseQueue(void); + // will ignore the item position and match it up against the current playlist (may cause queued item position merging) + void RefreshQueue(void); + BOOL LoadPlaylistIntoQueue(wchar_t* playlist_file, int reset_queue); + BOOL SaveQueueToPlaylist(wchar_t* playlist_file, int playlist_type/*PLAYLIST_TYPE*/); + + // enables/disables queue advancement and query this state + int EnableQueueAdvance(int enabled); + int IsQueueAdvanceEnabled(void); + +public: + DISPATCH_CODES + { + API_QUEUE_ADDITEMTOQUEUE = 1, + API_QUEUE_REMOVEQUEUEDITEM = 2, + API_QUEUE_CLEARQUEUE = 3, + + API_QUEUE_GETNUMBEROFQUEUEDITEMS = 10, + API_QUEUE_GETQUEUEDITEMFROMINDEX = 11, + API_QUEUE_GETQUEUEDITEMFILEPATH = 12, + API_QUEUE_GETQUEUEDITEMPLAYLISTPOSITION = 13, + API_QUEUE_ISITEMQUEUEDMULTIPLETIMES = 14, + + // Note: to be implemented after JTFE 1.0 + //API_QUEUE_MOVEQUEUEDITEM = 15, + //API_QUEUE_MOVEQUEUEDITEMS = 16, + + API_QUEUE_RANDOMISEQUEUE = 20, + API_QUEUE_REFRESHQUEUE = 21, + API_QUEUE_LOADPLAYLISTINTOQUEUE = 22, + API_QUEUE_SAVEQUEUETOPLAYLIST = 23, + + API_QUEUE_ENABLEQUEUEADVANCE = 30, + API_QUEUE_ISQUEUEADVANCEENABLED = 31 + }; +}; + +inline BOOL api_queue::AddItemToQueue(int item, int update_now, wchar_t* file) +{ + return _call(API_QUEUE_ADDITEMTOQUEUE, (BOOL)0, item, update_now, file); +} + +inline void api_queue::RemoveQueuedItem(int item, int no_update) +{ + _voidcall(API_QUEUE_REMOVEQUEUEDITEM, item, no_update); +} + +inline void api_queue::ClearQueue(void) +{ + _voidcall(API_QUEUE_CLEARQUEUE); +} + +inline int api_queue::GetNumberOfQueuedItems(void) +{ + return _call(API_QUEUE_GETNUMBEROFQUEUEDITEMS, (int)0); +} + +inline int api_queue::GetQueuedItemFromIndex(int idx) +{ + return _call(API_QUEUE_GETQUEUEDITEMFROMINDEX, (int)0, idx); +} + +inline wchar_t* api_queue::GetQueuedItemFilePath(int item) +{ + return _call(API_QUEUE_GETQUEUEDITEMFILEPATH, (wchar_t*)0, item); +} + +inline int api_queue::GetQueuedItemPlaylistPosition(int item) +{ + return _call(API_QUEUE_GETQUEUEDITEMPLAYLISTPOSITION, (int)0, item); +} + +inline int api_queue::IsItemQueuedMultipleTimes(int item, int test_only) +{ + return _call(API_QUEUE_ISITEMQUEUEDMULTIPLETIMES, (int)0, item, test_only); +} + +inline void api_queue::RandomiseQueue(void) +{ + _voidcall(API_QUEUE_RANDOMISEQUEUE); +} + +inline void api_queue::RefreshQueue(void) +{ + _voidcall(API_QUEUE_REFRESHQUEUE); +} + +inline int api_queue::LoadPlaylistIntoQueue(wchar_t* playlist_file, int reset_queue) +{ + return _call(API_QUEUE_LOADPLAYLISTINTOQUEUE, (int)0, playlist_file, reset_queue); +} + +inline int api_queue::SaveQueueToPlaylist(wchar_t* playlist_file, int playlist_type) +{ + return _call(API_QUEUE_SAVEQUEUETOPLAYLIST, (int)0, playlist_file, playlist_type); +} + +inline int api_queue::EnableQueueAdvance(int enabled) +{ + return _call(API_QUEUE_ENABLEQUEUEADVANCE, (int)0, enabled); +} + +inline int api_queue::IsQueueAdvanceEnabled(void) +{ + return _call(API_QUEUE_ISQUEUEADVANCEENABLED, (int)0); +} + +#endif + +// {7DC8C14F-F27F-48e8-A3D1-602BB3196E40} +static const GUID QueueManagerApiGUID = +{ 0x7dc8c14f, 0xf27f, 0x48e8, { 0xa3, 0xd1, 0x60, 0x2b, 0xb3, 0x19, 0x6e, 0x40 } }; + + +#endif
\ No newline at end of file diff --git a/Src/Agave/Random/api_random.h b/Src/Agave/Random/api_random.h new file mode 100644 index 00000000..d0618f16 --- /dev/null +++ b/Src/Agave/Random/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/Agave/URIHandler/svc_urihandler.h b/Src/Agave/URIHandler/svc_urihandler.h new file mode 100644 index 00000000..ed964e0e --- /dev/null +++ b/Src/Agave/URIHandler/svc_urihandler.h @@ -0,0 +1,63 @@ +#pragma once +#include <bfc/dispatch.h> +#include <bfc/platform/types.h> +#include <bfc/std_mkncc.h> // for MKnCC() + +class svc_urihandler : public Dispatchable +{ +protected: + svc_urihandler() {} + ~svc_urihandler() {} +public: + static FOURCC getServiceType() { return svc_urihandler::SERVICETYPE; } + enum + { + NOT_HANDLED = -1, // return if it's not yours + HANDLED = 0, // return if it's yours, but other services might want to handle also + HANDLED_EXCLUSIVE = 1, // if it's yours AND NO ONE ELSES + }; + int ProcessFilename(const wchar_t *filename); + int IsMine(const wchar_t *filename); // just like ProcessFilename but don't actually process + int EnumProtocols(size_t n, wchar_t *protocol, size_t protocolCch, wchar_t *description, size_t descriptionCch); // return 0 on success + int RegisterProtocol(const wchar_t *protocol, const wchar_t *winampexe); + int UnregisterProtocol(const wchar_t *protocol); + + enum + { + PROCESSFILENAME=0, + ISMINE=1, + ENUMPROTOCOLS=2, + REGISTERPROTOCOL=3, + UNREGISTERPROTOCOL=4, + }; + + enum + { + SERVICETYPE = MK4CC('u','r','i', 'h') + }; +}; + +inline int svc_urihandler::ProcessFilename(const wchar_t *filename) +{ + return _call(PROCESSFILENAME, (int)NOT_HANDLED, filename); +} + +inline int svc_urihandler::IsMine(const wchar_t *filename) +{ + return _call(ISMINE, (int)NOT_HANDLED, filename); +} + +inline int svc_urihandler::EnumProtocols(size_t n, wchar_t *protocol, size_t protocolCch, wchar_t *description, size_t descriptionCch) +{ + return _call(ENUMPROTOCOLS, (int)1, n, protocol, protocolCch, description, descriptionCch); +} + +inline int svc_urihandler::RegisterProtocol(const wchar_t *protocol, const wchar_t *winampexe) +{ + return _call(REGISTERPROTOCOL, (int)1, protocol, winampexe); +} + + inline int svc_urihandler::UnregisterProtocol(const wchar_t *protocol) + { + return _call(UNREGISTERPROTOCOL, (int)1, protocol); + } |