diff options
Diffstat (limited to 'Src/Wasabi/api/config')
38 files changed, 4286 insertions, 0 deletions
diff --git a/Src/Wasabi/api/config/api_config.cpp b/Src/Wasabi/api/config/api_config.cpp new file mode 100644 index 00000000..4cffc910 --- /dev/null +++ b/Src/Wasabi/api/config/api_config.cpp @@ -0,0 +1,12 @@ +// ---------------------------------------------------------------------------- +// Generated by InterfaceFactory [Thu May 15 21:06:24 2003] +// +// File : api_config.cpp +// Class : api_config +// class layer : Dispatchable Interface +// ---------------------------------------------------------------------------- + +#include <precomp.h> +#include "api_config.h" + + diff --git a/Src/Wasabi/api/config/api_config.h b/Src/Wasabi/api/config/api_config.h new file mode 100644 index 00000000..ece231b5 --- /dev/null +++ b/Src/Wasabi/api/config/api_config.h @@ -0,0 +1,149 @@ +// ---------------------------------------------------------------------------- +// Generated by InterfaceFactory [Thu May 15 21:06:24 2003] +// +// File : api_config.h +// Class : api_config +// class layer : Dispatchable Interface +// ---------------------------------------------------------------------------- + +#ifndef __API_CONFIG_H +#define __API_CONFIG_H + +#include <bfc/dispatch.h> +#include <bfc/platform/types.h> + +class CfgItem; +class ConfigFile; + + +// ---------------------------------------------------------------------------- + +class NOVTABLE api_config: public Dispatchable +{ + protected: + api_config() {} + ~api_config() {} + public: + void config_registerCfgItem(CfgItem *cfgitem); + void config_deregisterCfgItem(CfgItem *cfgitem); + int config_getNumCfgItems(); + CfgItem *config_enumCfgItem(int n); + CfgItem *config_getCfgItemByGuid(GUID g); + void setIntPrivate(const wchar_t *name, int val); + int getIntPrivate(const wchar_t *name, int def_val); + void setIntArrayPrivate(const wchar_t *name, const int *val, int nval); + int getIntArrayPrivate(const wchar_t *name, int *val, int nval); + void setStringPrivate(const wchar_t *name, const wchar_t *str); + int getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str); + int getStringPrivateLen(const wchar_t *name); + void setIntPublic(const wchar_t *name, int val); + int getIntPublic(const wchar_t *name, int def_val); + void setStringPublic(const wchar_t *name, const wchar_t *str); + int getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str); + + protected: + enum { + API_CONFIG_CONFIG_REGISTERCFGITEM = 10, + API_CONFIG_CONFIG_DEREGISTERCFGITEM = 20, + API_CONFIG_CONFIG_GETNUMCFGITEMS = 30, + API_CONFIG_CONFIG_ENUMCFGITEM = 40, + API_CONFIG_CONFIG_GETCFGITEMBYGUID = 50, + API_CONFIG_SETINTPRIVATE = 60, + API_CONFIG_GETINTPRIVATE = 70, + API_CONFIG_SETINTARRAYPRIVATE = 80, + API_CONFIG_GETINTARRAYPRIVATE = 90, + API_CONFIG_SETSTRINGPRIVATE = 100, + API_CONFIG_GETSTRINGPRIVATE = 110, + API_CONFIG_GETSTRINGPRIVATELEN = 120, + API_CONFIG_SETINTPUBLIC = 130, + API_CONFIG_GETINTPUBLIC = 140, + API_CONFIG_SETSTRINGPUBLIC = 150, + API_CONFIG_GETSTRINGPUBLIC = 160, + }; +}; + +// ---------------------------------------------------------------------------- + +inline void api_config::config_registerCfgItem(CfgItem *cfgitem) { + _voidcall(API_CONFIG_CONFIG_REGISTERCFGITEM, cfgitem); +} + +inline void api_config::config_deregisterCfgItem(CfgItem *cfgitem) { + _voidcall(API_CONFIG_CONFIG_DEREGISTERCFGITEM, cfgitem); +} + +inline int api_config::config_getNumCfgItems() { + int __retval = _call(API_CONFIG_CONFIG_GETNUMCFGITEMS, (int)0); + return __retval; +} + +inline CfgItem *api_config::config_enumCfgItem(int n) { + CfgItem *__retval = _call(API_CONFIG_CONFIG_ENUMCFGITEM, (CfgItem *)NULL, n); + return __retval; +} + +inline CfgItem *api_config::config_getCfgItemByGuid(GUID g) { + CfgItem *__retval = _call(API_CONFIG_CONFIG_GETCFGITEMBYGUID, (CfgItem *)NULL, g); + return __retval; +} + +inline void api_config::setIntPrivate(const wchar_t *name, int val) { + _voidcall(API_CONFIG_SETINTPRIVATE, name, val); +} + +inline int api_config::getIntPrivate(const wchar_t *name, int def_val) { + int __retval = _call(API_CONFIG_GETINTPRIVATE, (int)0, name, def_val); + return __retval; +} + +inline void api_config::setIntArrayPrivate(const wchar_t *name, const int *val, int nval) { + _voidcall(API_CONFIG_SETINTARRAYPRIVATE, name, val, nval); +} + +inline int api_config::getIntArrayPrivate(const wchar_t *name, int *val, int nval) { + int __retval = _call(API_CONFIG_GETINTARRAYPRIVATE, (int)0, name, val, nval); + return __retval; +} + +inline void api_config::setStringPrivate(const wchar_t *name, const wchar_t *str) { + _voidcall(API_CONFIG_SETSTRINGPRIVATE, name, str); +} + +inline int api_config::getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str) { + int __retval = _call(API_CONFIG_GETSTRINGPRIVATE, (int)0, name, buf, buf_len, default_str); + return __retval; +} + +inline int api_config::getStringPrivateLen(const wchar_t *name) { + int __retval = _call(API_CONFIG_GETSTRINGPRIVATELEN, (int)0, name); + return __retval; +} + +inline void api_config::setIntPublic(const wchar_t *name, int val) { + _voidcall(API_CONFIG_SETINTPUBLIC, name, val); +} + +inline int api_config::getIntPublic(const wchar_t *name, int def_val) { + int __retval = _call(API_CONFIG_GETINTPUBLIC, (int)0, name, def_val); + return __retval; +} + +inline void api_config::setStringPublic(const wchar_t *name, const wchar_t *str) { + _voidcall(API_CONFIG_SETSTRINGPUBLIC, name, str); +} + +inline int api_config::getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str) { + int __retval = _call(API_CONFIG_GETSTRINGPUBLIC, (int)0, name, buf, buf_len, default_str); + return __retval; +} + +// ---------------------------------------------------------------------------- + + +// {470B890C-4747-4113-ABA5-A8F8F4F8AB7E} +static const GUID configApiServiceGuid = +{ 0x470b890c, 0x4747, 0x4113, { 0xab, 0xa5, 0xa8, 0xf8, 0xf4, 0xf8, 0xab, 0x7e } }; + +extern api_config *configApi; + +#endif // __API_CONFIG_H diff --git a/Src/Wasabi/api/config/api_configi.cpp b/Src/Wasabi/api/config/api_configi.cpp new file mode 100644 index 00000000..d6b62189 --- /dev/null +++ b/Src/Wasabi/api/config/api_configi.cpp @@ -0,0 +1,124 @@ +#include <precomp.h> +//<?#include "<class data="implementationheader"/>" +#include "api_configi.h" +//?> + +#include <bfc/parse/pathparse.h> +#include <api/config/cfglist.h> + + +static CfgList cfglist; + +api_config *configApi = NULL; + +api_configI::api_configI() +: public_config(StringPrintfW(INVALID_GUID), L"public data") +{ + public_config.initialize(); +} + +api_configI::~api_configI() +{ +} + +void api_configI::config_registerCfgItem(CfgItem *cfgitem) +{ + cfglist.addItem(cfgitem); +} + +void api_configI::config_deregisterCfgItem(CfgItem *cfgitem) +{ + cfglist.delItem(cfgitem); +} + +int api_configI::config_getNumCfgItems() +{ + return cfglist.getNumItems(); +} + +CfgItem *api_configI::config_enumCfgItem(int n) +{ + return cfglist.enumItem(n); +} + +CfgItem *api_configI::config_getCfgItemByGuid(GUID g) +{ + return cfglist.getByGuid(g); +} + +// The private config functions are currently pointing at the public config item, this is because +// only the monolithic api gets instantiated once per component and thus can know its GUID, this +// version of the config api should eventually be instantiated once per component as well when +// we start making them use the modular apis +void api_configI::setIntPrivate(const wchar_t *name, int val) +{ + public_config.setInt(name, val); +} + +int api_configI::getIntPrivate(const wchar_t *name, int def_val) +{ + int ret = public_config.getInt(name, def_val); + return ret; +} + +void api_configI::setIntArrayPrivate(const wchar_t *name, const int *val, int nval) +{ + if (nval > 256) return; + wchar_t buf[12*256]=L""; + for (int i = 0; i < nval; i++) + { + wcscat(buf, StringPrintfW(L"%d", val[i])); + if (i != nval-1) + wcscat(buf, L","); + } + public_config.setString(name, buf); +} + +int api_configI::getIntArrayPrivate(const wchar_t *name, int *val, int nval) +{ + wchar_t buf[12*256]=L""; + public_config.getString(name, buf, sizeof(buf)/sizeof(*buf), L""); + PathParserW pp(buf, L","); + if (pp.getNumStrings() != nval) return 0; + for (int i = 0; i < nval; i++) { + *val = WTOI(pp.enumString(i)); + val ++; + } + return 1; +} + +void api_configI::setStringPrivate(const wchar_t *name, const wchar_t *str) +{ + public_config.setString(name, str); +} + +int api_configI::getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str) +{ + int ret = public_config.getString(name, buf, buf_len, default_str); + return ret; +} + +int api_configI::getStringPrivateLen(const wchar_t *name) +{ + return public_config.getStringLen(name); +} + +void api_configI::setIntPublic(const wchar_t *name, int val) +{ + public_config.setInt(name, val); +} + +int api_configI::getIntPublic(const wchar_t *name, int def_val) +{ + return public_config.getInt(name, def_val); +} + +void api_configI::setStringPublic(const wchar_t *name, const wchar_t *str) +{ + public_config.setString(name, str); +} + +int api_configI::getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str) +{ + return public_config.getString(name, buf, buf_len, default_str); +} diff --git a/Src/Wasabi/api/config/api_configi.h b/Src/Wasabi/api/config/api_configi.h new file mode 100644 index 00000000..d0e5f755 --- /dev/null +++ b/Src/Wasabi/api/config/api_configi.h @@ -0,0 +1,46 @@ +#ifndef __API_CONFIG_IMPL_H +#define __API_CONFIG_IMPL_H + +/*<?<autoheader/>*/ +#include "api_config.h" +#include "api_configx.h" +#include <api/config/config.h> + +class CfgItem; +/*?>*/ + +class api_configI : public api_configX +{ +public: + api_configI(); + virtual ~api_configI(); + + DISPATCH(10) virtual void config_registerCfgItem(CfgItem *cfgitem); + DISPATCH(20) virtual void config_deregisterCfgItem(CfgItem *cfgitem); + DISPATCH(30) virtual int config_getNumCfgItems(); + DISPATCH(40) virtual CfgItem *config_enumCfgItem(int n); + DISPATCH(50) virtual CfgItem *config_getCfgItemByGuid(GUID g); + DISPATCH(60) virtual void setIntPrivate(const wchar_t *name, int val); + DISPATCH(70) virtual int getIntPrivate(const wchar_t *name, int def_val); + DISPATCH(80) virtual void setIntArrayPrivate(const wchar_t *name, const int *val, int nval); + DISPATCH(90) virtual int getIntArrayPrivate(const wchar_t *name, int *val, int nval); + DISPATCH(100) virtual void setStringPrivate(const wchar_t *name, const wchar_t *str); + DISPATCH(110) virtual int getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str); + DISPATCH(120) virtual int getStringPrivateLen(const wchar_t *name); + DISPATCH(130) virtual void setIntPublic(const wchar_t *name, int val); + DISPATCH(140) virtual int getIntPublic(const wchar_t *name, int def_val); + DISPATCH(150) virtual void setStringPublic(const wchar_t *name, const wchar_t *str); + DISPATCH(160) virtual int getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str); +private: + ConfigFile public_config; +}; + +/*[interface.footer.h] +// {470B890C-4747-4113-ABA5-A8F8F4F8AB7E} +static const GUID configApiServiceGuid = +{ 0x470b890c, 0x4747, 0x4113, { 0xab, 0xa5, 0xa8, 0xf8, 0xf4, 0xf8, 0xab, 0x7e } }; + +extern api_config *configApi; +*/ + +#endif // __API_CONFIG_IMPL_H diff --git a/Src/Wasabi/api/config/api_configx.cpp b/Src/Wasabi/api/config/api_configx.cpp new file mode 100644 index 00000000..8296023e --- /dev/null +++ b/Src/Wasabi/api/config/api_configx.cpp @@ -0,0 +1,37 @@ +// ---------------------------------------------------------------------------- +// Generated by InterfaceFactory [Thu May 15 21:06:25 2003] +// +// File : api_configx.cpp +// Class : api_config +// class layer : Dispatchable Receiver +// ---------------------------------------------------------------------------- +#include <precomp.h> + +#include "api_configx.h" +#include "api_configi.h" + +#ifdef CBCLASS +#undef CBCLASS +#endif + +#define CBCLASS api_configX +START_DISPATCH; + VCB(API_CONFIG_CONFIG_REGISTERCFGITEM, config_registerCfgItem); + VCB(API_CONFIG_CONFIG_DEREGISTERCFGITEM, config_deregisterCfgItem); + CB(API_CONFIG_CONFIG_GETNUMCFGITEMS, config_getNumCfgItems); + CB(API_CONFIG_CONFIG_ENUMCFGITEM, config_enumCfgItem); + CB(API_CONFIG_CONFIG_GETCFGITEMBYGUID, config_getCfgItemByGuid); + VCB(API_CONFIG_SETINTPRIVATE, setIntPrivate); + CB(API_CONFIG_GETINTPRIVATE, getIntPrivate); + VCB(API_CONFIG_SETINTARRAYPRIVATE, setIntArrayPrivate); + CB(API_CONFIG_GETINTARRAYPRIVATE, getIntArrayPrivate); + VCB(API_CONFIG_SETSTRINGPRIVATE, setStringPrivate); + CB(API_CONFIG_GETSTRINGPRIVATE, getStringPrivate); + CB(API_CONFIG_GETSTRINGPRIVATELEN, getStringPrivateLen); + VCB(API_CONFIG_SETINTPUBLIC, setIntPublic); + CB(API_CONFIG_GETINTPUBLIC, getIntPublic); + VCB(API_CONFIG_SETSTRINGPUBLIC, setStringPublic); + CB(API_CONFIG_GETSTRINGPUBLIC, getStringPublic); +END_DISPATCH; +#undef CBCLASS + diff --git a/Src/Wasabi/api/config/api_configx.h b/Src/Wasabi/api/config/api_configx.h new file mode 100644 index 00000000..d8594b68 --- /dev/null +++ b/Src/Wasabi/api/config/api_configx.h @@ -0,0 +1,44 @@ +// ---------------------------------------------------------------------------- +// Generated by InterfaceFactory [Thu May 15 21:06:24 2003] +// +// File : api_configx.h +// Class : api_config +// class layer : Dispatchable Receiver +// ---------------------------------------------------------------------------- + +#ifndef __API_CONFIGX_H +#define __API_CONFIGX_H + +#include "api_config.h" + +class CfgItem; +class ConfigFile; + +// ---------------------------------------------------------------------------- + +class api_configX : public api_config { + protected: + api_configX() {} + public: + virtual void config_registerCfgItem(CfgItem *cfgitem)=0; + virtual void config_deregisterCfgItem(CfgItem *cfgitem)=0; + virtual int config_getNumCfgItems()=0; + virtual CfgItem *config_enumCfgItem(int n)=0; + virtual CfgItem *config_getCfgItemByGuid(GUID g)=0; + virtual void setIntPrivate(const wchar_t *name, int val)=0; + virtual int getIntPrivate(const wchar_t *name, int def_val)=0; + virtual void setIntArrayPrivate(const wchar_t *name, const int *val, int nval)=0; + virtual int getIntArrayPrivate(const wchar_t *name, int *val, int nval)=0; + virtual void setStringPrivate(const wchar_t *name, const wchar_t *str)=0; + virtual int getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str)=0; + virtual int getStringPrivateLen(const wchar_t *name)=0; + virtual void setIntPublic(const wchar_t *name, int val)=0; + virtual int getIntPublic(const wchar_t *name, int def_val)=0; + virtual void setStringPublic(const wchar_t *name, const wchar_t *str)=0; + virtual int getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str)=0; + + protected: + RECVS_DISPATCH; +}; + +#endif // __API_CONFIGX_H diff --git a/Src/Wasabi/api/config/cfglist.cpp b/Src/Wasabi/api/config/cfglist.cpp new file mode 100644 index 00000000..b6baaab5 --- /dev/null +++ b/Src/Wasabi/api/config/cfglist.cpp @@ -0,0 +1,50 @@ +#include <precomp.h> + +#include "cfglist.h" +#include <bfc/ptrlist.h> + +void CfgList::addItem(CfgItem *cfgitem) +{ + if (cfgitem == NULL || + cfgitem->getGuid() == INVALID_GUID || + list.haveItem(cfgitem)) return; + viewer_addViewItem(cfgitem); + list.addItem(cfgitem); + + cfgitem->onRegister(); // recurses children +} + +void CfgList::delItem(CfgItem *cfgitem) +{ + if (cfgitem == NULL || !list.haveItem(cfgitem)) return; + + list.removeItem(cfgitem); + viewer_delViewItem(cfgitem); + + cfgitem->onDeregister(); // recurses children +} + +int CfgList::getNumItems() +{ + return list.getNumItems(); +} + +CfgItem *CfgList::enumItem(int n) +{ + return list[n]; +} + +CfgItem *CfgList::getByGuid(GUID g) +{ + if (g == INVALID_GUID) return NULL; + foreach(list) + if (list.getfor()->getGuid() == g) return list.getfor(); + endfor + return NULL; +} + +int CfgList::viewer_onItemDeleted(CfgItem *item) +{ + list.removeItem(item); + return 1; +} diff --git a/Src/Wasabi/api/config/cfglist.h b/Src/Wasabi/api/config/cfglist.h new file mode 100644 index 00000000..cf456ccc --- /dev/null +++ b/Src/Wasabi/api/config/cfglist.h @@ -0,0 +1,23 @@ +#ifndef _CFGLIST_H +#define _CFGLIST_H + +#include <bfc/wasabi_std.h> +#include <bfc/depview.h> +#include <api/config/items/cfgitem.h> + +class CfgList : public DependentViewerTPtr<CfgItem> { +public: + void addItem(CfgItem *cfgitem); + void delItem(CfgItem *cfgitem); + + int getNumItems(); + CfgItem *enumItem(int n); + CfgItem *getByGuid(GUID g); + + virtual int viewer_onItemDeleted(CfgItem *item); + +private: + PtrList<CfgItem> list; +}; + +#endif diff --git a/Src/Wasabi/api/config/cfgscriptobj.cpp b/Src/Wasabi/api/config/cfgscriptobj.cpp new file mode 100644 index 00000000..6d220f02 --- /dev/null +++ b/Src/Wasabi/api/config/cfgscriptobj.cpp @@ -0,0 +1,371 @@ +#include <precomp.h> +#include "cfgscriptobj.h" + +#include <api/config/items/cfgitemi.h> + +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(ConfigObject_Svc); +DECLARE_SERVICE(ScriptObjectCreator<ConfigScriptObjectSvc>); +END_SERVICES(ConfigObject_Svc, _ConfigObject_Svc); + +#ifdef _X86_ +extern "C" { int _link_ConfigObjectSvc; } +#else +extern "C" { int __link_ConfigObjectSvc; } +#endif + +#endif + +static ConfigScriptObjectController _configController; +ScriptObjectController *configController = &_configController; + +static ConfigItemScriptObjectController _configItemController; +ScriptObjectController *configItemController = &_configItemController; + +static ConfigAttributeScriptObjectController _configAttributeController; +ScriptObjectController *configAttributeController = &_configAttributeController; + + +// ----------------------------------------------------------------------------------------------------- +// Service + +ScriptObjectController *ConfigScriptObjectSvc::getController(int n) +{ + switch (n) { + case 0: + return configController; + case 1: + return configItemController; + case 2: + return configAttributeController; + } + return NULL; +} + +// ----------------------------------------------------------------------------------------------------- +// ConfigObject + +ConfigObject::ConfigObject() { + numobjects++; + getScriptObject()->vcpu_setInterface(CONFIG_SCRIPTOBJECT_GUID, (void *)static_cast<ConfigObject *>(this)); + getScriptObject()->vcpu_setClassName(L"Config"); + getScriptObject()->vcpu_setController(configController); +} + +ConfigObject::~ConfigObject() { + numobjects--; + mylist.deleteAll(); + if (numobjects == 0) { + foreach(ouraddeditems) + WASABI_API_CONFIG->config_deregisterCfgItem(ouraddeditems.getfor()); + endfor + ouraddeditems.deleteAll(); + } +} + +PtrList<CfgItemI> ConfigObject::ouraddeditems; +int ConfigObject::numobjects=0; + + +function_descriptor_struct ConfigScriptObjectController::exportedFunction[] = { + {L"getItem", 1, (void*)ConfigObject::config_getItem}, + {L"getItemByGuid", 1, (void*)ConfigObject::config_getItemByGuid}, + {L"newItem", 2, (void*)ConfigObject::config_newItem}, +}; + +int ConfigScriptObjectController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +scriptVar ConfigObject::config_newItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar configitem_name, scriptVar configitem_guid) +{ + SCRIPT_FUNCTION_INIT + ConfigObject *co = static_cast<ConfigObject*>(o->vcpu_getInterface(CONFIG_SCRIPTOBJECT_GUID)); + ConfigItemObject *ret=getItem(GET_SCRIPT_STRING(configitem_name), co); + if (!ret) + ret = getItem(GET_SCRIPT_STRING(configitem_guid), co); + if (ret) + return MAKE_SCRIPT_OBJECT(ret->getScriptObject()); + CfgItemI *item = new CfgItemI(GET_SCRIPT_STRING(configitem_name), nsGUID::fromCharW(GET_SCRIPT_STRING(configitem_guid))); + ConfigObject::ouraddeditems.addItem(item); + WASABI_API_CONFIG->config_registerCfgItem(item); + ret = new ConfigItemObject(item); + co->mylist.addItem(ret); + return MAKE_SCRIPT_OBJECT(ret->getScriptObject()); +} + +ConfigItemObject *ConfigObject::getItem(const wchar_t *nameorguid, ConfigObject *co) { + int i=0; + ConfigItemObject *ret=NULL; + GUID g = nsGUID::fromCharW(nameorguid); + for (i=0;;i++) { + CfgItem *item = WASABI_API_CONFIG->config_enumCfgItem(i); + if (!item) break; + GUID ig = item->getGuid(); + if (g == ig || WCSCASEEQLSAFE(nameorguid, item->getName())) + { + ret = new ConfigItemObject(item); + co->mylist.addItem(ret); + break; + } +#if 0//CUT + for (int j=0;j<item->getNumChildren();j++) { + if (STRCASEEQL(nameorguid, item->enumChild(j)->getName())) { + ret = new ConfigItemObject(item->enumChild(j)); + co->mylist.addItem(ret); + break; + } + } +#endif + } + return ret; +} + +scriptVar ConfigObject::config_getItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar cfgitem_name) +{ + SCRIPT_FUNCTION_INIT + ConfigObject *co = static_cast<ConfigObject*>(o->vcpu_getInterface(CONFIG_SCRIPTOBJECT_GUID)); + ConfigItemObject *ret=getItem(GET_SCRIPT_STRING(cfgitem_name), co); + return MAKE_SCRIPT_OBJECT(ret ? ret->getScriptObject() : NULL); +} + +scriptVar ConfigObject::config_getItemByGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar cfgitem_guid) +{ + SCRIPT_FUNCTION_INIT +// GUID g = nsGUID::fromChar(GET_SCRIPT_STRING(guid)); +// api-> + int i=0; + ConfigItemObject *ret=NULL; + ConfigObject *co = static_cast<ConfigObject*>(o->vcpu_getInterface(CONFIG_SCRIPTOBJECT_GUID)); + + const wchar_t *p = GET_SCRIPT_STRING(cfgitem_guid); + if (p == NULL) { + RETURN_SCRIPT_ZERO; + } + + GUID g = nsGUID::fromCharW(p); + + for (i=0;;i++) { + CfgItem *item = WASABI_API_CONFIG->config_enumCfgItem(i); + if (!item) break; + if (g == item->getGuid()) { + ret = new ConfigItemObject(item); + co->mylist.addItem(ret); + break; + } +#if 0//CUT + for (int j=0;j<item->getNumChildren();j++) { + if (g == item->enumChild(j)->getName()) { + ret = new ConfigItemObject(item->enumChild(j)); + co->mylist.addItem(ret); + break; + } + } +#endif + } + return MAKE_SCRIPT_OBJECT(ret ? ret->getScriptObject() : NULL); +} + +ScriptObject *ConfigScriptObjectController::instantiate() { + ConfigObject *c = new ConfigObject; + if (!c) return NULL; + return c->getScriptObject(); +} + +void ConfigScriptObjectController::destroy(ScriptObject *o) { + ConfigObject *obj = static_cast<ConfigObject *>(o->vcpu_getInterface(CONFIG_SCRIPTOBJECT_GUID)); + ASSERT(obj != NULL); + delete obj; +} + +void *ConfigScriptObjectController::encapsulate(ScriptObject *o) { + return NULL; // no encapsulation for config +} + +void ConfigScriptObjectController::deencapsulate(void *) { +} + +// ----------------------------------------------------------------------------------------------------- +// ConfigItem + +function_descriptor_struct ConfigItemScriptObjectController::exportedFunction[] = { + {L"getAttribute", 1, (void*)ConfigItemObject::configItem_getAttribute}, + {L"getGuid", 0, (void*)ConfigItemObject::configItem_getGuid}, + {L"newAttribute", 2, (void*)ConfigItemObject::configItem_newAttribute}, +}; + +int ConfigItemScriptObjectController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +ConfigItemObject::ConfigItemObject(CfgItem *_item) +{ + getScriptObject()->vcpu_setInterface(CONFIGITEM_SCRIPTOBJECT_GUID, (void *)static_cast<ConfigItemObject *>(this)); + getScriptObject()->vcpu_setClassName(L"ConfigItem"); + getScriptObject()->vcpu_setController(configItemController); + wchar_t strguid[256]; + nsGUID::toCharW(_item->getGuid(), strguid); + guid = strguid; + item = _item; +} + +ConfigAttributeObject *ConfigItemObject::getAttribute(const wchar_t *name) +{ + if (!item) return NULL; + for (int i=0;i<item->getNumAttributes();i++) + { + if (!WCSICMP(item->enumAttribute(i), name)) + { + ConfigAttributeObject *o = new ConfigAttributeObject(item, name, this); + mylist.addItem(o); + return o; + } + } + return NULL; +} + +ConfigAttributeObject *ConfigItemObject::newAttribute(const wchar_t *name, const wchar_t *defaultvalue) +{ + if (!item) return NULL; + ConfigAttributeObject *o = getAttribute(name); + if (o != NULL) return o; + + item->addAttribute(name, defaultvalue); + + ConfigAttributeObject *cao = getAttribute(name); + cao->setAutoDelete(); + return cao; +} + +ConfigItemObject::~ConfigItemObject() +{ + mylist.deleteAll(); +} + +scriptVar ConfigItemObject::configItem_getAttribute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name) +{ + SCRIPT_FUNCTION_INIT + ConfigItemObject *cio = static_cast<ConfigItemObject *>(o->vcpu_getInterface(CONFIGITEM_SCRIPTOBJECT_GUID)); + ConfigAttributeObject *cao = NULL; + if (cio) + cao = cio->getAttribute(GET_SCRIPT_STRING(name)); + return MAKE_SCRIPT_OBJECT(cao ? cao->getScriptObject() : NULL); +} + +scriptVar ConfigItemObject::configItem_getGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) +{ + SCRIPT_FUNCTION_INIT + ConfigItemObject *cio = static_cast<ConfigItemObject *>(o->vcpu_getInterface(CONFIGITEM_SCRIPTOBJECT_GUID)); + if (cio) return MAKE_SCRIPT_STRING(cio->getGuid()); + return MAKE_SCRIPT_STRING(L""); +} + +scriptVar ConfigItemObject::configItem_newAttribute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar name, scriptVar defval) { + SCRIPT_FUNCTION_INIT + ConfigItemObject *cio = static_cast<ConfigItemObject *>(o->vcpu_getInterface(CONFIGITEM_SCRIPTOBJECT_GUID)); + ConfigAttributeObject *cao = NULL; + if (cio) + cao = cio->newAttribute(GET_SCRIPT_STRING(name), GET_SCRIPT_STRING(defval)); + return MAKE_SCRIPT_OBJECT(cao ? cao->getScriptObject() : NULL); +} + +// ----------------------------------------------------------------------------------------------------- +// ConfigAttribute + +function_descriptor_struct ConfigAttributeScriptObjectController::exportedFunction[] = { + {L"getData", 0, (void*)ConfigAttributeObject::configAttr_getData}, + {L"setData", 1, (void*)ConfigAttributeObject::configAttr_setData}, + {L"onDataChanged", 0, (void*)ConfigAttributeObject::configAttr_onDataChanged}, + {L"getParentItem", 0, (void*)ConfigAttributeObject::configAttr_getParentItem}, + {L"getAttributeName", 0, (void*)ConfigAttributeObject::configAttr_getAttributeName}, +}; + +int ConfigAttributeScriptObjectController::getNumFunctions() { + return sizeof(exportedFunction) / sizeof(function_descriptor_struct); +} + +void ConfigAttributeObject::setData(const wchar_t *data) +{ + if (!item || !attr) return; + item->setData(attr, data); +} + +const wchar_t *ConfigAttributeObject::getData() +{ + if (!item || !attr) return NULL; + static wchar_t t[WA_MAX_PATH]; + item->getData(attr, t, WA_MAX_PATH); + return t; +} + +ConfigAttributeObject::ConfigAttributeObject(CfgItem *_item, const wchar_t *_attr, ConfigItemObject *_parent) +{ + getScriptObject()->vcpu_setInterface(CONFIGATTRIBUTE_SCRIPTOBJECT_GUID, (void *)static_cast<ConfigAttributeObject *>(this)); + getScriptObject()->vcpu_setClassName(L"ConfigAttribute"); + getScriptObject()->vcpu_setController(configAttributeController); + attr = _attr; + item = _item; + parent = _parent; + viewer_addViewItem(item); + autodelete = 0; +} + +ConfigAttributeObject::~ConfigAttributeObject() { + if (autodelete) getParentItem()->getCfgItem()->delAttribute(attr); +} + +int ConfigAttributeObject::viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen) +{ + if (event == CfgItem::Event_ATTRIBUTE_CHANGED) + { + const wchar_t *_attr = reinterpret_cast<const wchar_t *>(ptr); + if (!WCSICMP(attr, _attr)) + configAttr_onDataChanged(SCRIPT_CALL, getScriptObject()); + } + return 1; +} + +scriptVar ConfigAttributeObject::configAttr_setData(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val) +{ + SCRIPT_FUNCTION_INIT + ConfigAttributeObject *cao = static_cast<ConfigAttributeObject *>(o->vcpu_getInterface(CONFIGATTRIBUTE_SCRIPTOBJECT_GUID)); + if (cao) + cao->setData(GET_SCRIPT_STRING(val)); + RETURN_SCRIPT_VOID; +} + +scriptVar ConfigAttributeObject::configAttr_getData(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ConfigAttributeObject *cao = static_cast<ConfigAttributeObject *>(o->vcpu_getInterface(CONFIGATTRIBUTE_SCRIPTOBJECT_GUID)); + if (cao) + return MAKE_SCRIPT_STRING(cao->getData()); + return MAKE_SCRIPT_STRING(L""); +} + +scriptVar ConfigAttributeObject::configAttr_onDataChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + PROCESS_HOOKS0(o, configAttributeController); + SCRIPT_FUNCTION_CHECKABORTEVENT; + SCRIPT_EXEC_EVENT0(o); +} + +scriptVar ConfigAttributeObject::configAttr_getParentItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ConfigAttributeObject *cao = static_cast<ConfigAttributeObject *>(o->vcpu_getInterface(CONFIGATTRIBUTE_SCRIPTOBJECT_GUID)); + if (cao) return MAKE_SCRIPT_OBJECT(cao->getParentItem()->getScriptObject()); + return MAKE_SCRIPT_OBJECT(NULL); +} + +scriptVar ConfigAttributeObject::configAttr_getAttributeName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) { + SCRIPT_FUNCTION_INIT + ConfigAttributeObject *cao = static_cast<ConfigAttributeObject *>(o->vcpu_getInterface(CONFIGATTRIBUTE_SCRIPTOBJECT_GUID)); + + if (cao) + return MAKE_SCRIPT_STRING(cao->getAttributeName()); + + return MAKE_SCRIPT_STRING(L""); +} + + + diff --git a/Src/Wasabi/api/config/cfgscriptobj.h b/Src/Wasabi/api/config/cfgscriptobj.h new file mode 100644 index 00000000..e446b618 --- /dev/null +++ b/Src/Wasabi/api/config/cfgscriptobj.h @@ -0,0 +1,198 @@ +#ifndef __CFGSCRIPTOBJ_H +#define __CFGSCRIPTOBJ_H + +#include <api/script/objects/rootobj.h> +#include <api/script/objcontroller.h> +#include <api/script/scriptobj.h> +#include <bfc/depview.h> +#include <api/service/svcs/svc_scriptobji.h> +#include <api/config/items/attribs.h> + +class CfgItem; +class ConfigObject; +class ConfigItemObject; +class ConfigAttributeObject; + +extern ScriptObjectController *configController; +extern ScriptObjectController *configItemController; +extern ScriptObjectController *configAttributeController; + +enum cfgtypes { + CFG_INT = 0, + CFG_BOOL = 1, + CFG_FLOAT = 2, + CFG_STRING = 3, +}; + +// ----------------------------------------------------------------------------------------------------- +// ScriptObject Provider Service + +class ConfigScriptObjectSvc : public svc_scriptObjectI { + +public: + ConfigScriptObjectSvc() {}; + virtual ~ConfigScriptObjectSvc() {}; + + static const char *getServiceName() { return "Config maki object"; } + virtual ScriptObjectController *getController(int n); + + static void addItemObject(ConfigItemObject *item); + static void addAttrObject(ConfigAttributeObject *attr); + static void removeItemObject(ConfigItemObject *item); + static void removeAttrObject(ConfigAttributeObject *attr); +}; + +// ----------------------------------------------------------------------------------------------------- +// Script classes GUIDS + +// {593DBA22-D077-4976-B952-F4713655400B} +static const GUID CONFIG_SCRIPTOBJECT_GUID = +{ 0x593dba22, 0xd077, 0x4976, { 0xb9, 0x52, 0xf4, 0x71, 0x36, 0x55, 0x40, 0xb } }; + +// {D4030282-3AAB-4d87-878D-12326FADFCD5} +static const GUID CONFIGITEM_SCRIPTOBJECT_GUID = +{ 0xd4030282, 0x3aab, 0x4d87, { 0x87, 0x8d, 0x12, 0x32, 0x6f, 0xad, 0xfc, 0xd5 } }; + +// {24DEC283-B76E-4a36-8CCC-9E24C46B6C73} +static const GUID CONFIGATTRIBUTE_SCRIPTOBJECT_GUID = +{ 0x24dec283, 0xb76e, 0x4a36, { 0x8c, 0xcc, 0x9e, 0x24, 0xc4, 0x6b, 0x6c, 0x73 } }; + +// ----------------------------------------------------------------------------------------------------- +// ScriptObject Interfaces + +// Config +class ConfigObject : public RootObjectInstance { + + public: + + ConfigObject(); + virtual ~ConfigObject(); + + static scriptVar config_getItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar configitem_name); + static scriptVar config_getItemByGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar configitem_name); + static scriptVar config_newItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar configitem_name, scriptVar guid); + private: + static ConfigItemObject *getItem(const wchar_t *nameorguid, ConfigObject *co); + PtrList<ConfigItemObject> mylist; + static PtrList<CfgItemI> ouraddeditems; + static int numobjects; +}; + +// ConfigItem +class ConfigItemObject : public RootObjectInstance { + + public: + + ConfigItemObject(CfgItem *item); + virtual ~ConfigItemObject(); + + ConfigAttributeObject *getAttribute(const wchar_t *name); + const wchar_t *getGuid() { return guid; } + ConfigAttributeObject *newAttribute(const wchar_t *name, const wchar_t *defval); + + CfgItem *getCfgItem() { return item; } + + static scriptVar configItem_getAttribute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar attr_name); + static scriptVar configItem_getGuid(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar configItem_newAttribute(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar attr_name, scriptVar defval); + + private: + CfgItem *item; + StringW guid; + PtrList<ConfigAttributeObject> mylist; +}; + +// ConfigAttribute +class ConfigAttributeObject : public RootObjectInstance, public DependentViewerTPtr<CfgItem> { + + public: + + ConfigAttributeObject(CfgItem *item, const wchar_t *attr, ConfigItemObject *parent); + virtual ~ConfigAttributeObject(); + + void setData(const wchar_t *data); + const wchar_t *getData(); + ConfigItemObject *getParentItem() { return parent; } + const wchar_t *getAttributeName() { return attr; } + void setAutoDelete() { autodelete = 1; } + + virtual int viewer_onEvent(CfgItem *item, int event, intptr_t param, void *ptr, size_t ptrlen); + + static scriptVar configAttr_getData(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar configAttr_setData(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar val); + static scriptVar configAttr_onDataChanged(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar configAttr_getParentItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + static scriptVar configAttr_getAttributeName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o); + + private: + CfgItem *item; + StringW attr; + ConfigItemObject *parent; + int autodelete; +}; + +// ----------------------------------------------------------------------------------------------------- +// ScriptObjectControllers for our script classes + +// Config +class ConfigScriptObjectController : public ScriptObjectControllerI { + public: + virtual const wchar_t *getClassName() { return L"Config"; } + virtual const wchar_t *getAncestorClassName() { return L"Object"; } + virtual ScriptObjectController *getAncestorController() { return NULL; } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions() { return exportedFunction; } + virtual GUID getClassGuid() { return CONFIG_SCRIPTOBJECT_GUID; } + virtual int getInstantiable() { return 0; } + virtual int getReferenceable() { return 0; } + virtual ScriptObject *instantiate(); + virtual void destroy(ScriptObject *o); + virtual void *encapsulate(ScriptObject *o); + virtual void deencapsulate(void *o); + + private: + static function_descriptor_struct exportedFunction[]; +}; + +// ConfigItem +class ConfigItemScriptObjectController : public ScriptObjectControllerI { + public: + virtual const wchar_t *getClassName() { return L"ConfigItem"; } + virtual const wchar_t *getAncestorClassName() { return L"Object"; } + virtual ScriptObjectController *getAncestorController() { return NULL; } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions() { return exportedFunction; } + virtual GUID getClassGuid() { return CONFIGITEM_SCRIPTOBJECT_GUID; } + virtual int getInstantiable() { return 0; } + virtual int getReferenceable() { return 1; } + virtual ScriptObject *instantiate() { return NULL; }; + virtual void destroy(ScriptObject *o) { }; + virtual void *encapsulate(ScriptObject *o) { return NULL; }; + virtual void deencapsulate(void *o) { }; + + private: + static function_descriptor_struct exportedFunction[]; +}; + +// ConfigAttribute +class ConfigAttributeScriptObjectController : public ScriptObjectControllerI { + public: + virtual const wchar_t *getClassName() { return L"ConfigAttribute"; } + virtual const wchar_t *getAncestorClassName() { return L"Object"; } + virtual ScriptObjectController *getAncestorController() { return NULL; } + virtual int getNumFunctions(); + virtual const function_descriptor_struct *getExportedFunctions() { return exportedFunction; } + virtual GUID getClassGuid() { return CONFIGATTRIBUTE_SCRIPTOBJECT_GUID; } + virtual int getInstantiable() { return 0; } + virtual int getReferenceable() { return 1; } + virtual ScriptObject *instantiate() { return NULL; }; + virtual void destroy(ScriptObject *o) { }; + virtual void *encapsulate(ScriptObject *o) { return NULL; }; + virtual void deencapsulate(void *o) { }; + + private: + static function_descriptor_struct exportedFunction[]; +}; + +#endif + diff --git a/Src/Wasabi/api/config/config.cpp b/Src/Wasabi/api/config/config.cpp new file mode 100644 index 00000000..3b45d934 --- /dev/null +++ b/Src/Wasabi/api/config/config.cpp @@ -0,0 +1,329 @@ +#include <precomp.h> + +#include "config.h" +#include <bfc/pair.h> +#include <bfc/ptrlist.h> +#include <bfc/parse/pathparse.h> +#include <api/xml/xmlwrite.h> + +#include "../xml/ifc_xmlreadercallbackI.h" +#include "../xml/obj_xml.h" +#include <bfc/string/url.h> +#include <api/service/waservicefactory.h> + +static StringW iniFile; +#define XNFNAME L"studio.xnf" + +class StringPairCompare +{ +public: + static int compareItem(StringPair *p1, StringPair *p2) + { + int r = wcscmp(p1->a.getValue(), p2->a.getValue()); + if (r == 0) + return CMP3(p1, p2); + else + return r; + } + static int compareAttrib(const wchar_t *attrib, StringPair *item) + { + return wcscmp(attrib, item->a.getValue()); + } +}; + +static PtrListQuickSorted<StringPair, StringPairCompare> strings; + +class Reader : public ifc_xmlreadercallbackI +{ +public: + ~Reader(); + void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params); + void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag); + + void readem(); + +private: + PtrList<StringW> sections; +}; + +Reader::~Reader() +{ + sections.deleteAll(); +} + +void Reader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params) +{ + if (!WCSICMP(xmltag, L"section")) + { + const wchar_t *name = params->getItemValue(L"name"); + if (name == NULL) + return ; + + StringW *strName = new StringW(name); + Url::decode(*strName); + sections.addItem(strName); + } + else if (!WCSICMP(xmltag, L"entry")) + { + const wchar_t *name = params->getItemValue(L"name"); + const wchar_t *value = params->getItemValue(L"value"); + + // just in case + if (!WCSICMP(name, L"(null)")) name = NULL; + if (!WCSICMP(value, L"(null)")) value = NULL; + + if (name == NULL /*| !*name */ || value == NULL /*|| !*value*/) return ; + StringW strName = name; + Url::decode(strName); + + StringW strValue = value; + Url::decode(strValue); + + StringW n; + for (int i = 0; i < sections.getNumItems(); i++) + { + n.catPostSeparator(*sections[i], '/'); + } + n += strName; + + StringPair *p = new StringPair(n, strValue); + strings.addItem(p); + } +} + +void Reader::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag) +{ + if (!WCSICMP(xmltag, L"section")) + { + StringW *last = sections.getLast(); + sections.removeLastItem(); + delete last; + } +} + +void LoadXmlFile(obj_xml *parser, const wchar_t *filename); + +void Reader::readem() +{ + strings.deleteAll(); + + if (iniFile.isempty()) + { + iniFile = StringPathCombine(WASABI_API_APP->path_getUserSettingsPath(), XNFNAME); + } + + waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID); + if (parserFactory) + { + obj_xml *parser = (obj_xml *)parserFactory->getInterface(); + + if (parser) + { + + parser->xmlreader_registerCallback(L"WinampXML\fconfiguration\f*", this); + parser->xmlreader_registerCallback(L"WasabiXML\fconfiguration\f*", this); + parser->xmlreader_open(); + LoadXmlFile(parser, iniFile); + + parser->xmlreader_unregisterCallback(this); + parser->xmlreader_close(); + parserFactory->releaseInterface(parser); + parser = 0; + } + } +} + +StringPair *ConfigFile::getPair(const wchar_t *name) +{ + ASSERT(!sectionname.isempty()); + StringW nname; + nname.catPostSeparator(sectionname.getValue(), '/'); + nname.cat(name); + return strings.findItem(nname.getValue()); // cast to make PtrListSorted happy +} + +StringPair *ConfigFile::makePair(const wchar_t *name, const wchar_t *value) +{ + StringPair *ret = getPair(name); + if (ret == NULL) + { + StringW nname; + nname.catPostSeparator(sectionname.getValue(), '/'); + nname.cat(name); + + ret = new StringPair(nname, value); + strings.addItem(ret); + } + else + { + ret->b.setValue(value); + } + return ret; +} + +static int ninstances, inited; + +ConfigFile::ConfigFile(const wchar_t *section, const wchar_t *name) +{ + sectionname = section; + prettyname = name; + ninstances++; +} + +void ConfigFile::initialize() +{ + Reader().readem(); +} + +ConfigFile::~ConfigFile() +{ + ninstances--; + if (ninstances == 0) + { + FILE *fp = _wfopen(iniFile, WF_WRITE_TEXT); + if (fp != NULL) + { + // write out the file + XMLWrite xml(fp, L"WasabiXML"); + const wchar_t *app = WASABI_API_APP->main_getVersionString(); + if (!app) + app = L"thousands of irascible butt monkeys"; + xml.comment(StringPrintfW(L"Generated by: %s (%d)", app, WASABI_API_APP->main_getBuildNumber())); + xml.pushCategory(L"configuration"); + + PtrList<StringW> cats; + + for (int i = 0; i < strings.getNumItems(); i++) + { + StringPair *p = strings[i]; + PathParserW pp(p->a); + + int climit = MIN(pp.getNumStrings() - 1, cats.getNumItems()); + int j; + for (j = 0; j < climit; j++) + { + if (WCSICMP(*cats[j], pp.enumString(j))) + { + climit = j; + break; + } + } + + while (cats.getNumItems() > climit) + { + StringW *s = cats.getLast(); + xml.popCategory(); + cats.removeLastItem(); + delete s; + } + for (j = climit; j < pp.getNumStrings() - 1; j++) + { + StringW *s = cats.addItem(new StringW(pp.enumString(j))); + xml.pushCategoryAttrib(L"section"); + StringW enc = *s; + Url::encode(enc, FALSE, URLENCODE_EXCLUDE_ABOVEEQ32); + xml.writeCategoryAttrib(L"name", enc); + xml.closeCategoryAttrib(); + } + + xml.pushCategoryAttrib(L"entry", TRUE); + StringW enc = pp.getLastString(); + Url::encode(enc, FALSE, URLENCODE_EXCLUDE_ABOVEEQ32); + xml.writeCategoryAttrib(L"name", enc); + enc = p->b; + Url::encode(enc, FALSE, URLENCODE_EXCLUDE_ABOVEEQ32); + if (enc.iscaseequal(L"(null)") || enc.getValue() == NULL) + enc.setValue(L""); + xml.writeCategoryAttrib(L"value", enc); + xml.closeCategoryAttrib(); + xml.popCategory(); + } + + while (xml.popCategory()) ; + + strings.deleteAll(); + fclose(fp); + } // fp != NULL + } // ninstances==0 +} + +int verifyName(const wchar_t *str) +{ + for (const wchar_t *p = str; *p; p++) + { + if (!ISALPHA(*p) && + !ISDIGIT(*p) && + !ISPUNCT(*p) && + !ISSPACE(*p) && + *p != '|' && *p != '_') + return 0; + } + return 1; +} + +void ConfigFile::setInt(const wchar_t *name, int val) +{ + INCRITICALSECTION(cs); + if (name == NULL) return ; + if (!verifyName(name)) + { + DebugStringW(L"illegal name given\n"); + //__asm { int 3 }; + return ; + } + makePair(name, StringPrintfW(val)); +} + +int ConfigFile::getInt(const wchar_t *name, int def_val) +{ + INCRITICALSECTION(cs); + if (name == NULL) return def_val; + StringPair *p = getPair(name); + if (p == NULL) return def_val; + return WTOI(p->b.getValue()); +} + +void ConfigFile::setString(const wchar_t *name, const wchar_t *str) +{ + INCRITICALSECTION(cs); + if (name == NULL) return ; + if (!verifyName(name)) + { + DebugStringW(L"illegal name given\n"); + return ; + } + if (str == NULL) + { + StringPair *p = getPair(name); + if (p != NULL) + { + strings.delItem(p); + delete p; + return ; + } + } + makePair(name, str); +} + +int ConfigFile::getString(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *def_str) +{ + INCRITICALSECTION(cs); + if (name == NULL || buf == NULL) return -1; + if (def_str == NULL) + def_str = L""; + StringPair *p = getPair(name); + if (p == NULL) + WCSCPYN(buf, def_str, buf_len); + else + WCSCPYN(buf, p->b.getValueSafe(), buf_len); + return 1; +} + +int ConfigFile::getStringLen(const wchar_t *name) +{ + INCRITICALSECTION(cs); + if (name == NULL) return -1; + StringPair *p = getPair(name); + if (p == NULL) return -1; + return wcslen(p->b.getValue()); +} diff --git a/Src/Wasabi/api/config/config.h b/Src/Wasabi/api/config/config.h new file mode 100644 index 00000000..0f027b61 --- /dev/null +++ b/Src/Wasabi/api/config/config.h @@ -0,0 +1,43 @@ +#ifndef _CONFIG_H +#define _CONFIG_H + +#include <bfc/string/bfcstring.h> +#include <bfc/pair.h> +#include <bfc/critsec.h> +#include <bfc/string/StringW.h> + +class StringPair : public Pair<StringW, StringW> +{ +public: + StringPair(StringW &_a, const wchar_t *_b) + { + b=_b; + a.swap(_a); + } +}; + +class ConfigFile +{ +public: + ConfigFile(const wchar_t *section, const wchar_t *name); + ~ConfigFile(); + + static void initialize(); + + void setInt(const wchar_t *name, int val); + int getInt(const wchar_t *name, int default_val); + + void setString(const wchar_t *name, const wchar_t *str); + int getString(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str); + + int getStringLen(const wchar_t *name); + +private: + StringW sectionname; + StringW prettyname; + StringPair *getPair(const wchar_t *name); + StringPair *makePair(const wchar_t *name, const wchar_t *value); + CriticalSection cs; +}; + +#endif diff --git a/Src/Wasabi/api/config/configapi.cpp b/Src/Wasabi/api/config/configapi.cpp new file mode 100644 index 00000000..e66e00f8 --- /dev/null +++ b/Src/Wasabi/api/config/configapi.cpp @@ -0,0 +1,95 @@ +#include "precomp.h" +#include "configapi.h" +#include "../../studio/config.h" + +#include "../../studio/cfglist.h" + +config_api *configApi = NULL; + +static CfgList cfglist; + +void ConfigApi::config_registerCfgItem(CfgItem *cfgitem) { + cfglist.addItem(cfgitem); +} + +void ConfigApi::config_deregisterCfgItem(CfgItem *cfgitem) { + cfglist.delItem(cfgitem); +} + +int ConfigApi::config_getNumCfgItems() { + return cfglist.getNumItems(); +} + +CfgItem *ConfigApi::config_enumCfgItem(int n) { + return cfglist.enumItem(n); +} + +CfgItem *ConfigApi::config_getCfgItemByGuid(GUID g) { + return NULL;//cfglist.getByGuid(g); +} + +void ConfigApi::setIntPrivate(const char *name, int val) { + //config->setInt(name, val); +} + +int ConfigApi::getIntPrivate(const char *name, int def_val) { +/* int ret = config->getInt(name, def_val); + return ret;*/ + return 0; +} + +void ConfigApi::setIntArrayPrivate(const char *name, const int *val, int nval) { + /*if (nval > 256) return; + char buf[12*256]=""; + for (int i = 0; i < nval; i++) { + STRCAT(buf, StringPrintf("%d", val[i])); + if (i != nval-1) STRCAT(buf, ","); + } + config->setString(name, buf);*/ +} + +int ConfigApi::getIntArrayPrivate(const char *name, int *val, int nval) { +/* char buf[12*256]=""; + config->getString(name, buf, sizeof(buf), ""); + PathParser pp(buf, ","); + if (pp.getNumStrings() != nval) return 0; + for (int i = 0; i < nval; i++) { + *val = ATOI(pp.enumString(i)); + val ++; + } + return 1;*/ + return 1; +} + +void ConfigApi::setStringPrivate(const char *name, const char *str) { + //config->setString(name, str); +} + +int ConfigApi::getStringPrivate(const char *name, char *buf, int buf_len, const char *default_str) { +/* int ret = config->getString(name, buf, buf_len, default_str); + return ret;*/ + return 0; +} + +int ConfigApi::getStringPrivateLen(const char *name) { + //return config->getStringLen(name); + return 0; +} + +void ConfigApi::setIntPublic(const char *name, int val) { + //public_config->setInt(name, val); +} + +int ConfigApi::getIntPublic(const char *name, int def_val) { + //return public_config->getInt(name, def_val); + return 0; +} + +void ConfigApi::setStringPublic(const char *name, const char *str) { +// public_config->setString(name, str); +} +int ConfigApi::getStringPublic(const char *name, char *buf, int buf_len, const char *default_str) { +// return public_config->getString(name, buf, buf_len, default_str); + return 0; +} + diff --git a/Src/Wasabi/api/config/configapi.h b/Src/Wasabi/api/config/configapi.h new file mode 100644 index 00000000..2ea59f46 --- /dev/null +++ b/Src/Wasabi/api/config/configapi.h @@ -0,0 +1,32 @@ +#ifndef __CONFIG_API_H +#define __CONFIG_API_H + +#include "../../bfc/api/api_configi.h" + +class ConfigApi : public config_apiI { + public: + ConfigApi() {} + virtual ~ConfigApi() {} + + virtual void config_registerCfgItem(CfgItem *cfgitem); + virtual void config_deregisterCfgItem(CfgItem *cfgitem); + virtual int config_getNumCfgItems(); + virtual CfgItem *config_enumCfgItem(int n); + virtual CfgItem *config_getCfgItemByGuid(GUID g); + virtual void setIntPrivate(const wchar_t *name, int val); + virtual int getIntPrivate(const wchar_t *name, int def_val); + virtual void setIntArrayPrivate(const wchar_t *name, const int *val, int nval); + virtual int getIntArrayPrivate(const wchar_t *name, int *val, int nval); + virtual void setStringPrivate(const wchar_t *name, const wchar_t *str); + virtual int getStringPrivate(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str); + virtual int getStringPrivateLen(const wchar_t *name); + virtual void setIntPublic(const wchar_t *name, int val); + virtual int getIntPublic(const wchar_t *name, int def_val); + virtual void setStringPublic(const wchar_t *name, const wchar_t *str); + virtual int getStringPublic(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *default_str); + + protected: +}; + + +#endif diff --git a/Src/Wasabi/api/config/filetypes.cpp b/Src/Wasabi/api/config/filetypes.cpp new file mode 100644 index 00000000..20298b99 --- /dev/null +++ b/Src/Wasabi/api/config/filetypes.cpp @@ -0,0 +1,576 @@ +#include "precomp.h" +#include "filetypes.h" +#include "api.h" +#include "main.h" +#include "core.h" + +#include <bfc/attribs/attribs.h> +#include <bfc/attribs/attrcb.h> + +#include "../common/locales.h" +#include "../bfc/paramparser.h" + +// {DB26AA7F-0CF4-4e48-8AC8-49F9B9855A98} +static const GUID winampa_guid = +{ 0xdb26aa7f, 0xcf4, 0x4e48, { 0x8a, 0xc8, 0x49, 0xf9, 0xb9, 0x85, 0x5a, 0x98 } }; + +class Filetypes; + +class ExtensionAttrCallback : public AttrCallback { +public: + ExtensionAttrCallback(const char *extname, Filetypes *ft) : ext(extname), filetypes(ft) {} + virtual void onValueChange(Attribute *attr) { + Filetypes::registerExtension(ext, attr->getValueAsInt()); + api->cmd_sendCommand(winampa_guid,"extchange",0,0,attr,sizeof(attr)); // CT> notifies winampa.wac of the change + // (dunno if there is a better method) + filetypes->updateKeepers(); + } +private: + String ext; + Filetypes *filetypes; +}; + +class KeepersCB : public AttrCallback { +public: + KeepersCB(CfgItemI *_par) : par(_par) { } + virtual void onValueChange(Attribute *attr) { + //CT> This is REAL SLOW, for each attribute modified, you reregister them all, this needs to have + // an old list and just register/unregister what's new + char bufero[WA_MAX_PATH]=""; + char data[WA_MAX_PATH]=""; + attr->getData(bufero, WA_MAX_PATH-1); + ParamParser pp(bufero); + const char *ext=api->core_getSupportedExtensions(); + const char *p=ext; + while(*p!=0 && *(p+1)!=0) { + if(*p) { + int v = !!pp.hasString(p); + int r = par->cfgitem_getData(StringPrintf("extension/%s", p), data, WA_MAX_PATH-1); + if (r == 0 || (!!ATOI(data) != v)) { + par->cfgitem_setData(StringPrintf("extension/%s", p), StringPrintf(v)); + } + } + while(*p!=0) p++; + p++; + } + } +private: + CfgItemI *par; +}; + +#ifdef WIN32 +static void DCM_cb(int v) { + if (v) { + HKEY mp3Key; + char programname[MAX_PATH]; + GetModuleFileName(Main::gethInstance(),programname,sizeof(programname)); + if (RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Play",&mp3Key) == ERROR_SUCCESS) { + const char *str=_("&Play in Winamp"); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,(unsigned char*)str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Play\\command",&mp3Key) == ERROR_SUCCESS) { + StringPrintf mstr("\"%s\" \"%%1\"", programname); + const char *blah = mstr; + const unsigned char *microsoft_sucks_ass = (const unsigned char*)blah; + RegSetValueEx(mp3Key, NULL,0,REG_SZ,microsoft_sucks_ass,mstr.len() + 1); + RegCloseKey(mp3Key); + } + + if (RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Enqueue",&mp3Key) == ERROR_SUCCESS) { + const char *str=_("&Enqueue in Winamp"); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,(unsigned char*)str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Enqueue\\command",&mp3Key) == ERROR_SUCCESS) { + StringPrintf mstr("\"%s\" /ADD \"%%1\"", programname); + const char *blah = mstr; + const unsigned char *microsoft_sucks_ass = (const unsigned char*)blah; + RegSetValueEx(mp3Key, NULL,0,REG_SZ,microsoft_sucks_ass,mstr.len() + 1); + RegCloseKey(mp3Key); + } + } else { + Filetypes::myRegDeleteKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Play"); + Filetypes::myRegDeleteKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Directory\\shell\\Winamp3.Enqueue"); + } +} +#endif + +// {C30C97E6-77E6-4da4-9F4F-C7F848F8F641} +const GUID filetypes_guid = +{ 0xc30c97e6, 0x77e6, 0x4da4, { 0x9f, 0x4f, 0xc7, 0xf8, 0x48, 0xf8, 0xf6, 0x41 } }; + +Filetypes::Filetypes() : CfgItemI("Filetypes", filetypes_guid) { } + +void Filetypes::registerAttributes() { + const char *ext=api->core_getSupportedExtensions(); + if (ext == NULL) return; //BU + + _bool *wantExtensions; + registerAttribute(wantExtensions = new _bool("Register associations on Winamp startup", TRUE)); + + const char *p=ext; + while(*p!=0 && *(p+1)!=0) { + if(*p) { + _bool *extenabled; + registerAttribute(extenabled = new _bool(StringPrintf("extension/%s", p), FALSE), new ExtensionAttrCallback(p, this)); + if (*wantExtensions) registerExtension(p, *extenabled); + } while(*p!=0) p++; + p++; + } + + registerAttribute(new _string("keepers"), new KeepersCB(this)); + +#ifdef WIN32 + registerAttribute(new _bool("Directory context menus", TRUE), new int_attrCB(DCM_cb)); +#endif + + // Always steal the ".wal" extension. + CfgItem *cift=WASABI_API_CONFIG->config_getCfgItemByGuid(filetypes_guid); + if (cift) { + cift->setDataAsInt("extension/wal",1); + } + + updateKeepers(); +} + +void Filetypes::updateKeepers() { + static int reentry=0; + if (reentry) return; + const char *ext=api->core_getSupportedExtensions(); + if (ext == NULL) return; //BU + + reentry = 1; + const char *p=ext; + String kstr; + while(*p!=0 && *(p+1)!=0) { + if(*p) { + _bool *extenabled = static_cast<_bool *>(getAttributeByName(StringPrintf("extension/%s", p))); + if (*extenabled) { + if (!kstr.isempty()) kstr += ";"; + kstr += p; + } + } while(*p!=0) p++; + p++; + } + _string *k = static_cast<_string *>(getAttributeByName("keepers")); + k->setValue(kstr); + reentry = 0; +} + +LONG Filetypes::myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey) +{ +#ifdef WIN32 + HKEY key; + int retval=RegOpenKey(thiskey,lpSubKey,&key); + if (retval==ERROR_SUCCESS) + { + char buffer[1024]; + while (RegEnumKey(key,0,buffer,1024)==ERROR_SUCCESS) + if ((retval=myRegDeleteKeyEx(key,buffer)) != ERROR_SUCCESS) break; + RegCloseKey(key); + retval=RegDeleteKey(thiskey,lpSubKey); + } + return retval; +#else + DebugString( "portme -- Filetypes::myRegDeleteKeyEx\n" ); + return 0; +#endif +} + +int Filetypes::isRegistered(const char *ext) { + char b[256]; + int rval=0; + unsigned long vt,s=sizeof(b); + HKEY key; + SPRINTF(b,".%s",ext); +#ifdef WIN32 + if (RegOpenKey(HKEY_CLASSES_ROOT,b,&key) != ERROR_SUCCESS) return 0; + if (RegQueryValueEx(key,NULL,0,&vt,b,&s) == ERROR_SUCCESS) { + if (vt != REG_SZ || (strcmp(b,"Winamp3.File") && strcmp(b,"Winamp3.PlayList") && strcmp(b,"Winamp3.SkinZip"))) rval=0; + else rval=1; + } else rval=0; + RegCloseKey(key); +#else +DebugString( "portme -- FileTypes::isRegistered\n" ); +#endif + return rval; +} + +void Filetypes::regmimetype(const char *mtype, const char *programname, const char *ext, int nsonly) { +#ifdef WIN32 + HKEY mp3Key; + if (!nsonly) { + char s[MAX_PATH]; + // Changed these to create rather than just open the mimetypes in the database. + if (RegCreateKey(HKEY_CLASSES_ROOT,ext,&mp3Key) == ERROR_SUCCESS) { + RegSetValueEx(mp3Key,"Content Type",0,REG_SZ,mtype,STRLEN(mtype) + 1); + RegCloseKey(mp3Key); + } + wsprintf(s,"MIME\\Database\\Content Type\\%s",mtype); + if (RegCreateKey(HKEY_CLASSES_ROOT,s,&mp3Key) == ERROR_SUCCESS) { + RegDeleteValue(mp3Key,"CLSID"); + RegSetValueEx(mp3Key,"Extension",0,REG_SZ,ext,strlen(ext) + 1); + RegCloseKey(mp3Key); + } + } + if (RegOpenKey(HKEY_CURRENT_USER,"Software\\Netscape\\Netscape Navigator\\Viewers",&mp3Key) == ERROR_SUCCESS) { + int x; + RegSetValueEx(mp3Key, mtype,0,REG_SZ,programname,strlen(programname) + 1); + for (x = 0; x < 999; x ++) { + char st[100]; + DWORD vt; + DWORD s=128; + char b[128]; + wsprintf(st,"TYPE%d",x); + if (RegQueryValueEx(mp3Key,st,0,&vt,b,&s) == ERROR_SUCCESS) { + if (!strcmp(b,mtype)) break; + } else { + RegSetValueEx(mp3Key,st,0,REG_SZ,mtype,strlen(mtype)+1); + break; + } + } + RegCloseKey(mp3Key); + } +#else +DebugString( "portme -- Filetypes::regmimetype\n" ); +#endif +} + +void Filetypes::registerExtension(const char *ext, int reg) { +#ifdef WIN32 + createWinampTypes(); + + char b[128]; + HKEY mp3Key; + char *which_str="Winamp3.File"; + + if (!_stricmp(ext,"m3u") || !_stricmp(ext,"pls")) which_str="Winamp3.PlayList"; + if (!_stricmp(ext,"wsz") || !_stricmp(ext,"wpz") || !_stricmp(ext,"wal")) + which_str="Winamp3.SkinZip"; + wsprintf(b,".%s",ext); + if (reg && !_stricmp(ext,"pls")) { + char programname[MAX_PATH]; + GetModuleFileName(Main::gethInstance(),programname,sizeof(programname)); + regmimetype("audio/x-scpls", programname,".pls",1); + regmimetype("audio/scpls", programname,".pls",1); + } + if (reg && !_stricmp(ext,"wma")) { + char programname[MAX_PATH]; + GetModuleFileName(Main::gethInstance(),programname,sizeof(programname)); + regmimetype("audio/x-ms-wma", programname,".wma",1); + regmimetype("application/x-msdownload", programname,".wma",1); + } + if (reg && !_stricmp(ext,"m3u")) { + char programname[MAX_PATH]; + GetModuleFileName(Main::gethInstance(),programname,sizeof(programname)); + regmimetype("audio/x-mpegurl", programname,".m3u",1); + regmimetype("audio/mpegurl", programname,".m3u",1); + } + if (reg && !_stricmp(ext,"mp3")) { + char programname[MAX_PATH]; + GetModuleFileName(Main::gethInstance(),programname,sizeof(programname)); + regmimetype("audio/x-mpeg", programname,".mp3",1); + regmimetype("audio/x-mp3", programname,".mp3",1); + regmimetype("audio/x-mpg", programname,".mp3",1); + regmimetype("audio/mp3", programname,".mp3",1); + regmimetype("audio/mpg", programname,".mp3",1); + regmimetype("audio/mpeg", programname,".mp3",1); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,b,&mp3Key) == ERROR_SUCCESS) { + if (reg) { + unsigned long s=sizeof(b); + if (RegQueryValueEx(mp3Key,NULL,0,NULL,b,&s) == ERROR_SUCCESS) { + if (strcmp(b,which_str)) { + RegSetValueEx(mp3Key,"Winamp_Back",0,REG_SZ,b,strlen(b)+1); + RegSetValueEx(mp3Key,NULL,0,REG_SZ,which_str,strlen(which_str)+1); + } + } else RegSetValueEx(mp3Key,NULL,0,REG_SZ,which_str,strlen(which_str)+1); + } else { + unsigned long s=sizeof(b); + if (RegQueryValueEx(mp3Key,NULL,0,NULL,b,&s) == ERROR_SUCCESS) { + if (!strcmp(b,which_str)) { + s=sizeof(b); + if (RegQueryValueEx(mp3Key,"Winamp_Back",0,NULL,b,&s) == ERROR_SUCCESS) { + if (RegSetValueEx(mp3Key, NULL,0,REG_SZ,b,strlen(b)+1) == ERROR_SUCCESS) + RegDeleteValue(mp3Key,"Winamp_Back"); + } else { + RegDeleteValue(mp3Key,NULL); + RegCloseKey(mp3Key); + mp3Key=NULL; + wsprintf(b,".%s",ext); + myRegDeleteKeyEx(HKEY_CLASSES_ROOT,b); + } + } + } + } + if (mp3Key) RegCloseKey(mp3Key); + } +#else +DebugString( "portme -- Filetypes::registerExtensions\n" ); +#endif +} + +void Filetypes::createWinampTypes() { +#ifdef WIN32 + HKEY mp3Key; + char programname[MAX_PATH]; + char str[MAX_PATH+32]; + char buf[128]="Winamp3.File"; + char buf2[128]="Winamp3.PlayList"; + char buf3[128]="Winamp3.SkinZip"; + if (!GetModuleFileName(Main::gethInstance(),programname,sizeof(programname))) return; + + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File",&mp3Key) == ERROR_SUCCESS) { + strcpy(str,"Winamp media file"); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1); + RegCloseKey(mp3Key); + } + + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\DefaultIcon",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"%s,%d",programname,whichicon); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell",&mp3Key) == ERROR_SUCCESS) { + if (addtolist) + RegSetValueEx(mp3Key, NULL,0,REG_SZ,"Enqueue",8); + else + RegSetValueEx(mp3Key, NULL,0,REG_SZ,"Play",5); + RegCloseKey(mp3Key); + } + + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\Play",&mp3Key) == ERROR_SUCCESS) { + const char *str=_("&Play in Winamp"); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\Play\\command",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"\"%s\" \"%%1\"",programname); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\open",&mp3Key) == ERROR_SUCCESS) { + RegSetValueEx(mp3Key, NULL,0,REG_SZ,"",1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\open\\command",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"\"%s\" \"%%1\"",programname); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\Enqueue",&mp3Key) == ERROR_SUCCESS) { + const char *str=_("&Enqueue in Winamp"); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\Enqueue\\command",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"\"%s\" /ADD \"%%1\"",programname); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\ListBookmark",&mp3Key) == ERROR_SUCCESS) { + const char *str=_("Add to Winamp's &Bookmark list"); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.File\\shell\\ListBookmark\\command",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"\"%s\" /BOOKMARK \"%%1\"",programname); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.Playlist",&mp3Key) == ERROR_SUCCESS) { + strcpy(str,"Winamp playlist file"); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1); + str[0]=0; + str[1]=0; + str[2]=1; + str[3]=0; + RegSetValueEx(mp3Key, "EditFlags",0,REG_BINARY,str,4); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\DefaultIcon",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"%s,%d",programname,whichicon2); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell",&mp3Key) == ERROR_SUCCESS) { + if (addtolist) + RegSetValueEx(mp3Key, NULL,0,REG_SZ,"Enqueue",8); + else + RegSetValueEx(mp3Key, NULL,0,REG_SZ,"Play",5); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\Play",&mp3Key) == ERROR_SUCCESS) { + const char *str=_("&Play in Winamp"); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\Play\\command",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"\"%s\" \"%%1\"",programname); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\open",&mp3Key) == ERROR_SUCCESS) { + RegSetValueEx(mp3Key, NULL,0,REG_SZ,"",1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\open\\command",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"\"%s\" \"%%1\"",programname); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\Enqueue",&mp3Key) == ERROR_SUCCESS) { + const char *str=_("&Enqueue in Winamp"); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\Enqueue\\command",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"\"%s\" /ADD \"%%1\"",programname); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\ListBookmark",&mp3Key) == ERROR_SUCCESS) { + const char *str=_("Add to Winamp's &Bookmark list"); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.PlayList\\shell\\ListBookmark\\command",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"\"%s\" /BOOKMARK \"%%1\"",programname); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip",&mp3Key) == ERROR_SUCCESS) { + strcpy(str,"Winamp3 skin file"); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1); + str[0]=0; + str[1]=0; + str[2]=1; + str[3]=0; + RegSetValueEx(mp3Key, "EditFlags",0,REG_BINARY,str,4); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\DefaultIcon",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"%s,%d",programname,whichicon); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str)+1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\shell",&mp3Key) == ERROR_SUCCESS) { + RegSetValueEx(mp3Key, NULL,0,REG_SZ,"Install and switch to",8); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\shell\\install",&mp3Key) == ERROR_SUCCESS) { + RegSetValueEx(mp3Key, NULL,0,REG_SZ,"",1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\shell\\install\\command",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"\"%s\" \"/installskin=%%1\"",programname); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\shell\\open",&mp3Key) == ERROR_SUCCESS) { + RegSetValueEx(mp3Key, NULL,0,REG_SZ,"",1); + RegCloseKey(mp3Key); + } + if (RegCreateKey(HKEY_CLASSES_ROOT,"Winamp3.SkinZip\\shell\\open\\command",&mp3Key) == ERROR_SUCCESS) { + wsprintf(str,"\"%s\" \"/installskin=%%1\"",programname); + RegSetValueEx(mp3Key, NULL,0,REG_SZ,str,strlen(str) + 1); + RegCloseKey(mp3Key); + } + + // Register the mimetypes to act like .wal files? + +// regmimetype("interface/x-winamp-skin", programname,".wsz",0); + regmimetype("interface/x-winamp-skin", programname,".wal",0); +// regmimetype("interface/x-winamp3-skin", programname,".wsz",0); + regmimetype("interface/x-winamp3-skin", programname,".wal",0); +// regmimetype("application/x-winamp-plugin", programname,"wpz",0); +#else +DebugString( "portme -- Filetypes::createWinampTypes\n" ); +#endif +} + +int Filetypes::isCdPlayer() { + int r=0; +#ifdef WIN32 + unsigned long s; + HKEY mp3Key; + char buf[MAX_PATH],buf2[MAX_PATH]="\""; + if (!GetModuleFileName(Main::gethInstance(),buf2+1,sizeof(buf2)-8)) return 0; + if (RegOpenKey(HKEY_CLASSES_ROOT,"AudioCD\\shell\\play\\command",&mp3Key) != ERROR_SUCCESS) return 0; + strcat(buf2,"\" /CDA:%1"); + s=sizeof(buf); + if (RegQueryValueEx(mp3Key,NULL,0,NULL,buf,&s) == ERROR_SUCCESS) + { + if (!lstrcmpi(buf,buf2)) r=1; + } + RegCloseKey(mp3Key); +#else +DebugString( "portme -- Filetypes::isCdPlayer\n" ); +#endif + return r; +} + +void Filetypes::registerCdPlayer(int reg) { +#ifdef WIN32 + char b[MAX_PATH]; + char buf2[MAX_PATH]="\""; + HKEY mp3Key; + if (!GetModuleFileName(Main::gethInstance(),buf2+1,sizeof(buf2)-8)) return; + strcat(buf2,"\" /CDA:%1"); + if (RegOpenKey(HKEY_CLASSES_ROOT,"AudioCD\\shell\\play\\command",&mp3Key) == ERROR_SUCCESS) + { + if (reg) + { + unsigned long s=sizeof(b); + if (RegQueryValueEx(mp3Key,NULL,0,NULL,b,&s) == ERROR_SUCCESS) + { + if (_stricmp(b,buf2)) + { + char buf3[MAX_PATH]; + unsigned long st=sizeof(buf3); + if (RegQueryValueEx(mp3Key,"Winamp_Back",0,NULL,buf3,&st) != ERROR_SUCCESS || + _stricmp(buf3,b)) + { + RegSetValueEx(mp3Key,"Winamp_Back",0,REG_SZ,b,strlen(b)+1); + } + RegSetValueEx(mp3Key,NULL,0,REG_SZ,buf2,strlen(buf2)+1); + } + } else RegSetValueEx(mp3Key,NULL,0,REG_SZ,buf2,strlen(buf2)+1); + } + else + { + unsigned long s=sizeof(b); + if (RegQueryValueEx(mp3Key,NULL,0,NULL,b,&s) == ERROR_SUCCESS) + { + if (!strcmp(b,buf2)) + { + s=sizeof(b); + if (RegQueryValueEx(mp3Key,"Winamp_Back",0,NULL,b,&s) == ERROR_SUCCESS) + { + if (!_stricmp(b,buf2)) b[0]=0; + if (RegSetValueEx(mp3Key, NULL,0,REG_SZ,b,strlen(b)+1) == ERROR_SUCCESS) + RegDeleteValue(mp3Key,"Winamp_Back"); + } + else + { + buf2[0]=0; + RegSetValueEx(mp3Key,NULL,0,REG_SZ,buf2,strlen(buf2)+1); + } + } + } + } + RegCloseKey(mp3Key); + } +#else +DebugString( "portme -- Filetypes::isCdPlayer\n" ); +#endif +} + +int Filetypes::whichicon=1; +int Filetypes::whichicon2=1; +int Filetypes::addtolist=0; diff --git a/Src/Wasabi/api/config/filetypes.h b/Src/Wasabi/api/config/filetypes.h new file mode 100644 index 00000000..4d7e6891 --- /dev/null +++ b/Src/Wasabi/api/config/filetypes.h @@ -0,0 +1,46 @@ +#ifndef _FILETYPES_H +#define _FILETYPES_H + +#include <api/config/items/cfgitemi.h> + +#define FILETYPES_PARENT CfgItemI +class Filetypes : public FILETYPES_PARENT { +public: + Filetypes(); + void registerAttributes(); + + static int isRegistered(const char *ext); + static void registerExtension(const char *ext, int reg); + static int isCdPlayer(); + static void registerCdPlayer(int reg); + + void updateKeepers(); + +private: + + static void createWinampTypes(); + static void regmimetype(const char *mtype, const char *programname, const char *ext, int nsonly); + + // workaround for (damn) c++ type checking + static LONG RegQueryValueEx(HKEY hKey, LPTSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, char *lpData, LPDWORD lpcbData) { +#ifdef WIN32 + return ::RegQueryValueEx(hKey, lpValueName, lpReserved, lpType, (unsigned char *)lpData, lpcbData); +#endif + } + static LONG RegSetValueEx(HKEY hKey, LPCTSTR lpValueName, DWORD Reserved, DWORD dwType, char *lpData, DWORD cbData) { +#ifdef WIN32 + return ::RegSetValueEx(hKey, lpValueName, Reserved, dwType, (const unsigned char *)lpData, cbData); +#endif + } + static LONG RegSetValueEx(HKEY hKey, LPCTSTR lpValueName, DWORD Reserved, DWORD dwType, const char *lpData, DWORD cbData) { +#ifdef WIN32 + return ::RegSetValueEx(hKey, lpValueName, Reserved, dwType, (const unsigned char *)lpData, cbData); +#endif + } +public: + static LONG myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey); + + static int whichicon, whichicon2, addtolist; +}; + +#endif diff --git a/Src/Wasabi/api/config/items/attrbool.h b/Src/Wasabi/api/config/items/attrbool.h new file mode 100644 index 00000000..324a2e11 --- /dev/null +++ b/Src/Wasabi/api/config/items/attrbool.h @@ -0,0 +1,65 @@ +#ifndef _ATTRBOOL_H +#define _ATTRBOOL_H + +#include "attribute.h" + +// inherit from this one, or just use it + +/** + Boolean configuration attributes have two values, true or false. + They can be used like any other config item. + + @short Boolean configuration attribute. + @ver 1.0 + @author Nullsoft + @see _int + @see _string + @see _float +*/ +class _bool : public Attribute { +public: + /** + Optionally set the name and default value of + your configuration attribute during construction. + + @param name Name of the configuration attribute. + @param default_val Default value. + */ + _bool(const wchar_t *name=NULL, int default_val=0) : Attribute(name) { + setValueAsInt(!!default_val, true); + } + + // convenience operators + /** + Get the value of the attribute. + */ + operator bool() { return !!getValueAsInt(); } + + /** + Set the value of the attribute. + */ + bool operator =(int newval) { setValueAsInt(!!newval); return *this; } + + // from Attribute + + /** + Get the attribute type. This will return + a constant representing the attribute type. + + These constants can be: BOOL, FLOAT, STRING and INT. + + @see AttributeType + @ret The attribute type. + */ + virtual int getAttributeType() { return AttributeType::BOOL; } + + /** + Get the configuration group to be used to represent + this attribute in the registry. + + @ret Config group to be used. + */ + virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.bool"; } +}; + +#endif diff --git a/Src/Wasabi/api/config/items/attrcb.h b/Src/Wasabi/api/config/items/attrcb.h new file mode 100644 index 00000000..3aa0e41d --- /dev/null +++ b/Src/Wasabi/api/config/items/attrcb.h @@ -0,0 +1,127 @@ +#ifndef _ATTRCB_H +#define _ATTRCB_H + +#include "attribute.h" + +/** + Enables you to register callbacks on + a specific attribute to monitor if it's + value has been changed by the user or other. + + This class is not meant to be used on it's own. + Please derive from it instead. + + @short Attribute callback + @ver 1.0 + @author Nullsoft + @see Attribute + @see int_attrCB + @see _int + @see _float + @see _string + @see _bool +*/ +class AttrCallback { +public: + /** + Does nothing. + */ + virtual ~AttrCallback() {} + + /** + Event triggered when the value of the attribute, + for which this callback has been registered, changes. + + This is a pure virtual, please override to implement + your custom behavior. + + @param attr Attribute for which the value has changed. + */ + virtual void onValueChange(Attribute *attr)=0; +}; + +/** + Enables you to register callbacks on a specific + integer or boolean attribute to monitor if the + value has been changed by the user or other. + + @short Integer or Boolean attribute Callback. + @ver 1.0 + @author Nullsoft + @see Attribute + @see _int + @see _bool +*/ +class int_attrCB : public AttrCallback { + typedef void (*fnPtrType)(int); +public: + /** + Upon construction, you must specify which + function will be called when the value of + the attribute has indeed changed. + + This is done using a pointer to the function. + The function must accept one parameter of type + int, like so: void myfunc(int val); + + @param _fn Pointer to the function to use on value change. + */ + int_attrCB(fnPtrType _fn) { fnptr = _fn; } + + /** + Event triggered when the value of the attribute, + for which this callback has been registered, changes. + + Override this to implement your own behavior. + The default is to send the new value of the attribute + to a function which you specify upon construction + of this object. + + @param attr Attribute for which the value has changed. + */ + virtual void onValueChange(Attribute *attr) { + ASSERT(attr->getAttributeType() == AttributeType::INT || + attr->getAttributeType() == AttributeType::BOOL); + (*fnptr)(attr->getValueAsInt()); + } +private: + fnPtrType fnptr; +}; + +class string_attrCB : public AttrCallback { + typedef void (*fnPtrType)(const wchar_t *); +public: + /** + Upon construction, you must specify which + function will be called when the value of + the attribute has indeed changed. + + This is done using a pointer to the function. + The function must accept one parameter of type + int, like so: void myfunc(const char *val); + + @param _fn Pointer to the function to use on value change. + */ + string_attrCB(fnPtrType _fn) { fnptr = _fn; } + + /** + Event triggered when the value of the attribute, + for which this callback has been registered, changes. + + Override this to implement your own behavior. + The default is to send the name of the attribute + to a function which you specify upon construction + of this object. + + @param attr Attribute for which the value has changed. + */ + virtual void onValueChange(Attribute *attr) + { + ASSERT(attr->getAttributeType() == AttributeType::STRING); + (*fnptr)(attr->getAttributeName()); + } +private: + fnPtrType fnptr; +}; + +#endif diff --git a/Src/Wasabi/api/config/items/attrfloat.h b/Src/Wasabi/api/config/items/attrfloat.h new file mode 100644 index 00000000..056f0c46 --- /dev/null +++ b/Src/Wasabi/api/config/items/attrfloat.h @@ -0,0 +1,52 @@ +#ifndef _ATTRFLOAT_H +#define _ATTRFLOAT_H + +#include "attribute.h" + +// actually it's a double :) + +class _float : public Attribute { +public: + /** + Optionally set the name and default value of + your configuration attribute during construction. + + @param name Name of the configuration attribute. + @param default_val Default value. + */ + _float(const wchar_t *name=NULL, double default_val=0.f) : Attribute(name) { + setValueAsDouble(default_val, true); + } + + /** + Get the attribute type. This will return + a constant representing the attribute type. + + These constants can be: BOOL, FLOAT, STRING and INT. + + @see AttributeType + @ret The attribute type. + */ + virtual int getAttributeType() { return AttributeType::FLOAT; } + + /** + Get the configuration group to be used to represent + this attribute in the registry. + + @ret Config group to be used. + */ + virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.float"; } + + // convenience operators + /** + Get the value of the attribute. + */ + operator double() { return getValueAsDouble(); } + + /** + Set the value of the attribute. + */ + double operator =(double newval) { return setValueAsDouble(newval) ? newval : getValueAsDouble(); } +}; + +#endif diff --git a/Src/Wasabi/api/config/items/attrfn.h b/Src/Wasabi/api/config/items/attrfn.h new file mode 100644 index 00000000..54f46df0 --- /dev/null +++ b/Src/Wasabi/api/config/items/attrfn.h @@ -0,0 +1,15 @@ +#ifndef _ATTRFN_H +#define _ATTRFN_H + +#include "attrstr.h" + +class _filename : public _string { +public: + _filename(const wchar_t *name, const wchar_t *default_val=L"") + : _string(name, default_val) { } + + virtual int getAttributeType() { return AttributeType::FILENAME; } + virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.filename"; } +}; + +#endif diff --git a/Src/Wasabi/api/config/items/attrhandler.h b/Src/Wasabi/api/config/items/attrhandler.h new file mode 100644 index 00000000..c2624f46 --- /dev/null +++ b/Src/Wasabi/api/config/items/attrhandler.h @@ -0,0 +1,129 @@ +//!## An object to multiplex the callbacks of multiple attributes. +#ifndef _ATTRHANDLER_H +#define _ATTRHANDLER_H + +// This class is meant to be subclassed. The methods you must provide +// are given as pure virtuals. See ExampleAttrib for more details, and +// an example subclass that you can copy for your own use. + +#include "attrcb.h" +#include "attribs.h" +#include <bfc/map.h> + +// +// Forward References +class WAComponentClient; +class Attribute; + + +// +// Class Definition +template <class TCallback> +class AttrHandler { +protected: + // Heh, oops. Can't have one AttrCallback handle lots of different attribs, anymore. I fix. + class AttrHandlerChild : public AttrCallback { + public: + AttrHandlerChild(AttrHandler *_parent) : AttrCallback() { + ASSERT(_parent != NULL); + recursion = 0; + callback = NULL; + parent = _parent; + } + + // Here is where we split out the different value types + virtual void onValueChange(Attribute *attr) { + if (!recursion) { + // protect our programmers from stack overflow, please. + recursion = 1; + if ((callback != NULL) && (parent != NULL)) { + int id; + // find the id from the map (friendly) + int success = parent->attribmap.getItem(attr,&id); + if (success) { + // and send it to the proper handling function (poorman's RTTI) + switch (attr->getAttributeType()) { + case AttributeType::INT: + callback->onIntChange(id,*static_cast<_int *>(attr)); + break; + case AttributeType::BOOL: + callback->onBoolChange(id, *static_cast<_bool *>(attr)); + break; + case AttributeType::FLOAT: + callback->onFloatChange(id, *static_cast<_float *>(attr)); + break; + case AttributeType::STRING: + callback->onStringChange(id, *static_cast<_string *>(attr)); + break; + } + } + } + recursion = 0; + } + } + + virtual void bindCallbackObj(TCallback *callbackobj) { + // Be advised, this may be null. That's okay, we test for it above. + callback = callbackobj; + } + private: + int recursion; + TCallback *callback; + AttrHandler *parent; + }; + +public: + AttrHandler() { + component = NULL; + callback = NULL; + } + + // Call this method to bind your component (in your component's constructor) + virtual void bindComponent(WAComponentClient *parentcomponent) { + component = parentcomponent; + } + + // Call this method to bind your callback object (usually your window in its constructor) + virtual void bindCallbackObj(TCallback *callbackobj) { + // Bind ourselves. + callback = callbackobj; + + // Then go through and rebind any children. + int i, num = attrchildren.getNumItems(); + for (i = 0; i < num; i++) { + AttrHandlerChild *child = attrchildren.enumItem(i); + child->bindCallbackObj(callback); + } + } + + // Call this method to register each attribute. + virtual void registerAttribute(Attribute *attr, int id) { + ASSERTPR(component != NULL, "BIND YOUR COMPONENT before registering Attributes to a Handler."); + // register the attrib with a child object as its callback + AttrHandlerChild *child = new AttrHandlerChild(this); + attrchildren.addItem(child); + component->registerAttribute(attr, child); + // and save its id mapping + attribmap.addItem(attr, id); + } + +#if 0 + // Your callback object (probably your primary window class) must implement + // its own versions of these methods here. They will be called by the + // switch statement below. + virtual void onIntChange(int id, int *attr); + virtual void onBoolChange(int id, bool *attr); + virtual void onFloatChange(int id, double *attr); + virtual void onStringChange(int id, const char *attr); +#endif + + +private: + friend AttrHandlerChild; + TCallback *callback; + WAComponentClient *component; + Map< Attribute *, int > attribmap; + PtrList<AttrHandlerChild> attrchildren; +}; + +#endif // _ATTRHANDLER_H diff --git a/Src/Wasabi/api/config/items/attribs.h b/Src/Wasabi/api/config/items/attribs.h new file mode 100644 index 00000000..1e35f78b --- /dev/null +++ b/Src/Wasabi/api/config/items/attribs.h @@ -0,0 +1,12 @@ +#ifndef _ATTRIBS_H +#define _ATTRIBS_H + +// a convenience header to get all the attrib types in one whack + +#include "attrbool.h" +#include "attrfloat.h" +#include "attrint.h" +#include "attrstr.h" +#include "attrfn.h" + +#endif diff --git a/Src/Wasabi/api/config/items/attribute.cpp b/Src/Wasabi/api/config/items/attribute.cpp new file mode 100644 index 00000000..27b519b6 --- /dev/null +++ b/Src/Wasabi/api/config/items/attribute.cpp @@ -0,0 +1,131 @@ +#include <precomp.h> + +#include "attribute.h" +#include <api/config/items/cfgitemi.h> + + +Attribute::Attribute(const wchar_t *newname, const wchar_t *_desc) : + NamedW(newname), desc(_desc), cfgitemi(NULL), private_storage(NULL) { } + +Attribute::~Attribute() { + delete private_storage; +} + +const wchar_t *Attribute::getAttributeName() { + return NamedW::getName(); +} + +const wchar_t *Attribute::getAttributeDesc() { + return desc; +} + +int Attribute::getValueAsInt() +{ + wchar_t buf[1024]=L""; + getData(buf, 1024); + return WTOI(buf); +} + +int Attribute::setValueAsInt(int newval, bool def) +{ + return setData(StringPrintfW(newval), def); +} + +double Attribute::getValueAsDouble() +{ + wchar_t buf[1024] = {0}; + getData(buf, 1024); + return WTOF(buf); +} + +double Attribute::setValueAsDouble(double newval, bool def) +{ + return setData(StringPrintfW(newval), def); +} + +int Attribute::getDataLen() { + if (private_storage != NULL) + return (int)private_storage->len()+1; + + ASSERTPR(WASABI_API_CONFIG != NULL, "getDataLen() before API"); + int r = WASABI_API_CONFIG->getStringPrivateLen(mkTag()); + if (r < 0) { + r = (int)default_val.len()+1; + } + return r; +} + +int Attribute::getData(wchar_t *data, int data_len) +{ + if (data == NULL || data_len < 0) + return 0; + if (private_storage != NULL) + { + if (private_storage->isempty()) + { + if (data_len >= 1) { + *data = 0; + return 1; + } + return 0; + } + WCSCPYN(data, private_storage->getValue(), data_len); + return MIN((int)private_storage->len(), data_len); + } + ASSERTPR(WASABI_API_CONFIG != NULL, "can't get without api"); + if (WASABI_API_CONFIG == NULL) return 0; + int r = WASABI_API_CONFIG->getStringPrivate(mkTag(), data, data_len, default_val.isempty() ? L"" : default_val.getValue()); + return r; +} + +int Attribute::setData(const wchar_t *data, bool def) +{ + if (def) { // setting default value + default_val = data; + return 1; + } + ASSERTPR(WASABI_API_CONFIG != NULL, "can't set data before api"); + if (WASABI_API_CONFIG == NULL) return 0; + + int r = setDataNoCB(data); + if (r && cfgitemi != NULL) cfgitemi->cfgitem_onAttribSetValue(this); + return r; +} + +int Attribute::setDataNoCB(const wchar_t *data) +{ + if (private_storage != NULL) { + private_storage->setValue(data); + } else { + WASABI_API_CONFIG->setStringPrivate(mkTag(), data); + } + dependent_sendEvent(Attribute::depend_getClassGuid(), Event_DATACHANGE); + return 1; +} + +void Attribute::setCfgItem(CfgItemI *item) +{ + delete private_storage; private_storage = NULL; + ASSERT(cfgitemi == NULL || item == NULL); + cfgitemi = item; + if (cfgitemi != NULL) + { + if (cfgitemi->cfgitem_usePrivateStorage()) + private_storage = new StringW; + } +} + +StringW Attribute::mkTag() +{ + StringW ret; + if (cfgitemi) + { + ret = cfgitemi->cfgitem_getPrefix(); + } + ret.cat(getName()); + return ret; +} + +void Attribute::disconnect() { + setCfgItem(NULL); +} diff --git a/Src/Wasabi/api/config/items/attribute.h b/Src/Wasabi/api/config/items/attribute.h new file mode 100644 index 00000000..c91e8065 --- /dev/null +++ b/Src/Wasabi/api/config/items/attribute.h @@ -0,0 +1,218 @@ +#ifndef _ATTRIBUTE_H +#define _ATTRIBUTE_H + +#include <bfc/depend.h> +#include <bfc/named.h> +#include <bfc/common.h> +#include <bfc/string/StringW.h> + +class CfgItemI; + +// lowercase types are reserved for official Nullsoft use +// uppercase are 3rd-party defined +namespace AttributeType { + /** + Attribute types. + */ + enum { + NONE = 0, + INT = MK3CC('i','n','t'), // attrint.h + STRING = MK3CC('s','t','r'), // attrstr.h + BOOL = MK4CC('b','o','o','l'), // attrbool.h + FLOAT = MK4CC('f','l','o','t'), // attrfloat.h + FILENAME = MK2CC('f','n'), // attrfn.h + }; +}; + +/** + Generic configuration attribute. + + Configuration attributes enable you to store + uniquely identifiable values that get pushed + to a configuration file automatically upon shutdown + of any Wasabi application. + + You shouldn't normally use this on + it's own, look at the CfgItemI class + instead. + + @short Generic configuration attribute. + @ver 1.0 + @author Nullsoft + @see _float + @see _int + @see _bool + @see _string + @see CfgItemI +*/ +class NOVTABLE Attribute : public DependentI, private NamedW +{ +public: + static const GUID *depend_getClassGuid() { + // {5AB601D4-1628-4604-808A-7ED899849BEB} + static const GUID ret = + { 0x5ab601d4, 0x1628, 0x4604, { 0x80, 0x8a, 0x7e, 0xd8, 0x99, 0x84, 0x9b, 0xeb } }; + return &ret; + } +protected: + + /** + Optionally set the name and default value of + your configuration attribute during construction. + + @param name Name of the configuration attribute. + @param default_val Default value. + */ + Attribute(const wchar_t *name=NULL, const wchar_t *desc=NULL); + +public: + virtual ~Attribute(); + + /** + Set the name of the configuration + attribute. + + @param newname Name of the attribute. + */ + void setName(const wchar_t *newname); + + /** + Get the name of the configuration + attribute. + + @ret Name of the attribute. + */ + const wchar_t *getAttributeName(); + + /** + Get the attribute's description. + + @ret Attribute's description. + */ + const wchar_t *getAttributeDesc(); + + /** + Get the attribute type. Override + this for your custom attribute type. + + @ret Attribute type. + */ + virtual int getAttributeType()=0; // override me + + /** + Get the configuration group to be used to represent + this attribute in the registry. + + This is only called if the kernel doesn't have a default + config group set for your type already. + + @ret Config group to be used. + */ + virtual const wchar_t *getConfigGroup() { return NULL; } // override me + + /** + Get the attribute's value as signed integer. + + @ret Attribute value, as a signed integer. + */ + int getValueAsInt(); + + /** + Set the attribute's value with a signed integer while + also being able to replace the default value previously + set. + + @param newval Attribute's new value. + @param def true, replace the current default value; false, leave the default value unchanged; + */ + int setValueAsInt(int newval, bool def=false); + + /** + Get the attribute's value as signed double. + + @ret Attribute value, as a signed double. + */ + double getValueAsDouble(); + + /** + Set the attribute's value with a signed double while + also being able to replace the default value previously + set. + + @param newval Attribute's new value. + @param def true, replace the current default value; false, leave the default value unchanged; + */ + double setValueAsDouble(double newval, bool def=false); + + /** + Get the length of the attribute's value (data) + in bytes. + + @ret Attribute value (data) length, in bytes. + */ + int getDataLen(); + + /** + Get the attribute's raw data. + + This will return the data the attribute is storing + in a char buffer you hand to it. + + @ret Attribute value, as a signed double. + @param data Pointer to a char buffer. + @param data_len The maximum amount of bytes the char buffer can hold. + */ + int getData(wchar_t *data, int data_len); + + /** + Set the attribute's value with a zero terminated string. Also + enables you to replace the default value previously + set. + + @param newval Attribute's new value. + @param def true, replace the current default value; false, leave the default value unchanged; + */ + int setData(const wchar_t *data, bool def=false); + + void disconnect(); + + enum { + Event_DATACHANGE=100, + }; +protected: + friend class CfgItemI; + + /** + Set the attribute's value without causing + a callback. + + @ret 1. + @param data Attribute's new value. + */ + int setDataNoCB(const wchar_t *data); + + /** + Set the configuration item associated with this + attribute. + */ + void setCfgItem(CfgItemI *item); + + StringW mkTag(); + +private: + StringW desc; + StringW default_val, *private_storage; + CfgItemI *cfgitemi; +}; + +#define ATTR_PERM_READ 1 +#define ATTR_PERM_WRITE 2 + +#define ATTR_PERM_ALL (~0) + +// render hints for getRenderHint +enum { + ATTR_RENDER_HINT_INT_CHECKMARK +}; + +#endif diff --git a/Src/Wasabi/api/config/items/attrint.h b/Src/Wasabi/api/config/items/attrint.h new file mode 100644 index 00000000..c63af8ce --- /dev/null +++ b/Src/Wasabi/api/config/items/attrint.h @@ -0,0 +1,65 @@ +#ifndef _ATTRINT_H +#define _ATTRINT_H + +#include "attribute.h" + +// inherit from this one, or just use it +/** + Boolean configuration attributes have two values, true or false. + They can be used like any other config item. + + @short Integer configuration attribute. + @ver 1.0 + @author Nullsoft + @see CfgItemI + @see _bool + @see _string + @see _float +*/ +class _int : public Attribute { +public: + /** + Optionally set the name and default value of + your configuration attribute during construction. + + @param name Name of the configuration attribute. + @param default_val Default value. + */ + _int(const wchar_t *name=NULL, int default_val=0) : Attribute(name) { + setValueAsInt(default_val, true); + } + + // from AttributeI + /** + Get the attribute type. This will return + a constant representing the attribute type. + + These constants can be: BOOL, FLOAT, STRING and INT. + + @see AttributeType + @ret The attribute type. + */ + virtual int getAttributeType() { return AttributeType::INT; } + + /** + Get the configuration group to be used to represent + this attribute in the registry. + + @ret Config group to be used. + */ + virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.int"; } +// virtual int getPermissions(); + + // convenience operators + /** + Get the value of the attribute. + */ + operator int() { return getValueAsInt(); } + + /** + Set the value of the attribute. + */ + int operator =(int newval) { return setValueAsInt(newval) ? newval : getValueAsInt(); } +}; + +#endif diff --git a/Src/Wasabi/api/config/items/attrstr.cpp b/Src/Wasabi/api/config/items/attrstr.cpp new file mode 100644 index 00000000..1209e2f3 --- /dev/null +++ b/Src/Wasabi/api/config/items/attrstr.cpp @@ -0,0 +1,14 @@ +#include <precomp.h> +#include "attrstr.h" + +#include <bfc/memblock.h> + +const wchar_t *_string::getValue() +{ + int l = getDataLen(); + if (l <= 0) return L""; + MemBlock<wchar_t> mb(l+2); + getData(mb.getMemory(), l+2); + returnval = mb; + return returnval; +} diff --git a/Src/Wasabi/api/config/items/attrstr.h b/Src/Wasabi/api/config/items/attrstr.h new file mode 100644 index 00000000..cde81a64 --- /dev/null +++ b/Src/Wasabi/api/config/items/attrstr.h @@ -0,0 +1,85 @@ +#ifndef _ATTRSTR_H +#define _ATTRSTR_H + +#include "attribute.h" + +#include <bfc/string/bfcstring.h> +#include <bfc/common.h> + +/** + String configuration attributes, can have any string value + of any length. They can be used like any other config item. + + @short String configuration attribute. + @ver 1.0 + @author Nullsoft + @see _int + @see _bool + @see _float +*/ +class _string : public Attribute { +public: + /** + Optionally set the name and default value of + your configuration attribute during construction. + + @param name + @param default_val + */ + _string(const wchar_t *name=NULL, const wchar_t *default_val=NULL) + : Attribute(name) { + setData(default_val, true); + } + + /** + Get the attribute type. This will return + a constant representing the attribute type. + + These constants can be: BOOL, FLOAT, STRING and INT. + + @see AttributeType + @ret The attribute type. + */ + virtual int getAttributeType() { return AttributeType::STRING; } + + /** + Get the configuration group to be used to represent + this attribute in the registry. + + @ret Config group to be used. + */ + virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.string"; } + +//CUT virtual int getPermissions() { return ATTR_PERM_ALL; } + + /** + Get the value of the attribute. + + @ret The value of the attribute + */ + const wchar_t *getValue(); + + /** + Set the value of the attribute. + + @param val The value you want to set. + @ret 1, success; 0, failure; + */ + int setValue(const wchar_t *val) { return setData(val); } + + // convenience operators + /** + Get the value of the attribute. + */ + operator const wchar_t *() { return getValue(); } + + /** + Set the value of the attribute. + */ + const wchar_t *operator =(const wchar_t *newval) { return setValue(newval) ? newval : getValue(); } + +private: + StringW returnval; +}; + +#endif diff --git a/Src/Wasabi/api/config/items/cfgitem.h b/Src/Wasabi/api/config/items/cfgitem.h new file mode 100644 index 00000000..560198f0 --- /dev/null +++ b/Src/Wasabi/api/config/items/cfgitem.h @@ -0,0 +1,233 @@ +#ifndef _CFGITEM_H +#define _CFGITEM_H + +#include <bfc/dispatch.h> +#include <bfc/platform/types.h> +#include <bfc/platform/guid.h> +#include <bfc/wasabi_std.h> + +class ifc_dependent; +class ifc_window; + +/* A CfgItem is a named, possibly unique (if GUID is set) interface to +an object with 0 or more named attributes. If offers api_dependent-based callbacks +when those attributes change. +*/ + +// abstract base class presented to the world +/** + + + @short Base Config Item + @ver 1.0 + @author Nullsoft + @see CfgItemI +*/ +class NOVTABLE CfgItem : public Dispatchable +{ +public: + /** + */ + static const GUID *depend_getClassGuid() { + // {B4BE480E-2005-457c-A445-294F12387E74} + static const GUID ret = + { 0xb4be480e, 0x2005, 0x457c, { 0xa4, 0x45, 0x29, 0x4f, 0x12, 0x38, 0x7e, 0x74 } }; + return &ret; + } + + const wchar_t *getName(); + + /** + Get the GUID + */ + GUID getGuid(); + + /** + Get the number of attributes + associated with this configuration + item. + + @ret Number of attributes for this configuration item. + */ + int getNumAttributes(); + + const wchar_t *enumAttribute(int n); + + // so people can watch you for changes + ifc_dependent *getDependencyPtr(); + + // return * to your config xml if you want to specify it + const wchar_t *getConfigXML(); + void onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname=NULL); + void onCfgGroupDelete(ifc_window *cfggroup); + + // if you have child cfgitems, list them here + int getNumChildren(); + CfgItem *enumChild(int n); + GUID getParentGuid(); + + void onRegister(); // kernel calls these + void onDeregister(); + + int getAttributeType(const wchar_t *name); + const wchar_t *getAttributeConfigGroup(const wchar_t *name); + int getDataLen(const wchar_t *name); + int getData(const wchar_t *name, wchar_t *data, int data_len); + int setData(const wchar_t *name, const wchar_t *data); + + int getDataAsInt(const wchar_t *name, int def_val=0) + { + wchar_t buf[256]; + if (getData(name, buf, sizeof(buf))==-1) return def_val; + return WTOI(buf); + } + void setDataAsInt(const wchar_t *name, int val) { + wchar_t buf[256]; + WCSNPRINTF(buf, 256, L"%d", val); // this uses SPRINTF ON PURPOSE, motherfucker BU + setData(name, buf); + } + + double getDataAsFloat(const wchar_t *name, double def_val=0) { + wchar_t buf[256]; + if (getData(name, buf, sizeof(buf))==-1) return def_val; + return WTOF(buf); + } + void setDataAsFloat(const wchar_t *name, double val) { + wchar_t buf[256]; + WCSNPRINTF(buf, 256, L"%f", val); // this uses SPRINTF ON PURPOSE, motherfucker BU + setData(name, buf); + } + + int addAttribute(const wchar_t *name, const wchar_t *defval); + int delAttribute(const wchar_t *name); + + enum { + Event_ATTRIBUTE_ADDED=100, // ptr is name of attrib + Event_ATTRIBUTE_REMOVED=200,// ptr is name of attrib + Event_ATTRIBUTE_CHANGED=300, // ptr is name of attrib + Event_NAMECHANGE=400, + }; + +protected: + enum { + CFGITEM_GETNAME=100, + CFGITEM_GETGUID=110, + CFGITEM_GETNUMATTRIBUTES=200, + CFGITEM_ENUMATTRIBUTE=210, + CFGITEM_GETDEPENDENCYPTR=300, + CFGITEM_GETNUMCHILDREN=400, + CFGITEM_ENUMCHILD=410, + CFGITEM_GETPARENTGUID=420, + CFGITEM_ONREGISTER=500, + CFGITEM_ONDEREGISTER=510, + CFGITEM_GETCONFIGXML=600, + CFGITEM_ONCFGGROUPCREATE=610, + CFGITEM_ONCFGGROUPDELETE=620, + CFGITEM_GETATTRIBUTETYPE=700, + CFGITEM_GETATTRIBUTECONFIGGROUP=710, + CFGITEM_GETDATALEN=800, + CFGITEM_GETDATA=810, + CFGITEM_SETDATA=820, + CFGITEM_ADDATTRIB=830, + CFGITEM_DELATTRIB=840, + }; +}; + +inline const wchar_t *CfgItem::getName() { + return _call(CFGITEM_GETNAME, L""); +} + +inline GUID CfgItem::getGuid() { + return _call(CFGITEM_GETGUID, INVALID_GUID); +} + +inline int CfgItem::getNumAttributes() { + return _call(CFGITEM_GETNUMATTRIBUTES, 0); +} + +inline const wchar_t *CfgItem::enumAttribute(int n) { + return _call(CFGITEM_ENUMATTRIBUTE, (const wchar_t *)NULL, n); +} + +inline ifc_dependent *CfgItem::getDependencyPtr() { + return _call(CFGITEM_GETDEPENDENCYPTR, (ifc_dependent*)NULL); +} + +inline const wchar_t *CfgItem::getConfigXML() { + return _call(CFGITEM_GETCONFIGXML, (const wchar_t*)NULL); +} + +inline void CfgItem::onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname) { + _voidcall(CFGITEM_ONCFGGROUPCREATE, cfggroup, attrname); +} + +inline void CfgItem::onCfgGroupDelete(ifc_window *cfggroup) { + _voidcall(CFGITEM_ONCFGGROUPDELETE, cfggroup); +} + +inline int CfgItem::getNumChildren() { + return _call(CFGITEM_GETNUMCHILDREN, 0); +} + +inline CfgItem *CfgItem::enumChild(int n) { + return _call(CFGITEM_ENUMCHILD, (CfgItem*)NULL, n); +} + +inline +GUID CfgItem::getParentGuid() { + return _call(CFGITEM_GETPARENTGUID, INVALID_GUID); +} + +inline void CfgItem::onRegister() { _voidcall(CFGITEM_ONREGISTER); } +inline void CfgItem::onDeregister() { _voidcall(CFGITEM_ONDEREGISTER); } + +inline +int CfgItem::getAttributeType(const wchar_t *name) { + return _call(CFGITEM_GETATTRIBUTETYPE, 0, name); +} + +inline +const wchar_t *CfgItem::getAttributeConfigGroup(const wchar_t *name) { + return _call(CFGITEM_GETATTRIBUTECONFIGGROUP, (const wchar_t *)NULL, name); +} + +inline +int CfgItem::getDataLen(const wchar_t *name) { + return _call(CFGITEM_GETDATALEN, -1, name); +} + +inline +int CfgItem::getData(const wchar_t *name, wchar_t *data, int data_len) { + return _call(CFGITEM_GETDATA, -1, name, data, data_len); +} + +inline +int CfgItem::setData(const wchar_t *name, const wchar_t *data) { + return _call(CFGITEM_SETDATA, -1, name, data); +} + +inline +int CfgItem::addAttribute(const wchar_t *name, const wchar_t *defval) { + return _call(CFGITEM_ADDATTRIB, 0, name, defval); +} + +inline +int CfgItem::delAttribute(const wchar_t *name) { + return _call(CFGITEM_DELATTRIB, 0, name); +} + +inline int _intVal(CfgItem *cfgitem, const wchar_t *name, int def_val=0) { + if (cfgitem == NULL) return def_val; + return cfgitem->getDataAsInt(name, def_val); +} + +#define _int_getValue _intVal + +//CUT kill these +inline void _int_setValue(CfgItem *cfgitem, const wchar_t *name, int val) { + cfgitem->setDataAsInt(name, val); +} +// CfgItemI is in cfgitemi.h if you need it + + +#endif diff --git a/Src/Wasabi/api/config/items/cfgitemi.cpp b/Src/Wasabi/api/config/items/cfgitemi.cpp new file mode 100644 index 00000000..b8734031 --- /dev/null +++ b/Src/Wasabi/api/config/items/cfgitemi.cpp @@ -0,0 +1,274 @@ +#include <precomp.h> + +#include "cfgitemi.h" +#include <api/config/items/attrcb.h> +#include <api/config/items/attribs.h> + +#include <bfc/wasabi_std.h> +#include <bfc/memblock.h> + +CfgItemI::CfgItemI(const wchar_t *name, GUID guid) +:NamedW(name), myguid(guid), parent_guid(INVALID_GUID) { } + +CfgItemI::~CfgItemI() +{ + deregisterAll(); +} + +const wchar_t *CfgItemI::cfgitem_getName() +{ + return NamedW::getName(); +} + +GUID CfgItemI::cfgitem_getGuid() +{ + return myguid; +} + +void CfgItemI::cfgitem_setPrefix(const wchar_t *_prefix) +{ + prefix = _prefix; +} + +const wchar_t *CfgItemI::cfgitem_getPrefix() +{ + return prefix.c_str(); +} + +int CfgItemI::cfgitem_getNumAttributes() +{ + return attributes.getNumItems(); +} + +const wchar_t *CfgItemI::cfgitem_enumAttribute(int n) +{ + Attribute *attr = attributes[n]; + if (attr) return attr->getAttributeName(); + return NULL; +} + +const wchar_t *CfgItemI::cfgitem_getConfigXML() +{ + return cfgxml.c_str(); +} + +int CfgItemI::cfgitem_getNumChildren() +{ + return children.getNumItems(); +} + +CfgItem *CfgItemI::cfgitem_enumChild(int n) +{ + return children[n]; +} + +GUID CfgItemI::cfgitem_getParentGuid() +{ + return parent_guid; +} + +void CfgItemI::cfgitem_onRegister() +{ + foreach(children) + WASABI_API_CONFIG->config_registerCfgItem(children.getfor()); + endfor +} +void CfgItemI::cfgitem_onDeregister() +{ + foreach(children) + WASABI_API_CONFIG->config_deregisterCfgItem(children.getfor()); + endfor +} + +Attribute *CfgItemI::getAttributeByName(const wchar_t *name) +{ + Attribute *attr; + foreach(attributes) + attr = attributes.getfor(); + if (!WCSICMP(name, attr->getAttributeName())) return attr; + endfor + return NULL; +} + +int CfgItemI::cfgitem_getAttributeType(const wchar_t *name) +{ + Attribute *attr = getAttributeByName(name); + if (attr == NULL) return AttributeType::NONE; + return attr->getAttributeType(); +} + +const wchar_t *CfgItemI::cfgitem_getAttributeConfigGroup(const wchar_t *name) +{ + Attribute *attr = getAttributeByName(name); + if (attr == NULL) return NULL; + return attr->getConfigGroup(); +} + +int CfgItemI::cfgitem_getDataLen(const wchar_t *name) +{ + Attribute *attr = getAttributeByName(name); + if (attr == NULL) return -1; + return attr->getDataLen(); +} + +int CfgItemI::cfgitem_getData(const wchar_t *name, wchar_t *data, int data_len) +{ + Attribute *attr = getAttributeByName(name); + if (attr == NULL) return -1; + return attr->getData(data, data_len); +} + +int CfgItemI::cfgitem_setData(const wchar_t *name, const wchar_t *data) +{ + Attribute *attr = getAttributeByName(name); + if (attr == NULL) return -1; + int ret = attr->setDataNoCB(data); + if (ret) cfgitem_onAttribSetValue(attr); + return ret; +} + +int CfgItemI::cfgitem_onAttribSetValue(Attribute *attr) +{ + // notify dependency watchers that an attribute changed + dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_ATTRIBUTE_CHANGED, 0, (void*)attr->getAttributeName()); + + //for (int i = 0; ; i++) + //{ + // AttrCallback *acb; + // if (!callbacks.multiGetItem(attr, i, &acb)) + // break; + // + // acb->onValueChange(attr); + //} + auto elements = callbacks.equal_range(attr); + for (auto& it = elements.first; it != elements.second; ++it) + { + AttrCallback* acb = it->second; + if (acb) + { + acb->onValueChange(attr); + } + } + + return 0; +} + +void CfgItemI::cfgitem_setGUID(GUID guid) +{ + myguid = guid; +} + +int CfgItemI::setName(const wchar_t *name) +{ + NamedW::setName(name); + // notify dependency watchers that name changed? + dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_NAMECHANGE); + return 1; +} + +int CfgItemI::registerAttribute(Attribute *attr, AttrCallback *acb) +{ + if (attributes.haveItem(attr)) return 0; + int ret = attributes.addItem(attr) != NULL; + if (!ret) return ret; + + attr->setCfgItem(this); + + // set optional callback + if (acb != NULL) + { + addCallback(attr, acb); + } + + // notify dependency watchers of new attribute + dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_ATTRIBUTE_ADDED, 0, (void*)attr->getAttributeName()); + + return ret; +} + +int CfgItemI::deregisterAttribute(Attribute *attr) +{ + if (!attributes.haveItem(attr)) return 0; + int ret = attributes.removeItem(attr); + // notify dependency watchers of attribute going away + dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_ATTRIBUTE_REMOVED, 0, (void*)attr->getAttributeName()); + + // remove callbacks + //callbacks.multiDelAllForItem(attr, TRUE); + auto elements = callbacks.equal_range(attr); + for (auto& it = elements.first; it != elements.second; ++it) + { + AttrCallback* acb = it->second; + if (acb) + { + delete acb; + } + } + callbacks.erase(attr); + + + attr->disconnect(); + + return ret; +} + +void CfgItemI::addCallback(Attribute *attr, AttrCallback *acb) +{ + ASSERT(attr != NULL); + ASSERT(acb != NULL); + //callbacks.multiAddItem(attr, acb); + callbacks.insert({ attr, acb }); +} + +void CfgItemI::deregisterAll() +{ + foreach(children) + children.getfor()->deregisterAll(); + endfor + while (attributes.getNumItems()) deregisterAttribute(attributes[0]); +} + +void CfgItemI::addChildItem(CfgItemI *child) +{ + ASSERT(child != NULL); + if (!children.haveItem(child)) + { + children.addItem(child); + child->setParentGuid(myguid); + } +} + +void CfgItemI::setCfgXml(const wchar_t *groupname) +{ + cfgxml = groupname; +} + +void CfgItemI::setParentGuid(GUID guid) +{ + parent_guid = guid; +} + +void *CfgItemI::dependent_getInterface(const GUID *classguid) +{ + HANDLEGETINTERFACE(CfgItem); + return NULL; +} + +int CfgItemI::cfgitem_addAttribute(const wchar_t *name, const wchar_t *defval) +{ + if (getAttributeByName(name)) return 0; + registerAttribute(newattribs.addItem(new _string(name, defval))); + return 1; +} + +int CfgItemI::cfgitem_delAttribute(const wchar_t *name) +{ + Attribute *attr = getAttributeByName(name); + if (!newattribs.haveItem(attr)) return 0; + deregisterAttribute(attr); + delete attr; + newattribs.removeItem(attr); + return 1; +} + + diff --git a/Src/Wasabi/api/config/items/cfgitemi.h b/Src/Wasabi/api/config/items/cfgitemi.h new file mode 100644 index 00000000..7824abf5 --- /dev/null +++ b/Src/Wasabi/api/config/items/cfgitemi.h @@ -0,0 +1,158 @@ +#ifndef _CFGITEMI_H +#define _CFGITEMI_H + +#include "cfgitemx.h" + +#include <bfc/named.h> +#include <bfc/ptrlist.h> +#include <bfc/depend.h> + +#include <map> +#include <string> + +class AttrCallback; +class Attribute; + +// this is the one you inherit from/use +/** + + @short Configuration Item + @ver 1.0 + @author Nullsoft + @see Attribute + @see _bool + @see _int + @see _float + @see _string +*/ +class CfgItemI : public CfgItemX, public DependentI, private NamedW +{ +public: + /** + Optionally sets the name and the GUID of the + configuration item if they are specified + upon creation of the object. + + @param name Name of the configuration item. + @param guid GUID of the configuration item. + */ + CfgItemI(const wchar_t *name=NULL, GUID guid=INVALID_GUID); + + /** + Does nothing. + */ + virtual ~CfgItemI(); + + /** + Get the name of the configuration item. + + @ret Name of the configuration item. + */ + const wchar_t *cfgitem_getName(); + + /** + Get the GUID of the configuration item. + + @ret GUID of the configuration item. + */ + GUID cfgitem_getGuid(); + + /** + Sets the prefix to be prepended in the config file for all attributes + of this item. + + @see cfgitem_getPrefix + @param prefix The prefix. + */ + void cfgitem_setPrefix(const wchar_t *prefix); +/** + Gets the config prefix, if any was set. + + @see cfgitem_setPrefix + @ret Pointer to the config prefix. +*/ + const wchar_t *cfgitem_getPrefix(); + + /** + Get the number of attributes registered + to this configuration item. + + @ret Number of attributes. + */ + int cfgitem_getNumAttributes(); + + /** + Enumerate the attributes registered + with this configuration item. + + @ret + */ + const wchar_t *cfgitem_enumAttribute(int n); + + const wchar_t *cfgitem_getConfigXML(); + virtual void cfgitem_onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname) {} + virtual void cfgitem_onCfgGroupDelete(ifc_window *cfggroup) {} + + virtual int cfgitem_getNumChildren(); + virtual CfgItem *cfgitem_enumChild(int n); + virtual GUID cfgitem_getParentGuid(); + + virtual void cfgitem_onRegister(); + virtual void cfgitem_onDeregister(); + + int cfgitem_getAttributeType(const wchar_t *name); + const wchar_t *cfgitem_getAttributeConfigGroup(const wchar_t *name); + int cfgitem_getDataLen(const wchar_t *name); + int cfgitem_getData(const wchar_t *name, wchar_t *data, int data_len); + int cfgitem_setData(const wchar_t *name, const wchar_t *data); + + // override these to catch notifications from attribs, call down + virtual int cfgitem_onAttribSetValue(Attribute *attr); + + virtual int cfgitem_usePrivateStorage() { return 0; } //override and return 1 to keep stuff out of system settings + +protected: + void cfgitem_setGUID(GUID guid); + +public: + int setName(const wchar_t *name); + int registerAttribute(Attribute *attr, AttrCallback *acb=NULL); + // does not call delete on the attribute + int deregisterAttribute(Attribute *attr); + void deregisterAll(); + + void addCallback(Attribute *attr, AttrCallback *acb); + + int cfgitem_addAttribute(const wchar_t *name, const wchar_t *defval); + int cfgitem_delAttribute(const wchar_t *name); + +protected: + + // derived classes can override this to catch name changes + virtual void cfgitem_onSetName() { } + + Attribute *getAttributeByName(const wchar_t *name); + + void addChildItem(CfgItemI *child); + + void setCfgXml(const wchar_t *groupname); + + void setParentGuid(GUID guid); + +private: + api_dependent *cfgitem_getDependencyPtr() { return this; }; + virtual void *dependent_getInterface(const GUID *classguid); + + // from Named + virtual void onSetName() { cfgitem_onSetName(); } + + std::wstring prefix; + PtrList<Attribute> attributes; + std::multimap<Attribute*, AttrCallback*> callbacks; //CUT + PtrList<CfgItemI> children; + std::wstring cfgxml; + GUID myguid, parent_guid; + PtrList<Attribute> newattribs; +}; + +#endif diff --git a/Src/Wasabi/api/config/items/cfgitemx.cpp b/Src/Wasabi/api/config/items/cfgitemx.cpp new file mode 100644 index 00000000..b656dfc9 --- /dev/null +++ b/Src/Wasabi/api/config/items/cfgitemx.cpp @@ -0,0 +1,27 @@ +#include <precomp.h> +#include "cfgitemx.h" + +#define CBCLASS CfgItemX +START_DISPATCH + CB(CFGITEM_GETNAME, cfgitem_getName); + CB(CFGITEM_GETGUID, cfgitem_getGuid); + CB(CFGITEM_GETNUMATTRIBUTES, cfgitem_getNumAttributes); + CB(CFGITEM_ENUMATTRIBUTE, cfgitem_enumAttribute); + CB(CFGITEM_GETCONFIGXML, cfgitem_getConfigXML); + VCB(CFGITEM_ONCFGGROUPCREATE, cfgitem_onCfgGroupCreate); + VCB(CFGITEM_ONCFGGROUPDELETE, cfgitem_onCfgGroupDelete); + CB(CFGITEM_GETNUMCHILDREN, cfgitem_getNumChildren); + CB(CFGITEM_ENUMCHILD, cfgitem_enumChild); + CB(CFGITEM_GETPARENTGUID, cfgitem_getParentGuid); + VCB(CFGITEM_ONREGISTER, cfgitem_onRegister); + VCB(CFGITEM_ONDEREGISTER, cfgitem_onDeregister); + CB(CFGITEM_GETATTRIBUTETYPE, cfgitem_getAttributeType); + CB(CFGITEM_GETATTRIBUTECONFIGGROUP, cfgitem_getAttributeConfigGroup); + CB(CFGITEM_GETDATALEN, cfgitem_getDataLen); + CB(CFGITEM_GETDATA, cfgitem_getData); + CB(CFGITEM_SETDATA, cfgitem_setData); + CB(CFGITEM_GETDEPENDENCYPTR, cfgitem_getDependencyPtr); + CB(CFGITEM_ADDATTRIB, cfgitem_addAttribute); + CB(CFGITEM_DELATTRIB, cfgitem_delAttribute); +END_DISPATCH +#undef CBCLASS
\ No newline at end of file diff --git a/Src/Wasabi/api/config/items/cfgitemx.h b/Src/Wasabi/api/config/items/cfgitemx.h new file mode 100644 index 00000000..6d5a9408 --- /dev/null +++ b/Src/Wasabi/api/config/items/cfgitemx.h @@ -0,0 +1,42 @@ +#ifndef NULLSOFT_WASABI_CFGITEMX_H +#define NULLSOFT_WASABI_CFGITEMX_H + +#include "cfgitem.h" + +class CfgItemX : public CfgItem +{ +public: + virtual ~CfgItemX() {} + virtual const wchar_t *cfgitem_getName()=0; + virtual GUID cfgitem_getGuid()=0; + virtual int cfgitem_getNumAttributes()=0; + virtual const wchar_t *cfgitem_enumAttribute(int n)=0; + virtual const wchar_t *cfgitem_getConfigXML()=0; + virtual void cfgitem_onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname)=0; + virtual void cfgitem_onCfgGroupDelete(ifc_window *cfggroup)=0; + + virtual int cfgitem_getNumChildren()=0; + virtual CfgItem *cfgitem_enumChild(int n)=0; + virtual GUID cfgitem_getParentGuid()=0; + + virtual void cfgitem_onRegister()=0; + virtual void cfgitem_onDeregister()=0; + + virtual int cfgitem_getAttributeType(const wchar_t *name)=0; + virtual const wchar_t *cfgitem_getAttributeConfigGroup(const wchar_t *name)=0; + + virtual int cfgitem_getDataLen(const wchar_t *name)=0; + virtual int cfgitem_getData(const wchar_t *name, wchar_t *data, int data_len)=0; + virtual int cfgitem_setData(const wchar_t *name, const wchar_t *data)=0; + virtual ifc_dependent *cfgitem_getDependencyPtr()=0; + virtual int cfgitem_delAttribute(const wchar_t *name)=0; + virtual int cfgitem_addAttribute(const wchar_t *name, const wchar_t *defval)=0; + +protected: + RECVS_DISPATCH; + + +}; + + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/config/items/intarray.cpp b/Src/Wasabi/api/config/items/intarray.cpp new file mode 100644 index 00000000..c6ba4676 --- /dev/null +++ b/Src/Wasabi/api/config/items/intarray.cpp @@ -0,0 +1,49 @@ +#include <precomp.h> + +#include "intarray.h" + + +enum { MAX_ARRAY=8 }; + +int IntArray::read(const wchar_t *name, int *x1, int *x2, int *x3, int *x4, int *x5, int *x6, int *x7, int *x8) { + PtrList<int> list; + if (x1) { list.addItem(x1); } + if (x2) { list.addItem(x2); } + if (x3) { list.addItem(x3); } + if (x4) { list.addItem(x4); } + if (x5) { list.addItem(x5); } + if (x6) { list.addItem(x6); } + if (x7) { list.addItem(x7); } + if (x8) { list.addItem(x8); } + ASSERT(list.getNumItems() >= 1); + + int array[MAX_ARRAY]; // gcc rules, msvc drools + for (int i = 0; i < list.getNumItems(); i++) { + if (list[i]) array[i] = *list[i]; + } + if (!WASABI_API_CONFIG->getIntArrayPrivate(name, array, list.getNumItems())) return 0; + for (int j = 0; j < list.getNumItems(); j++) { + if (list[j]) *list[j] = array[j]; + } + return 1; +} + +void IntArray::write(const wchar_t *name, int x1) { + int array[] = { x1 }; + WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int)); +} + +void IntArray::write(const wchar_t *name, int x1, int x2) { + int array[] = { x1, x2 }; + WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int)); +} + +void IntArray::write(const wchar_t *name, int x1, int x2, int x3) { + int array[] = { x1, x2, x3 }; + WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int)); +} + +void IntArray::write(const wchar_t *name, int x1, int x2, int x3, int x4) { + int array[] = { x1, x2, x3, x4 }; + WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int)); +} diff --git a/Src/Wasabi/api/config/items/intarray.h b/Src/Wasabi/api/config/items/intarray.h new file mode 100644 index 00000000..edb26322 --- /dev/null +++ b/Src/Wasabi/api/config/items/intarray.h @@ -0,0 +1,18 @@ +#ifndef _INTARRAY_H +#define _INTARRAY_H + +#include <bfc/common.h> +#include <bfc/named.h> +#include <bfc/ptrlist.h> + +class IntArray +{ +public: + static int read(const wchar_t *name, int *x1, int *x2=NULL, int *x3=NULL, int *x4=NULL, int *x5=NULL, int *x6=NULL, int *x7=NULL, int *x8=NULL); + static void write(const wchar_t *name, int x1); + static void write(const wchar_t *name, int x1, int x2); + static void write(const wchar_t *name, int x1, int x2, int x3); + static void write(const wchar_t *name, int x1, int x2, int x3, int x4); +}; + +#endif diff --git a/Src/Wasabi/api/config/options.cpp b/Src/Wasabi/api/config/options.cpp new file mode 100644 index 00000000..e5c0d27a --- /dev/null +++ b/Src/Wasabi/api/config/options.cpp @@ -0,0 +1,211 @@ +#include <precomp.h> + +#include "options.h" + +//#include <api/wac/main.h>//CUT!! +#include <api/wnd/wndtrack.h> + +#include <bfc/util/inifile.h> +#include <api/config/items/attribs.h> +#include <api/config/items/attrcb.h> +#include <bfc/wasabi_std_wnd.h> + +#include <api/locales/localesmgr.h> +#include <api/font/font.h> + +#define ININAME "wasabi.ini" + +// {280876CF-48C0-40bc-8E86-73CE6BB462E5} +const GUID options_guid = +{ 0x280876cf, 0x48c0, 0x40bc, { 0x8e, 0x86, 0x73, 0xce, 0x6b, 0xb4, 0x62, 0xe5 } }; + +#ifndef GEN_FF + +static void setMultipleInstance(int val) +{ + StringPrintf fn("%s%s%s", WASABI_API_APP->path_getAppPath(), DIRCHARSTR, ININAME); + IniFile(fn).setBool("Wasabi", "MultipleInstance", val); +} + +_int forward_skip_time("Forward skip time", 5000); +_int reverse_skip_time("Reverse skip time", 5000); +#endif + +_bool cfg_options_altfonts(L"Alternate Fonts", FALSE); +_bool cfg_options_allowbitmapfonts(L"Use bitmap fonts (no international support)", FALSE); +_string cfg_options_defaultfont(L"Default font", WASABI_DEFAULT_FONTNAMEW L".ttf"); +_int cfg_options_defaultfontscale(L"Default font scale", 100); +_string cfg_options_ttfoverridefont(L"TTF font override", WASABI_DEFAULT_FONTNAMEW L".ttf"); +_int cfg_options_ttfoverridescale(L"TTF Override Scale", 100); +_bool cfg_options_no7bitsttfoverride(L"No 7-bit TTF override", TRUE); +_bool cfg_options_noalt7bitsttfoverride(L"No 7-bit TTF AltFonts", TRUE); +_bool cfg_options_usefontmapper(L"Enable Font Mapper", FALSE); + +#ifdef USEAPPBAR +_bool cfg_options_appbarondrag(L"Dock Appbars on Window Drag", FALSE); +_int cfg_options_appbardockingdistance(L"Appbars Docking Distance", 5); +#endif + +void invalidateAll(int b) { +#ifdef WASABI_COMPILE_WNDMGR + WASABI_API_WNDMGR->wndTrackInvalidateAll(); +#endif +} + +void onDefaultFontChanged(const wchar_t *attribute) { + Font::uninstallAll(1); + Wasabi::Std::setDefaultFont(cfg_options_defaultfont.getValue()); + invalidateAll(1); +} + +void onOverrideFontChanged(const wchar_t *attribute) { + Font::uninstallAll(1); + invalidateAll(1); +} + +void onDefaultFontScaleChanged(int scale) { + Wasabi::Std::setDefaultFontScale(scale); + invalidateAll(1); +} + +void onOverrideFontScaleChanged(int scale) { + invalidateAll(1); +} + +void onFontRendererChanged(const wchar_t *s) { + Font::uninstallAll(1); + invalidateAll(1); +} + +void onFontMapperChanged(int b) { + Font::uninstallAll(1); + invalidateAll(1); +} + +_bool cfg_audiooptions_crossfader(L"Enable crossfading", DEFAULT_CROSSFADE_ENABLED); +_bool cfg_options_alwaysontop(L"Always on top", FALSE); +_bool cfg_options_docking(L"Enable docking", TRUE); +_int cfg_options_dockingdistance(L"Docking distance", DEFAULT_DOCK_DIST); +_string cfg_options_fontrenderer(L"Font Renderer", WASABI_FONT_RENDERER); +_int cfg_options_freetypecharmap(L"Character mapping", -1); + +Options::Options() : CfgItemI(L"Options", options_guid) +{ +#ifdef _WASABIRUNTIME + registerAttribute(&cfg_options_alwaysontop, new int_attrCB(Main::setOnTop)); +#else + extern void setOnTop(int ontop); + registerAttribute(&cfg_options_alwaysontop, new int_attrCB(setOnTop)); +#endif + /* TODO: benski> move to wndmgr.w5s (or wherever it's final home is */ + registerAttribute(&cfg_options_dockingdistance, new int_attrCB(WindowTracker::setDockDistance)); + registerAttribute(&cfg_options_docking, new int_attrCB(WindowTracker::setEnableDocking)); + /* --- END TO MOVE --- */ + registerAttribute(new _bool(L"Find open rect", FALSE)); + registerAttribute(new _bool(L"Animated rects", TRUE)); + registerAttribute(&cfg_options_fontrenderer, new string_attrCB(onFontRendererChanged)); + registerAttribute(&cfg_options_allowbitmapfonts, new int_attrCB(invalidateAll)); + registerAttribute(&cfg_options_altfonts, new int_attrCB(invalidateAll)); + registerAttribute(&cfg_options_defaultfont, new string_attrCB(onDefaultFontChanged)); + registerAttribute(&cfg_options_ttfoverridefont, new string_attrCB(onOverrideFontChanged)); + registerAttribute(&cfg_options_ttfoverridescale, new int_attrCB(onOverrideFontScaleChanged)); + registerAttribute(&cfg_options_defaultfontscale, new int_attrCB(onDefaultFontScaleChanged)); + registerAttribute(&cfg_options_freetypecharmap, new int_attrCB(invalidateAll)); + registerAttribute(&cfg_options_no7bitsttfoverride, new int_attrCB(invalidateAll)); + registerAttribute(&cfg_options_noalt7bitsttfoverride, new int_attrCB(invalidateAll)); + registerAttribute(&cfg_options_usefontmapper, new int_attrCB(onFontMapperChanged)); +#ifdef USEAPPBAR + registerAttribute(&cfg_options_appbarondrag); + registerAttribute(&cfg_options_appbardockingdistance); +#endif +#ifdef _WASABIRUNTIME + registerAttribute(new _bool(L"Allow multiple instances", FALSE), new int_attrCB(setMultipleInstance)); + registerAttribute(new _int(L"Icon mode", 1), new int_attrCB(Main::setIconMode)); + registerAttribute(new _bool(L"Auto-play at startup", FALSE)); + registerAttribute(new _string(L"Language", "English"), new LanguageCB(this)); +#ifdef WIN32 + registerAttribute(new _bool("Associate with audio CDs", TRUE), new int_attrCB(Filetypes::registerCdPlayer)); +#endif + registerAttribute(new _string("Monitor aspect ratio", "4:3")); + registerAttribute(new _int("Internet connection",3)); //3==autodetect + registerAttribute(&forward_skip_time); + registerAttribute(&reverse_skip_time); +#endif + + //registerAttribute(new _bool("Use Mozilla instead of IE for minibrowser", FALSE)); // TODO:move into minibrowser component +/* registerAttribute(new _bool("Force antialias on all TTF", FALSE));*/ + addChildItem(&audio_options); + addChildItem(&ui_options); +} + +void Options::checkCd() { +#ifdef _WASABIRUNTIME +#ifdef WIN32 + if(getDataAsInt("Associate with audio CDs") && !Filetypes::isCdPlayer()) setDataAsInt("Associate with audio CDs",false); +#endif +#endif +} + +// {FC3EAF78-C66E-4ed2-A0AA-1494DFCC13FF} +static const GUID audio_options_guid = +{ 0xfc3eaf78, 0xc66e, 0x4ed2, { 0xa0, 0xaa, 0x14, 0x94, 0xdf, 0xcc, 0x13, 0xff } }; + +AudioOptions::AudioOptions() : CfgItemI(L"Audio options", audio_options_guid) +{ +#ifdef GEN_FF +#ifdef WASABI_COMPILE_MEDIACORE + extern void setCrossfader(int crossfade); + registerAttribute(&cfg_audiooptions_crossfader, new int_attrCB(setCrossfader)); +#endif +#endif +#ifdef _WASABIRUNTIME + registerAttribute(&cfg_audiooptions_crossfader); + int use_dsound=0; +#ifdef WIN32 + //check for Windows version for whether we make DSOUND default + DWORD dwVersion = GetVersion(); + DWORD dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); + if (dwVersion < 0x80000000) { + if(dwWindowsMajorVersion<=4) use_dsound=0; // no dsound on NT4/3.51 + else use_dsound=1; // dsound yes on 2000/XP + } else + use_dsound=0; // no dsound by default on win9x (per PP) +#endif + registerAttribute(new _bool("DirectSound output", use_dsound)); +#endif +} + +#ifdef _WASABIRUNTIME + +// {C1BD5354-5EC4-406c-B5C0-549718D3AF45} +static const GUID setup_guid = +{ 0xc1bd5354, 0x5ec4, 0x406c, { 0xb5, 0xc0, 0x54, 0x97, 0x18, 0xd3, 0xaf, 0x45 } }; + +SetupOptions::SetupOptions() : CfgItemI("Setup", setup_guid) { +#ifdef WIN32 + addChildItem(&filetypes); +#endif +} + +// {99CFD75C-1CA7-49e5-B8C0-7D78AA443C10} +static const GUID installed_guid = +{ 0x99cfd75c, 0x1ca7, 0x49e5, { 0xb8, 0xc0, 0x7d, 0x78, 0xaa, 0x44, 0x3c, 0x10 } }; + +InstalledComponents::InstalledComponents() : CfgItemI("Installed components", installed_guid) { +//CUT setCfgXml("config.components"); +} + +void LanguageCB::onValueChange(Attribute *attr) { + char bufero[WA_MAX_PATH]=""; + attr->getData(bufero, WA_MAX_PATH-1); + const char *locname; + for(int i=0;locname=LocalesManager::enumLoadableLocales(i);i++) { + if (STRCASEEQLSAFE(bufero, locname)) { + LocalesManager::setNewLocaleNum(i); + return; + } + } + WASABI_API_WNDMGR->messageBox(StringPrintf("Internal problem switching to language %s, the language name couldn't be found in the list of loaded resources", bufero), "Error", 0, NULL, NULL); +} + +#endif diff --git a/Src/Wasabi/api/config/options.h b/Src/Wasabi/api/config/options.h new file mode 100644 index 00000000..c86a7f3a --- /dev/null +++ b/Src/Wasabi/api/config/options.h @@ -0,0 +1,64 @@ +#ifndef _OPTIONS_H +#define _OPTIONS_H + +#include <api/config/items/cfgitemi.h> +#include <api/config/items/attrcb.h> + +//#include <api/config/filetypes.h> +#include <api/config/uioptions.h> + +class Options; + +class _string; +class _int; +class _bool; + +extern _string cfg_options_defaultfont; +extern _int cfg_options_ttfoverridescale; +extern _bool cfg_options_no7bitsttfoverride; +extern _bool cfg_options_allowbitmapfonts; +extern _string cfg_options_fontrenderer; + +#ifdef _WASABIRUNTIME + +class SetupOptions : public CfgItemI { +public: + SetupOptions(); + + Filetypes filetypes; +}; + +class InstalledComponents : public CfgItemI { +public: + InstalledComponents(); +}; +#endif + +class AudioOptions : public CfgItemI { +public: + AudioOptions(); +}; + +#define OPTIONS_PARENT CfgItemI +class Options : public OPTIONS_PARENT { +public: + Options(); + void checkCd(); + + AudioOptions audio_options; + UIOptions ui_options; +}; + +#ifdef _WASABIRUNTIME + +class LanguageCB : public AttrCallback { +public: + LanguageCB(CfgItemI *_par) : par(_par) { } + virtual void onValueChange(Attribute *attr); +private: + CfgItemI *par; +}; + +#endif + +#endif diff --git a/Src/Wasabi/api/config/uioptions.cpp b/Src/Wasabi/api/config/uioptions.cpp new file mode 100644 index 00000000..0ccc33f7 --- /dev/null +++ b/Src/Wasabi/api/config/uioptions.cpp @@ -0,0 +1,109 @@ +#include <precomp.h> + +#include "uioptions.h" + +#include <api/wndmgr/layout.h> + +#include <api/config/items/attribs.h> +#include <api/config/items/attrcb.h> + +#include <api/skin/skinparse.h> +#include <api/wndmgr/alphamgr.h> + +// {9149C445-3C30-4e04-8433-5A518ED0FDDE} +const GUID uioptions_guid = +{ 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } }; + +_bool cfg_uioptions_desktopalpha(L"Enable desktop alpha", DEFAULT_DESKTOPALPHA); +_bool cfg_uioptions_linkratio(L"Link layouts scale", DEFAULT_LINKLAYOUTSCALE); +_bool cfg_uioptions_linkalpha(L"Link layouts alpha", DEFAULT_LINKLAYOUTSALPHA); +_bool cfg_uioptions_linkallalpha(L"Link All layouts alpha", DEFAULT_LINKALLALPHA); +_bool cfg_uioptions_linkallratio(L"Link All layouts scale", DEFAULT_LINKALLRATIO); +_int cfg_uioptions_linkedalpha(L"Linked layouts alpha", DEFAULT_LINKEDALPHA); +_int cfg_uioptions_autoopacitytime(L"Auto Opacity hold time", DEFAULT_AUTOOPACITYTIME); +_int cfg_uioptions_autoopacityfadein(L"Auto Opacity fade in time", DEFAULT_AUTOOPACITYFADEIN); +_int cfg_uioptions_autoopacityfadeout(L"Auto Opacity fade out time", DEFAULT_AUTOOPACITYFADEOUT); +_int cfg_uioptions_autoopacitylinked(L"Use Auto Opacity", DEFAULT_AUTOOPACITYTYPE); +_int cfg_uioptions_extendautoopacity(L"Auto Opacity extend by", DEFAULT_EXTENDAUTOOPACITY); +_bool cfg_uioptions_uselocks(L"Use layout scale locks", DEFAULT_USERATIOLOCKS); +_int cfg_uioptions_timerresolution(L"Multiplexed timers resolution", DEFAULT_TIMERRESOLUTION); +_bool cfg_uioptions_tooltips(L"Enable tooltips", DEFAULT_TOOLTIPS); +_float cfg_uioptions_textspeed(L"Text Ticker Speed", DEFAULT_TEXTSPEED); +_int cfg_uioptions_textincrement(L"Text Ticker Increment", DEFAULT_TEXTINCREMENT); +_int cfg_uioptions_appbarshidetime(L"Appbar Hide Time", DEFAULT_APPBARHIDETIME); +_int cfg_uioptions_appbarsshowtime(L"Appbar Show Time", DEFAULT_APPBARSHOWTIME); + +void onSetOpacityTime(int n) { + Layout *l = SkinParser::getMainLayout(); + if (l) l->getAlphaMgr()->setHoldTime(n); +} + +void onSetOpacityFadeIn(int n) { + Layout *l = SkinParser::getMainLayout(); + if (l) l->getAlphaMgr()->setFadeInTime(n); +} + +void onSetOpacityFadeOut(int n) { + Layout *l = SkinParser::getMainLayout(); + if (l) l->getAlphaMgr()->setFadeOutTime(n); +} + +void onSetAllRatio(int on) { + if (on) { + Layout *l = SkinParser::getMainLayout(); + if (l) l->setRenderRatio(l->getRenderRatio()); + } +} + +void onSetAllAlpha(int on) { + Layout *l = SkinParser::getMainLayout(); + if (l) l->getAlphaMgr()->setAllLinked(on); +} + +void onSetLinkedAlpha(int a) { + Layout *l = SkinParser::getMainLayout(); + if (l) l->getAlphaMgr()->setGlobalAlpha(a); +} + +void onSetLinkedAuto100(int v) { + Layout *l = SkinParser::getMainLayout(); + if (l) l->getAlphaMgr()->setAutoOpacify(v); +} + +void onSetExtendAutoOpacity(int v) { + Layout *l = SkinParser::getMainLayout(); + if (l) l->getAlphaMgr()->setExtendAutoOpacity(v); +} + +UIOptions::UIOptions(const wchar_t *name) : CfgItemI(name ? name : L"Skins and UI Tweaks", uioptions_guid) +{ + registerAttribute(&cfg_uioptions_linkratio); + registerAttribute(&cfg_uioptions_linkalpha); + registerAttribute(&cfg_uioptions_uselocks); + registerAttribute(&cfg_uioptions_autoopacitylinked, new int_attrCB(onSetLinkedAuto100)); + registerAttribute(&cfg_uioptions_linkallratio, new int_attrCB(onSetAllRatio)); + registerAttribute(&cfg_uioptions_linkallalpha, new int_attrCB(onSetAllAlpha)); + registerAttribute(&cfg_uioptions_desktopalpha, new int_attrCB(Layout::onGlobalEnableDesktopAlpha)); + registerAttribute(&cfg_uioptions_linkedalpha, new int_attrCB(onSetLinkedAlpha)); + registerAttribute(&cfg_uioptions_tooltips); + registerAttribute(&cfg_uioptions_timerresolution); + registerAttribute(&cfg_uioptions_textspeed); + registerAttribute(&cfg_uioptions_textincrement); + registerAttribute(&cfg_uioptions_appbarshidetime); + registerAttribute(&cfg_uioptions_appbarsshowtime); + registerAttribute(&cfg_uioptions_autoopacitytime, new int_attrCB(onSetOpacityTime)); + registerAttribute(&cfg_uioptions_autoopacityfadein, new int_attrCB(onSetOpacityFadeIn)); + registerAttribute(&cfg_uioptions_autoopacityfadeout, new int_attrCB(onSetOpacityFadeOut)); + registerAttribute(&cfg_uioptions_extendautoopacity, new int_attrCB(onSetExtendAutoOpacity)); + registerAttribute(new _int(L"Timer refresh rate", 30), new int_attrCB(onTimerRefreshRate)); + registerAttribute(new _int(L"Popup menu alpha", 240)); + registerAttribute(new _int(L"Spectrum analyzer mode",1)); +} + +void UIOptions::onTimerRefreshRate(int rate) { + if(rate==0 || rate<9 || rate>70) return; + int res=1000/rate; + CfgItem *ci=WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid); + if(!ci) return; + ci->setDataAsInt(L"Multiplexed timers resolution",res); +} diff --git a/Src/Wasabi/api/config/uioptions.h b/Src/Wasabi/api/config/uioptions.h new file mode 100644 index 00000000..bf2cb963 --- /dev/null +++ b/Src/Wasabi/api/config/uioptions.h @@ -0,0 +1,13 @@ +#ifndef _UIOPTIONS_H +#define _UIOPTIONS_H + +#include <api/config/items/cfgitemi.h> + +#define UIOPTIONS_PARENT CfgItemI +class UIOptions : public UIOPTIONS_PARENT { +public: + UIOptions(const wchar_t *name=NULL); + static void onTimerRefreshRate(int rate); +}; + +#endif |